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 traceback
from decouple import config
from django.core.management.base import BaseCommand
from django.db import transaction
from api.messages import Telegram
from api.models import Profile
@ -15,42 +17,57 @@ class Command(BaseCommand):
bot_token = config("TELEGRAM_TOKEN")
updates_url = f"https://api.telegram.org/bot{bot_token}/getUpdates"
session = get_session()
telegram = Telegram()
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
while True:
time.sleep(self.rest)
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()
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
for result in response["result"]:
try: # if there is no key message, skips this result.
text = result["message"]["text"]
except Exception:
if not result.get("message") or not result.get("message").get("text"):
continue
splitted_text = text.split(" ")
if splitted_text[0] == "/start":
token = splitted_text[-1]
try:
profile = Profile.objects.get(telegram_token=token)
except Exception:
print(f"No profile with token {token}")
message = result["message"]["text"]
if not message or not message.startswith("/start"):
continue
parts = message.split(" ")
if len(parts) < 2:
self.telegram.send_message(
chat_id=result["message"]["from"]["id"],
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
attempts = 5
while attempts >= 0:
try:
with transaction.atomic():
profile.telegram_chat_id = result["message"]["from"]["id"]
profile.telegram_lang_code = result["message"]["from"][
"language_code"
@ -61,6 +78,5 @@ class Command(BaseCommand):
break
except Exception:
time.sleep(5)
attempts = attempts - 1
attempts -= 1
offset = response["result"][-1]["update_id"]

View File

@ -29,12 +29,11 @@ class Telegram:
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"""
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}"
# 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."
else:
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.save()
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."
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."
self.send_message(order.maker, text)
self.send_message(order.maker.profile.telegram_chat_id, text)
if order.taker.profile.telegram_enabled:
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}."
else:
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
@ -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."
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."
self.send_message(user, text)
self.send_message(user.profile.telegram_chat_id, text)
return
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."
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."
self.send_message(order.maker, text)
self.send_message(order.maker.profile.telegram_chat_id, text)
return
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."
else:
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
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}."
else:
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
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."
else:
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
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."
else:
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
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."
else:
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