-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathchat_platforms.py
More file actions
159 lines (131 loc) · 4.69 KB
/
chat_platforms.py
File metadata and controls
159 lines (131 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# -*- coding: utf-8 -*-
import pprint
import json
import urllib
import requests
from celery import Celery
from celery.utils.log import get_task_logger
from app_config import APP_NAME, TG_BASE_MESSAGE_URL, FB_URL, FB_PROFILE_URL
# configura Celery object
app = Celery(__name__)
app.config_from_object('app_config')
logger = get_task_logger(__name__)
# Telegram
def _telegram_payload(payload):
logger.debug('telegram payload:')
logger.debug(pprint.pformat(payload))
chat_id = payload['message']['chat']['id']
text = payload['message']['text']
return text.strip(), chat_id
def _telegram_get_name(payload):
return payload['message']['chat']['first_name']
@app.task(bind=True)
def _telegram_dispatch(self, chat_id, text, keyboard=None):
logger.debug('telegram dispatch self: {}'.format(self))
# codifica mensagem para url
text = urllib.parse.quote_plus(text)
# constroi url
url = TG_BASE_MESSAGE_URL.format(chat_id, text)
if keyboard:
keyboard = [[item] for item in keyboard]
reply_markup = {'keyboard': keyboard, 'one_time_keyboard': True}
url += '&reply_markup={}'.format(json.dumps(reply_markup))
# envia requisicao para plataforma de chat
r = requests.get(url)
logger.debug('telegram dispatch:')
logger.debug(url)
logger.debug('return: {}-{}'.format(r.status_code, r.text))
if not r.ok:
raise self.retry(exc=r.json())
return r.json()
# Facebook
def _facebook_payload(payload):
logger.debug('facebook payload:')
logger.debug(pprint.pformat(payload))
message = payload['entry'][0]['messaging'][0]
chat_id = message['sender']['id']
try:
_message = message['message']
try:
text = _message['quick_reply']['payload']
except:
text = _message['text']
except:
text = message['postback']['payload']
return text.strip(), chat_id
def _facebook_get_name(payload):
message = payload['entry'][0]['messaging'][0]
chat_id = message['sender']['id']
try:
r = requests.get(FB_PROFILE_URL % (chat_id))
nome = r.json()['first_name']
except:
nome = None
return nome
@app.task(bind=True)
def _facebook_dispatch(self, chat_id, text, keyboard=None):
payload = {
'recipient': {'id': chat_id},
'message': {
'text': text,
}
}
if keyboard:
max_length = max(map(len, keyboard))
if max_length >= 20:
# dada a limitacao de 20 caracteres para botoes
# enviar uma nova mensagem só com texto, e outra com as opções
_facebook_dispatch(chat_id, text)
# constroi a lista com 4 elementos, e o resto como botões secundários
buttons = keyboard[4:7]
keyboard = keyboard[:4]
# constroi payload
payload['message'] = {
'attachment': {
'type': 'template',
'payload': {
'template_type': 'list',
'top_element_style': 'compact',
'elements': [{
'title': item,
'buttons': [{
'type': 'postback',
'title': item,
'payload': item,
}]
} for item in keyboard]
}
}
}
if buttons:
payload['message']['attachment']['payload']['buttons'] = [{
'type': 'postback',
'title': item,
'payload': item,
} for item in buttons]
else:
payload['message'] = {
'text': text,
'quick_replies': [{
'content_type': 'text',
'title': item,
'payload': item
} for item in keyboard]
}
# envia requisicao para plataforma de chat
r = requests.post(FB_URL, json=payload)
logger.debug('facebook dispatch:')
logger.debug(pprint.pformat(payload))
logger.debug('return: {}-{}'.format(r.status_code, r.text))
response = r.json()
if 'error' in response:
error = response['error']
if error['code'] in [1200, 613]:
exc_msg = '{}: {}'.format(error['code'], error['message'])
raise self.retry(exc=exc_msg)
return r.json()
# dicts
services = ['telegram', 'facebook']
processors = {k: globals()['_{}_payload'.format(k)] for k in services}
dispatchers = {k: globals()['_{}_dispatch'.format(k)] for k in services}
usernames = {k: globals()['_{}_get_name'.format(k)] for k in services}