Own Telegram bot for tracking uptime of its servers in python and docker

1. We make a telegram bot



First you need to write a bot that will ping the necessary ip and send a message when the desired service disappears from the network, and then appears







I understand that for the habr resource, the article is quite simple, and besides, I did not try to paint every line of code, because all the code is simple enough for beginners to understand. I decided to share how easy it is to make your bot in the docker, which will do useful work.



1.1 How to store a config



I decided to store the config as a yaml file.



botid:  userid: id_,    hosts: - "8.8.8.8:Google DNS Server" - "yandex.ru:Yandex domain name"
      
      





In order, botid is the token that @botfather issues when creating a new bot.



userid is the id of the telegram user who will receive messages from the bot in the chat. Can be obtained using @userinfobot



hosts are those services that the bot will ping. You can specify both an ip address and a domain name. The comment on the address is indicated through a colon, this comment will be substituted in the message instead of the address.



1.2 The script itself



First, create a class for the host.



 class address: def __init__ (self, address, comment): self.address = address self.comment = comment self.status = True
      
      





address is an ip or domain name.

comment - comment from the yaml file.

status - on the network host or not. The default is online.



Script



 from telegram import Bot from pythonping import ping import time import yaml from libs.host import address def init(): """       ,  userid      set_hosts """ global bot, userid with open('/usr/src/app/config.yaml') as f: try: docs = yaml.load_all(f, Loader=yaml.FullLoader) for doc in docs: for k, v in doc.items(): if k == "botid": bot = Bot(v) elif k == "userid": userid = v elif k == "hosts": set_hosts(v) except yaml.YAMLError as exc: print(exc) def set_hosts(hosts): """          """ global hosts_list hosts_list = [] for item in hosts: ac = item.split(":") hosts_list.append(address(ac[0], ac[1])) def send_message(message): """    """ bot.send_message(userid, message, parse_mode='HTML', disable_web_page_preview=True) def ping_host(address): """  .     .    ,          .      ,       . """ if ping_url(address.address): if not address.status: address.status = True send_message(address.comment + " is up again") else: if (address.status): address.status = False send_message(address.comment + " is down") def ping_url(url): """  . Response list -    ping.      .    ,    . """ i = 0; try: response_list = ping(url) for response in response_list: if (not response.success): i += 1 if (i == 4): return False else: return True except Exception as e: send_message(str(e)) def main(): """  .  ,      . """ init() while True: for host in hosts_list: ping_host(host) time.sleep(30) if __name__ == '__main__': main()
      
      





Putting the docker image together



How to install docker and docker-compose I wrote in this article.



Need to create a dockerfile. Next to the code folder, put the source code of the bot.



 FROM python:buster RUN pip3 install python-telegram-bot pythonping pyyaml WORKDIR /usr/src/app COPY ./code/. . ENTRYPOINT ["python"] CMD ["main.py"]
      
      





We connect the docker image from the official python repository. Install the libraries. Set the current folder to / usr / src / app. Copy the code to this folder. The utility called at startup will be python. CMD passes the parameter to run - main.py.



Next, you need to collect the image and put it in the repository



 docker build -t alsoeast/pingbot:1.0 . docker push alsoeast/pingbot:1.0
      
      





To run docker images, I use docker-compose.



 version: '3' networks: default: external: name: network services: pingbot: container_name: pingbot image: alsoeast/pingbot:1.0 restart: always volumes: - ./config.yaml:/usr/src/app/config.yaml
      
      





The image is taken from the repository, the config.yaml file is mounted so that the script can receive the arguments. It remains only to run



 docker-compose up -d
      
      





If anyone needs it, the bot is available on the docker hub.



UPD: a new version of 1.1 or latest image is uploaded to docker hub. In the configuration file, the botid parameter changed to botkey, the optional interval parameter was added



All Articles