Python telegram bot 🤖Оповещение об изменении баланса на криптобирже

Python Telegram bot и оповещение об изменении баланса Poloniex

Все подробности можно узнать из видео, которое закреплено снизу статьи, а нас тут больше интересует код и его разбор.

Приступим.

Создаем папку и в ней 4 файла:

  • В config.py будем держать данные по телеграмм боту, poloniex ключам и данным для подключения к базе;
  • mysql.py будет содержать все функции для работы с базой данных;
  • poloniex.py главный файл, который будет парсить API биржи и делать вообще все, что нам нужно;
  • send_status.py содержит функцию для отправки сообщения в telegram.

Составляем файл конфигураций.

Открываем config.py и вписываем:

exch_host = 'IP ADDRESS'
exch_user = 'USER'
exch_passwd = 'PASS'
exch_db = 'DATABASE'
exch_base_info = [exch_host, exch_user, exch_passwd, exch_db]

poloniex_key = 'POLO KEY'
poloniex_sign = b'POLO SECRET'

token_dev = 'TELEGRAM BOT KEY'
  • По первым четырем строкам вроде понятно что нужно указывать — IP ADDRESS сервера, где крутится mysql
  • к нему USER и PASS
  • DATABASE выбираем какую создали (о поднятии сервера можно почитать в моей статье и посмотреть видеоролик )
  • poloniex_key и poloniex_sign берутся из личного кабинета Poloniex
  • token_dev берем при создании бота

Функция отправки сообщения.

import requests
import time
from config import token
url = "https://api.telegram.org/bot{0}/sendMessage".format(token)
def message_user(message_text, chat_id):
message_data = {
'chat_id': chat_id,
'text': message_text,
'parse_mode':'HTML'
}
requests.post(url, data=message_data)
def main():
message_dev('asdasd')
if name == "main":
main()

Ничего сложного. В документации Telegram API написано, чтобы отправить сообщение, нужно обратиться к методу sendMessage (который у нас в url — https://api.telegram.org/bot{0}/sendMessage), при этом не забыв вставить свой ключ telegram бота. Обязательные параметры при отправке это chat_id и text. Если с TEXT все понятно, то где достать chat_id ? Для этого есть метод getUpdates. Запрос вернет нам всю информацию об отправителе сообщения. В качестве домашнего задания узнайте свой chat_id.

Файл mysql.py

import pymysql
import time, re
#импорт наших настроек для подключения из файла config
from config import exch_base_info

# создаем класс, который будет отвечать за все операции с базой данных
class sql_db:
def init(self):
#пробуем подключиться к базе
try:
self.conn = pymysql.connect(*exch_base_info, use_unicode=True, charset='utf8')
except pymysql.OperationalError:
print("can't find base")
try:
self.cursor = self.conn.cursor()
except pymysql.OperationalError:
print("can't get cursor")
#функция для выборки данных из нашей таблички
def select_all(self):
try:
self.cursor.execute("SELECT * FROM poloniex")
except pymysql.Error:
print("can't select poloniex")
result = self.cursor.fetchall()
#если данных в базе нет, то возвращаем False (0)
if len(result) <= 0:
return False
else:
# если данные есть, то делаем из них словарь, чтобы потом было проще работать
data = {}
for i in result:
data.update({i[1]:i[2]})
return data
# функция для вставки данных в таблицу poloniex
def insert_coin(self, coin, value):
try:
self.cursor.execute("INSERT INTO poloniex (name_coin, coin_value) values ('{0}', {1})".format(coin, value))
except pymysql.Error:
print("can't insert coins poloniex")
self.conn.commit()
# обновление данных в таблице poloniex
def update_value(self, coin, value):
try:
self.cursor.execute("UPDATE poloniex set coin_value={1} where name_coin='{0}'".format(coin, value))
except pymysql.Error:
print("can't update poloniex value")
self.conn.commit()
def main():
pass
if name == "main":
main()

Итак! Самое интересное. Создаем класс sql_db, который будет отвечать за подключение к базе и делать разные запросы. Не буду описывать детально каждый блок, комментариями я все обозначил и в ролике рассказал. В классе происходит подключение к базе данных с помощью наших данных из файла config. Вызываются нужные функции и происходит магия выборки \ записи \ обновления данных в базу и из базы данных.

Основной блок программы.

import requests, json
from config import poloniex_key, poloniex_sign, chat_id
import hmac, hashlib
import urllib
import time
from mysql import sql_db
from send_status import message_user

def api_query(command, req={}):
req['command'] = command
req['nonce'] = int(time.time()*1000)
post_data = urllib.parse.urlencode(req)
sign = hmac.new(poloniex_sign, post_data.encode('utf-8'), hashlib.sha512).hexdigest()
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Key': poloniex_key,
'Sign': sign
}
with requests.Session() as s:
api = s.post('https://poloniex.com/tradingApi', data=post_data, headers=headers)
data = json.loads(api.text) return data

