0.0.8-fixes
This commit is contained in:
parent
437a50fa3c
commit
acb86ac200
|
@ -1,7 +1,7 @@
|
||||||
from sanic import Sanic
|
from sanic import Sanic
|
||||||
from sanic.response import text
|
from sanic.response import text
|
||||||
|
|
||||||
from tgbot.config import WEBHOOK, FEEDBACK_CHAT_ID
|
from tgbot.config import WEBHOOK, FEEDBACK_CHAT_ID, BUTTON_VOUCH
|
||||||
|
|
||||||
from tgbot.handlers.handle_feedback import handle_feedback, handle_answer
|
from tgbot.handlers.handle_feedback import handle_feedback, handle_answer
|
||||||
from tgbot.handlers.handle_members_change import handle_join, handle_left
|
from tgbot.handlers.handle_members_change import handle_join, handle_left
|
||||||
|
@ -12,7 +12,7 @@ from tgbot.handlers.command_graph import handle_command_graph
|
||||||
from tgbot.handlers.callback_vouch import handle_button
|
from tgbot.handlers.callback_vouch import handle_button
|
||||||
from tgbot.handlers.callback_unlink import handle_unlink
|
from tgbot.handlers.callback_unlink import handle_unlink
|
||||||
|
|
||||||
from tgbot.api import register_webhook
|
from tgbot.api import register_webhook, send_message
|
||||||
|
|
||||||
|
|
||||||
app = Sanic(name="welcomecenter")
|
app = Sanic(name="welcomecenter")
|
||||||
|
@ -41,22 +41,25 @@ async def handle(req):
|
||||||
# видимые сообщения
|
# видимые сообщения
|
||||||
msg = update.get('message', update.get('edited_message'))
|
msg = update.get('message', update.get('edited_message'))
|
||||||
if msg:
|
if msg:
|
||||||
if msg['chat']['id'] == msg['from']['id']:
|
if 'text' in msg:
|
||||||
if msg['text'] == '/my':
|
if msg['chat']['id'] == msg['from']['id']:
|
||||||
handle_command_my(msg)
|
if msg['text'] == '/my':
|
||||||
|
handle_command_my(msg)
|
||||||
|
else:
|
||||||
|
handle_feedback(msg)
|
||||||
|
elif str(msg['chat']['id']) == FEEDBACK_CHAT_ID:
|
||||||
|
if 'reply_to_message' in msg:
|
||||||
|
handle_answer(msg)
|
||||||
|
elif msg['text'] == '/graph':
|
||||||
|
await handle_command_graph(msg)
|
||||||
else:
|
else:
|
||||||
handle_feedback(msg)
|
handle_default(msg)
|
||||||
elif str(msg['chat']['id']) == FEEDBACK_CHAT_ID:
|
|
||||||
if 'reply_to_message' in msg:
|
|
||||||
handle_answer(msg)
|
|
||||||
elif 'text' in msg and msg['text'] == '/graph':
|
|
||||||
await handle_command_graph(msg)
|
|
||||||
elif 'new_chat_member' in msg:
|
elif 'new_chat_member' in msg:
|
||||||
handle_join(msg)
|
handle_join(msg)
|
||||||
elif 'left_chat_member' in msg:
|
elif 'left_chat_member' in msg:
|
||||||
handle_left(msg)
|
handle_left(msg)
|
||||||
else:
|
else:
|
||||||
handle_default(msg)
|
print('message without text')
|
||||||
|
|
||||||
# кнопки
|
# кнопки
|
||||||
elif 'callback_query' in update:
|
elif 'callback_query' in update:
|
||||||
|
@ -78,5 +81,6 @@ async def handle(req):
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
import traceback
|
import traceback
|
||||||
|
r = send_message(FEEDBACK_CHAT_ID, f'<pre>{traceback.format_exc()}</pre>')
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return text('ok')
|
return text('ok')
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
sanic
|
sanic==19.6.0
|
||||||
requests
|
requests
|
||||||
redis
|
redis
|
||||||
aiohttp
|
aiohttp
|
19
tgbot/api.py
19
tgbot/api.py
|
@ -96,9 +96,10 @@ def approve_chat_join_request(chat_id, user_id):
|
||||||
async def send_document(chat_id, data='', filename='chart.svg'):
|
async def send_document(chat_id, data='', filename='chart.svg'):
|
||||||
url = apiBase + "sendDocument"
|
url = apiBase + "sendDocument"
|
||||||
params = { "chat_id": chat_id }
|
params = { "chat_id": chat_id }
|
||||||
files = { "document": data }
|
filedata = aiohttp.FormData()
|
||||||
|
filedata.add_field('document', data, filename=filename)
|
||||||
|
|
||||||
async with aiohttp.ClientSession(headers=headers) as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.post(url, params=params, data=filedata) as response:
|
async with session.post(url, params=params, data=filedata) as response:
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
error_text = await response.text()
|
error_text = await response.text()
|
||||||
|
@ -114,18 +115,20 @@ async def send_document(chat_id, data='', filename='chart.svg'):
|
||||||
|
|
||||||
|
|
||||||
# https://core.telegram.org/bots/api#sendphoto
|
# https://core.telegram.org/bots/api#sendphoto
|
||||||
async def send_photo(png_data, chat_id):
|
async def send_photo(chat_id, img_data, filename='chart.png'):
|
||||||
url = apiBase + f"sendPhoto"
|
url = apiBase + f"sendPhoto"
|
||||||
headers = {"Content-Type": "multipart/form-data"}
|
params = {"chat_id": chat_id }
|
||||||
files = {"photo": ("chart.png", png_data)}
|
filedata = aiohttp.FormData()
|
||||||
params = {"chat_id": chat_id}
|
filedata.add_field('photo', img_data, filename=filename)
|
||||||
|
|
||||||
async with aiohttp.ClientSession(headers=headers) as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.post(url, params=params, data=filedata) as response:
|
async with session.post(url, params=params, data=filedata) as response:
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
print(f"Error sending photo: {response.status}")
|
error_text = await response.text()
|
||||||
|
print(f"Error sending photo: {response.status} - {error_text}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return await response.json()
|
return await response.json()
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from tgbot.api import send_message, forward_message, delete_message
|
from tgbot.api import send_message, forward_message, delete_message
|
||||||
from tgbot.storage import Profile
|
from tgbot.storage import Profile
|
||||||
|
from tgbot.config import BUTTON_VOUCH
|
||||||
|
|
||||||
|
|
||||||
def handle_button(callback_query):
|
def handle_button(callback_query):
|
||||||
|
|
|
@ -25,5 +25,6 @@ async def handle_command_graph(msg):
|
||||||
members.append(member)
|
members.append(member)
|
||||||
print(f'found {len(members)} members')
|
print(f'found {len(members)} members')
|
||||||
data = generate_chart(members)
|
data = generate_chart(members)
|
||||||
r = await send_document(msg['chat']['id'], data, 'chart.svg')
|
if data:
|
||||||
print(r)
|
r = await send_document(msg['chat']['id'], data, 'chart.svg')
|
||||||
|
print(r)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from tgbot.storage import Profile
|
from tgbot.storage import Profile
|
||||||
from tgbot.api import get_member
|
from tgbot.api import get_member, send_message
|
||||||
|
|
||||||
def construct_unlink_buttons(actor):
|
def construct_unlink_buttons(actor):
|
||||||
buttons = []
|
buttons = []
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from tgbot.api import send_message, delete_message, get_chat_administrators
|
from tgbot.api import send_message, delete_message, get_chat_administrators
|
||||||
from tgbot.storage import Profile
|
from tgbot.storage import Profile
|
||||||
from tgbot.handlers.send_button import show_request_msg
|
from tgbot.handlers.send_button import show_request_msg
|
||||||
|
from tgbot.storage import storage
|
||||||
|
|
||||||
def handle_default(msg):
|
def handle_default(msg):
|
||||||
print(f'default handler for all messages')
|
print(f'default handler for all messages')
|
||||||
|
@ -18,14 +18,14 @@ def handle_default(msg):
|
||||||
print(r)
|
print(r)
|
||||||
|
|
||||||
# удалить предыдушее сообщение с кнопкой в этом чате
|
# удалить предыдушее сообщение с кнопкой в этом чате
|
||||||
if sender['request_msg_id'].startswith(chat_id):
|
prev_msg_id = storage.get(f'btn-{chat_id}-{from_id}')
|
||||||
chat_id, rmid = sender['request_msg_id'].split(':')
|
if prev_msg_id:
|
||||||
r = delete_message(chat_id, rmid)
|
r = delete_message(chat_id, prev_msg_id)
|
||||||
print(r)
|
print(r)
|
||||||
|
|
||||||
# показать новое сообщение с кнопкой
|
# показать новое сообщение с кнопкой
|
||||||
request_msg_id = show_request_msg(msg)
|
btn_msg_id = show_request_msg(msg)
|
||||||
sender['request_msg_id'] = f'{chat_id}:{request_msg_id}'
|
storage.set(f'btn-{chat_id}-{from_id}', btn_msg_id)
|
||||||
else:
|
else:
|
||||||
# любое другое сообщение
|
# любое другое сообщение
|
||||||
if len(sender['parents']) == 0:
|
if len(sender['parents']) == 0:
|
||||||
|
@ -33,11 +33,13 @@ def handle_default(msg):
|
||||||
print(f'setting owner as parent for {from_id}')
|
print(f'setting owner as parent for {from_id}')
|
||||||
r = get_chat_administrators(chat_id)
|
r = get_chat_administrators(chat_id)
|
||||||
print(r)
|
print(r)
|
||||||
|
owner_id = ''
|
||||||
|
for admin in r['result']:
|
||||||
|
if admin['status'] == 'creator':
|
||||||
|
owner_id = admin['user']['id']
|
||||||
|
break
|
||||||
|
|
||||||
owner_id = r['result'][0]['id'] # DEBUG!!
|
|
||||||
|
|
||||||
sender['parents'].append(owner_id)
|
sender['parents'].append(owner_id)
|
||||||
|
|
||||||
# обновляем профиль владельца
|
# обновляем профиль владельца
|
||||||
owner = Profile.get(owner_id)
|
owner = Profile.get(owner_id)
|
||||||
owner['children'].append(from_id)
|
owner['children'].append(from_id)
|
||||||
|
|
|
@ -19,11 +19,14 @@ def handle_feedback(msg):
|
||||||
|
|
||||||
|
|
||||||
def handle_answer(msg):
|
def handle_answer(msg):
|
||||||
print(f'handle answer from support')
|
answered_msg = msg['reply_to_message']
|
||||||
support_msg_id = str(msg['reply_to_message']['message_id'])
|
if answered_msg['from']['is_bot']:
|
||||||
# получение сохраненного айди сообщения из личной переписки с ботом
|
support_msg_id = str(answered_msg['message_id'])
|
||||||
stored_feedback = storage.get(f'fbk-{support_msg_id}')
|
# получение сохраненного информации о сообщении для ответа
|
||||||
stored_feedback = json.loads(stored_feedback)
|
stored_feedback = storage.get(f'fbk-{support_msg_id}')
|
||||||
r = send_message(f'{stored_feedback["chat_id"]}', msg['text'], reply_to=stored_feedback["message_id"])
|
if stored_feedback:
|
||||||
print(r)
|
print(f'handle answer from support')
|
||||||
|
stored_feedback = json.loads(stored_feedback)
|
||||||
|
r = send_message(f'{stored_feedback["chat_id"]}', msg['text'], reply_to=stored_feedback["message_id"])
|
||||||
|
print(r)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from tgbot.api import approve_chat_join_request, delete_message
|
from tgbot.api import approve_chat_join_request, delete_message
|
||||||
from tgbot.handlers.send_button import show_request_msg
|
from tgbot.handlers.send_button import show_request_msg
|
||||||
from tgbot.storage import Profile
|
from tgbot.storage import Profile, storage
|
||||||
|
|
||||||
|
|
||||||
def handle_join_request(msg):
|
def handle_join_request(msg):
|
||||||
|
@ -11,13 +11,13 @@ def handle_join_request(msg):
|
||||||
|
|
||||||
if len(actor['parents']) == 0:
|
if len(actor['parents']) == 0:
|
||||||
# показываем сообщение с кнопкой "поручиться"
|
# показываем сообщение с кнопкой "поручиться"
|
||||||
request_msg_id = show_request_msg(msg)
|
btn_msg_id = show_request_msg(msg)
|
||||||
# удаляем предыдущее сообщение с кнопкой в этом чате
|
# удаляем предыдущее сообщение с кнопкой в этом чате
|
||||||
if actor['request_msg_id'].startswith(chat_id):
|
prev_msg_id = storage.get(f'btn-{chat_id}-{from_id}')
|
||||||
chat_id, rmid = actor['request_msg_id'].split(':')
|
if prev_msg_id:
|
||||||
r = delete_message(chat_id, rmid)
|
r = delete_message(chat_id, prev_msg_id)
|
||||||
print(r)
|
print(r)
|
||||||
actor['request_msg_id'] = f'{chat_id}:{request_msg_id}'
|
storage.set(f'btn-{chat_id}-{from_id}', btn_msg_id)
|
||||||
else:
|
else:
|
||||||
# за пользователя поручились ранее
|
# за пользователя поручились ранее
|
||||||
r = approve_chat_join_request(chat_id, from_id)
|
r = approve_chat_join_request(chat_id, from_id)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from tgbot.handlers.send_button import show_request_msg
|
from tgbot.handlers.send_button import show_request_msg
|
||||||
from tgbot.api import unmute_member, mute_member, delete_message
|
from tgbot.api import unmute_member, mute_member, delete_message
|
||||||
from tgbot.storage import Profile
|
from tgbot.storage import Profile, storage
|
||||||
|
|
||||||
def handle_join(msg):
|
def handle_join(msg):
|
||||||
chat_id = str(msg['chat']['id'])
|
chat_id = str(msg['chat']['id'])
|
||||||
|
@ -12,15 +12,13 @@ def handle_join(msg):
|
||||||
if from_id == newcomer_id:
|
if from_id == newcomer_id:
|
||||||
if len(actor['parents']) == 0:
|
if len(actor['parents']) == 0:
|
||||||
# показываем сообщение с кнопкой "поручиться"
|
# показываем сообщение с кнопкой "поручиться"
|
||||||
request_msg_id = show_request_msg(msg)
|
btn_msg_id = show_request_msg(msg)
|
||||||
|
storage.set(f'btn-{chat_id}-{from_id}', btn_msg_id)
|
||||||
|
|
||||||
# до одобрения - мьют
|
# до одобрения - мьют
|
||||||
r = mute_member(chat_id, newcomer_id)
|
r = mute_member(chat_id, newcomer_id)
|
||||||
print(r)
|
print(r)
|
||||||
|
|
||||||
# обновляем профиль присоединившегося
|
|
||||||
actor['request_msg_id'] = f'{chat_id}:{request_msg_id}'
|
|
||||||
Profile.save(actor)
|
|
||||||
else:
|
else:
|
||||||
# за пользователя поручились ранее
|
# за пользователя поручились ранее
|
||||||
pass
|
pass
|
||||||
|
@ -44,14 +42,11 @@ def handle_left(msg):
|
||||||
member_id = msg["left_chat_member"]["id"]
|
member_id = msg["left_chat_member"]["id"]
|
||||||
chat_id = msg['chat']['id']
|
chat_id = msg['chat']['id']
|
||||||
|
|
||||||
# профиль покидающего чат
|
|
||||||
leaver = Profile.get(member_id)
|
|
||||||
|
|
||||||
# удаление сообщения с кнопкой в этом чате
|
# удаление сообщения с кнопкой в этом чате
|
||||||
if leaver['request_msg_id'].startswith(chat_id):
|
prev_msg_id = storage.get(f'btn-{chat_id}-{member_id}')
|
||||||
chat_id, rmid = leaver['request_msg_id'].split(':')
|
if prev_msg_id:
|
||||||
r = delete_message(chat_id, rmid)
|
r = delete_message(chat_id, prev_msg_id)
|
||||||
print(r)
|
print(r)
|
||||||
|
storage.remove(f'btn-{chat_id}-{member_id}')
|
||||||
|
|
||||||
Profile.leaving(leaver)
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from tgbot.api import send_message
|
from tgbot.api import send_message
|
||||||
from tgbot.config import BUTTON_VOUCH, NEWCOMER_MSG
|
from tgbot.config import BUTTON_VOUCH, NEWCOMER_MSG
|
||||||
from tgbot.utils import mention
|
from tgbot.utils.mention import mention
|
||||||
|
|
||||||
def show_request_msg(msg):
|
def show_request_msg(msg):
|
||||||
reply_markup = {
|
reply_markup = {
|
||||||
|
@ -20,8 +20,6 @@ def show_request_msg(msg):
|
||||||
reply_to=msg.get('message_id', ''),
|
reply_to=msg.get('message_id', ''),
|
||||||
reply_markup=reply_markup
|
reply_markup=reply_markup
|
||||||
)
|
)
|
||||||
request_msg_id = r['result']['message_id']
|
btn_msg_id = r['result']['message_id']
|
||||||
chat_id = msg['chat']['id']
|
print(f'request message id: {btn_msg_id}')
|
||||||
print(r)
|
return btn_msg_id
|
||||||
print(f'request message id: {chat_id}:{request_msg_id}')
|
|
||||||
return request_msg_id
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import redis
|
||||||
from tgbot.storage.profile import Profile as ProfileObj
|
from tgbot.storage.profile import Profile as ProfileObj
|
||||||
from tgbot.config import REDIS_URL
|
from tgbot.config import REDIS_URL
|
||||||
|
|
||||||
# сохраняет сессии и пересылаемые сообщения между перезагрузками
|
# сохраняет сессии, айди кнопок в чатах для удаления и пересылаемые сообщения между перезагрузками
|
||||||
storage = redis.from_url(REDIS_URL)
|
storage = redis.from_url(REDIS_URL)
|
||||||
|
|
||||||
# хранение необходимой информации о пользователях
|
# хранение необходимой информации о пользователях
|
||||||
|
|
|
@ -9,7 +9,6 @@ class Profile:
|
||||||
def create(self, member_id, msg=None):
|
def create(self, member_id, msg=None):
|
||||||
s = {
|
s = {
|
||||||
"id": member_id,
|
"id": member_id,
|
||||||
"request_msg_id": 0,
|
|
||||||
"parents": [],
|
"parents": [],
|
||||||
"children": [],
|
"children": [],
|
||||||
"chats": []
|
"chats": []
|
||||||
|
@ -38,7 +37,3 @@ class Profile:
|
||||||
else:
|
else:
|
||||||
r = json.loads(data)
|
r = json.loads(data)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def leaving(self, s):
|
|
||||||
if len(s['parents']) == 0:
|
|
||||||
self.storage.delete(f'usr-{s["id"]}')
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user