Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Telegram notifications for order takers #244

Merged
merged 4 commits into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions api/logics.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ def take(cls, order, user, amount=None):
order.expires_at = timezone.now() + timedelta(
seconds=order.t_to_expire(Order.Status.TAK))
order.save()
# send_message.delay(order.id,'order_taken') # Too spammy
return True, None

def is_buyer(order, user):
Expand Down Expand Up @@ -315,7 +314,6 @@ def order_expires(cls, order):
elif order.status == Order.Status.TAK:
cls.cancel_bond(order.taker_bond)
cls.kick_taker(order)
# send_message.delay(order.id,'taker_expired_b4bond') # Too spammy
return True

elif order.status == Order.Status.WF2:
Expand Down Expand Up @@ -882,7 +880,6 @@ def cancel_order(cls, order, user, state=None):
# adds a timeout penalty
cls.cancel_bond(order.taker_bond)
cls.kick_taker(order)
# send_message.delay(order.id,'taker_canceled_b4bond') # too spammy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of leaving commented code, do you want to just check how it goes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree,

I had commented out this line long time ago. I was not sure the solution we found was good enough. But now that I revisited this file, I think it's clear the solution worked out and it is time to delete this commented code, forever (actually, this PR also deletes the function this line is calling to) :D

return True, None

# 4) When taker or maker cancel after bond (before escrow)
Expand Down
244 changes: 94 additions & 150 deletions api/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Telegram():
''' Simple telegram messages by requesting to API'''

session = get_session()
site = config('HOST_NAME')

def get_context(user):
"""returns context needed to enable TG notifications"""
Expand Down Expand Up @@ -41,188 +42,131 @@ def send_message(self, user, text):
return
except:
pass

def welcome(self, user):
''' User enabled Telegram Notifications'''
lang = user.profile.telegram_lang_code

# In weird cases the order cannot be found (e.g. it is cancelled)
queryset = Order.objects.filter(maker=user)
order = queryset.last()

print(str(order.id))
if lang == 'es':
text = f'Hola {user.username}, te enviaré un mensaje cuando tu orden con ID {str(order.id)} haya sido tomada.'
text = f'Hola {user.username}, te enviaré notificaciones sobre tus órdenes en RoboSats.'
else:
text = f"Hey {user.username}, I will send you a message when someone takes your order with ID {str(order.id)}."
text = f"Hey {user.username}, I will send you notifications about your RoboSats orders."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not for this PR but probably it's worth it to include also i18n on the backend https://github.com/danhper/python-i18n

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, agree. There is no internationalization implemented on the backend yet, but would be very useful for the Telegram messages.

self.send_message(user, text)
user.profile.telegram_welcomed = True
user.profile.save()
return

def order_taken(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return
# def welcome(self, user):
# lang = user.profile.telegram_lang_code

# # In weird cases the order cannot be found (e.g. it is cancelled)
# queryset = Order.objects.filter(maker=user)
# order = queryset.last()

# print(str(order.id))
# if lang == 'es':
# text = f'Hola {user.username}, te enviaré un mensaje cuando tu orden con ID {str(order.id)} haya sido tomada.'
# else:
# text = f"Hey {user.username}, I will send you a message when someone takes your order with ID {str(order.id)}."
# self.send_message(user, text)
# user.profile.telegram_welcomed = True
# user.profile.save()
# return

lang = user.profile.telegram_lang_code
taker_nick = order.taker.username
site = config('HOST_NAME')
if lang == 'es':
text = f'Hey {order.maker.username} ¡Tu orden con ID {order.id} ha sido tomada por {taker_nick}!🥳 Visita http://{site}/order/{order.id} para continuar.'
else:
text = f'Hey {order.maker.username}, your order was taken by {taker_nick}!🥳 Visit http://{site}/order/{order.id} to proceed with the trade.'

self.send_message(user, text)
return

def order_taken_confirmed(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return
if order.maker.profile.telegram_enabled:
lang = order.maker.profile.telegram_lang_code
if lang == 'es':
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)

if order.taker.profile.telegram_enabled:
lang = order.taker.profile.telegram_lang_code
if lang == 'es':
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)

