mirror of
https://github.com/miloszowi/everyone-mention-telegram-bot.git
synced 2025-10-10 17:16:03 +00:00
Dynamic mentioning added, removed some unwanted properties, updated README
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
__all__ = [
|
||||
'abstractHandler', 'everyoneHandler', 'groupsHandler',
|
||||
'inlineQueryHandler', 'joinHandler', 'leaveHandler',
|
||||
'startHandler'
|
||||
'startHandler', 'dynamicMentionHandler'
|
||||
]
|
||||
|
@@ -9,6 +9,7 @@ from bot.message.replier import Replier
|
||||
from exception.actionNotAllowedException import ActionNotAllowedException
|
||||
from exception.invalidActionException import InvalidActionException
|
||||
from exception.invalidArgumentException import InvalidArgumentException
|
||||
from exception.notFoundException import NotFoundException
|
||||
from logger import Logger
|
||||
|
||||
|
||||
@@ -30,6 +31,8 @@ class AbstractHandler:
|
||||
Logger.action(self.inbound, self.action)
|
||||
except (InvalidActionException, InvalidArgumentException, ActionNotAllowedException) as e:
|
||||
Replier.markdown(update, str(e))
|
||||
except NotFoundException:
|
||||
pass # probably just mentioning user
|
||||
except Exception as e:
|
||||
Logger.exception(e)
|
||||
|
||||
|
28
src/bot/handler/dynamicMentionHandler.py
Normal file
28
src/bot/handler/dynamicMentionHandler.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import re
|
||||
|
||||
from telegram.ext import Filters, MessageHandler
|
||||
from telegram.ext.callbackcontext import CallbackContext
|
||||
from telegram.update import Update
|
||||
|
||||
from bot.handler.abstractHandler import AbstractHandler
|
||||
from bot.message.replier import Replier
|
||||
from repository.chatRepository import ChatRepository
|
||||
from utils.messageBuilder import MessageBuilder
|
||||
|
||||
|
||||
class DynamicMentionHandler(AbstractHandler):
|
||||
bot_handler: MessageHandler
|
||||
chat_repository: ChatRepository
|
||||
action: str = 'dynamic-mention'
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.bot_handler = MessageHandler(
|
||||
Filters.regex(re.compile(r'@[^ ]')),
|
||||
self.wrap
|
||||
)
|
||||
self.chat_repository = ChatRepository()
|
||||
|
||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||
users = self.chat_repository.get_users_for_group(self.inbound)
|
||||
|
||||
Replier.markdown(update, MessageBuilder.mention_message(users))
|
@@ -8,24 +8,21 @@ from config.contents import mention_failed
|
||||
from exception.invalidActionException import InvalidActionException
|
||||
from exception.notFoundException import NotFoundException
|
||||
from repository.chatRepository import ChatRepository
|
||||
from repository.userRepository import UserRepository
|
||||
from utils.messageBuilder import MessageBuilder
|
||||
|
||||
|
||||
class EveryoneHandler(AbstractHandler):
|
||||
bot_handler: CommandHandler
|
||||
chat_repository: ChatRepository
|
||||
user_repository: UserRepository
|
||||
action: str = 'everyone'
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.bot_handler = CommandHandler(self.action, self.wrap)
|
||||
self.chat_repository = ChatRepository()
|
||||
self.user_repository = UserRepository()
|
||||
|
||||
def handle(self, update: Update, context: CallbackContext) -> None:
|
||||
try:
|
||||
users = self.chat_repository.get_users_for_group(self.inbound.chat_id, self.inbound.group_name)
|
||||
users = self.chat_repository.get_users_for_group(self.inbound)
|
||||
|
||||
Replier.markdown(update, MessageBuilder.mention_message(users))
|
||||
except NotFoundException as e:
|
||||
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
|
||||
import names
|
||||
import re
|
||||
from telegram.ext.callbackcontext import CallbackContext
|
||||
from telegram.update import Update
|
||||
|
||||
@@ -27,11 +28,20 @@ class InboundMessage:
|
||||
chat_id = str(update.effective_chat.id)
|
||||
group_name = InboundMessage.default_group
|
||||
|
||||
# done upon resolving a command action
|
||||
if context.args and context.args[0] and group_specific:
|
||||
group_name = str(context.args[0]).lower()
|
||||
|
||||
GroupNameValidator.validate(group_name)
|
||||
|
||||
# done upon resolving a message handler action
|
||||
if '@' in update.message.text:
|
||||
searched_message_part = [part for part in update.message.text.split(' ') if '@' in part][0]
|
||||
group_name = re.sub(r'\W+', '', searched_message_part)
|
||||
|
||||
if group_name in GroupNameValidator.FORBIDDEN_GROUP_NAMES:
|
||||
group_name = InboundMessage.default_group
|
||||
|
||||
username = update.effective_user.username or update.effective_user.first_name
|
||||
|
||||
if not username:
|
||||
|
@@ -10,13 +10,16 @@ no_groups = 'There are no groups for this chat'
|
||||
start_text = """
|
||||
Hello!
|
||||
@everyone_mention_bot here.
|
||||
|
||||
<b>Description</b>:
|
||||
I <b>do not</b> have access to your messages!
|
||||
I am here to help you with multiple user mentions.
|
||||
|
||||
<b>Usage</b>:
|
||||
Users that joined the group by <code>/join</code> command, can be mentioned after calling <code>/everyone</code> command.
|
||||
Users that joined the group by <code>/join</code> command,
|
||||
can be mentioned after typing one of those in your message:
|
||||
<code>@all</code>, <code>@channel</code>, <code>@chat</code>, <code>@everyone</code>, <code>@group</code> or <code>@here</code>.
|
||||
|
||||
If you did create a group named <code>gaming</code>, simply use <code>@gaming</code> to call users from that group.
|
||||
|
||||
You can also use <code>/everyone</code> command.
|
||||
|
||||
<b>Commands</b>:
|
||||
<pre>/join {group-name}</pre>
|
||||
@@ -36,6 +39,4 @@ Show start & help text
|
||||
|
||||
<b>Please note</b>
|
||||
<code>{group-name}</code> is not required, <code>default</code> if not given.
|
||||
|
||||
If your chat does have multiple bots <b>I might not receive your command</b> according to <a href="https://core.telegram.org/bots/faq#what-messages-will-my-bot-get">policy of bots with privacy mode enabled</a> - use <code>Inline Mode</code> to avoid this.
|
||||
"""
|
||||
|
@@ -39,12 +39,17 @@ class ChatRepository(AbstractRepository):
|
||||
|
||||
return Chat.from_mongo_document(chat)
|
||||
|
||||
def get_users_for_group(self, chat_id: str, group: str) -> Iterable[User]:
|
||||
chat = self.get(chat_id)
|
||||
if not chat.groups.get(group):
|
||||
def get_users_for_group(self, inbound: InboundMessage) -> Iterable[User]:
|
||||
chat = self.get(inbound.chat_id)
|
||||
if not chat.groups.get(inbound.group_name):
|
||||
raise NotFoundException
|
||||
|
||||
return [self.user_repository.get(user_id) for user_id in chat.groups.get(group)]
|
||||
users = [self.user_repository.get(user_id) for user_id in chat.groups.get(inbound.group_name) if user_id != inbound.user_id]
|
||||
|
||||
if not users:
|
||||
raise NotFoundException
|
||||
|
||||
return users
|
||||
|
||||
def save(self, chat: Chat) -> None:
|
||||
self.database_client.save(
|
||||
|
@@ -5,6 +5,7 @@ from exception.invalidArgumentException import InvalidArgumentException
|
||||
|
||||
class GroupNameValidator:
|
||||
MAX_GROUP_NAME_LENGTH: int = 40
|
||||
FORBIDDEN_GROUP_NAMES = ['all', 'channel', 'chat', 'everyone', 'group', 'here']
|
||||
|
||||
@staticmethod
|
||||
def validate(group: str) -> None:
|
||||
@@ -15,3 +16,6 @@ class GroupNameValidator:
|
||||
|
||||
if len(group) > GroupNameValidator.MAX_GROUP_NAME_LENGTH:
|
||||
raise InvalidArgumentException(re.escape(f'Group name length can not be greater than {GroupNameValidator.MAX_GROUP_NAME_LENGTH}.'))
|
||||
|
||||
if group in GroupNameValidator.FORBIDDEN_GROUP_NAMES:
|
||||
raise InvalidArgumentException(re.escape(f'This group name is forbidden, please try with other name.'))
|
||||
|
Reference in New Issue
Block a user