2023-04-21 13:06:48 +03:00
|
|
|
|
from tgbot.api import send_message, forward_message, delete_message, \
|
2023-04-22 04:17:50 +03:00
|
|
|
|
ban_member, unban_member, mute_member, unmute_member, \
|
2023-04-22 04:21:24 +03:00
|
|
|
|
approve_chat_join_request, send_graph
|
|
|
|
|
from tgbot.graph import generate_chart
|
2023-04-22 04:17:50 +03:00
|
|
|
|
from tgbot.config import REDIS_URL, FEEDBACK_CHAT_ID, BUTTON_VOUCH, NEWCOMER_MSG
|
2023-04-18 00:42:25 +03:00
|
|
|
|
import json
|
|
|
|
|
import redis
|
2023-04-21 13:09:10 +03:00
|
|
|
|
from tgbot.profile import Profile as ProfileObj
|
|
|
|
|
|
2023-04-18 00:42:25 +03:00
|
|
|
|
|
|
|
|
|
# сохраняет сессии и пересылаемые сообщения между перезагрузками
|
|
|
|
|
storage = redis.from_url(REDIS_URL)
|
|
|
|
|
|
2023-04-21 13:09:10 +03:00
|
|
|
|
# хранение необходимой информации о пользователях
|
|
|
|
|
Profile = ProfileObj(storage)
|
2023-04-21 13:06:48 +03:00
|
|
|
|
|
2023-04-22 04:21:24 +03:00
|
|
|
|
def newcomer_show(msg):
|
2023-04-22 04:17:50 +03:00
|
|
|
|
reply_markup = {
|
|
|
|
|
"inline_keyboard": [
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
"text": BUTTON_VOUCH,
|
|
|
|
|
"callback_data": BUTTON_VOUCH + str(msg['from']['id'])
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
}
|
2023-04-22 04:21:24 +03:00
|
|
|
|
identity = f"{msg['from']['first_name']} {msg['from'].get('last_name', '')}"
|
|
|
|
|
if 'username' in msg['from']:
|
|
|
|
|
identity += f" @{msg['from']['username']}"
|
2023-04-22 04:17:50 +03:00
|
|
|
|
r = send_message(
|
|
|
|
|
msg['chat']['id'],
|
2023-04-22 04:21:24 +03:00
|
|
|
|
NEWCOMER_MSG + identity,
|
2023-04-22 04:17:50 +03:00
|
|
|
|
reply_to=msg['message_id'],
|
|
|
|
|
reply_markup=reply_markup
|
|
|
|
|
)
|
|
|
|
|
welcome_msg_id = r.json()['result']['message_id']
|
|
|
|
|
print(r.json())
|
|
|
|
|
print(f'welcome message id: {welcome_msg_id}')
|
|
|
|
|
return welcome_msg_id
|
|
|
|
|
|
2023-04-21 13:06:48 +03:00
|
|
|
|
|
2023-04-18 00:42:25 +03:00
|
|
|
|
def handle_feedback(msg):
|
|
|
|
|
mid = msg['message_id']
|
|
|
|
|
cid = msg['chat']['id']
|
|
|
|
|
r = forward_message(cid, mid, FEEDBACK_CHAT_ID).json()
|
|
|
|
|
support_msg_id = r['result']['message_id']
|
2023-04-21 13:09:10 +03:00
|
|
|
|
# сохранение айди сообщения в приватной переписке с ботом
|
2023-04-18 00:42:25 +03:00
|
|
|
|
storage.set(f'fbk-{support_msg_id}', json.dumps({
|
2023-04-21 13:06:48 +03:00
|
|
|
|
"author_id": msg["from"]["id"],
|
2023-04-18 00:42:25 +03:00
|
|
|
|
"message_id": mid,
|
|
|
|
|
"chat_id": cid
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_answer(msg):
|
|
|
|
|
print(f'handle answer from support')
|
|
|
|
|
support_msg_id = str(msg['reply_to_message']['message_id'])
|
2023-04-21 13:09:10 +03:00
|
|
|
|
# получение сохраненного айди сообщения из личной переписки с ботом
|
2023-04-18 00:42:25 +03:00
|
|
|
|
stored_feedback = storage.get(f'fbk-{support_msg_id}')
|
|
|
|
|
stored_feedback = json.loads(stored_feedback)
|
|
|
|
|
r = send_message(f'{stored_feedback["chat_id"]}', msg['text'], reply_to=stored_feedback["message_id"]) # notice 'u' before private chat ID
|
|
|
|
|
print(r.json())
|
|
|
|
|
|
|
|
|
|
|
2023-04-21 13:09:10 +03:00
|
|
|
|
def handle_join(msg):
|
2023-04-18 00:42:25 +03:00
|
|
|
|
chat_id = str(msg['chat']['id'])
|
|
|
|
|
from_id = str(msg['from']['id'])
|
2023-04-22 04:17:50 +03:00
|
|
|
|
actor = Profile.get(from_id)
|
|
|
|
|
|
|
|
|
|
actor["name"] = msg['from']['first_name'] + msg['from'].get('last_name', '')
|
|
|
|
|
actor["mention"] = msg['from'].get('username', '')
|
2023-04-22 04:21:24 +03:00
|
|
|
|
newcomer_id = str(msg['new_chat_member']['id'])
|
|
|
|
|
if from_id == newcomer_id:
|
2023-04-22 04:17:50 +03:00
|
|
|
|
if len(actor['parents']) == 0:
|
|
|
|
|
# показываем сообщение с кнопкой "поручиться"
|
2023-04-22 04:21:24 +03:00
|
|
|
|
welcome_msg_id = newcomer_show(msg)
|
|
|
|
|
|
|
|
|
|
# до одобрения - мьют
|
|
|
|
|
r = mute_member(chat_id, newcomer_id)
|
|
|
|
|
print(r.json())
|
2023-04-22 04:17:50 +03:00
|
|
|
|
|
|
|
|
|
# обновляем профиль присоединившегося
|
|
|
|
|
actor['welcome_id'] = welcome_msg_id
|
|
|
|
|
Profile.save(actor)
|
|
|
|
|
else:
|
|
|
|
|
# за пользователя поручились ранее
|
|
|
|
|
r = delete_message(chat_id, actor['welcome_id'])
|
|
|
|
|
print(r.json())
|
|
|
|
|
else:
|
|
|
|
|
# пользователи приглашены другим участником
|
|
|
|
|
print(f'{len(msg["new_chat_members"])} members were invited by {from_id}')
|
2023-04-21 13:09:10 +03:00
|
|
|
|
for m in msg['new_chat_members']:
|
|
|
|
|
newcomer = Profile.get(m['id'])
|
2023-04-22 04:17:50 +03:00
|
|
|
|
newcomer['parents'].append(from_id)
|
2023-04-21 13:09:10 +03:00
|
|
|
|
Profile.save(newcomer)
|
2023-04-22 04:17:50 +03:00
|
|
|
|
actor['children'].append(m['id'])
|
2023-04-22 04:21:24 +03:00
|
|
|
|
r = unmute_member(chat_id, newcomer['id'])
|
|
|
|
|
print(r.json())
|
2023-04-21 13:09:10 +03:00
|
|
|
|
|
|
|
|
|
# обновляем профиль пригласившего
|
2023-04-22 04:17:50 +03:00
|
|
|
|
Profile.save(actor)
|
2023-04-18 00:42:25 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_left(msg):
|
2023-04-18 12:22:43 +03:00
|
|
|
|
print(f'handling member leaving')
|
2023-04-18 00:42:25 +03:00
|
|
|
|
member_id = msg["left_chat_member"]["id"]
|
|
|
|
|
|
2023-04-21 13:09:10 +03:00
|
|
|
|
# профиль покидающего чат
|
|
|
|
|
leaver = Profile.get(member_id)
|
2023-04-18 00:42:25 +03:00
|
|
|
|
|
2023-04-22 04:17:50 +03:00
|
|
|
|
# удаление сообщения с кнопкой
|
|
|
|
|
r = delete_message(msg['chat']['id'], leaver['welcome_id'])
|
2023-04-21 13:09:10 +03:00
|
|
|
|
print(r.json())
|
2023-04-18 00:42:25 +03:00
|
|
|
|
|
2023-04-21 13:09:10 +03:00
|
|
|
|
Profile.leaving(leaver)
|
2023-04-18 00:42:25 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_button(callback_query):
|
2023-04-22 04:17:50 +03:00
|
|
|
|
# получаем профиль нажавшего кнопку
|
|
|
|
|
actor_id = str(callback_query['from']['id'])
|
|
|
|
|
actor = Profile.get(actor_id)
|
|
|
|
|
|
|
|
|
|
callback_data = callback_query['data']
|
|
|
|
|
if callback_data.startswith(BUTTON_VOUCH):
|
|
|
|
|
print(f'vouch button pressed by {actor_id}')
|
|
|
|
|
|
|
|
|
|
newcomer_id = callback_data[len(BUTTON_VOUCH):]
|
|
|
|
|
newcomer = Profile.get(newcomer_id)
|
2023-04-22 04:21:24 +03:00
|
|
|
|
if newcomer_id not in actor['children'] and \
|
2023-04-22 04:17:50 +03:00
|
|
|
|
actor_id not in newcomer['parents']:
|
|
|
|
|
newcomer['parents'].append(newcomer_id)
|
|
|
|
|
actor['children'].append(actor_id)
|
2023-04-21 13:09:10 +03:00
|
|
|
|
Profile.save(newcomer)
|
|
|
|
|
Profile.save(actor)
|
2023-04-22 04:17:50 +03:00
|
|
|
|
try:
|
|
|
|
|
chat_id = str(callback_query['message']['chat']['id'])
|
|
|
|
|
|
|
|
|
|
print('unmute newcomer')
|
|
|
|
|
r = unmute_member(chat_id, newcomer_id)
|
|
|
|
|
print(r.json())
|
2023-04-22 04:21:24 +03:00
|
|
|
|
|
|
|
|
|
print('accept join request')
|
|
|
|
|
r = approve_chat_join_request(chat_id, newcomer_id)
|
|
|
|
|
print(r.json())
|
|
|
|
|
|
2023-04-22 04:17:50 +03:00
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_join_request(update):
|
|
|
|
|
print(f'handle join request')
|
|
|
|
|
chat_id = str(update['message']['chat']['id'])
|
|
|
|
|
from_id = str(update['message']['from']['id'])
|
|
|
|
|
actor = Profile.get(from_id)
|
|
|
|
|
|
|
|
|
|
actor["name"] = update['message']['from']['first_name'] + update['message']['from'].get('last_name', '')
|
|
|
|
|
actor["mention"] = update['message']['from'].get('username', '')
|
|
|
|
|
|
|
|
|
|
if from_id == str(update['message']['new_chat_member']['id']):
|
|
|
|
|
if len(actor['parents']) == 0:
|
|
|
|
|
# показываем сообщение с кнопкой "поручиться"
|
2023-04-22 04:21:24 +03:00
|
|
|
|
welcome_msg_id = show_request_msg(update)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_graph(_msg):
|
|
|
|
|
cursor = 0
|
|
|
|
|
keys = []
|
|
|
|
|
while True:
|
|
|
|
|
# Scan for keys starting with 'urs-*' in batches of 100
|
|
|
|
|
cursor, batch_keys = r.scan(cursor=cursor, match='urs-*', count=100)
|
|
|
|
|
keys += batch_keys
|
|
|
|
|
# If the cursor is 0, then we've reached the end of the keys
|
|
|
|
|
if cursor == 0:
|
|
|
|
|
break
|
|
|
|
|
# Get the values of all the keys
|
|
|
|
|
values = r.mget(keys)
|
|
|
|
|
# Parse the JSON data from each value
|
|
|
|
|
members = []
|
|
|
|
|
for value in values:
|
|
|
|
|
member = json.loads(value)
|
|
|
|
|
members.append(member)
|
|
|
|
|
png_data = generate_chart(values)
|
|
|
|
|
r = send_graph(png_data, chat_id)
|
|
|
|
|
print(r.json())
|