Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Welcome Mutes #51

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion tg_bot/modules/sql/welcome_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,80 @@ def __init__(self, chat_id, name, url, same_line=False):
self.url = url
self.same_line = same_line

class WelcomeMute(BASE):
__tablename__ = "welcome_mutes"
chat_id = Column(String(14), primary_key=True)
welcomemutes = Column(UnicodeText, default=False)

def __init__(self, chat_id, welcomemutes):
self.chat_id = str(chat_id) # ensure string
self.welcomemutes = welcomemutes

class WelcomeMuteUsers(BASE):
__tablename__ = "human_checks"
user_id = Column(Integer, primary_key=True)
chat_id = Column(String(14), primary_key=True)
human_check = Column(Boolean)
def __init__(self, user_id, chat_id, human_check):

self.user_id = (user_id) # ensure string
self.chat_id = str(chat_id)
self.human_check = human_check


Welcome.__table__.create(checkfirst=True)
WelcomeButtons.__table__.create(checkfirst=True)
GoodbyeButtons.__table__.create(checkfirst=True)
WelcomeMute.__table__.create(checkfirst=True)
WelcomeMuteUsers.__table__.create(checkfirst=True)

INSERTION_LOCK = threading.RLock()
WELC_BTN_LOCK = threading.RLock()
LEAVE_BTN_LOCK = threading.RLock()
WM_LOCK = threading.RLock()

def welcome_mutes(chat_id):
try:
welcomemutes = SESSION.query(WelcomeMute).get(str(chat_id))
if welcomemutes:
return welcomemutes.welcomemutes
return False
finally:
SESSION.close()


def set_welcome_mutes(chat_id, welcomemutes):
with WM_LOCK:
prev = SESSION.query(WelcomeMute).get((str(chat_id)))
if prev:
SESSION.delete(prev)
welcome_m = WelcomeMute(str(chat_id), welcomemutes)
SESSION.add(welcome_m)
SESSION.commit()

def set_human_checks(user_id, chat_id):
with INSERTION_LOCK:
human_check = SESSION.query(WelcomeMuteUsers).get((user_id, str(chat_id)))
if not human_check:
human_check = WelcomeMuteUsers(user_id, str(chat_id), True)

else:
human_check.human_check = True

SESSION.add(human_check)
SESSION.commit()

return human_check

def get_human_checks(user_id, chat_id):
try:
human_check = SESSION.query(WelcomeMuteUsers).get((user_id, str(chat_id)))
if not human_check:
return None
human_check = human_check.human_check
return human_check
finally:
SESSION.close()


def get_welc_pref(chat_id):
Expand Down Expand Up @@ -112,6 +178,15 @@ def get_clean_pref(chat_id):
return welc.clean_welcome

return False

def get_welc_mutes_pref(chat_id):
welcomemutes = SESSION.query(WelcomeMute).get(str(chat_id))
SESSION.close()

if welcomemutes:
return welcomemutes.welcomemutes

return False


def set_del_joined(chat_id, del_joined):
Expand All @@ -125,7 +200,6 @@ def set_del_joined(chat_id, del_joined):
SESSION.add(curr)
SESSION.commit()


def get_del_pref(chat_id):
welc = SESSION.query(Welcome).get(str(chat_id))
SESSION.close()
Expand Down
90 changes: 87 additions & 3 deletions tg_bot/modules/welcome.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import html, time
import re
from typing import Optional, List

from telegram import Message, Chat, Update, Bot, User
from telegram import ParseMode, InlineKeyboardMarkup
from telegram import Message, Chat, Update, Bot, User, CallbackQuery
from telegram import ParseMode, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.error import BadRequest
from telegram.ext import MessageHandler, Filters, CommandHandler, run_async
from telegram.ext import MessageHandler, Filters, CommandHandler, run_async, CallbackQueryHandler
from telegram.utils.helpers import mention_markdown, mention_html, escape_markdown

import tg_bot.modules.sql.welcome_sql as sql
from tg_bot.modules.sql.safemode_sql import is_safemoded
from tg_bot.modules.sql.global_bans_sql import get_gbanned_user
from tg_bot import dispatcher, OWNER_ID, LOGGER
from tg_bot.modules.helper_funcs.chat_status import user_admin, can_delete, is_user_ban_protected
from tg_bot.modules.helper_funcs.misc import build_keyboard, revert_buttons
Expand Down Expand Up @@ -94,6 +96,10 @@ def new_member(bot: Bot, update: Update):
LOGGER.exception("ERROR muting user %s in chat %s (%s) due to %s", mems.id, chat.title, chat.id, excp.message)

should_welc, cust_welcome, welc_type = sql.get_welc_pref(chat.id)
welc_mutes = sql.welcome_mutes(chat.id)
user_id = user.id
human_checks = sql.get_human_checks(user_id, chat.id)
gban_checks = get_gbanned_user(user_id)
if should_welc:
sent = None
new_members = update.effective_message.new_chat_members
Expand Down Expand Up @@ -142,6 +148,23 @@ def new_member(bot: Bot, update: Update):

sent = send(update, res, keyboard,
sql.DEFAULT_WELCOME.format(first=first_name)) # type: Optional[Message]


#User exception from mutes:
if is_user_ban_protected(chat, new_mem.id, chat.get_member(new_mem.id)) or human_checks or gban_checks:
continue