lang = user.profile.telegram_lang_code
taker_nick = order.taker.username
site = config('HOST_NAME')
if lang == 'es':
text = f'Hey {order.maker.username} ¡Tu orden con ID {order.id} ha sido tomada por {taker_nick}!🥳 El tomador ya ha bloqueado su fianza. Visita http://{site}/order/{order.id} para continuar.'
else:
text = f'Hey {order.maker.username}, your order with ID {order.id} was taken by {taker_nick}!🥳 The taker bond has already been locked. Visit http://{site}/order/{order.id} to proceed with the trade.'

self.send_message(user, text)
return

def fiat_exchange_starts(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return

lang = user.profile.telegram_lang_code
site = config('HOST_NAME')
if lang == 'es':
text = f'Hey {order.maker.username}, el depósito de garantía y el recibo del comprador han sido recibidos. Es hora de enviar el dinero fiat. Visita http://{site}/order/{order.id} para hablar con tu contraparte.'
else:
text = f'Hey {order.maker.username}, the escrow and invoice have been submitted. The fiat exchange starts now via the platform chat. Visit http://{site}/order/{order.id} to talk with your counterpart.'

self.send_message(user, text)
for user in [order.maker, order.taker]:
if user.profile.telegram_enabled:
lang = user.profile.telegram_lang_code
if lang == 'es':
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)
return

def order_expired_untaken(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return

lang = user.profile.telegram_lang_code
site = config('HOST_NAME')
if lang == 'es':
text = f'Hey {order.maker.username}, tu orden con ID {order.id} ha expirado sin ser tomada por ningún robot. Visita http://{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://{site}/order/{order.id} to renew it.'

self.send_message(user, text)
if order.maker.profile.telegram_enabled:
lang = order.maker.profile.telegram_lang_code
if lang == 'es':
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)
return

def trade_successful(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return

lang = user.profile.telegram_lang_code
if lang == 'es':
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)
for user in [order.maker, order.taker]:
if user.profile.telegram_enabled:
lang = user.profile.telegram_lang_code
if lang == 'es':
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)
return

def public_order_cancelled(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return

lang = user.profile.telegram_lang_code
if lang == 'es':
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(user, text)
return

def taker_canceled_b4bond(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return

lang = user.profile.telegram_lang_code
if lang == 'es':
text = f'Hey {order.maker.username}, el tomador ha cancelado antes de bloquear su fianza.'
else:
text = f'Hey {order.maker.username}, the taker has canceled before locking the bond.'

self.send_message(user, text)
return

def taker_expired_b4bond(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return

lang = user.profile.telegram_lang_code
if lang == 'es':
text = f'Hey {order.maker.username}, el tomador no ha bloqueado la fianza a tiempo.'
else:
text = f'Hey {order.maker.username}, the taker has not locked the bond in time.'

self.send_message(user, text)
if order.maker.profile.telegram_enabled:
lang = order.maker.profile.telegram_lang_code
if lang == 'es':
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)
return

def collaborative_cancelled(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return

lang = user.profile.telegram_lang_code
if lang == 'es':
text = f'Hey {order.maker.username}, tu orden con ID {str(order.id)} fue cancelada colaborativamente.'
else:
text = f'Hey {order.maker.username}, your order with ID {str(order.id)} has been collaboratively cancelled.'

self.send_message(user, text)
for user in [order.maker, order.taker]:
if user.profile.telegram_enabled:
lang = user.profile.telegram_lang_code
if lang == 'es':
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)
return

def dispute_opened(self, order):
user = order.maker
if not user.profile.telegram_enabled:
return

lang = user.profile.telegram_lang_code
if lang == 'es':
text = f'Hey {order.maker.username}, la orden con ID {str(order.id)} ha entrado en disputa.'
else:
text = f'Hey {order.maker.username}, a dispute has been opened on your order with ID {str(order.id)}.'

self.send_message(user, text)
for user in [order.maker, order.taker]:
if user.profile.telegram_enabled:
lang = user.profile.telegram_lang_code
if lang == 'es':
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)
return

def order_published(self, order):

time.sleep(1) # Just so this message always arrives after the previous two

user = order.maker
lang = user.profile.telegram_lang_code

# In weird cases the order cannot be found (e.g. it is cancelled)

queryset = Order.objects.filter(maker=user)
order = queryset.last()

print(str(order.id))
if lang == 'es':
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(user, text)
user.profile.telegram_welcomed = True
user.profile.save()
if order.maker.profile.telegram_enabled:
lang = order.maker.profile.telegram_lang_code
# In weird cases the order cannot be found (e.g. it is cancelled)
queryset = Order.objects.filter(maker=order.maker)
if len(queryset) == 0:
return
order = queryset.last()
if lang == 'es':
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)
return
6 changes: 0 additions & 6 deletions api/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,6 @@ def send_message(order_id, message):

