Fix telegram watcher (#354)

* Update telegram_watcher.py

It is used "startswith()" to check if the text start with  "/start".
"filter()" instead of "get()" to avoid an exception if there is no profile asociated with a token.
"attempts -= 1" instead of "attempts = attempts - 1"
An "error.log" file is created if "response = self.session.get" does not work

* Update telegram_watcher.py

Added instructions for the user if the format is not correct

* Update telegram_watcher.py

* Update telegram_watcher.py

* Update telegram_watcher.py

* Update telegram_watcher.py

* Update telegram_watcher.py

* Fix bugs

---------

Co-authored-by: Kote <45825337+Gravity2106@users.noreply.github.com>
This commit is contained in:
Reckless_Satoshi 2023-02-13 12:41:06 +00:00 committed by GitHub
parent 88bb58bcb6
commit 1c696beb5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 39 deletions

View File

@ -1,7 +1,9 @@
import time import time
import traceback
from decouple import config from decouple import config
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.db import transaction
from api.messages import Telegram from api.messages import Telegram
from api.models import Profile from api.models import Profile
@ -15,42 +17,57 @@ class Command(BaseCommand):
bot_token = config("TELEGRAM_TOKEN") bot_token = config("TELEGRAM_TOKEN")
updates_url = f"https://api.telegram.org/bot{bot_token}/getUpdates" updates_url = f"https://api.telegram.org/bot{bot_token}/getUpdates"
session = get_session() session = get_session()
telegram = Telegram() telegram = Telegram()
def handle(self, *args, **options): def handle(self, *args, **options):
"""Infinite loop to check for telegram updates.
If it finds a new user (/start), enables it's taker found
notification and sends a 'Hey {username} {order_id}' message back"""
offset = 0 offset = 0
while True: while True:
time.sleep(self.rest) time.sleep(self.rest)
params = {"offset": offset + 1, "timeout": 5} params = {"offset": offset + 1, "timeout": 5}
try:
response = self.session.get(self.updates_url, params=params)
if response.status_code != 200:
with open("error.log", "a") as f:
f.write(
f"Error getting updates, status code: {response.status_code}\n"
)
continue
response = response.json()
response = self.session.get(self.updates_url, params=params).json() response = self.session.get(self.updates_url, params=params).json()
if len(list(response["result"])) == 0: except Exception as e:
with open("error.log", "a") as f:
f.write(f"Error getting updates: {e}\n{traceback.format_exc()}\n")
continue
if not response["result"]:
continue continue
for result in response["result"]: for result in response["result"]:
if not result.get("message") or not result.get("message").get("text"):
try: # if there is no key message, skips this result.
text = result["message"]["text"]
except Exception:
continue continue
message = result["message"]["text"]
splitted_text = text.split(" ") if not message or not message.startswith("/start"):
if splitted_text[0] == "/start": continue
token = splitted_text[-1] parts = message.split(" ")
try: if len(parts) < 2:
profile = Profile.objects.get(telegram_token=token) self.telegram.send_message(
except Exception: chat_id=result["message"]["from"]["id"],
print(f"No profile with token {token}") text='You must enable the notifications bot using the RoboSats client. Click on your "Robot profile" -> "Enable Telegram" and follow the link or scan the QR code.',
)
continue
token = parts[-1]
profile = Profile.objects.filter(telegram_token=token).first()
if not profile:
self.telegram.send_message(
chat_id=result["message"]["from"]["id"],
text=f'Wops, invalid token! There is no Robot with telegram chat token "{token}"',
)
continue continue
attempts = 5 attempts = 5
while attempts >= 0: while attempts >= 0:
try: try:
with transaction.atomic():
profile.telegram_chat_id = result["message"]["from"]["id"] profile.telegram_chat_id = result["message"]["from"]["id"]
profile.telegram_lang_code = result["message"]["from"][ profile.telegram_lang_code = result["message"]["from"][
"language_code" "language_code"
@ -61,6 +78,5 @@ class Command(BaseCommand):
break break
except Exception: except Exception:
time.sleep(5) time.sleep(5)
attempts = attempts - 1 attempts -= 1
offset = response["result"][-1]["update_id"] offset = response["result"][-1]["update_id"]

View File

@ -29,12 +29,11 @@ class Telegram:
return context return context
def send_message(self, user, text): def send_message(self, chat_id, text):
"""sends a message to a user with telegram notifications enabled""" """sends a message to a user with telegram notifications enabled"""
bot_token = config("TELEGRAM_TOKEN") bot_token = config("TELEGRAM_TOKEN")
chat_id = user.profile.telegram_chat_id
message_url = f"https://api.telegram.org/bot{bot_token}/sendMessage?chat_id={chat_id}&text={text}" message_url = f"https://api.telegram.org/bot{bot_token}/sendMessage?chat_id={chat_id}&text={text}"
# if it fails, it should keep trying # if it fails, it should keep trying
@ -53,7 +52,7 @@ class Telegram:
text = f"Hola {user.username}, te enviaré notificaciones sobre tus órdenes en RoboSats." text = f"Hola {user.username}, te enviaré notificaciones sobre tus órdenes en RoboSats."
else: else:
text = f"Hey {user.username}, I will send you notifications about your RoboSats orders." text = f"Hey {user.username}, I will send you notifications about your RoboSats orders."
self.send_message(user, text) self.send_message(user.profile.telegram_chat_id, text)
user.profile.telegram_welcomed = True user.profile.telegram_welcomed = True
user.profile.save() user.profile.save()
return return
@ -65,7 +64,7 @@ class Telegram:
text = f"Hey {order.maker.username} ¡Tu orden con ID {order.id} ha sido tomada por {order.taker.username}!🥳 Visita http://{self.site}/order/{order.id} para continuar." text = f"Hey {order.maker.username} ¡Tu orden con ID {order.id} ha sido tomada por {order.taker.username}!🥳 Visita http://{self.site}/order/{order.id} para continuar."
else: else:
text = f"Hey {order.maker.username}, your order was taken by {order.taker.username}!🥳 Visit http://{self.site}/order/{order.id} to proceed with the trade." text = f"Hey {order.maker.username}, your order was taken by {order.taker.username}!🥳 Visit http://{self.site}/order/{order.id} to proceed with the trade."
self.send_message(order.maker, text) self.send_message(order.maker.profile.telegram_chat_id, text)
if order.taker.profile.telegram_enabled: if order.taker.profile.telegram_enabled:
lang = order.taker.profile.telegram_lang_code lang = order.taker.profile.telegram_lang_code
@ -73,7 +72,7 @@ class Telegram:
text = f"Hey {order.taker.username}, acabas de tomar la orden con ID {order.id}." text = f"Hey {order.taker.username}, acabas de tomar la orden con ID {order.id}."
else: else:
text = f"Hey {order.taker.username}, you just took the order with ID {order.id}." text = f"Hey {order.taker.username}, you just took the order with ID {order.id}."
self.send_message(order.taker, text) self.send_message(order.taker.profile.telegram_chat_id, text)
return return
@ -85,7 +84,7 @@ class Telegram:
text = f"Hey {user.username}, el depósito de garantía y el recibo del comprador han sido recibidos. Es hora de enviar el dinero fiat. Visita http://{self.site}/order/{order.id} para hablar con tu contraparte." text = f"Hey {user.username}, el depósito de garantía y el recibo del comprador han sido recibidos. Es hora de enviar el dinero fiat. Visita http://{self.site}/order/{order.id} para hablar con tu contraparte."
else: else:
text = f"Hey {user.username}, the escrow and invoice have been submitted. The fiat exchange starts now via the platform chat. Visit http://{self.site}/order/{order.id} to talk with your counterpart." text = f"Hey {user.username}, the escrow and invoice have been submitted. The fiat exchange starts now via the platform chat. Visit http://{self.site}/order/{order.id} to talk with your counterpart."
self.send_message(user, text) self.send_message(user.profile.telegram_chat_id, text)
return return
def order_expired_untaken(self, order): def order_expired_untaken(self, order):
@ -95,7 +94,7 @@ class Telegram:
text = f"Hey {order.maker.username}, tu orden con ID {order.id} ha expirado sin ser tomada por ningún robot. Visita http://{self.site}/order/{order.id} para renovarla." text = f"Hey {order.maker.username}, tu orden con ID {order.id} ha expirado sin ser tomada por ningún robot. Visita http://{self.site}/order/{order.id} para renovarla."
else: else:
text = f"Hey {order.maker.username}, your order with ID {order.id} has expired without a taker. Visit http://{self.site}/order/{order.id} to renew it." text = f"Hey {order.maker.username}, your order with ID {order.id} has expired without a taker. Visit http://{self.site}/order/{order.id} to renew it."
self.send_message(order.maker, text) self.send_message(order.maker.profile.telegram_chat_id, text)
return return
def trade_successful(self, order): def trade_successful(self, order):
@ -106,7 +105,7 @@ class Telegram:
text = f"¡Tu orden con ID {order.id} ha finalizado exitosamente!⚡ Únete a nosotros en @robosats_es y ayúdanos a mejorar." text = f"¡Tu orden con ID {order.id} ha finalizado exitosamente!⚡ Únete a nosotros en @robosats_es y ayúdanos a mejorar."
else: else:
text = f"Your order with ID {order.id} has finished successfully!⚡ Join us @robosats and help us improve." text = f"Your order with ID {order.id} has finished successfully!⚡ Join us @robosats and help us improve."
self.send_message(user, text) self.send_message(user.profile.telegram_chat_id, text)
return return
def public_order_cancelled(self, order): def public_order_cancelled(self, order):
@ -116,7 +115,7 @@ class Telegram:
text = f"Hey {order.maker.username}, has cancelado tu orden pública con ID {order.id}." text = f"Hey {order.maker.username}, has cancelado tu orden pública con ID {order.id}."
else: else:
text = f"Hey {order.maker.username}, you have cancelled your public order with ID {order.id}." text = f"Hey {order.maker.username}, you have cancelled your public order with ID {order.id}."
self.send_message(order.maker, text) self.send_message(order.maker.profile.telegram_chat_id, text)
return return
def collaborative_cancelled(self, order): def collaborative_cancelled(self, order):
@ -127,7 +126,7 @@ class Telegram:
text = f"Hey {user.username}, tu orden con ID {str(order.id)} fue cancelada colaborativamente." text = f"Hey {user.username}, tu orden con ID {str(order.id)} fue cancelada colaborativamente."
else: else:
text = f"Hey {user.username}, your order with ID {str(order.id)} has been collaboratively cancelled." text = f"Hey {user.username}, your order with ID {str(order.id)} has been collaboratively cancelled."
self.send_message(user, text) self.send_message(user.profile.telegram_chat_id, text)
return return
def dispute_opened(self, order): def dispute_opened(self, order):
@ -138,7 +137,7 @@ class Telegram:
text = f"Hey {user.username}, la orden con ID {str(order.id)} ha entrado en disputa." text = f"Hey {user.username}, la orden con ID {str(order.id)} ha entrado en disputa."
else: else:
text = f"Hey {user.username}, a dispute has been opened on your order with ID {str(order.id)}." text = f"Hey {user.username}, a dispute has been opened on your order with ID {str(order.id)}."
self.send_message(user, text) self.send_message(user.profile.telegram_chat_id, text)
return return
def order_published(self, order): def order_published(self, order):
@ -153,5 +152,5 @@ class Telegram:
text = f"Hey {order.maker.username}, tu orden con ID {str(order.id)} es pública en el libro de ordenes." text = f"Hey {order.maker.username}, tu orden con ID {str(order.id)} es pública en el libro de ordenes."
else: else:
text = f"Hey {order.maker.username}, your order with ID {str(order.id)} is public in the order book." text = f"Hey {order.maker.username}, your order with ID {str(order.id)} is public in the order book."
self.send_message(order.maker, text) self.send_message(order.maker.profile.telegram_chat_id, text)
return return