Browse Source

If a user is a member of a chat, but not a member of the corresponding community, suggest it

master
Lev 2 years ago
parent
commit
cb89542809
  1. 16
      bot.py
  2. 7
      main.py
  3. 10
      templates.txt
  4. 17
      user.py
  5. 32
      views.py

16
bot.py

@ -205,6 +205,21 @@ class Bot(telebot.TeleBot):
self.poll_user_for_community(user, community)
self.save_community(community)
def run_suggestions(self):
for user in self.iter_users():
found_communities = False
try:
for community in self.iter_communities():
if user.check_chat(community.chat_id, self):
self.send_template(user.user_id, 'community_suggest', community=community)
found_communities = True
except KeyboardInterrupt as e:
raise e
except Exception:
print(f'An exception occured in suggestions: {traceback.format_exc()}')
if found_communities:
self.save_user(user)
def send_meeting_info_in_community(self, community: Community):
for meeting in community.scheduled_meetings:
person_1, person_2 = self.get_chat(meeting[0]), self.get_chat(meeting[1])
@ -240,6 +255,7 @@ class Bot(telebot.TeleBot):
raise e
except Exception:
print(f'An exception occurred while iterating through communities: {traceback.format_exc()}')
Thread(target=self.run_suggestions).start()
time.sleep(60)
def register_next_step_handler(self, message, callback, *args, **kwargs):

7
main.py

@ -2,12 +2,13 @@ from bot import Bot
from views import views
from threading import Thread
import traceback
import os
config = {
'mongo': __import__('os').getenv('DB'),
'name': 'ranteabot',
'token': __import__('os').getenv('TOKEN'),
'mongo': os.getenv('DB'),
'name': 'ranteabot' if not os.getenv('DEBUG') else 'flazhokbot',
'token': os.getenv('TOKEN'),
'template_files': ['templates.txt'],
'main_keyboard': {'en': [[' About']], 'ru': [[' О боте']]}
}

10
templates.txt

@ -81,6 +81,16 @@ You have already requested a meeting in the community <b>{{ community.name }}</b
//| ru |//
Вы уже запрашивали встречу в сообществе <b>{{ community.name }}</b> недавно. Вы сможете запросить еще одну встречу через несколько дней.
||<| community_suggest |>||
//| en |//
You are a member of the chat {{ community.name }}. Do you want to add this community in the bot and participate in meetings?
>>| Yes :-: community_add_{{ community.chat_id }} |<<
>>| No :-: dismiss |<<
//| ru |//
Вы являетесь участником чата {{ community.name }}. Хотите добавить его как сообщество в бота и присоединиться к встречам?
>>| Да :-: community_add_{{ community.chat_id }} |<<
>>| Нет :-: dismiss |<<
||<| canceled |>||
//| en |//
Canceled

17
user.py

@ -3,6 +3,7 @@ from dataclasses import dataclass, field, asdict
import typing
import time
from community import Community
from telebot.types import ChatMember
if typing.TYPE_CHECKING:
from bot import Bot
@ -15,6 +16,20 @@ class User:
locale: str = ''
start_timestamp: int = field(default_factory=lambda: int(time.time()))
last_action_timestamp: int = field(default_factory=lambda: int(time.time()))
# Store the chats which were checked
# (so that we send a message for communities
# where the user is a member of the chat but not a member of the RT community)
checked_chats: typing.List[int] = field(default_factory=list)
def check_chat(self, chat_id: int, bot: Bot) -> bool:
"""
Check if the user should be notified of this chat
"""
if chat_id in self.checked_chats:
return False
self.checked_chats.append(chat_id)
chat_member_info: ChatMember = bot.get_chat_member(chat_id, self.user_id)
return chat_member_info.is_member or chat_member_info.status in ['creator', 'administrator', 'admin', 'member']
def dict(self) -> dict:
data = asdict(self)
@ -25,7 +40,7 @@ class User:
def from_dict(cls, data: dict) -> User:
data = getattr(data, '__dict__', data)
data_ = {key: data[key] for key in data.keys() if
key in ['user_id', 'chat_id', 'locale', 'start_timestamp', 'last_action_timestamp']}
key in ['user_id', 'chat_id', 'locale', 'start_timestamp', 'last_action_timestamp', 'checked_chats']}
self = cls(**data_)
return self

32
views.py

@ -1,4 +1,5 @@
from datetime import date
from telebot.types import CallbackQuery, Message
from bot import Bot
from community import Community
@ -6,7 +7,7 @@ from community import Community
def views(bot: Bot):
@bot.handle_commands(['/start'])
def handle_start(msg, user, args):
def handle_start(msg: Message, user, args):
if msg.chat.type in 'supergroup':
bot.reply_with_template(msg, 'welcome', community=Community.by_id(msg.chat.id, bot))
return
@ -20,6 +21,7 @@ def views(bot: Bot):
bot.poll_user_for_community(user, community)
else:
bot.reply_with_template(msg, 'err_not_a_member', community=community)
bot.save_community(community)
bot.reply_with_template(msg, 'info', start=True)
@bot.handle_commands(['/help', ' About', ' О боте'])
@ -27,7 +29,7 @@ def views(bot: Bot):
bot.reply_with_template(msg, 'info', start=False)
@bot.handle_commands(['/request', '📝 Request a meeting', '📝 Запросить встречу'])
def request_meeting(msg, user, _args):
def request_meeting(msg: Message, user, _args):
if msg.chat.type != 'private':
bot.reply_with_template(msg, 'err_not_private')
return
@ -35,7 +37,7 @@ def views(bot: Bot):
bot.reply_with_template(msg, 'request_meeting', comm_list=comm_ids_and_names)
@bot.handle_commands(['/join'])
def join_community(msg, user, args):
def join_community(msg: Message, user, args):
# check if it really is a community
if msg.chat.type == 'private':
bot.reply_with_template(msg, 'err_not_community')
@ -45,15 +47,31 @@ def views(bot: Bot):
bot.reply_with_template(msg, 'welcome', community=community, join=True)
@bot.handle_callback('request_meeting')
def request_meeting_callback(msg, user, args):
def request_meeting_callback(query: CallbackQuery, user, args):
community = Community.by_id(int(args), bot)
if community.can_user_request_a_meeting(user.user_id):
community.polled[user.user_id] = date.today()
community.pool.append(user.user_id)
bot.reply_with_template(msg, 'request_meeting_success', community=community)
bot.reply_with_template(query, 'request_meeting_success', community=community)
else:
bot.reply_with_template(msg, 'request_meeting_failure', community=community)
bot.answer_callback_query(msg.id)
bot.reply_with_template(query, 'request_meeting_failure', community=community)
bot.answer_callback_query(query.id)
@bot.handle_callback('dismiss')
def dismiss_callback(query: CallbackQuery, user, _args):
bot.answer_callback_query(query.id, {'en': 'Ok, fine', 'ru': 'ладно'}.get(user.locale, 'Ok'))
bot.delete_message(query.message.chat.id, query.message.message_id)
@bot.handle_callback('community_add')
def community_add_callback(query: CallbackQuery, user, args):
community = Community.by_id(int(args), bot)
if user.user_id in community.members:
bot.reply_with_template(query, 'community_added', community=community, already_member=True)
elif community.add_member(user.user_id, bot):
bot.reply_with_template(query, 'community_added', community=community, already_member=False)
bot.poll_user_for_community(user, community)
bot.answer_callback_query(query.id)
bot.save_community(community)
@bot.handle_commands(['/send_all'])
def send_spam(msg, user, _args):

Loading…
Cancel
Save