def public_method(command):
url = 'https://poloniex.com/public?command={0}'.format(command)
api = requests.post(url, data=command)
data = json.loads(api.text)
return data

def main():
select_all_coins = sql_db().select_all()
#возвращает связку USDT-BTC на Poloniex
last = public_method('returnTicker')
for i in last.keys():
if 'USDT_BTC' in i:
print('Poloniex : ', last[i]['last'])
#Возвращает баланс с Poloniex. (не забудьте добавить свой ключ и секрет в файле config.py)
balance = api_query('returnBalances')
# проверяем у нас новая база или нет, если да, то записываем значения if select_all_coins == False:
for i in balance.items():
if i[1] != '0.00000000':
sql_db().insert_coin(i[0], i[1])
print(i[0], ': \n\t', i[1] )
# если не пустая, то нужно проверить что у нас в базе
else:
for i in balance.items():
if i[1] != '0.00000000': # проверяем баланс на нулевой
if i[0] not in select_all_coins.keys(): # если имя монеты не найдено в базе, то добавляем запись
sql_db().insert_coin(i[0], i[1])
else:
if float(select_all_coins[i[0]]) != float(i[1]):
message_user("Изменение баланса по монете <b>{0}</b>".format(i[0]), chat_id)
sql_db().update_value(i[0], i[1])
if name == 'main':
main()

Про первую половину этого текста я уже рассказывал когда то давно на видео. Поэтому нас интересует только то, что находится в функции main.

  • select_all_coins = sql_db().select_all() содержит выборку из нашей базы данных (даже если данных нет, то значение False все равно записывается)
  • balance = api_query(‘returnBalances’) вытаскиваем данные с биржи (с личного кабинета) при помощи метода
    returnBalances. Все методы можно глянуть здесь

Далее логика простая:

  • если в базе нет данных (!!!), то проверяем баланс монеты, чтобы он был не нулевой и записываем в базу
  • если же в базе есть данные, то нужно так же сначала проверить баланс на ноль и после этого сверить, есть ли в нашей базе запись с такой монетой — если нет записи, то записываем, а если есть, то нужно сравнить значение (баланс) и если значения отличаются, то обновить данные в базе по этой записи

Переменные в строчке float(select_all_coins[i[0]]) != float(i[1]) специально переопределяются как float, чтобы избежать различных проблем при сравнении данных. Например из базы может быть извлечена запись в виде строки, а не числа.

Весь код полностью рабочий, его можно скопировать, вставить свои данные и запустить. Правда при копировании с сайта скорее всего будет много ошибок, связанных с отступами, поэтому копируйте блочно и правьте =)

Все файлы и код можно посмотреть и скачать с github.

Если есть вопросы, то пишите на форум, в раздел «программирование».

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Отправить ответ

avatar
  Subscribe  
Уведомить