if message == 'welcome':
telegram.welcome(order)

if message == 'order_taken':
telegram.order_taken(order)

elif message == 'order_expired_untaken':
telegram.order_expired_untaken(order)
Expand All @@ -288,9 +285,6 @@ def send_message(order_id, message):
elif message == 'taker_expired_b4bond':
telegram.taker_expired_b4bond(order)

elif message == 'taker_canceled_b4bond':
telegram.taker_canceled_b4bond(order)

elif message == 'order_published':
telegram.order_published(order)

Expand Down
5 changes: 2 additions & 3 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,11 @@ def get(self, request, format=None):
data["price_now"], data["premium_now"] = Logics.price_and_premium_now(order)

# 3. c) If maker and Public/Paused, add premium percentile
# num similar orders, and maker information to enable telegram notifications.
if data["is_maker"] and order.status in [Order.Status.PUB, Order.Status.PAU]:
data["premium_percentile"] = compute_premium_percentile(order)
data["num_similar_orders"] = len(
Order.objects.filter(currency=order.currency,
status=Order.Status.PUB))
# Adds/generate telegram token and whether it is enabled
data = {**data,**Telegram.get_context(request.user)}

# 4) Non participants can view details (but only if PUB)
elif not data["is_participant"] and order.status != Order.Status.PUB:
Expand Down Expand Up @@ -921,6 +918,8 @@ def get(self, request):
context["nickname"] = request.user.username
context["referral_code"] = str(request.user.profile.referral_code)
context["earned_rewards"] = request.user.profile.earned_rewards
# Adds/generate telegram token and whether it is enabled
context = {**context,**Telegram.get_context(request.user)}
has_no_active_order, _, order = Logics.validate_already_maker_or_taker(
request.user)
if not has_no_active_order:
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ services:
environment:
REDIS_URL: redis://localhost:6379
command: celery -A robosats beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
volumes:
- .:/usr/src/robosats
depends_on:
- redis
network_mode: service:tor
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/components/BottomBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ class BottomBar extends Component {
activeOrderId: data.active_order_id ? data.active_order_id : null,
lastOrderId: data.last_order_id ? data.last_order_id : null,
referralCode: data.referral_code,
tgEnabled: data.tg_enabled,
tgBotName: data.tg_bot_name,
tgToken: data.tg_token,
earnedRewards: data.earned_rewards,
lastDayPremium: data.last_day_nonkyc_btc_premium,
}),
Expand Down Expand Up @@ -658,6 +661,9 @@ class BottomBar extends Component {
activeOrderId={this.props.activeOrderId}
lastOrderId={this.props.lastOrderId}
referralCode={this.props.referralCode}
tgEnabled={this.props.tgEnabled}
tgBotName={this.props.tgBotName}
tgToken={this.props.tgToken}
handleSubmitInvoiceClicked={this.handleSubmitInvoiceClicked}
host={this.getHost()}
showRewardsSpinner={this.state.showRewardsSpinner}
Expand Down
Loading