def set_url_conversation(bot: telegram.Bot, update: telegram.Update, state): s = state.get_state() keyboard = None message = 'unexpected input!!' if s == 0: if update.message.text in ['hint', 'opdracht', 'nieuws']: message = 'Wat is de url zonder de id?\n bijv. ' \ 'http://www.jotihunt.net/groep/opdracht.php?MID=' state['soort'] = update.message.text else: message = 'kies uit hint, opdracht of nieuws. of /cancel om ' \ 'terug te gaan.' if s == 1: state['url'] = update.message.text s.done() message = 'De url is aangepast voor ' + state['soort'] if keyboard is not None: kb = telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=True, selective=True) bot.sendMessage(update.message.chat_id, message, reply_to_message_id=update.message.message_id, reply_markup=kb) else: kb = telegram.ReplyKeyboardHide() if update.message.chat_id > 0: keyboard = DEFAULT_KEYBOARD kb = telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=False, selective=True) bot.sendMessage(update.message.chat_id, message, reply_to_message_id=update.message.message_id, reply_markup=kb)
def start(bot: Bot, update: Update): users_handler(bot, update) message: Message = update.message with menus_lock: if message.chat_id not in menus: menus[message.chat_id] = Menu() else: # todo remove old keyboard and replace with the new one? pass menu = menus[message.chat_id] api = RpApi.get_instance(settings.Settings().rp_username, settings.Settings().rp_pass) response = api.get_telegram_link(update.effective_user.id) rp_acc = response.data if rp_acc is None: user: User = update.effective_user api.send_telegram_user(user.id, user.first_name, user.last_name, user.username) bot.send_message(update.effective_chat.id, 'Je telegram account is nog niet gelinkt.' 'Vraag aan de homebase of ze dat willen doen. ' 'En zeg daarna /start.', reply_to_message_id=update.effective_message.message_id) text, buttons = menu.get_next_buttons(update, '0', rp_acc) keyboard = [[button] for button in buttons] reply_markup = InlineKeyboardMarkup(keyboard) if update.effective_chat.type == Chat.PRIVATE: keyboard = ReplyKeyboardMarkup([[KeyboardButton('/start met het laten zien van het menu')] , [KeyboardButton('verstuur hunter locatie', request_location=True)]]) else: keyboard = ReplyKeyboardMarkup([]) bot.send_message(update.effective_chat.id, welcome_message, reply_markup=keyboard) message.reply_text(text, reply_markup=reply_markup)
def delete(bot: Bot, update: Update): if not DELETE: return global data_set chat_id = update.message.chat_id user = data_set.participants[update.message.chat_id] user.active_ = False user.delete_participant() try: os.remove('survey/data_incomplete/' + str(user.chat_id_) + '.csv') except OSError: pass try: os.remove('survey/data_complete/' + str(user.chat_id_) + '.csv') except OSError: pass del data_set.participants[update.message.chat_id] try: bot.send_message(chat_id=chat_id, text="Successfully deleted DB entry and user data. To restart enter /start") except TelegramError as error: if error.message == 'Unauthorized': user.pause()
def cancel(bot: telegram.Bot, update: telegram.Update): """ :param bot: :param update: :return: """ chat_id = update.message.chat_id user_id = update.message.from_user.id h = str(user_id) + str(chat_id) try: state = State.states[h] state.cancel() except KeyError: kb = telegram.ReplyKeyboardHide() if update.message.chat_id > 0: keyboard = DEFAULT_KEYBOARD kb = telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=False, selective=True) bot.sendMessage(chat_id, "Er is geen commando actief.", reply_to_message_id=update.message.message_id, reply_markup=kb) Updates.get_updates().botan.track(update.message, 'incorrect_cancel') else: kb = telegram.ReplyKeyboardHide() if update.message.chat_id > 0: keyboard = DEFAULT_KEYBOARD kb = telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=False, selective=True) bot.sendMessage(update.message.chat_id, "Het commando is gestopt.", reply_to_message_id=update.message.message_id, reply_markup=kb) Updates.get_updates().botan.track(update.message, 'cancel')
def bug(bot: telegram.Bot, update: telegram.Update): """ :param bot: :param update: :return: """ chat_id = update.message.chat_id user_id = update.message.from_user.id try: state = State(bot, chat_id, user_id, bug_conversation, bug_done) state['command'] = update.message.text state['from'] = update.message.from_user.name keyboard = telegram.ReplyKeyboardMarkup([['app'], ['site'], ['anders']]) bot.sendMessage(chat_id, "Waar wil je een tip of een top voor " "sturen?\napp/bot/site/anders", reply_to_message_id=update.message.message_id, reply_markup=keyboard) Updates.get_updates().botan.track(update.message, 'bug') except MultipleConversationsError: bot.sendMessage(chat_id, "Er is al een commando actief je kunt dit " "commando niet starten.\n" " type /cancel om het vorige commando te " "stoppen te stoppen", reply_to_message_id=update.message.message_id) Updates.get_updates().botan.track(update.message, 'incorrect_bug')
def register_webhooks(force=False): global BOTS_REGISTERED if BOTS_REGISTERED and not force: return BOTS_REGISTERED = {} for bot_config in settings.TELEGRAM_BOT: bot = Bot(bot_config['token']) if 'webhook' in bot_config: url = bot_config['webhook'] % bot.token if url[-1] != '/': url += '/' else: webhook = reverse('telegram_webhook', kwargs={'token': bot.token}) from django.contrib.sites.models import Site current_site = Site.objects.get_current() url = 'https://' + current_site.domain + webhook bot.set_webhook(url) bot = Bot(bot_config['token']) dispatcher = DjangoDispatcher(bot) register = import_string(bot_config['register']) register(dispatcher) BOTS_REGISTERED[bot.token] = dispatcher logger.info('bot %s registered on url %s', bot.token, url)
def set_phpsessid(bot: telegram.Bot, update: telegram.Update): chat_id = update.message.chat_id user_id = update.message.from_user.id try: state = State(bot, chat_id, user_id, phpsessid_conversation, phpsessid_done) state['command'] = update.message.text state['from'] = update.message.from_user.name message = 'stap 1: login op jotihunt.net\n ' \ 'stap2: zoek uit hoe je cookies van jothunt.net uitleest in je browser. \n ' \ 'stap 3: ga op zook naar de cookie met de naam PHPSESSID.\n ' \ 'stap 4: plak de waarde hier om de cookie te verversen van de bot.\n' \ ' of /cancel om te stoppen' bot.sendMessage(chat_id, message, reply_to_message_id=update.message.message_id) # TODO add a keyboard Updates.get_updates().botan.track(update.message, 'phpsessid') except MultipleConversationsError: bot.sendMessage(chat_id, "Er is al een commando actief je kunt dit " "commando niet starten.\n" " type /cancel om het vorige commando te " "stoppen te stoppeny", reply_to_message_id=update.message.message_id) Updates.get_updates().botan.track(update.message, 'incorrect_phpsessid')
def join(bot: Bot, update): """Unisciti a una partita.""" game = findgamebyid(update.message.chat.id) # Nessuna partita in corso if game is None: bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN) return # Fase di join finita if game.phase != 'Join': game.message(s.error_join_phase_ended) return p = game.findplayerbyid(update.message.from_user['id']) # Giocatore già in partita if p is not None: game.message(s.error_player_already_joined) return # Giocatore senza username if update.message.from_user.username is None: game.message(s.error_no_username) return p = Player(game, update.message.from_user.id, update.message.from_user.username) try: p.message(s.you_joined.format(game=game.name, adminname=game.admin.tusername if game.admin is not None else p.tusername)) except Unauthorized: # Bot bloccato dall'utente game.message(s.error_chat_unavailable) return # Aggiungi il giocatore alla partita game.joinplayer(p) # Salva game.save()
def help_command(bot: telegram.Bot, update: telegram.Update): message = start_message + "\n\n" for commando in CommandHandlerWithHelp.helps: message += '/' + commando + ' - ' + CommandHandlerWithHelp.helps[ commando] + '\n' bot.sendMessage(update.message.chat_id, message) Updates.get_updates().botan.track(update.message, 'help')
def save(bot: Bot, update): """Salva una partita su file.""" game = findgamebyid(update.message.chat.id) if game is not None: game.save() else: bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
def debug(bot: Bot, update): """Visualizza tutti i ruoli e gli id.""" if __debug__: game = findgamebyid(update.message.chat.id) if game is not None: game.revealallroles() else: bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
def error(bot, update, error): try: ch_id = "27002116" starter = Bot(token=token) txt = "An error happened" starter.sendMessage(ch_id, text=txt) except: pass logger.warn('Update "%s" caused error "%s"' % (update, error))
def test(bot: telegram.Bot, update: telegram.Update): bot.sendMessage(update.message.chat_id, 'de bot is online') if update.message.chat_id > 0: url = Updates.get_updates().botan.shorten('http://google.com', update.message.from_user.id) else: url = 'http://google.com' bot.sendMessage(update.message.chat_id, url) Updates.get_updates().botan.track(update.message, 'test')
def debugchangerole(bot: Bot, update): """Cambia il ruolo a un giocatore.""" if __debug__: game = findgamebyid(update.message.chat.id) if game is not None: cmd = update.message.text.split(' ', 2) game.changerole(game.findplayerbyusername(cmd[1]), globals()[cmd[2]]) else: bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
def phpsessid_conversation(bot: telegram.Bot, update: telegram.Update, state): s = state.get_state() if s == 0: state['cookie'] = update.message.text state.done() bot.sendMessage(update.message.chat_id, update.message.from_user.name + ' de cookie is ' 'aangepast.')
def load(bot: Bot, update): """Carica una partita salvata.""" game = findgamebyid(update.message.chat.id) if game is not None: bot.sendMessage(update.message.chat.id, s.error_game_in_progress, parse_mode=ParseMode.MARKDOWN) return file = open(str(update.message.chat.id) + ".p", "rb") game = pickle.load(file) inprogress.append(game) game.message(s.game_loaded)
def endjoin(bot: Bot, update): """Termina la fase di join e inizia quella di votazione.""" game = findgamebyid(update.message.chat.id) if game is not None and game.phase == 'Join': if update.message.from_user.id == game.admin.tid: game.message(s.join_phase_ended) game.startpreset() else: game.message(s.error_not_admin) else: bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
def start(bot: telegram.Bot, update: telegram.Update): if update.message.chat_id > 0: keyboard = telegram.ReplyKeyboardMarkup(DEFAULT_KEYBOARD, one_time_keyboard=False) bot.sendMessage(update.message.chat_id, start_message, reply_markup=keyboard) else: bot.sendMessage(update.message.chat_id, start_message) x = authenticate() x(lambda bot2, update2: print('authenticated:\n' + str(update.to_dict( ))))(bot, update) Updates.get_updates().botan.track(update.message, 'start')
class TelegramBotAlert: def __init__(self): self.model = Model() config = configparser.ConfigParser() config.read('settings.ini') self.__list_of_chat_ids = self.model.get_chat_ids() self.__token = config.get("TELEGRAM", "token") self.__bot = Bot(token=self.__token) def create_alert_message(self, list_of_alredy_online_hosts, list_of_offline_hosts): message = "" if len(list_of_alredy_online_hosts) > 0: serialize_list_of_alredy_online_hosts = create_serialize_list_of_hosts(list_of_alredy_online_hosts) message += self.create_alert_message_with_alredy_online_hosts(serialize_list_of_alredy_online_hosts) if len(list_of_offline_hosts) > 0: serialize_list_of_offline_hosts = create_serialize_list_of_hosts(list_of_offline_hosts) message += self.create_alert_message_with_offline_hosts(serialize_list_of_offline_hosts) else: message += "Все узлы доступны." self.send_message(message) def create_alert_message_with_offline_hosts(self, list_of_hosts): message = "<b>Следующие узлы недоступны!</b>\n" for group in list_of_hosts: message += "\tГруппа: <i>{group_name}</i>\n".format(group_name=group) for host in list_of_hosts[group]: message += "\t\t{host}, {hostip}\n".format(host=host.get_name(), hostip=host.get_ip()) message += "\n" return message def create_alert_message_with_alredy_online_hosts(self, list_of_hosts): message = "<b>Следующие узлы снова доступны:</b>\n" for group in list_of_hosts: message += "\tГруппа: <i>{group_name}</i>\n".format(group_name=group) for host in list_of_hosts[group]: message += "\t\t{host}, {hostip}\n".format(host=host.get_name(), hostip=host.get_ip()) message += "\n" return message def send_message(self, message, send_to="All"): if send_to == "All": for chat_id in self.__list_of_chat_ids: self.__bot.send_message(chat_id=str(chat_id), text=message, parse_mode=ParseMode.HTML) else: self.__bot.send_message(chat_id=str(send_to), text=message, parse_mode=ParseMode.HTML)
def telegram_sender(data, context): ''' Notifies a web hook over HTTP regarding alert. All context parameters are sent, via GET. data['url']: the target web hook context: encoded as GET parameters ''' if 'token' not in data and 'chat_id' not in data: util.die('telegram_sender: missing token or chat_id') from telegram import Bot bot = Bot(data['token']) bot.sendMessage(chat_id=data['chat_id'], text=context['message'])
def stop(bot: Bot, update: Update): global data_set chat_id = update.message.chat_id user = data_set.participants[update.message.chat_id] user.pause() try: message = STOP_TEXT[user.language_] bot.send_message(chat_id=chat_id, text=message, reply_markup=ReplyKeyboardRemove()) except KeyError: message = STOP_TEXT[DEFAULT_LANGUAGE] bot.send_message(chat_id=chat_id, text=message, reply_markup=ReplyKeyboardRemove()) except TelegramError as error: if error.message == 'Unauthorized': user.pause()
def admin_reply(bot, update, args): msg = update.message.to_dict() pyUnipdbot.writedb(msg) servicer = Bot(token=servicetoken) if update.message.from_user.id == 27002116: try: tmp = "/reply " + args[0] + " " sent = bot.sendMessage(chat_id=args[0], text=(update.message.text).replace(tmp, "")) servicer.sendMessage(chat_id=27002116, text=str(sent)) except: servicer.sendMessage(chat_id=27002116, text="error happened") else: bot.sendMessage(chat_id=update.message.chat_id, text="error - you're not powerful enough")
def role(bot: Bot, update): """Visualizza il tuo ruolo.""" game = findgamebyid(update.message.chat.id) if game is not None and game.phase is 'Voting': player = game.findplayerbyid(update.message.from_user.id) if player is not None: if player.alive: player.message(s.role_assigned.format(icon=player.role.icon, name=player.role.name)) game.message(s.check_private) else: game.message(s.error_dead) else: bot.sendMessage(update.message.chat.id, s.error_not_in_game, parse_mode=ParseMode.MARKDOWN) else: bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
def info(bot: Bot, update: Update): global data_set try: user = data_set.participants[update.message.chat_id] message = INFO_TEXT[user.language_] try: bot.sendMessage(update.message.chat_id, text=message) except TelegramError: return except KeyError: message = INFO_TEXT[DEFAULT_LANGUAGE] try: bot.sendMessage(update.message.chat_id, text=message) except TelegramError: return
def main(): # Create the EventHandler and pass it your bot's token. updater = Updater(token) # Get the dispatcher to register handlers dp = updater.dispatcher # on different commands - answer in Telegram dp.addHandler(CommandHandler("help", home)) dp.addHandler(CommandHandler("start", home)) dp.addHandler(CommandHandler("home", home)) dp.addHandler(CommandHandler("botinfo", botinfo)) dp.addHandler(CommandHandler("mensa", mensa)) dp.addHandler(CommandHandler("aulastudio", aulastudio)) dp.addHandler(CommandHandler("biblioteca", biblioteca)) dp.addHandler(CommandHandler("udupadova", udupadova)) dp.addHandler(CommandHandler("diritto_studio", dirittostudio)) for command in commands: dp.addHandler(CommandHandler(command, replier)) dp.addHandler(CommandHandler("reply", admin_reply, pass_args=True)) dp.addHandler(MessageHandler([Filters.location], position)) dp.addHandler(MessageHandler([Filters.text], simpleText)) dp.addHandler(MessageHandler([Filters.audio], simpleText)) dp.addHandler(MessageHandler([Filters.photo], simpleText)) dp.addHandler(MessageHandler([Filters.document], simpleText)) dp.addHandler(MessageHandler([Filters.sticker], simpleText)) dp.addHandler(MessageHandler([Filters.video], simpleText)) dp.addHandler(MessageHandler([Filters.voice], simpleText)) dp.addHandler(MessageHandler([Filters.contact], simpleText)) dp.addErrorHandler(error) updater.start_polling() ch_id = "27002116" starter = Bot(token=token) txt = "I'm starting" starter.sendMessage(ch_id, text=txt) updater.idle() txt = "Bot stopped!" starter.sendMessage(ch_id, text=txt)
def check_updates(b: telegram.Bot, update_id: int) -> int: for update in b.getUpdates( offset=update_id, timeout=INTERVAL, ): message = update.message.text upd_chat_id = update.message.chat_id update_id = update.update_id + 1 cmd = message.lower() if upd_chat_id in CHAT_ID: # commands list if '/ping' in cmd: send('Pong!', ch_id=upd_chat_id) elif 'сиськ' in cmd or '/boobs' in cmd: bot.sendPhoto(chat_id=upd_chat_id, photo=get_boobs_url()) elif 'жоп' in cmd or '/ass' in cmd: bot.sendPhoto(chat_id=upd_chat_id, photo=get_butts_url()) elif 'курс' in cmd or 'currency' in cmd: send(msg=get_currency(), ch_id=upd_chat_id) elif '/ver' in cmd: send(msg=VERSION, ch_id=upd_chat_id) else: pass return update_id
def __init__(self, token=None, base_url=None, workers=4, bot=None): if (token is None) and (bot is None): raise ValueError('`token` or `bot` must be passed') if (token is not None) and (bot is not None): raise ValueError('`token` and `bot` are mutually exclusive') if bot is not None: self.bot = bot else: # we need a connection pool the size of: # * for each of the workers # * 1 for Dispatcher # * 1 for polling Updater (even if webhook is used, we can spare a connection) # * 1 for JobQueue # * 1 for main thread self._request = Request(con_pool_size=workers + 4) self.bot = Bot(token, base_url, request=self._request) self.update_queue = Queue() self.job_queue = JobQueue(self.bot) self.__exception_event = Event() self.dispatcher = Dispatcher( self.bot, self.update_queue, job_queue=self.job_queue, workers=workers, exception_event=self.__exception_event) self.last_update_id = 0 self.logger = logging.getLogger(__name__) self.running = False self.is_idle = False self.httpd = None self.__lock = Lock() self.__threads = [] """:type: list[Thread]"""
def __init__(self, token=None, base_url=None, workers=4, bot=None, job_queue_tick_interval=1.0): if (token is None) and (bot is None): raise ValueError('`token` or `bot` must be passed') if (token is not None) and (bot is not None): raise ValueError('`token` and `bot` are mutually exclusive') if bot is not None: self.bot = bot else: self.bot = Bot(token, base_url) self.update_queue = UpdateQueue() self.job_queue = JobQueue(self.bot, job_queue_tick_interval) self.__exception_event = Event() self.dispatcher = Dispatcher(self.bot, self.update_queue, workers, self.__exception_event) self.last_update_id = 0 self.logger = logging.getLogger(__name__) self.running = False self.is_idle = False self.httpd = None self.__lock = Lock() self.__threads = [] """:type: list[Thread]"""
def __init__(self, auth_key): self.chats = dict() self.users = dict() self.chat_user_actions = dict() self.bot = Updater(auth_key) self.manualbot = Bot(token=auth_key) # Initialize google distance class self.googleDist = travelBotdistance.travelBotdistance() self.googleDist.setUp() # Get the dispatcher to register handlers dp = self.bot.dispatcher # Register commands dp.addTelegramCommandHandler("start", self.start) #dp.addTelegramCommandHandler("search", self.search) dp.addTelegramCommandHandler("help", self.help) dp.addTelegramMessageHandler(self.echo) dp.addErrorHandler(self.error) dest = travelBotdestinations.travelBotdestinations() #self.travelDestinations = dest.load_destinations('./csv/destinations2.csv') self.botnltk = travelBotnltk.travelBotnltk()
def debugjoin(bot: Bot, update): """Aggiungi dei bot alla partita.""" if __debug__: game = findgamebyid(update.message.chat.id) if game is None: bot.sendMessage(update.message.chat.id, s.error_no_games_found, parse_mode=ParseMode.MARKDOWN) return if game.phase != 'Join': game.message(s.error_join_phase_ended) return arg = update.message.text.split(" ") for name in range(1, int(arg[1]) + 1): p = Player(game, int(name), str(name), True) try: game.joinplayer(p, silent=True) except RetryAfter: pass
def add_blackliststicker(bot: Bot, update: Update): msg = update.effective_message # type: Optional[Message] chat = update.effective_chat # type: Optional[Chat] user = update.effective_user # type: Optional[User] words = msg.text.split(None, 1) conn = connected(bot, update, chat, user.id) if conn: chat_id = conn chat_name = dispatcher.bot.getChat(conn).title else: chat_id = update.effective_chat.id if chat.type == "private": return else: chat_name = chat.title if len(words) > 1: text = words[1].replace('https://t.me/addstickers/', '') to_blacklist = list( set(trigger.strip() for trigger in text.split("\n") if trigger.strip())) added = 0 for trigger in to_blacklist: try: get = bot.getStickerSet(trigger) sql.add_to_stickers(chat_id, trigger.lower()) added += 1 except BadRequest: send_message(update.effective_message, "Sticker `{}` can not be found!".format(trigger), parse_mode="markdown") if added == 0: return if len(to_blacklist) == 1: send_message( update.effective_message, "Sticker <code>{}</code> added to blacklist stickers in <b>{}</b>!" .format(html.escape(to_blacklist[0]), chat_name), parse_mode=ParseMode.HTML) else: send_message( update.effective_message, "<code>{}</code> stickers added to blacklist sticker in <b>{}</b>!" .format(added, chat_name), parse_mode=ParseMode.HTML) elif msg.reply_to_message: added = 0 trigger = msg.reply_to_message.sticker.set_name if trigger == None: send_message(update.effective_message, "Sticker is invalid!") return try: get = bot.getStickerSet(trigger) sql.add_to_stickers(chat_id, trigger.lower()) added += 1 except BadRequest: send_message(update.effective_message, "Sticker `{}` can not be found!".format(trigger), parse_mode="markdown") if added == 0: return send_message( update.effective_message, "Sticker <code>{}</code> added to blacklist stickers in <b>{}</b>!" .format(trigger, chat_name), parse_mode=ParseMode.HTML) else: send_message( update.effective_message, "Tell me what stickers you want to add to the blacklist stickers.")
def unfban(bot: Bot, update: Update, args: List[str]): chat = update.effective_chat user = update.effective_user message = update.effective_message fed_id = sql.get_fed_id(chat.id) if not fed_id: update.effective_message.reply_text( "This group is not a part of any federation!") return if is_user_fed_admin(fed_id, user.id) is False: update.effective_message.reply_text( "Only federation admins can do this!") return user_id = extract_user(message, args) if not user_id: message.reply_text("You do not seem to be referring to a user.") return user_chat = bot.get_chat(user_id) if user_chat.type != 'private': message.reply_text("That's not a user!") return fban, fbanreason = sql.get_fban_user(fed_id, user_id) if fban is False: message.reply_text("This user is not fbanned!") if not fbanreason: return return message.reply_text( "I'll give {} a second chance in this federation".format( user_chat.first_name)) chat_list = sql.all_fed_chats(fed_id) for chat in chat_list: try: member = bot.get_chat_member(chat, user_id) if member.status == 'kicked': bot.unban_chat_member(chat, user_id) except BadRequest as excp: if excp.message in UNFBAN_ERRORS: pass else: LOGGER.warning("Cannot remove fban on {} because: {}".format( chat, excp.message)) except TelegramError: pass try: x = sql.un_fban_user(fed_id, user_id) if not x: message.reply_text( "Fban failure, this user may have been un-fedbanned!") return except Exception: pass message.reply_text("This person is un-fbanned.")
def new_member(bot: Bot, update: Update): chat = update.effective_chat # type: Optional[Chat] chat_id = update.effective_chat.id bot_member = chat.get_member(bot.id) should_welc, cust_welcome, welc_type = sql.get_welc_pref(chat.id) if should_welc: new_members = update.effective_message.new_chat_members for new_mem in new_members: # Give the owner a special welcome if new_mem.id == OWNER_ID: update.effective_message.reply_text( "Ayy, pro thug arrived, let's get this party started!") bot.promoteChatMember( chat_id, new_mem.id, can_change_info=bot_member.can_change_info, can_post_messages=bot_member.can_post_messages, can_edit_messages=bot_member.can_edit_messages, can_delete_messages=bot_member.can_delete_messages, # can_invite_users=bot_member.can_invite_users, can_restrict_members=bot_member.can_restrict_members, can_pin_messages=bot_member.can_pin_messages, can_promote_members=bot_member.can_promote_members) continue elif new_mem.id in SUDO_USERS: update.effective_message.reply_text( "Wew, a sudo user arrived!") bot.promoteChatMember( chat_id, new_mem.id, can_change_info=bot_member.can_change_info, can_post_messages=bot_member.can_post_messages, can_edit_messages=bot_member.can_edit_messages, can_delete_messages=bot_member.can_delete_messages, # can_invite_users=bot_member.can_invite_users, can_restrict_members=bot_member.can_restrict_members, can_pin_messages=bot_member.can_pin_messages, can_promote_members=bot_member.can_promote_members) continue # Don't welcome yourself elif new_mem.id == bot.id: continue else: # If welcome message is media, send with appropriate function if welc_type != sql.Types.TEXT and welc_type != sql.Types.BUTTON_TEXT: ENUM_FUNC_MAP[welc_type](chat.id, cust_welcome) return # else, move on first_name = new_mem.first_name or "PersonWithNoName" # edge case of empty name - occurs for some bugs. if cust_welcome: if new_mem.last_name: fullname = "{} {}".format(first_name, new_mem.last_name) else: fullname = first_name count = chat.get_members_count() mention = "[{}](tg://user?id={})".format( first_name, new_mem.id) if new_mem.username: username = "******" + escape_markdown(new_mem.username) else: username = mention valid_format = escape_invalid_curly_brackets( cust_welcome, VALID_WELCOME_FORMATTERS) res = valid_format.format( first=escape_markdown(first_name), last=escape_markdown(new_mem.last_name or first_name), fullname=escape_markdown(fullname), username=username, mention=mention, count=count, chatname=escape_markdown(chat.title), id=new_mem.id) buttons = sql.get_welc_buttons(chat.id) keyb = build_keyboard(buttons) else: res = sql.DEFAULT_WELCOME.format(first=first_name) keyb = [] keyboard = InlineKeyboardMarkup(keyb) send(update, res, keyboard, sql.DEFAULT_WELCOME.format(first=first_name)) else: new_members = update.effective_message.new_chat_members for new_mem in new_members: # Give the owner a special welcome if new_mem.id == OWNER_ID: update.effective_message.reply_text( "Ayy, pro thug arrived, let's get this party started!") bot.promoteChatMember( chat_id, new_mem.id, can_change_info=bot_member.can_change_info, can_post_messages=bot_member.can_post_messages, can_edit_messages=bot_member.can_edit_messages, can_delete_messages=bot_member.can_delete_messages, # can_invite_users=bot_member.can_invite_users, can_restrict_members=bot_member.can_restrict_members, can_pin_messages=bot_member.can_pin_messages, can_promote_members=bot_member.can_promote_members) continue elif new_mem.id in SUDO_USERS: update.effective_message.reply_text( "Wew, a sudo user arrived!") bot.promoteChatMember( chat_id, new_mem.id, can_change_info=bot_member.can_change_info, can_post_messages=bot_member.can_post_messages, can_edit_messages=bot_member.can_edit_messages, can_delete_messages=bot_member.can_delete_messages, # can_invite_users=bot_member.can_invite_users, can_restrict_members=bot_member.can_restrict_members, can_pin_messages=bot_member.can_pin_messages, can_promote_members=bot_member.can_promote_members) continue # Don't welcome yourself elif new_mem.id == bot.id: continue
def runban(bot: Bot, update: Update, args: List[str]): message = update.effective_message if not args: message.reply_text("You don't seem to be referring to a chat/user.") return user_id, chat_id = extract_user_and_text(message, args) if not user_id: message.reply_text("You don't seem to be referring to a user.") return elif not chat_id: message.reply_text("You don't seem to be referring to a chat.") return try: chat = bot.get_chat(chat_id.split()[0]) except BadRequest as excp: if excp.message == "Chat not found": message.reply_text( "Chat not found! Make sure you entered a valid chat ID and I'm part of that chat." ) return else: raise if chat.type == 'private': message.reply_text("I'm sorry, but that's a private chat!") return if not is_bot_admin(chat, bot.id) or not chat.get_member( bot.id).can_restrict_members: message.reply_text( "I can't unrestrict people there! Make sure I'm admin and can unban users." ) return try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text("I can't seem to find this user there") return else: raise if is_user_in_chat(chat, user_id): message.reply_text( "Why are you trying to remotely unban someone that's already in that chat?" ) return if user_id == bot.id: message.reply_text("I'm not gonna UNBAN myself, I'm an admin there!") return try: chat.unban_member(user_id) message.reply_text("Yep, this user can join that chat!") except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text('Unbanned!', quote=False) elif excp.message in RUNBAN_ERRORS: message.reply_text(excp.message) else: LOGGER.warning(update) LOGGER.exception( "ERROR unbanning user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text("Well damn, I can't unban that user.")
def temp_ban(bot: Bot, update: Update, args: List[str]) -> str: chat = update.effective_chat # type: Optional[Chat] user = update.effective_user # type: Optional[User] message = update.effective_message # type: Optional[Message] user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text("You don't seem to be referring to a user.") return "" try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text("I can't seem to find this user") return "" else: raise if is_user_ban_protected(chat, user_id, member): message.reply_text("I really wish I could ban admins...") return "" if user_id == bot.id: message.reply_text("I'm not gonna BAN myself, are you crazy?") return "" if not reason: message.reply_text( "You haven't specified a time to ban this user for!") return "" split_reason = reason.split(None, 1) time_val = split_reason[0].lower() if len(split_reason) > 1: reason = split_reason[1] else: reason = "" bantime = extract_time(message, time_val) if not bantime: return "" log = "<b>{}:</b>" \ "\n#TEMP BANNED" \ "\n<b>Admin:</b> {}" \ "\n<b>User:</b> {} (<code>{}</code>)" \ "\n<b>Time:</b> {}".format(html.escape(chat.title), mention_html(user.id, user.first_name), mention_html(member.user.id, member.user.first_name), member.user.id, time_val) if reason: log += "\n<b>Reason:</b> {}".format(reason) try: chat.kick_member(user_id, until_date=bantime) bot.send_sticker(chat.id, BAN_STICKER) # banhammer marie sticker message.reply_text( "Banned! User will be banned for {}.".format(time_val)) return log except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text( "Banned! User will be banned for {}.".format(time_val), quote=False) return log else: LOGGER.warning(update) LOGGER.exception("ERROR banning user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text("Well damn, I can't ban that user.") return ""
def ungmute(bot: Bot, update: Update, args: List[str]): message = update.effective_message # type: Optional[Message] user_id = extract_user(message, args) if not user_id: message.reply_text("You don't seem to be referring to a user.") return user_chat = bot.get_chat(user_id) if user_chat.type != 'private': message.reply_text("That's not a user!") return if not sql.is_user_gmuted(user_id): message.reply_text("This user is not gmuted!") return muter = update.effective_user # type: Optional[User] message.reply_text("I'll let {} speak again, globally.".format( user_chat.first_name)) send_to_list(bot, SUDO_USERS + SUPPORT_USERS, "{} has ungmuted user {}".format( mention_html(muter.id, muter.first_name), mention_html(user_chat.id, user_chat.first_name)), html=True) chats = get_all_chats() for chat in chats: chat_id = chat.chat_id # Check if this group has disabled gmutes if not sql.does_chat_gmute(chat_id): continue try: member = bot.get_chat_member(chat_id, user_id) if member.status == 'restricted': bot.restrict_chat_member(chat_id, int(user_id), can_send_messages=True, can_send_media_messages=True, can_send_other_messages=True, can_add_web_page_previews=True) except BadRequest as excp: if excp.message == "User is an administrator of the chat": pass elif excp.message == "Chat not found": pass elif excp.message == "Not enough rights to restrict/unrestrict chat member": pass elif excp.message == "User_not_participant": pass elif excp.message == "Method is available for supergroup and channel chats only": pass elif excp.message == "Not in the chat": pass elif excp.message == "Channel_private": pass elif excp.message == "Chat_admin_required": pass else: message.reply_text("Could not un-gmute due to: {}".format( excp.message)) bot.send_message( OWNER_ID, "Could not un-gmute due to: {}".format(excp.message)) return except TelegramError: pass sql.ungmute_user(user_id) send_to_list(bot, SUDO_USERS + SUPPORT_USERS, "un-gmute complete!") message.reply_text("Person has been un-gmuted.")
def runmute(bot: Bot, update: Update, args: List[str]): message = update.effective_message if not args: message.reply_text("You don't seem to be referring to a chat/user.") return user_id, chat_id = extract_user_and_text(message, args) if not user_id: message.reply_text("You don't seem to be referring to a user.") return elif not chat_id: message.reply_text("You don't seem to be referring to a chat.") return try: chat = bot.get_chat(chat_id.split()[0]) except BadRequest as excp: if excp.message == "Chat not found": message.reply_text( "Chat not found! Make sure you entered a valid chat ID and I'm part of that chat." ) return else: raise if chat.type == 'private': message.reply_text("I'm sorry, but that's a private chat!") return if not is_bot_admin(chat, bot.id) or not chat.get_member( bot.id).can_restrict_members: message.reply_text( "I can't unrestrict people there! Make sure I'm admin and can unban users." ) return try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text("I can't seem to find this user there") return else: raise if is_user_in_chat(chat, user_id): if member.can_send_messages and member.can_send_media_messages \ and member.can_send_other_messages and member.can_add_web_page_previews: message.reply_text( "This user already has the right to speak in that chat.") return if user_id == bot.id: message.reply_text("I'm not gonna UNMUTE myself, I'm an admin there!") return try: bot.restrict_chat_member(chat.id, int(user_id), can_send_messages=True, can_send_media_messages=True, can_send_other_messages=True, can_add_web_page_previews=True) message.reply_text("Yep, this user can talk in that chat!") except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text('Unmuted!', quote=False) elif excp.message in RUNMUTE_ERRORS: message.reply_text(excp.message) else: LOGGER.warning(update) LOGGER.exception( "ERROR unmnuting user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text("Well damn, I can't unmute that user.")
def main() -> None: # initialise bot and set commands bot = Bot(token=TELEGRAM_BOT_TOKEN) bot.set_my_commands([ BotCommand(command='start', description='start the bot session'), BotCommand(command='age', description='change age preference'), BotCommand(command='addpincode', description='add pincode'), BotCommand(command='getpincodes', description='get registered pincodes'), BotCommand(command='alert', description='enable alerts on new slots'), BotCommand(command='resume', description='resume alerts on new slots'), BotCommand(command='pause', description='disable alerts on new slots'), BotCommand(command='delete', description='delete user data'), BotCommand(command='help', description='provide help on how to use the bot'), ]) # connect and create tables db.connect() db.create_tables([ User, ]) # create the required index # TODO: # User.add_index(User.enabled, User.pincode, # where=((User.enabled == True) & (User.pincode.is_null(False)))) # initialise the handler updater = Updater(TELEGRAM_BOT_TOKEN) # Add handlers updater.dispatcher.add_handler(CommandHandler("start", start)) updater.dispatcher.add_handler(CommandHandler("age", age_command)) updater.dispatcher.add_handler( CommandHandler("addpincode", pincode_command)) updater.dispatcher.add_handler( CommandHandler("getpincodes", get_pincodes_command)) updater.dispatcher.add_handler(CommandHandler("alert", setup_alert_command)) updater.dispatcher.add_handler( CommandHandler("resume", setup_alert_command)) updater.dispatcher.add_handler( CommandHandler("pause", disable_alert_command)) updater.dispatcher.add_handler(CommandHandler("delete", delete_cmd_handler)) updater.dispatcher.add_handler(CommandHandler("help", help_command)) updater.dispatcher.add_handler( CallbackQueryHandler(set_age_preference, pattern=AGE_BUTTON_REGEX)) updater.dispatcher.add_handler( CallbackQueryHandler(cmd_button_handler, pattern=CMD_BUTTON_REGEX)) updater.dispatcher.add_handler( MessageHandler( Filters.regex(re.compile(PINCODE_PREFIX_REGEX, re.IGNORECASE)), set_pincode)) updater.dispatcher.add_handler( MessageHandler( Filters.regex(re.compile(DISABLE_TEXT_REGEX, re.IGNORECASE)), disable_alert_command)) updater.dispatcher.add_handler(MessageHandler(~Filters.command, default)) updater.dispatcher.add_error_handler(error_handler) # launch two background threads, one for slow worker (age group 45+) and another for fast one (age group 18-44) threading.Thread(target=frequent_background_worker).start() threading.Thread(target=periodic_background_worker).start() # Start the Bot updater.start_polling() # block it, baby updater.idle()
def background_worker(age_limit: AgeRangePref): bot = Bot(token=TELEGRAM_BOT_TOKEN) time_now = datetime.now() # find all distinct pincodes where pincode is not null and at least one user exists with alerts enabled query = User.select( User.pincode).where((User.pincode.is_null(False)) & (User.enabled == True) & ((User.age_limit == AgeRangePref.MinAgeAny) | (User.age_limit == age_limit))).distinct() # TODO: Quick hack to load all pincodes in memory query = list(query) counter = 0 for distinct_user in query: if counter == 20: # sleep, since we have hit CoWin APIs # current api limit is 100 requests/300s time.sleep(COWIN_API_DELAY_INTERVAL) counter = 0 vaccination_centers = [] regular_list = [] lst = distinct_user.pincode.split(":") for pincode in lst: counter = counter + 1 regular_list.append(get_available_centers_by_pin(pincode)) if not any(regular_list): continue vaccination_centers = list(itertools.chain(*regular_list)) if not vaccination_centers: continue # find all users for this pincode and alerts enabled user_query = User.select().where( (User.pincode == distinct_user.pincode) & (User.enabled == True) & ((User.age_limit == AgeRangePref.MinAgeAny) | (User.age_limit == age_limit))) for user in user_query: delta = time_now - user.last_alert_sent_at # if user age limit is 45, then we shouldn't ping them too often if user.age_limit == AgeRangePref.MinAge45: if delta.seconds < MIN_45_NOTIFICATION_DELAY: continue filtered_centers = filter_centers_by_age_limit( user.age_limit, vaccination_centers) if not filtered_centers: continue send_alert_to_user(bot, user, filtered_centers) # for users with age limit of 18, we send the alert if user.age_limit == AgeRangePref.MinAge18: filtered_centers = filter_centers_by_age_limit( user.age_limit, vaccination_centers) if not filtered_centers: continue filtered_centers = filter_centers_by_age_limit( user.age_limit, vaccination_centers) if not filtered_centers: continue send_alert_to_user(bot, user, filtered_centers) # here comes the tricky part. for users who have set up both # we would want to send 18-44 alerts more often than 45+ if user.age_limit == AgeRangePref.MinAgeAny: filtered_centers: List[VaccinationCenter] if delta.seconds < MIN_45_NOTIFICATION_DELAY: # include only 18-44 results filtered_centers = filter_centers_by_age_limit( AgeRangePref.MinAge18, vaccination_centers) else: # include both results filtered_centers = filter_centers_by_age_limit( user.age_limit, vaccination_centers) if not filtered_centers: continue send_alert_to_user(bot, user, filtered_centers)
def do_start(bot: Bot, update: Update): bot.send_message( chat_id=update.message.chat_id, text='Привет, отправь мне что-нибудь', )
def sendMessage(text: str, bot: Bot, update: Update): return bot.send_message(update.message.chat_id, reply_to_message_id=update.message.message_id, text=text, parse_mode=ParseMode.HTML)
class Updater(object): """ This class, which employs the :class:`telegram.ext.Dispatcher`, provides a frontend to :class:`telegram.Bot` to the programmer, so they can focus on coding the bot. Its purpose is to receive the updates from Telegram and to deliver them to said dispatcher. It also runs in a separate thread, so the user can interact with the bot, for example on the command line. The dispatcher supports handlers for different kinds of data: Updates from Telegram, basic text commands and even arbitrary types. The updater can be started as a polling service or, for production, use a webhook to receive updates. This is achieved using the WebhookServer and WebhookHandler classes. Attributes: bot (:class:`telegram.Bot`): The bot used with this Updater. user_sig_handler (:obj:`signal`): signals the updater will respond to. update_queue (:obj:`Queue`): Queue for the updates. job_queue (:class:`telegram.ext.JobQueue`): Jobqueue for the updater. dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that handles the updates and dispatches them to the handlers. running (:obj:`bool`): Indicates if the updater is running. persistence (:class:`telegram.ext.BasePersistence`): Optional. The persistence class to store data that should be persistent over restarts. use_context (:obj:`bool`, optional): ``True`` if using context based callbacks. Args: token (:obj:`str`, optional): The bot's token given by the @BotFather. base_url (:obj:`str`, optional): Base_url for the bot. workers (:obj:`int`, optional): Amount of threads in the thread pool for functions decorated with ``@run_async``. bot (:class:`telegram.Bot`, optional): A pre-initialized bot instance. If a pre-initialized bot is used, it is the user's responsibility to create it using a `Request` instance with a large enough connection pool. private_key (:obj:`bytes`, optional): Private key for decryption of telegram passport data. private_key_password (:obj:`bytes`, optional): Password for above private key. user_sig_handler (:obj:`function`, optional): Takes ``signum, frame`` as positional arguments. This will be called when a signal is received, defaults are (SIGINT, SIGTERM, SIGABRT) setable with :attr:`idle`. request_kwargs (:obj:`dict`, optional): Keyword args to control the creation of a `telegram.utils.request.Request` object (ignored if `bot` argument is used). The request_kwargs are very useful for the advanced users who would like to control the default timeouts and/or control the proxy used for http communication. use_context (:obj:`bool`, optional): If set to ``True`` Use the context based callback API. During the deprecation period of the old API the default is ``False``. **New users**: set this to ``True``. persistence (:class:`telegram.ext.BasePersistence`, optional): The persistence class to store data that should be persistent over restarts. Note: You must supply either a :attr:`bot` or a :attr:`token` argument. Raises: ValueError: If both :attr:`token` and :attr:`bot` are passed or none of them. """ _request = None def __init__(self, token=None, base_url=None, workers=4, bot=None, private_key=None, private_key_password=None, user_sig_handler=None, request_kwargs=None, persistence=None, use_context=False): if (token is None) and (bot is None): raise ValueError('`token` or `bot` must be passed') if (token is not None) and (bot is not None): raise ValueError('`token` and `bot` are mutually exclusive') if (private_key is not None) and (bot is not None): raise ValueError('`bot` and `private_key` are mutually exclusive') self.logger = logging.getLogger(__name__) con_pool_size = workers + 4 if bot is not None: self.bot = bot if bot.request.con_pool_size < con_pool_size: self.logger.warning( 'Connection pool of Request object is smaller than optimal value (%s)', con_pool_size) else: # we need a connection pool the size of: # * for each of the workers # * 1 for Dispatcher # * 1 for polling Updater (even if webhook is used, we can spare a connection) # * 1 for JobQueue # * 1 for main thread if request_kwargs is None: request_kwargs = {} if 'con_pool_size' not in request_kwargs: request_kwargs['con_pool_size'] = con_pool_size self._request = Request(**request_kwargs) self.bot = Bot(token, base_url, request=self._request, private_key=private_key, private_key_password=private_key_password) self.user_sig_handler = user_sig_handler self.update_queue = Queue() self.job_queue = JobQueue() self.__exception_event = Event() self.persistence = persistence self.dispatcher = Dispatcher( self.bot, self.update_queue, job_queue=self.job_queue, workers=workers, exception_event=self.__exception_event, persistence=persistence, use_context=use_context) self.job_queue.set_dispatcher(self.dispatcher) self.last_update_id = 0 self.running = False self.is_idle = False self.httpd = None self.__lock = Lock() self.__threads = [] def _init_thread(self, target, name, *args, **kwargs): thr = Thread(target=self._thread_wrapper, name=name, args=(target,) + args, kwargs=kwargs) thr.start() self.__threads.append(thr) def _thread_wrapper(self, target, *args, **kwargs): thr_name = current_thread().name self.logger.debug('{0} - started'.format(thr_name)) try: target(*args, **kwargs) except Exception: self.__exception_event.set() self.logger.exception('unhandled exception in %s', thr_name) raise self.logger.debug('{0} - ended'.format(thr_name)) def start_polling(self, poll_interval=0.0, timeout=10, clean=False, bootstrap_retries=-1, read_latency=2., allowed_updates=None): """Starts polling updates from Telegram. Args: poll_interval (:obj:`float`, optional): Time to wait between polling updates from Telegram in seconds. Default is 0.0. timeout (:obj:`float`, optional): Passed to :attr:`telegram.Bot.get_updates`. clean (:obj:`bool`, optional): Whether to clean any pending updates on Telegram servers before actually starting to poll. Default is False. bootstrap_retries (:obj:`int`, optional): Whether the bootstrapping phase of the `Updater` will retry on failures on the Telegram server. * < 0 - retry indefinitely (default) * 0 - no retries * > 0 - retry up to X times allowed_updates (List[:obj:`str`], optional): Passed to :attr:`telegram.Bot.get_updates`. read_latency (:obj:`float` | :obj:`int`, optional): Grace time in seconds for receiving the reply from server. Will be added to the `timeout` value and used as the read timeout from server (Default: 2). Returns: :obj:`Queue`: The update queue that can be filled from the main thread. """ with self.__lock: if not self.running: self.running = True # Create & start threads self.job_queue.start() dispatcher_ready = Event() self._init_thread(self.dispatcher.start, "dispatcher", ready=dispatcher_ready) self._init_thread(self._start_polling, "updater", poll_interval, timeout, read_latency, bootstrap_retries, clean, allowed_updates) dispatcher_ready.wait() # Return the update queue so the main thread can insert updates return self.update_queue def start_webhook(self, listen='127.0.0.1', port=80, url_path='', cert=None, key=None, clean=False, bootstrap_retries=0, webhook_url=None, allowed_updates=None): """ Starts a small http server to listen for updates via webhook. If cert and key are not provided, the webhook will be started directly on http://listen:port/url_path, so SSL can be handled by another application. Else, the webhook will be started on https://listen:port/url_path Args: listen (:obj:`str`, optional): IP-Address to listen on. Default ``127.0.0.1``. port (:obj:`int`, optional): Port the bot should be listening on. Default ``80``. url_path (:obj:`str`, optional): Path inside url. cert (:obj:`str`, optional): Path to the SSL certificate file. key (:obj:`str`, optional): Path to the SSL key file. clean (:obj:`bool`, optional): Whether to clean any pending updates on Telegram servers before actually starting the webhook. Default is ``False``. bootstrap_retries (:obj:`int`, optional): Whether the bootstrapping phase of the `Updater` will retry on failures on the Telegram server. * < 0 - retry indefinitely (default) * 0 - no retries * > 0 - retry up to X times webhook_url (:obj:`str`, optional): Explicitly specify the webhook url. Useful behind NAT, reverse proxy, etc. Default is derived from `listen`, `port` & `url_path`. allowed_updates (List[:obj:`str`], optional): Passed to :attr:`telegram.Bot.set_webhook`. Returns: :obj:`Queue`: The update queue that can be filled from the main thread. """ with self.__lock: if not self.running: self.running = True # Create & start threads self.job_queue.start() self._init_thread(self.dispatcher.start, "dispatcher"), self._init_thread(self._start_webhook, "updater", listen, port, url_path, cert, key, bootstrap_retries, clean, webhook_url, allowed_updates) # Return the update queue so the main thread can insert updates return self.update_queue def _start_polling(self, poll_interval, timeout, read_latency, bootstrap_retries, clean, allowed_updates): # pragma: no cover # Thread target of thread 'updater'. Runs in background, pulls # updates from Telegram and inserts them in the update queue of the # Dispatcher. self.logger.debug('Updater thread started (polling)') self._bootstrap(bootstrap_retries, clean=clean, webhook_url='', allowed_updates=None) self.logger.debug('Bootstrap done') def polling_action_cb(): updates = self.bot.get_updates( self.last_update_id, timeout=timeout, read_latency=read_latency, allowed_updates=allowed_updates) if updates: if not self.running: self.logger.debug('Updates ignored and will be pulled again on restart') else: for update in updates: self.update_queue.put(update) self.last_update_id = updates[-1].update_id + 1 return True def polling_onerr_cb(exc): # Put the error into the update queue and let the Dispatcher # broadcast it self.update_queue.put(exc) self._network_loop_retry(polling_action_cb, polling_onerr_cb, 'getting Updates', poll_interval) def _network_loop_retry(self, action_cb, onerr_cb, description, interval): """Perform a loop calling `action_cb`, retrying after network errors. Stop condition for loop: `self.running` evaluates False or return value of `action_cb` evaluates False. Args: action_cb (:obj:`callable`): Network oriented callback function to call. onerr_cb (:obj:`callable`): Callback to call when TelegramError is caught. Receives the exception object as a parameter. description (:obj:`str`): Description text to use for logs and exception raised. interval (:obj:`float` | :obj:`int`): Interval to sleep between each call to `action_cb`. """ self.logger.debug('Start network loop retry %s', description) cur_interval = interval while self.running: try: if not action_cb(): break except RetryAfter as e: self.logger.info('%s', e) cur_interval = 0.5 + e.retry_after except TimedOut as toe: self.logger.debug('Timed out %s: %s', description, toe) # If failure is due to timeout, we should retry asap. cur_interval = 0 except InvalidToken as pex: self.logger.error('Invalid token; aborting') raise pex except TelegramError as te: self.logger.error('Error while %s: %s', description, te) onerr_cb(te) cur_interval = self._increase_poll_interval(cur_interval) else: cur_interval = interval if cur_interval: sleep(cur_interval) @staticmethod def _increase_poll_interval(current_interval): # increase waiting times on subsequent errors up to 30secs if current_interval == 0: current_interval = 1 elif current_interval < 30: current_interval += current_interval / 2 elif current_interval > 30: current_interval = 30 return current_interval def _start_webhook(self, listen, port, url_path, cert, key, bootstrap_retries, clean, webhook_url, allowed_updates): self.logger.debug('Updater thread started (webhook)') use_ssl = cert is not None and key is not None if not url_path.startswith('/'): url_path = '/{0}'.format(url_path) # Create Tornado app instance app = WebhookAppClass(url_path, self.bot, self.update_queue) # Form SSL Context # An SSLError is raised if the private key does not match with the certificate if use_ssl: try: ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_ctx.load_cert_chain(cert, key) except ssl.SSLError: raise TelegramError('Invalid SSL Certificate') else: ssl_ctx = None # Create and start server self.httpd = WebhookServer(listen, port, app, ssl_ctx) if use_ssl: # DO NOT CHANGE: Only set webhook if SSL is handled by library if not webhook_url: webhook_url = self._gen_webhook_url(listen, port, url_path) self._bootstrap( max_retries=bootstrap_retries, clean=clean, webhook_url=webhook_url, cert=open(cert, 'rb'), allowed_updates=allowed_updates) elif clean: self.logger.warning("cleaning updates is not supported if " "SSL-termination happens elsewhere; skipping") self.httpd.serve_forever() @staticmethod def _gen_webhook_url(listen, port, url_path): return 'https://{listen}:{port}{path}'.format(listen=listen, port=port, path=url_path) def _bootstrap(self, max_retries, clean, webhook_url, allowed_updates, cert=None, bootstrap_interval=5): retries = [0] def bootstrap_del_webhook(): self.bot.delete_webhook() return False def bootstrap_clean_updates(): self.logger.debug('Cleaning updates from Telegram server') updates = self.bot.get_updates() while updates: updates = self.bot.get_updates(updates[-1].update_id + 1) return False def bootstrap_set_webhook(): self.bot.set_webhook( url=webhook_url, certificate=cert, allowed_updates=allowed_updates) return False def bootstrap_onerr_cb(exc): if not isinstance(exc, Unauthorized) and (max_retries < 0 or retries[0] < max_retries): retries[0] += 1 self.logger.warning('Failed bootstrap phase; try=%s max_retries=%s', retries[0], max_retries) else: self.logger.error('Failed bootstrap phase after %s retries (%s)', retries[0], exc) raise exc # Cleaning pending messages is done by polling for them - so we need to delete webhook if # one is configured. # We also take this chance to delete pre-configured webhook if this is a polling Updater. # NOTE: We don't know ahead if a webhook is configured, so we just delete. if clean or not webhook_url: self._network_loop_retry(bootstrap_del_webhook, bootstrap_onerr_cb, 'bootstrap del webhook', bootstrap_interval) retries[0] = 0 # Clean pending messages, if requested. if clean: self._network_loop_retry(bootstrap_clean_updates, bootstrap_onerr_cb, 'bootstrap clean updates', bootstrap_interval) retries[0] = 0 sleep(1) # Restore/set webhook settings, if needed. Again, we don't know ahead if a webhook is set, # so we set it anyhow. if webhook_url: self._network_loop_retry(bootstrap_set_webhook, bootstrap_onerr_cb, 'bootstrap set webhook', bootstrap_interval) def stop(self): """Stops the polling/webhook thread, the dispatcher and the job queue.""" self.job_queue.stop() with self.__lock: if self.running or self.dispatcher.has_running_threads: self.logger.debug('Stopping Updater and Dispatcher...') self.running = False self._stop_httpd() self._stop_dispatcher() self._join_threads() # Stop the Request instance only if it was created by the Updater if self._request: self._request.stop() def _stop_httpd(self): if self.httpd: self.logger.debug('Waiting for current webhook connection to be ' 'closed... Send a Telegram message to the bot to exit ' 'immediately.') self.httpd.shutdown() self.httpd = None def _stop_dispatcher(self): self.logger.debug('Requesting Dispatcher to stop...') self.dispatcher.stop() def _join_threads(self): for thr in self.__threads: self.logger.debug('Waiting for {0} thread to end'.format(thr.name)) thr.join() self.logger.debug('{0} thread has ended'.format(thr.name)) self.__threads = [] def signal_handler(self, signum, frame): self.is_idle = False if self.running: self.logger.info('Received signal {} ({}), stopping...'.format( signum, get_signal_name(signum))) if self.persistence: # Update user_data and chat_data before flushing self.dispatcher.update_persistence() self.persistence.flush() self.stop() if self.user_sig_handler: self.user_sig_handler(signum, frame) else: self.logger.warning('Exiting immediately!') import os os._exit(1) def idle(self, stop_signals=(SIGINT, SIGTERM, SIGABRT)): """Blocks until one of the signals are received and stops the updater. Args: stop_signals (:obj:`iterable`): Iterable containing signals from the signal module that should be subscribed to. Updater.stop() will be called on receiving one of those signals. Defaults to (``SIGINT``, ``SIGTERM``, ``SIGABRT``). """ for sig in stop_signals: signal(sig, self.signal_handler) self.is_idle = True while self.is_idle: sleep(1)
def settings_button(bot: Bot, update: Update): query = update.callback_query user = update.effective_user mod_match = re.match(r"stngs_module\((.+?),(.+?)\)", query.data) prev_match = re.match(r"stngs_prev\((.+?),(.+?)\)", query.data) next_match = re.match(r"stngs_next\((.+?),(.+?)\)", query.data) back_match = re.match(r"stngs_back\((.+?)\)", query.data) try: if mod_match: chat_id = mod_match.group(1) module = mod_match.group(2) chat = bot.get_chat(chat_id) text = "*{}* has the following settings for the *{}* module:\n\n".format(escape_markdown(chat.title), CHAT_SETTINGS[module].__mod_name__) + \ CHAT_SETTINGS[module].__chat_settings__(chat_id, user.id) query.message.reply_text(text=text, parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( [[InlineKeyboardButton(text="Back", callback_data="stngs_back({})".format(chat_id))]])) elif prev_match: chat_id = prev_match.group(1) curr_page = int(prev_match.group(2)) chat = bot.get_chat(chat_id) query.message.reply_text("Hi there! There are quite a few settings for {} - go ahead and pick what " "you're interested in.".format(chat.title), reply_markup=InlineKeyboardMarkup( paginate_modules(curr_page - 1, CHAT_SETTINGS, "stngs", chat=chat_id))) elif next_match: chat_id = next_match.group(1) next_page = int(next_match.group(2)) chat = bot.get_chat(chat_id) query.message.reply_text("Hi there! There are quite a few settings for {} - go ahead and pick what " "you're interested in.".format(chat.title), reply_markup=InlineKeyboardMarkup( paginate_modules(next_page + 1, CHAT_SETTINGS, "stngs", chat=chat_id))) elif back_match: chat_id = back_match.group(1) chat = bot.get_chat(chat_id) query.message.reply_text(text="Hi there! There are quite a few settings for {} - go ahead and pick what " "you're interested in.".format(escape_markdown(chat.title)), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup(paginate_modules(0, CHAT_SETTINGS, "stngs", chat=chat_id))) # ensure no spinny white circle bot.answer_callback_query(query.id) query.message.delete() except BadRequest as excp: if excp.message == "Message is not modified": pass elif excp.message == "Query_id_invalid": pass elif excp.message == "Message can't be deleted": pass else: LOGGER.exception("Exception in settings buttons. %s", str(query.data))
def temp_nomedia(bot: Bot, update: Update, args: List[str]) -> str: chat = update.effective_chat user = update.effective_user message = update.effective_message conn = connected(bot, update, chat, user.id) if conn: chatD = dispatcher.bot.getChat(conn) else: if chat.type == "private": return else: chatD = chat user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text(tld(chat.id, "mute_not_refer")) return "" try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text(tld(chat.id, "mute_not_existed")) return "" else: raise if is_user_admin(chat, user_id, member): message.reply_text(tld(chat.id, "restrict_is_admin")) return "" if user_id == bot.id: message.reply_text(tld(chat.id, "restrict_is_bot")) return "" if not reason: message.reply_text(tld(chat.id, "nomedia_need_time")) return "" split_reason = reason.split(None, 1) time_val = split_reason[0].lower() if len(split_reason) > 1: reason = split_reason[1] else: reason = "" mutetime = extract_time(message, time_val) if not mutetime: return "" log = "<b>{}:</b>" \ "\n#TEMP RESTRICTED" \ "\n<b>• Admin:</b> {}" \ "\n<b>• User:</b> {}" \ "\n<b>• ID:</b> <code>{}</code>" \ "\n<b>• Time:</b> {}".format(html.escape(chat.title), mention_html(user.id, user.first_name), mention_html(member.user.id, member.user.first_name), user_id, time_val) if reason: log += tld(chat.id, "bans_logger_reason").format(reason) try: if member.can_send_messages is None or member.can_send_messages: bot.restrict_chat_member(chat.id, user_id, until_date=mutetime, can_send_messages=True, can_send_media_messages=False, can_send_other_messages=False, can_add_web_page_previews=False) message.reply_text( tld(chat.id, "nomedia_success").format(time_val, chatD.title)) return log else: message.reply_text( tld(chat.id, "restrict_already_restricted").format(chatD.title)) except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text(tld(chat.id, "nomedia_success").format( time_val, chatD.title), quote=False) return log else: LOGGER.warning(update) LOGGER.exception("ERROR muting user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text(tld(chat.id, "restrict_cant_restricted")) return ""
def del_blackliststicker(bot: Bot, update: Update): chat = update.effective_chat # type: Optional[Chat] message = update.effective_message # type: Optional[Message] user = update.effective_user to_match = message.sticker if not to_match: return getmode, value = sql.get_blacklist_setting(chat.id) chat_filters = sql.get_chat_stickers(chat.id) for trigger in chat_filters: if to_match.set_name.lower() == trigger.lower(): try: if getmode == 0: return elif getmode == 1: message.delete() elif getmode == 2: message.delete() warn(update.effective_user, chat, "Using sticker '{}' which in blacklist stickers". format(trigger), message, update.effective_user, conn=False) return elif getmode == 3: message.delete() bot.restrict_chat_member(chat.id, update.effective_user.id, can_send_messages=False) bot.sendMessage( chat.id, "{} muted because using '{}' which in blacklist stickers" .format(mention_markdown(user.id, user.first_name), trigger), parse_mode="markdown") return elif getmode == 4: message.delete() res = chat.unban_member(update.effective_user.id) if res: bot.sendMessage( chat.id, "{} kicked because using '{}' which in blacklist stickers" .format(mention_markdown(user.id, user.first_name), trigger), parse_mode="markdown") return elif getmode == 5: message.delete() chat.kick_member(user.id) bot.sendMessage( chat.id, "{} banned because using '{}' which in blacklist stickers" .format(mention_markdown(user.id, user.first_name), trigger), parse_mode="markdown") return elif getmode == 6: message.delete() bantime = extract_time(message, value) chat.kick_member(user.id, until_date=bantime) bot.sendMessage( chat.id, "{} banned for {} because using '{}' which in blacklist stickers" .format(mention_markdown(user.id, user.first_name), value, trigger), parse_mode="markdown") return elif getmode == 7: message.delete() mutetime = extract_time(message, value) bot.restrict_chat_member(chat.id, user.id, until_date=mutetime, can_send_messages=False) bot.sendMessage( chat.id, "{} muted for {} because using '{}' which in blacklist stickers" .format(mention_markdown(user.id, user.first_name), value, trigger), parse_mode="markdown") return except BadRequest as excp: if excp.message == "Message to delete not found": pass else: LOGGER.exception("Error while deleting blacklist message.") break
def del_blacklist(bot: Bot, update: Update): chat = update.effective_chat # type: Optional[Chat] message = update.effective_message # type: Optional[Message] user = update.effective_user to_match = extract_text(message) if not to_match: return getmode, value = sql.get_blacklist_setting(chat.id) chat_filters = sql.get_chat_blacklist(chat.id) for trigger in chat_filters: pattern = r"( |^|[^\w])" + re.escape(trigger) + r"( |$|[^\w])" if re.search(pattern, to_match, flags=re.IGNORECASE): try: if getmode == 0: return elif getmode == 1: message.delete() elif getmode == 2: message.delete() warn(update.effective_user, chat, tl(update.effective_message, "Mengatakan kata '{}' yang ada di daftar hitam"). format(trigger), message, update.effective_user, conn=False) return elif getmode == 3: message.delete() bot.restrict_chat_member(chat.id, update.effective_user.id, can_send_messages=False) bot.sendMessage( chat.id, tl( update.effective_message, "{} di bisukan karena mengatakan kata '{}' yang ada di daftar hitam" ).format(mention_markdown(user.id, user.first_name), trigger), parse_mode="markdown") return elif getmode == 4: message.delete() res = chat.unban_member(update.effective_user.id) if res: bot.sendMessage( chat.id, tl( update.effective_message, "{} di tendang karena mengatakan kata '{}' yang ada di daftar hitam" ).format( mention_markdown(user.id, user.first_name), trigger), parse_mode="markdown") return elif getmode == 5: message.delete() chat.kick_member(user.id) bot.sendMessage( chat.id, tl( update.effective_message, "{} di blokir karena mengatakan kata '{}' yang ada di daftar hitam" ).format(mention_markdown(user.id, user.first_name), trigger), parse_mode="markdown") return elif getmode == 6: message.delete() bantime = extract_time(message, value) chat.kick_member(user.id, until_date=bantime) bot.sendMessage( chat.id, tl( update.effective_message, "{} di blokir selama {} karena mengatakan kata '{}' yang ada di daftar hitam" ).format(mention_markdown(user.id, user.first_name), value, trigger), parse_mode="markdown") return elif getmode == 7: message.delete() mutetime = extract_time(message, value) bot.restrict_chat_member(chat.id, user.id, until_date=mutetime, can_send_messages=False) bot.sendMessage( chat.id, tl( update.effective_message, "{} di bisukan selama {} karena mengatakan kata '{}' yang ada di daftar hitam" ).format(mention_markdown(user.id, user.first_name), value, trigger), parse_mode="markdown") return except BadRequest as excp: if excp.message == "Message to delete not found": pass else: LOGGER.exception("Error while deleting blacklist message.") break
def gmute(bot: Bot, update: Update, args: List[str]): message = update.effective_message # type: Optional[Message] user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text("You don't seem to be referring to a user.") return if int(user_id) in SUDO_USERS: message.reply_text( "I spy, with my little eye... a sudo user war! Why are you guys turning on each other?" ) return if int(user_id) in SUPPORT_USERS: message.reply_text( "OOOH someone's trying to gmute a support user! *grabs popcorn*") return if user_id == bot.id: message.reply_text( "-_- So funny, lets gmute myself why don't I? Nice try.") return try: user_chat = bot.get_chat(user_id) except BadRequest as excp: message.reply_text(excp.message) return if user_chat.type != 'private': message.reply_text("That's not a user!") return if sql.is_user_gmuted(user_id): if not reason: message.reply_text( "This user is already gmuted; I'd change the reason, but you haven't given me one..." ) return success = sql.update_gmute_reason( user_id, user_chat.username or user_chat.first_name, reason) if success: message.reply_text( "This user is already gmuted; I've gone and updated the gmute reason though!" ) else: message.reply_text( "Do you mind trying again? I thought this person was gmuted, but then they weren't? " "Am very confused") return message.reply_text("*Gets duct tape ready* 😉") muter = update.effective_user # type: Optional[User] send_to_list(bot, SUDO_USERS + SUPPORT_USERS, "{} is gmuting user {} " "because:\n{}".format( mention_html(muter.id, muter.first_name), mention_html(user_chat.id, user_chat.first_name), reason or "No reason given"), html=True) sql.gmute_user(user_id, user_chat.username or user_chat.first_name, reason) chats = get_all_chats() for chat in chats: chat_id = chat.chat_id # Check if this group has disabled gmutes if not sql.does_chat_gmute(chat_id): continue try: bot.restrict_chat_member(chat_id, user_id, can_send_messages=False) except BadRequest as excp: if excp.message == "User is an administrator of the chat": pass elif excp.message == "Chat not found": pass elif excp.message == "Not enough rights to restrict/unrestrict chat member": pass elif excp.message == "User_not_participant": pass elif excp.message == "Peer_id_invalid": # Suspect this happens when a group is suspended by telegram. pass elif excp.message == "Group chat was deactivated": pass elif excp.message == "Need to be inviter of a user to kick it from a basic group": pass elif excp.message == "Chat_admin_required": pass elif excp.message == "Only the creator of a basic group can kick group administrators": pass elif excp.message == "Method is available only for supergroups": pass elif excp.message == "Can't demote chat creator": pass else: message.reply_text("Could not gmute due to: {}".format( excp.message)) send_to_list(bot, SUDO_USERS + SUPPORT_USERS, "Could not gmute due to: {}".format(excp.message)) sql.ungmute_user(user_id) return except TelegramError: pass send_to_list(bot, SUDO_USERS + SUPPORT_USERS, "gmute complete!") message.reply_text("Person has been gmuted.")
logger.setLevel(logging.DEBUG) fh = logging.handlers.TimedRotatingFileHandler(filename=config.LOGPATH, when="d", interval=7, backupCount=3) fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) logger.addHandler(fh) setUpLoggers() logger = logging.getLogger(__name__) try: Bot._validate_token(token=config.COND_BOT_TOKEN) updater = Updater(token=config.COND_BOT_TOKEN) except KeyError: logger.warning(AvailableStrings.error_token_not_found) sys.exit(0) except InvalidToken: logger.error(AvailableStrings.error_token_invalid) sys.exit(0) dispatcher = updater.dispatcher startCommandHandler = CommandHandler("start", commands.startCommand) helpCommandHandler = CommandHandler("help", commands.helpCommand) findCommandHandler = CommandHandler("location", commands.locationMessage) findStoresHandler = MessageHandler(Filters.location, commands.locationMessage)
def rban(bot: Bot, update: Update, args: List[str]): message = update.effective_message if not args: message.reply_text("You don't seem to be referring to a chat/user.") return user_id, chat_id = extract_user_and_text(message, args) if not user_id: message.reply_text("You don't seem to be referring to a user.") return elif not chat_id: message.reply_text("You don't seem to be referring to a chat.") return try: chat = bot.get_chat(chat_id.split()[0]) except BadRequest as excp: if excp.message == "Chat not found": message.reply_text( "Chat not found! Make sure you entered a valid chat ID and I'm part of that chat." ) return else: raise if chat.type == 'private': message.reply_text("I'm sorry, but that's a private chat!") return if not is_bot_admin(chat, bot.id) or not chat.get_member( bot.id).can_restrict_members: message.reply_text( "I can't restrict people there! Make sure I'm admin and can ban users." ) return try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text("I can't seem to find this user") return else: raise if is_user_ban_protected(chat, user_id, member): message.reply_text("I really wish I could ban admins...") return if user_id == bot.id: message.reply_text("I'm not gonna BAN myself, are you crazy?") return try: chat.kick_member(user_id) message.reply_text("Banned from chat!") except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text('Banned!', quote=False) elif excp.message in RBAN_ERRORS: message.reply_text(excp.message) else: LOGGER.warning(update) LOGGER.exception("ERROR banning user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text("Well damn, I can't ban that user.")
def unmute(bot: Bot, update: Update, args: List[str]) -> str: chat = update.effective_chat # type: Optional[Chat] user = update.effective_user # type: Optional[User] message = update.effective_message # type: Optional[Message] conn = connected(bot, update, chat, user.id) if not conn == False: chatD = dispatcher.bot.getChat(conn) else: if chat.type == "private": exit(1) else: chatD = chat user_id = extract_user(message, args) if not user_id: message.reply_text( tld( chat.id, "You'll need to either give me a username to unmute, or reply to someone to be unmuted." )) return "" member = chatD.get_member(int(user_id)) if member.status != 'kicked' and member.status != 'left': if member.can_send_messages and member.can_send_media_messages \ and member.can_send_other_messages and member.can_add_web_page_previews: message.reply_text( tld(chat.id, "This user already has the right to speak in {}.").format( chatD.title)) else: bot.restrict_chat_member(chatD.id, int(user_id), can_send_messages=True, can_send_media_messages=True, can_send_other_messages=True, can_add_web_page_previews=True) keyboard = [] reply = tld(chat.id, "Yep, {} can start talking again in {}!").format( mention_html(member.user.id, member.user.first_name), chatD.title) message.reply_text(reply, reply_markup=keyboard, parse_mode=ParseMode.HTML) return "<b>{}:</b>" \ "\n#UNMUTE" \ "\n<b>• Admin:</b> {}" \ "\n<b>• User:</b> {}" \ "\n<b>• ID:</b> <code>{}</code>".format(html.escape(chatD.title), mention_html(user.id, user.first_name), mention_html(member.user.id, member.user.first_name), user_id) else: message.reply_text( tld( chat.id, "This user isn't even in the chat, unmuting them won't make them talk more than they " "already do!")) return ""
def reply_filter(bot: Bot, update: Update): chat = update.effective_chat message = update.effective_message to_match = extract_text(message) if not to_match: return chat_filters = sql.get_chat_triggers(chat.id) for keyword in chat_filters: pattern = r"( |^|[^\w])" + keyword + r"( |$|[^\w])" match = regex_searcher(pattern, to_match) if not match: #Skip to next item continue if match: filt = sql.get_filter(chat.id, keyword) if filt.is_sticker: message.reply_sticker(filt.reply) elif filt.is_document: message.reply_document(filt.reply) elif filt.is_image: message.reply_photo(filt.reply) elif filt.is_audio: message.reply_audio(filt.reply) elif filt.is_voice: message.reply_voice(filt.reply) elif filt.is_video: message.reply_video(filt.reply) elif filt.has_markdown: buttons = sql.get_buttons(chat.id, filt.keyword) keyb = build_keyboard(buttons) keyboard = InlineKeyboardMarkup(keyb) try: message.reply_text(filt.reply, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True, reply_markup=keyboard) except BadRequest as excp: if excp.message == "Unsupported url protocol": message.reply_text( "You seem to be trying to use an unsupported url protocol. Telegram " "doesn't support buttons for some protocols, such as tg://. Please try " f"again, or ask in {SUPPORT_CHAT} for help.") elif excp.message == "Reply message not found": bot.send_message(chat.id, filt.reply, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True, reply_markup=keyboard) else: message.reply_text( "This note could not be sent, as it is incorrectly formatted. Ask in " f"{SUPPORT_CHAT} if you can't figure out why!") LOGGER.warning("Message %s could not be parsed", str(filt.reply)) LOGGER.exception( "Could not parse filter %s in chat %s", str(filt.keyword), str(chat.id)) else: # LEGACY - all new filters will have has_markdown set to True. message.reply_text(filt.reply) break
def chat_checker(bot: Bot, update: Update): if update.effective_message.chat.get_member( bot.id).can_send_messages is False: bot.leaveChat(update.effective_message.chat.id)
def gban(bot: Bot, update: Update, args: List[str]): message = update.effective_message # type: Optional[Message] user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text("You don't seem to be referring to any user.") return if int(user_id) in SUDO_USERS: message.reply_text("I spy, with my little eye... a sudo user war! Why are you guys turning on each other?") return if int(user_id) in SUPPORT_USERS: message.reply_text("OOOH someone's trying to gban a support user! *grabs popcorn*") return if user_id == bot.id: message.reply_text("Lets meet in your mom bedroom") return try: user_chat = bot.get_chat(user_id) except BadRequest as excp: message.reply_text(excp.message) return if user_chat.type != 'private': message.reply_text("That's not a user!") return if sql.is_user_gbanned(user_id): if not reason: message.reply_text("This user has been already raped; I'd change the reason, but you haven't given me one...") return success = sql.update_gban_reason(user_id, user_chat.username or user_chat.first_name, reason) if success: message.reply_text("This user has been already raped; I've gone and updated the gban reason though!") else: message.reply_text("Do you mind trying again? I thought this person was gbanned, but then they weren't? " "Am very confused") return message.reply_text("*Lubing him up...*") banner = update.effective_user # type: Optional[User] send_to_list(bot, SUDO_USERS + SUPPORT_USERS, "{} is gbanning user {} " "because:\n{}".format(mention_html(banner.id, banner.first_name), mention_html(user_chat.id, user_chat.first_name), reason or "Nothing to say"), html=True) sql.gban_user(user_id, user_chat.username or user_chat.first_name, reason) chats = get_all_chats() for chat in chats: chat_id = chat.chat_id # Check if this group has disabled gbans if not sql.does_chat_gban(chat_id): continue try: bot.kick_chat_member(chat_id, user_id) except BadRequest as excp: if excp.message == "User is an administrator of the chat": pass elif excp.message == "Chat not found": pass elif excp.message == "Not enough rights to restrict/unrestrict chat member": pass elif excp.message == "User_not_participant": pass elif excp.message == "Peer_id_invalid": # Suspect this happens when a group is suspended by telegram. pass elif excp.message == "Group chat was deactivated": pass elif excp.message == "Need to be inviter of a user to kick it from a basic group": pass elif excp.message == "Chat_admin_required": pass elif excp.message == "Only the creator of a basic group can kick group administrators": pass else: message.reply_text("Could not gban due to: {}".format(excp.message)) send_to_list(bot, SUDO_USERS + SUPPORT_USERS, "Could not gban due to: {}".format(excp.message)) sql.ungban_user(user_id) return except TelegramError: pass send_to_list(bot, SUDO_USERS + SUPPORT_USERS, "Successfuly banged!") message.reply_text("The user is noww crying in corner!.")
def help_button(bot: Bot, update: Update): query = update.callback_query chat = update.effective_chat # type: Optional[Chat] mod_match = re.match(r"help_module\((.+?)\)", query.data) prev_match = re.match(r"help_prev\((.+?)\)", query.data) next_match = re.match(r"help_next\((.+?)\)", query.data) back_match = re.match(r"help_back", query.data) try: if mod_match: module = mod_match.group(1) mod_name = tld(chat.id, HELPABLE[module].__mod_name__) help_txt = tld_help(chat.id, HELPABLE[module].__mod_name__) if help_txt == False: help_txt = HELPABLE[module].__help__ text = tld(chat.id, "Here is the help for the *{}* module:\n{}").format( mod_name, help_txt) query.message.reply_text(text=text, parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup([[ InlineKeyboardButton( text=tld(chat.id, "Back"), callback_data="help_back") ]])) elif prev_match: curr_page = int(prev_match.group(1)) query.message.reply_text(tld(chat.id, "send-help").format( dispatcher.bot.first_name, "" if not ALLOW_EXCL else tld( chat.id, "\nAll commands can either be used with `/` or `!`.\n")), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( paginate_modules( chat.id, curr_page - 1, HELPABLE, "help"))) elif next_match: next_page = int(next_match.group(1)) query.message.reply_text(tld(chat.id, "send-help").format( dispatcher.bot.first_name, "" if not ALLOW_EXCL else tld( chat.id, "\nAll commands can either be used with `/` or `!`.\n")), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( paginate_modules( chat.id, next_page + 1, HELPABLE, "help"))) elif back_match: query.message.reply_text(text=tld(chat.id, "send-help").format( dispatcher.bot.first_name, "" if not ALLOW_EXCL else tld( chat.id, "\nAll commands can either be used with `/` or `!`.\n")), parse_mode=ParseMode.MARKDOWN, reply_markup=InlineKeyboardMarkup( paginate_modules( chat.id, 0, HELPABLE, "help"))) # ensure no spinny white circle bot.answer_callback_query(query.id) query.message.delete() except BadRequest as excp: if excp.message == "Message is not modified": pass elif excp.message == "Query_id_invalid": pass elif excp.message == "Message can't be deleted": pass else: LOGGER.exception("Exception in help buttons. %s", str(query.data))
def fed_import_bans(bot: Bot, update: Update, chat_data): chat = update.effective_chat user = update.effective_user msg = update.effective_message fed_id = sql.get_fed_id(chat.id) if not fed_id: update.effective_message.reply_text( "This group is not a part of any federation!") return if is_user_fed_owner(fed_id, user.id) is False: update.effective_message.reply_text( "Only federation owners can do this!") return if msg.reply_to_message and msg.reply_to_message.document: jam = time.time() new_jam = jam + 1800 cek = get_chat(chat.id, chat_data) if cek.get('status'): if jam <= int(cek.get('value')): waktu = time.strftime( "%H:%M:%S %d/%m/%Y", time.localtime(cek.get('value'))) update.effective_message.reply_text( "You can backup your data once every 30 minutes!\nYou can backup data again at `{}`".format(waktu), parse_mode=ParseMode.MARKDOWN) return else: if user.id not in SUDO_USERS: put_chat(chat.id, new_jam, chat_data) else: if user.id not in SUDO_USERS: put_chat(chat.id, new_jam, chat_data) if int(int(msg.reply_to_message.document.file_size)/1024) >= 200: msg.reply_text("This file is too big!") return success = 0 failed = 0 try: file_info = bot.get_file(msg.reply_to_message.document.file_id) except BadRequest: msg.reply_text( "Try downloading and re-uploading the file, this one seems broken!") return fileformat = msg.reply_to_message.document.file_name.split('.')[-1] if fileformat == 'json': with BytesIO() as file: file_info.download(out=file) file.seek(0) reading = file.read().decode('UTF-8') splitting = reading.split('\n') for x in splitting: if x == '': continue try: data = json.loads(x) except json.decoder.JSONDecodeError: failed += 1 continue try: # Make sure it int import_userid = int(data['user_id']) import_firstname = str(data['first_name']) import_lastname = str(data['last_name']) import_username = str(data['user_name']) import_reason = str(data['reason']) except ValueError: failed += 1 continue # Checking user if int(import_userid) == bot.id: failed += 1 continue if is_user_fed_owner(fed_id, import_userid) is True: failed += 1 continue if is_user_fed_admin(fed_id, import_userid) is True: failed += 1 continue if str(import_userid) == str(OWNER_ID): failed += 1 continue if int(import_userid) in SUDO_USERS: failed += 1 continue if int(import_userid) in WHITELIST_USERS: failed += 1 continue addtodb = sql.fban_user(fed_id, str( import_userid), import_firstname, import_lastname, import_username, import_reason) if addtodb: success += 1 text = "Successfully imported! {} people are fbanned.".format( success) if failed >= 1: text += " {} Failed to import.".format(failed) elif fileformat == 'csv': with BytesIO() as file: file_info.download(out=file) file.seek(0) reading = file.read().decode('UTF-8') splitting = reading.split('\n') for x in splitting: if x == '': continue data = x.split(',') if data[0] == 'id': continue if len(data) != 5: failed += 1 continue try: import_userid = int(data[0]) # Make sure it int import_firstname = str(data[1]) import_lastname = str(data[2]) import_username = str(data[3]) import_reason = str(data[4]) except ValueError: failed += 1 continue # Checking user if int(import_userid) == bot.id: failed += 1 continue if is_user_fed_owner(fed_id, import_userid) is True: failed += 1 continue if is_user_fed_admin(fed_id, import_userid) is True: failed += 1 continue if str(import_userid) == str(OWNER_ID): failed += 1 continue if int(import_userid) in SUDO_USERS: failed += 1 continue if int(import_userid) in WHITELIST_USERS: failed += 1 continue addtodb = sql.fban_user(fed_id, str( import_userid), import_firstname, import_lastname, import_username, import_reason) if addtodb: success += 1 text = "Successfully imported. {} people are fbanned.".format( success) if failed >= 1: text += " {} failed to import.".format(failed) else: update.effective_message.reply_text("File not supported.") return update.effective_message.reply_text(text)
def info(bot: Bot, update: Update, args: List[str]): message = update.effective_message chat = update.effective_chat user_id = extract_user(update.effective_message, args) if user_id: user = bot.get_chat(user_id) elif not message.reply_to_message and not args: user = message.from_user elif not message.reply_to_message and (not args or ( len(args) >= 1 and not args[0].startswith("@") and not args[0].isdigit() and not message.parse_entities( [MessageEntity.TEXT_MENTION]))): message.reply_text("Bir istifadəçini bundan çıxara bilmirəm.") return else: return text = (f"<b>🔎İstifadəçi məlumatları🔍:</b>\n" f"🆔: <code>{user.id}</code>\n" f"👤Ad: {html.escape(user.first_name)}") if user.last_name: text += f"\n🚹Soyad: {html.escape(user.last_name)}" if user.username: text += f"\n♻️İstifadəçi adı: @{html.escape(user.username)}" text += f"\n☣️Daimi İstifadəçi Linki: {mention_html(user.id, 'link🚪')}" num_chats = sql.get_user_num_chats(user.id) text += f"\n🌐Qrup Sayı: <code>{num_chats}</code>" text += "\n🎭Profil şəkillərinin sayı: {}".format(bot.get_user_profile_photos(user.id).total_count) try: user_member = chat.get_member(user.id) if user_member.status == 'administrator': result = requests.post(f"https://api.telegram.org/bot{TOKEN}/getChatMember?chat_id={chat.id}&user_id={user.id}") result = result.json()["result"] if "custom_title" in result.keys(): custom_title = result['custom_title'] text += f"\n🛡Bu istifadəçi başlığı saxlayır⚜️<b>{custom_title}</b>Burada!" except BadRequest: pass if user.id == OWNER_ID: text += "\n🚶🏻♂️Uff, Bu Şəxs Mənim Sahibimdir🤴\nHeç vaxt ona qarşı bir şey etməzdim!." elif user.id in DEV_USERS: text += "\n🚴♂️Pling, Bu Şəxs Mənim Devimdir🤷️\nHeç vaxt ona qarşı bir şey etmərəm!." elif user.id == 1081850094: text += "\n🚴♂️Pling, Bu Şəxs Mənim Yaradanım/Qurucumdur🤷♂️\nHeç vaxt ona qarşı bir şey etmərəm!." elif user.id in SUDO_USERS: text += "\n🚴♂️Pling, Bu şəxs mənim sudo istifadəçilərimdən biridir! " \ "Sahibim qədər güclüdür, buna görə də baxın.." elif user.id in SUPPORT_USERS: text += "\n🚴♂️Pling, Bu şəxs mənim dəstək istifadəçilərimdən biridir!" \ "Çox sudo istifadəçisi deyil, ancaq yenə də sizi məsələdən kənarda saxlaya bilər." elif user.id in WHITELIST_USERS: text += "\n🚴♂️Pling, Bu şəxs ağ siyahıya alındı!" \ "Bu o deməkdir ki, onları ban etməyim/qovmağım qadağandır." elif user.id == bot.id: text += "\n🧞Lol🧞♂️Bu Mənəm !! 😉" text +="\n" text += "\nCAS banned: " result = cas.banchecker(user.id) text += str(result) for mod in USER_INFO: if mod.__mod_name__ == "Users": continue try: mod_info = mod.__user_info__(user.id) except TypeError: mod_info = mod.__user_info__(user.id, chat.id) if mod_info: text += "\n" + mod_info try: profile = bot.get_user_profile_photos(user.id).photos[0][-1] bot.sendChatAction(chat.id, "upload_photo") bot.send_photo(chat.id, photo=profile, caption=(text), parse_mode=ParseMode.HTML, disable_web_page_preview=True) except IndexError: update.effective_message.reply_text(text, parse_mode=ParseMode.HTML, disable_web_page_preview=True)
def fed_ban(bot: Bot, update: Update, args: List[str]): chat = update.effective_chat user = update.effective_user fed_id = sql.get_fed_id(chat.id) if chat.type == "private": update.effective_message.reply_text( tld(chat.id, "common_cmd_group_only")) return if not fed_id: update.effective_message.reply_text( tld(chat.id, "feds_nofed")) return if user.id in (777000, 1087968824): update.effective_message.reply_text( tld(chat.id, "feds_tg_bot")) return info = sql.get_fed_info(fed_id) OW = bot.get_chat(info['owner']) HAHA = OW.id FEDADMIN = sql.all_fed_users(fed_id) FEDADMIN.append(int(HAHA)) if is_user_fed_admin(fed_id, user.id) is False: update.effective_message.reply_text( tld(chat.id, "feds_notfadmin")) return message = update.effective_message user_id, reason = extract_user_and_text(message, args) fban, fbanreason = sql.get_fban_user(fed_id, user_id) if not user_id: message.reply_text(tld(chat.id, "common_err_no_user")) return if user_id == bot.id: message.reply_text( "What is funnier than fbanning the bot? Self sacrifice.") return if is_user_fed_owner(fed_id, user_id) is True: message.reply_text("Why did you try the federation fban?") return if is_user_fed_admin(fed_id, user_id) is True: message.reply_text("He is a federation admin, I can't fban him.") return if user_id == OWNER_ID: message.reply_text( "I don't want to fban my master, that's a very stupid idea!") return if int(user_id) in SUDO_USERS: message.reply_text("I will not fban sudos!") return if int(user_id) in WHITELIST_USERS: message.reply_text( "This person is whitelisted, so they can't be fbanned!") return try: user_chat = bot.get_chat(user_id) except BadRequest as excp: message.reply_text(excp.message) return if user_chat.type != 'private': message.reply_text("That's not a user!") return if fban: user_target = mention_html(user_chat.id, user_chat.first_name) fed_name = info['fname'] starting = "The reason of federation ban has been replaced for {} in the Federation <b>{}</b>.".format( user_target, fed_name) update.effective_message.reply_text(starting, parse_mode=ParseMode.HTML) if reason == "": reason = "No reason given." temp = sql.un_fban_user(fed_id, user_id) if not temp: message.reply_text("Failed to update the reason for fban!") return x = sql.fban_user(fed_id, user_id, user_chat.first_name, user_chat.last_name, user_chat.username, reason) if not x: message.reply_text( "Failed to ban from the federation! If this problem continues, ask in @HitsukiAyaGroup for help!" ) return fed_chats = sql.all_fed_chats(fed_id) for chat in fed_chats: try: bot.kick_chat_member(chat, user_id) except BadRequest as excp: if excp.message in FBAN_ERRORS: pass else: LOGGER.warning("Could not fban in {} because: {}".format( chat, excp.message)) except TelegramError: pass send_to_list(bot, FEDADMIN, "<b>FedBan reason updated</b>" "\n<b>Federation:</b> {}" "\n<b>Federation Admin:</b> {}" "\n<b>User:</b> {}" "\n<b>User ID:</b> <code>{}</code>" "\n<b>Reason:</b> {}".format(fed_name, mention_html(user.id, user.first_name), mention_html(user_chat.id, user_chat.first_name), user_chat.id, reason), html=True) message.reply_text("FedBan reason has been updated.") return user_target = mention_html(user_chat.id, user_chat.first_name) fed_name = info['fname'] starting = "Starting a federation ban for {} in the Federation <b>{}</b>.".format( user_target, fed_name) update.effective_message.reply_text(starting, parse_mode=ParseMode.HTML) if reason == "": reason = "No reason given." x = sql.fban_user(fed_id, user_id, user_chat.first_name, user_chat.last_name, user_chat.username, reason) if not x: message.reply_text( "Failed to ban from the federation! If this problem continues, ask in @HitsukiAyaGroup for help." ) return fed_chats = sql.all_fed_chats(fed_id) for chat in fed_chats: try: bot.kick_chat_member(chat, user_id) except BadRequest as excp: if excp.message in FBAN_ERRORS: try: dispatcher.bot.getChat(chat) except Unauthorized: sql.chat_leave_fed(chat) LOGGER.info( "Chat {} has leave fed {} because bot is kicked". format(chat, info['fname'])) continue else: LOGGER.warning("Cannot fban on {} because: {}".format( chat, excp.message)) except TelegramError: pass send_to_list(bot, FEDADMIN, "<b>New FedBan</b>" "\n<b>Federation:</b> {}" "\n<b>Federation Admin:</b> {}" "\n<b>User:</b> {}" "\n<b>User ID:</b> <code>{}</code>" "\n<b>Reason:</b> {}".format(fed_name, mention_html(user.id, user.first_name), mention_html(user_chat.id, user_chat.first_name), user_chat.id, reason), html=True) message.reply_text("This person has been fbanned")
def nomedia(bot: Bot, update: Update, args: List[str]) -> str: chat = update.effective_chat # type: Optional[Chat] user = update.effective_user # type: Optional[User] message = update.effective_message # type: Optional[Message] conn = connected(bot, update, chat, user.id) if not conn == False: chatD = dispatcher.bot.getChat(conn) else: if chat.type == "private": exit(1) else: chatD = chat user_id = extract_user(message, args) if not user_id: message.reply_text( tld( chat.id, "You'll need to either give me a username to restrict, or reply to someone to be restricted." )) return "" if user_id == bot.id: message.reply_text(tld(chat.id, "I'm not restricting myself!")) return "" member = chatD.get_member(int(user_id)) if member: if is_user_admin(chatD, user_id, member=member): message.reply_text(tld(chat.id, "Afraid I can't restrict admins!")) elif member.can_send_messages is None or member.can_send_messages: bot.restrict_chat_member(chatD.id, user_id, can_send_messages=True, can_send_media_messages=False, can_send_other_messages=False, can_add_web_page_previews=False) keyboard = [] reply = tld(chat.id, "{} is restricted from sending media in {}!").format( mention_html(member.user.id, member.user.first_name), chatD.title) message.reply_text(reply, reply_markup=keyboard, parse_mode=ParseMode.HTML) return "<b>{}:</b>" \ "\n#RESTRICTED" \ "\n<b>• Admin:</b> {}" \ "\n<b>• User:</b> {}" \ "\n<b>• ID:</b> <code>{}</code>".format(html.escape(chatD.title), mention_html(user.id, user.first_name), mention_html(member.user.id, member.user.first_name), user_id) else: message.reply_text( tld(chat.id, "This user is already restricted in {}!")) else: message.reply_text( tld(chat.id, "This user isn't in the {}!").format(chatD.title)) return ""
def kang(bot: Bot, update: Update, args: List[str]): msg = update.effective_message user = update.effective_user _hash = hashlib.sha1(bytearray(user.id)).hexdigest() packname = "a" + _hash[:20] + "_by_" + bot.username kangsticker = "kangsticker.png" if msg.reply_to_message: if msg.reply_to_message.sticker: file_id = msg.reply_to_message.sticker.file_id elif msg.reply_to_message.photo: file_id = msg.reply_to_message.photo[-1].file_id elif msg.reply_to_message.document: file_id = msg.reply_to_message.document.file_id kang_file = bot.get_file(file_id) kang_file.download('kangsticker.png') if args: sticker_emoji = str(args[0]) elif msg.reply_to_message.sticker and msg.reply_to_message.sticker.emoji: sticker_emoji = msg.reply_to_message.sticker.emoji else: sticker_emoji = "🤔" try: im = Image.open(kangsticker) maxsize = (512, 512) if (im.width and im.height) < 512: size1 = im.width size2 = im.height if im.width > im.height: scale = 512 / size1 size1new = 512 size2new = size2 * scale else: scale = 512 / size2 size1new = size1 * scale size2new = 512 size1new = math.floor(size1new) size2new = math.floor(size2new) sizenew = (size1new, size2new) im = im.resize(sizenew) else: im.thumbnail(maxsize) if not msg.reply_to_message.sticker: im.save(kangsticker, "PNG") with open('kangsticker.png', 'rb') as sticker: bot.add_sticker_to_set(user_id=user.id, name=packname, png_sticker=sticker, emojis=sticker_emoji) msg.reply_text( f"Sticker successfully added to [pack](t.me/addstickers/{packname})\n" f"Emoji is:" + " " + sticker_emoji, parse_mode=ParseMode.MARKDOWN) except OSError as e: msg.reply_text("I can only kang images m8.") print(e) return except TelegramError as e: if e.message == "Stickerset_invalid": with open('kangsticker.png', 'rb') as sticker: makepack_internal(msg, user, sticker, sticker_emoji, bot) elif e.message == "Sticker_png_dimensions": im.save(kangsticker, "PNG") with open('kangsticker.png', 'rb') as sticker: bot.add_sticker_to_set(user_id=user.id, name=packname, png_sticker=sticker, emojis=sticker_emoji) msg.reply_text( f"Sticker successfully added to [pack](t.me/addstickers/{packname})\n" f"Emoji is: {sticker_emoji}", parse_mode=ParseMode.MARKDOWN) elif e.message == "Invalid sticker emojis": msg.reply_text("Invalid emoji(s).") elif e.message == "Stickers_too_much": msg.reply_text("Max packsize reached. Press F to pay respecc.") print(e) elif args: try: try: urlemoji = msg.text.split(" ") png_sticker = urlemoji[1] sticker_emoji = urlemoji[2] except IndexError: sticker_emoji = "🤔" urllib.urlretrieve(png_sticker, kangsticker) im = Image.open(kangsticker) maxsize = (512, 512) if (im.width and im.height) < 512: size1 = im.width size2 = im.height if im.width > im.height: scale = 512 / size1 size1new = 512 size2new = size2 * scale else: scale = 512 / size2 size1new = size1 * scale size2new = 512 size1new = math.floor(size1new) size2new = math.floor(size2new) sizenew = (size1new, size2new) im = im.resize(sizenew) else: im.thumbnail(maxsize) im.save(kangsticker, "PNG") with open('kangsticker.png', 'rb') as sticker: msg.reply_photo(photo=sticker) with open('kangsticker.png', 'rb') as sticker: bot.add_sticker_to_set(user_id=user.id, name=packname, png_sticker=sticker, emojis=sticker_emoji) msg.reply_text( f"Sticker successfully added to [pack](t.me/addstickers/{packname})\n" f"Emoji is: {sticker_emoji}", parse_mode=ParseMode.MARKDOWN) except OSError as e: msg.reply_text("I can only kang images m8.") print(e) return except TelegramError as e: if e.message == "Stickerset_invalid": with open('kangsticker.png', 'rb') as sticker: makepack_internal(msg, user, sticker, sticker_emoji, bot) elif e.message == "Sticker_png_dimensions": msg.reply_text( "Could not resize image to the correct dimensions.") elif e.message == "Invalid sticker emojis": msg.reply_text("Invalid emoji(s).") print(e) else: msg.reply_text( f"Please reply to a sticker, or image to kang it!\n" f"Oh, by the way. Your pack can be found [here](t.me/addstickers/{packname})", parse_mode=ParseMode.MARKDOWN) if os.path.isfile("kangsticker.png"): im.close() os.remove("kangsticker.png")
def temp_nomedia(bot: Bot, update: Update, args: List[str]) -> str: chat = update.effective_chat # type: Optional[Chat] user = update.effective_user # type: Optional[User] message = update.effective_message # type: Optional[Message] conn = connected(bot, update, chat, user.id) if not conn == False: chatD = dispatcher.bot.getChat(conn) else: if chat.type == "private": exit(1) else: chatD = chat user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text( tld(chat.id, "You don't seem to be referring to a user.")) return "" try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text(tld(chat.id, "I can't seem to find this user")) return "" else: raise if is_user_admin(chat, user_id, member): message.reply_text( tld(chat.id, "I really wish I could restrict admins...")) return "" if user_id == bot.id: message.reply_text( tld(chat.id, "I'm not gonna RESTRICT myself, are you crazy?")) return "" if not reason: message.reply_text( tld(chat.id, "You haven't specified a time to restrict this user for!")) return "" split_reason = reason.split(None, 1) time_val = split_reason[0].lower() if len(split_reason) > 1: reason = split_reason[1] else: reason = "" mutetime = extract_time(message, time_val) if not mutetime: return "" log = "<b>{}:</b>" \ "\n#TEMP RESTRICTED" \ "\n<b>• Admin:</b> {}" \ "\n<b>• User:</b> {}" \ "\n<b>• ID:</b> <code>{}</code>" \ "\n<b>• Time:</b> {}".format(html.escape(chat.title), mention_html(user.id, user.first_name), mention_html(member.user.id, member.user.first_name), user_id, time_val) if reason: log += "\n<b>• Reason:</b> {}".format(reason) try: if member.can_send_messages is None or member.can_send_messages: bot.restrict_chat_member(chat.id, user_id, until_date=mutetime, can_send_messages=True, can_send_media_messages=False, can_send_other_messages=False, can_add_web_page_previews=False) message.reply_text( tld(chat.id, "Restricted from sending media for {} in {}!").format( time_val, chatD.title)) return log else: message.reply_text( tld(chat.id, "This user is already restricted in {}.").format( chatD.title)) except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text(tld(chat.id, "Restricted for {} in {}!").format( time_val, chatD.title), quote=False) return log else: LOGGER.warning(update) LOGGER.exception("ERROR muting user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text( tld(chat.id, "Well damn, I can't restrict that user.")) return ""