#Join welcome:
if welc_mutes == "on":
new_join_mem = "[{}](tg://user?id={})".format(new_mem.first_name, user.id)
msg.reply_text("{},\nClick the button below to prove you're human".format(new_join_mem),
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="Yes, I'm a human",
callback_data="user_join_({})".format(new_mem.id))]]), parse_mode=ParseMode.MARKDOWN)
bot.restrict_chat_member(chat.id, new_mem.id,
can_send_messages=False,
can_send_media_messages=False,
can_send_other_messages=False,
can_add_web_page_previews=False)
delete_join(bot, update)


Expand Down Expand Up @@ -374,6 +397,41 @@ def reset_goodbye(bot: Bot, update: Update) -> str:
"\nReset the goodbye message.".format(html.escape(chat.title),
mention_html(user.id, user.first_name))

@run_async
@user_admin
@loggable
def welcomemute(bot: Bot, update: Update, args: List[str]) -> str:
chat = update.effective_chat # type: Optional[Chat]
user = update.effective_user # type: Optional[User]
msg = update.effective_message # type: Optional[Message]

if len(args) >= 1:
if args[0].lower() in ("off", "no"):
sql.set_welcome_mutes(chat.id, False)
msg.reply_text("I will no longer mute people on joining!")
return "<b>{}:</b>" \
"\n#WELCOME_MUTE" \
"\n<b>Admin:</b> {}" \
"\nHas toggled welcome mute to <b>OFF</b>.".format(html.escape(chat.title),
mention_html(user.id, user.first_name))

elif args[0].lower() in ("on", "yes"):
sql.set_welcome_mutes(chat.id, "on")
msg.reply_text("I will now mute people when they join and"
" click on the button to be unmuted.")
return "<b>{}:</b>" \
"\n#WELCOME_MUTE" \
"\n<b>Admin:</b> {}" \
"\nHas toggled welcome mute to <b>ON</b>.".format(html.escape(chat.title),
mention_html(user.id, user.first_name))
else:
msg.reply_text("Please enter `off` or `on`!", parse_mode=ParseMode.MARKDOWN)
return ""
else:
curr_setting = sql.welcome_mutes(chat.id)
reply = "\n Give me a setting! Choose one of: `off`/`no` or `on`/`yes` only! \nCurrent setting: `{}`"
msg.reply_text(reply.format(curr_setting), parse_mode=ParseMode.MARKDOWN)
return ""

@run_async
@user_admin
Expand Down Expand Up @@ -458,6 +516,26 @@ def delete_join(bot: Bot, update: Update):
if del_join:
update.message.delete()

@run_async
def user_button(bot: Bot, update: Update):
chat = update.effective_chat # type: Optional[Chat]
user = update.effective_user # type: Optional[User]
query = update.callback_query # type: Optional[CallbackQuery]
match = re.match(r"user_join_\((.+?)\)", query.data)
message = update.effective_message # type: Optional[Message]
db_checks = sql.set_human_checks(user.id, chat.id)
join_user = int(match.group(1))

if join_user == user.id:
query.answer(text="Yus! You're a human, Unmuted!")
bot.restrict_chat_member(chat.id, user.id, can_send_messages=True,
can_send_media_messages=True,
can_send_other_messages=True,
can_add_web_page_previews=True)
bot.deleteMessage(chat.id, message.message_id)
db_checks
else:
query.answer(text="You're not allowed to do this!")

WELC_HELP_TXT = "Your group's welcome/goodbye messages can be personalised in multiple ways. If you want the messages" \
" to be individually generated, like the default welcome message is, you can use *these* variables:\n" \
Expand Down Expand Up @@ -527,6 +605,8 @@ def __chat_settings__(chat_id, user_id):
- /resetgoodbye: reset to the default goodbye message.
- /cleanwelcome <on/off>: On new member, try to delete the previous welcome message to avoid spamming the chat.
- /rmjoin <on/off>: when someone joins, try to delete the *user* joined the group message.
- /welcomemute <on/off/yes/no>: all users that join, get muted; a button gets added to the welcome message for them \
to unmute themselves. This proves they aren't a bot!

- /welcomehelp: view more formatting information for custom welcome/goodbye messages.
""".format(WELC_HELP_TXT)
Expand All @@ -542,8 +622,10 @@ def __chat_settings__(chat_id, user_id):
RESET_WELCOME = CommandHandler("resetwelcome", reset_welcome, filters=Filters.group)
RESET_GOODBYE = CommandHandler("resetgoodbye", reset_goodbye, filters=Filters.group)
CLEAN_WELCOME = CommandHandler("cleanwelcome", clean_welcome, pass_args=True, filters=Filters.group)
WELCOMEMUTE_HANDLER = CommandHandler("welcomemute", welcomemute, pass_args=True, filters=Filters.group)
DEL_JOINED = CommandHandler("rmjoin", del_joined, pass_args=True, filters=Filters.group)
WELCOME_HELP = CommandHandler("welcomehelp", welcome_help)
BUTTON_VERIFY_HANDLER = CallbackQueryHandler(user_button, pattern=r"user_join_")

dispatcher.add_handler(NEW_MEM_HANDLER)
dispatcher.add_handler(LEFT_MEM_HANDLER)
Expand All @@ -554,5 +636,7 @@ def __chat_settings__(chat_id, user_id):
dispatcher.add_handler(RESET_WELCOME)
dispatcher.add_handler(RESET_GOODBYE)
dispatcher.add_handler(CLEAN_WELCOME)
dispatcher.add_handler(WELCOMEMUTE_HANDLER)
dispatcher.add_handler(BUTTON_VERIFY_HANDLER)
dispatcher.add_handler(DEL_JOINED)
dispatcher.add_handler(WELCOME_HELP)