def handle(self, **options): notify = options['notify'] == 'on' scheduler = BackgroundScheduler() client = Client('session_jobs', api_id=TG_API_ID, api_hash=TG_API_HASH, bot_token=API_TOKEN, no_updates=True) client.start() scheduler.add_job(update_user_balances, 'interval', seconds=USER_BALANCE_JOB_INTERVAL, args=(client, )) scheduler.add_job(update_chat_balances, 'interval', seconds=CHAT_BALANCE_JOB_INTERVAL, args=(client, notify)) scheduler.add_job(make_multisend_list_and_pay, 'interval', seconds=PAYMENT_JOB_INTERVAL) scheduler.add_job(local_chat_pay, 'interval', seconds=LOCAL_PAYMENT_JOB_INTERVAL) scheduler.start() Client.idle() scheduler.shutdown() client.stop()
def main(): # Pyrogram setup client = Client("example") # Set the update_handler callback function client.set_update_handler(update_handler) client.start() # Blocks the program execution until you press CTRL+C then # automatically stops the Client by closing the underlying connection client.idle()
from pyrogram import Client, Filters app = Client("silencert") @app.on_message(Filters.group) def delete_unwanted_message(client, message): unwanted_messages = [ message.new_chat_members, message.left_chat_member, message.new_chat_title, ] for unwanted in unwanted_messages: if unwanted is not None: client.delete_messages(message.chat.id, [message.message_id]) if message.text is not None and message.text.find( "https://t.me/joinchat/") > -1: client.delete_messages(message.chat.id, [message.message_id]) app.start() app.idle()
msg = self.bot.send_message( creator_id, text= f'Привет, твой бот @{bot_username} перестал работать и был скрыт от пользователей.' ) markup = InlineKeyboardButton() markup.add( InlineKeyboardButton( text='Починил!', callback_data= f'checkfix bot_id:{bot_id} msg_id:{msg.message_id}')) markup.add( InlineKeyboardButton(text='Закрить!', callback_data='hide')) self.bot.edit_message_reply_markup(chat_id=msg.chat.id, message_id=msg.message_id, reply_markup=markup) except Exception as e: print(f'[Checker] Error send msg not work to: {creator_id}') cli.start() Checker(bot, cli) cli.idle()
def run(session_name): last_time = 0 doned = [] bonuses_id = 1317469445 bot_id = 398938067 class NewBonus: def __init__(self, peer, msg_id: int, data: bytes): self.peer = peer self.msg_id = msg_id self.data = data class NewCaptcha: def __init__(self, peer, msg_id: int, data: bytes): self.peer = peer self.msg_id = msg_id self.data = data class Work(Thread): def __init__(self): Thread.__init__(self) self.active = True def run(self): print('new work') while self.active: sleep(10) client.send_message(bot_id, '👁 Смотреть пост') def stop(self): self.active = False self.join() def captcha(update): if isinstance(update, Update): for m in update.updates: if isinstance(m, UpdateNewMessage): msg = m.message if msg.from_id == bot_id: str_cap = re.match( r'^Чтобы продолжить, найдите кнопку . и нажмите на нее!$', msg.message) if str_cap is not None: row = msg.reply_markup.rows for i in row: for b in i.buttons: if b.data.decode() == 'anti-nakrut': ret = NewCaptcha( peer=client.resolve_peer( '@PayViewBot'), msg_id=msg.id, data=b.data) return ret elif 'Уведомления о появлении новых постов' in msg.message: return 'posts_end' elif isinstance(m, UpdateNewChannelMessage): msg = m.message if msg.to_id.channel_id == bonuses_id: try: if msg.reply_markup: ret = NewBonus( peer=client.resolve_peer( msg.to_id.channel_id), msg_id=msg.id, data=msg.reply_markup.rows[0].buttons[1]. data, ) return ret except AttributeError: pass client = Client(session_name=session_name) work = Work() def replier(update): nonlocal work nonlocal last_time captcha_ret = captcha(update) if isinstance(captcha_ret, NewCaptcha): if captcha_ret.msg_id not in doned: sleep(3) client.send( GetBotCallbackAnswer(peer=captcha_ret.peer, msg_id=captcha_ret.msg_id, data=captcha_ret.data)) doned.append(captcha_ret.msg_id) return None elif captcha_ret == 'posts_end': if time() - last_time > 30: last_time = time() work.stop() sleep(300) work = Work() work.start() elif isinstance(captcha_ret, NewBonus): sleep(3) client.send( GetBotCallbackAnswer( msg_id=captcha_ret.msg_id, peer=captcha_ret.peer, data=captcha_ret.data, )) work.start() client.set_update_handler(replier) client.start() client.idle()
while PUMP_BALANCE > API.get_coin_balance('BTC')['Available']: print('You can\'t invest more than {}'.format( API.get_coin_balance('BTC')['Available'])) PUMP_BALANCE = float( input("How much BTC would you like to use?: ")) if manual: print('\n***Wait input data***\n') while True: try: PUMP_COIN = input().rstrip(' \t\r\n\0').upper() if PUMP_COIN != '': print(PUMP_COIN) callback(PUMP_COIN) break except Exception as e: print(e) time.sleep(0.01) else: # Инициализация клиента client = Client( session_name="pyro", phone_number=PHONE, phone_code=input("code: "), ) client.set_update_handler(callback) client.start() print(client.get_me().user) client.idle()
# Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from pyrogram import Client from pyrogram.api import types def update_handler(client, update, users, chats): if isinstance(update, types.UpdateNewMessage): message = update.message # Filter by Message to exclude MessageService and MessageEmpty if isinstance(message, types.Message): # Private Messages (Message from user) if isinstance(message.to_id, types.PeerUser): text = message.message user = users[message.from_id].first_name if user == 'IFTTT' and text.startswith('lego-sorter:'): log.write(text) log.write('\n') log.flush() with open('/home/pi/legogram/command.log', 'a') as log: c = Client("lego-sorter") c.set_update_handler(update_handler) c.start() c.idle()
class custom_service_bot_class(object): SECTION = [ 'VERIFICATION', 'OTHER' ] INIT_STATUS = 0 SELECT_SECTION = 1 SEND_QUESTION = 2 SEND_FINISH = 3 RE_TICKET_ID = re.compile(r'[a-f\d]{32}') def __init__(self, config_file: str or ConfigParser, mysql_handle: tg_tools.mysqldb, send_link_callback: callable): if isinstance(config_file, ConfigParser): self.config = config_file else: self.config = ConfigParser() self.config.read(config_file) self.mysqldb = mysql_handle if mysql_handle else tg_tools.mysqldb('localhost', 'root', self.config['database']['passwd'], self.config['database']['db_name']) self.bot = Client( self.config['account']['custom_api_key'], api_id = self.config['account']['api_id'], api_hash = self.config['account']['api_hash'] ) self.bot_id = int(self.config['account']['custom_api_key'].split(':')[0]) self.help_group = int(self.config['fuduji']['help_group']) self.send_link_callback = send_link_callback self.emerg_contact = eval(self.config['account']['emerg_contact']) if self.config.has_option('account', 'emerg_contact') and self.config['account']['emerg_contact'] != '' else self.config['account']['owner'] self.create_lock = Lock() def start(self): self.bot.add_handler(MessageHandler(self.handle_start, Filters.command('start') & Filters.private)) self.bot.add_handler(MessageHandler(self.handle_create, Filters.command('create',) & Filters.private)) self.bot.add_handler(MessageHandler(self.handle_cancel, Filters.command('cancel') & Filters.private)) self.bot.add_handler(MessageHandler(self.handle_list, Filters.command('list') & Filters.private)) self.bot.add_handler(MessageHandler(self.handle_close, Filters.command('close') & Filters.private)) self.bot.add_handler(MessageHandler(self.handle_reply, Filters.reply & Filters.text & Filters.private)) self.bot.add_handler(MessageHandler(self.handle_msg, Filters.text & Filters.private)) self.bot.add_handler(MessageHandler(self.call_superuser_function, Filters.chat(self.help_group) & Filters.reply & Filters.command('m'))) self.bot.add_handler(MessageHandler(self.handle_group, Filters.reply & Filters.chat(self.help_group))) self.bot.add_handler(MessageHandler(self.handle_manual_add_blacklist, Filters.command('a') & Filters.chat(self.help_group))) self.bot.add_handler(MessageHandler(self.handle_other, Filters.private)) self.bot.add_handler(CallbackQueryHandler(self.answer)) return self.bot.start() def stop(self): #self.save_session() return self.bot.stop() def idle(self): return self.bot.idle() def active(self): self.start() self.idle() def send_emerg_msg(self, text: str): if isinstance(self.emerg_contact, str): self.bot.send_message(self.emerg_contact, text) else: for x in self.emerg_contact: self.bot.send_message(x, text) @staticmethod def hash_msg(msg: Message): return hashlib.md5(' '.join((str(msg.from_user.id), str(msg.date), str(msg.message_id))).encode()).hexdigest() def get_hash_from_reply_msg(self, msg: Message): if msg.reply_to_message is None or \ msg.reply_to_message.text is None or \ msg.reply_to_message.from_user.id != self.bot_id or \ msg.reply_to_message.entities is None or \ msg.reply_to_message.entities[0].type != 'hashtag': print(msg.reply_to_message is None, msg.reply_to_message.text is None, msg.reply_to_message.from_user.id != self.bot_id, msg.reply_to_message.entities is None, msg.reply_to_message.entities[0].type != 'hashtag') raise ValueError("hash message info error") r = self.RE_TICKET_ID.search(msg.reply_to_message.text) if r is not None: return r.group(0) else: raise ValueError('hash info not found') @staticmethod def generate_section_pad(): return ReplyKeyboardMarkup( keyboard = [ [KeyboardButton( text = x )] for x in custom_service_bot_class.SECTION ], resize_keyboard = True, one_time_keyboard = True) @staticmethod def generate_ticket_keyboard(ticket_id: str, user_id: int, closed: bool = False, other: bool = False): kb = [ InlineKeyboardButton(text = 'Close', callback_data = 'close {}'.format(ticket_id).encode()), InlineKeyboardButton(text = 'Send link', callback_data = 'send {}'.format(user_id).encode()), InlineKeyboardButton(text = 'Block', callback_data = 'block {}'.format(user_id).encode()) ] if closed: kb = kb[2:] elif other: kb.pop(1) return InlineKeyboardMarkup( inline_keyboard = [kb] ) @staticmethod def returnYNemoji(i: int): return '✅' if i else '❌' def handle_list(self, client: Client, msg: Message): q = self.mysqldb.query3("SELECT `hash`, `status` FROM `tickets` WHERE `user_id` = {} ORDER BY `timestamp` DESC LIMIT 3".format(msg.chat.id)) if len(q) == 0 or q is None: return msg.reply('You have never used this system before.', True) for _ticket in q: _ticket['status'] = self.returnYNemoji(_ticket['status'] != 'closed') msg.reply('Here are the last three tickets (up to 3)\n#{}'.format('\n#'.join(' '.join(value for _, value in _ticket.items()) for _ticket in q)), True) def handle_close(self, client: Client, msg: Message): if msg.reply_to_message is not None and msg.text == '/close': try: ticket_id = self.get_hash_from_reply_msg(msg) except ValueError: return msg.reply('TICKET NUMBER NOT FOUND\nPlease make sure that you have replied to the message which contains the ticket number.', True) else: if len(msg.text) < 8: return msg.reply('ERROR: COMMAND FORMAT Please use `/close <ticket number>` or **Reply to the message which contains the ticket number** to close the ticket', True, 'markdown', True) ticket_id = msg.text.split()[-1] if len(ticket_id) != 32: return msg.reply('ERROR: TICKET NUMBER FORMAT', True) q = self.mysqldb.query1("SELECT `user_id` FROM `tickets` WHERE `hash` = '{}' AND `status` != 'closed'".format(ticket_id)) if q is None: return msg.reply('TICKET NUMBER NOT FOUND or TICKET CLOSED', True) if q['user_id'] != msg.chat.id: return msg.reply('403 Forbidden(You cannot close a ticket created by others. If this ticket is indeed created by yourself, please report the problem using the same ticket.)', True) self.mysqldb.execute("UPDATE `tickets` SET `status` = 'closed' WHERE `user_id` = {} AND `hash` = '{}'".format(msg.chat.id, ticket_id)) self.mysqldb.execute("UPDATE `tickets_user` SET `last_time` = CURRENT_TIMESTAMP() WHERE `user_id` = {}".format(msg.chat.id)) self.mysqldb.commit() client.send_message(self.help_group, "UPDATE\n[ #{} ]\nThis ticket is already closed by {}".format(ticket_id, tg_tools.build_html_parse.parse_user(msg.chat.id, '创建者')), reply_markup = self.generate_ticket_keyboard(ticket_id, msg.chat.id, True)) msg.reply('DONE!', True) def add_user(self, user_id: int, step: int = 0): self.mysqldb.execute("INSERT INTO `tickets_user` (`user_id`, `create_time`, `last_time`, `last_msg_sent`, `step`) VALUES ({}, CURRENT_TIMESTAMP(), DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 minute), CURRENT_TIMESTAMP(), {})".format(user_id, step)) def change_step(self, user_id: int, step: int, section: str = ''): if section == '': self.mysqldb.execute("UPDATE `tickets_user` SET `step` = {} WHERE `user_id` = {}".format(step, user_id)) else: self.mysqldb.execute("UPDATE `tickets_user` SET `step` = {0}, `section` = '{2}' WHERE `user_id` = {1}".format(step, user_id, section)) self.mysqldb.commit() def query_status(self, user_id: int): return self.mysqldb.query1("SELECT `step`, `section` FROM `tickets_user` WHERE `user_id` = {}".format(user_id)) def query_user(self, user_id: int): return self.mysqldb.query1("SELECT `section` FROM `tickets_user` WHERE `user_id` = {}".format(user_id)) def set_section(self, user_id: int, section: str): self.mysqldb.execute("UPDATE `tickets_user` SET `section` = '{1}' WHERE `user_id` = {0}".format(user_id, section)) self.mysqldb.commit() def query_user_exam_status(self, user_id: int): return self.mysqldb.query1("SELECT `baned`, `bypass`, `passed`, `unlimited`, `retries` FROM `exam_user_session` WHERE `user_id` = {}".format(user_id)) def handle_start(self, client: Client, msg: Message): q = self.mysqldb.query1("SELECT `last_msg_sent` FROM `tickets_user` WHERE `user_id` = {}".format(msg.chat.id)) msg.reply('Welcome to Google Hosts Telegram Ticket System\n\nATTENTION:PLEASE DO NOT ABUSE THIS SYSTEM. Otherwise there is a possibility of getting blocked.\n\n/create - to create a new ticket\n/list - to list recent tickets\n/close - to close the ticket\n/cancel - to reset', True) if q is None: self.add_user(msg.chat.id) def handle_create(self, client: Client, msg: Message): if self.flood_check(client, msg): return q = self.mysqldb.query1("SELECT `hash` FROM `tickets` WHERE `user_id` = {} AND `status` = 'open' LIMIT 1".format(msg.chat.id)) if q: msg.reply('UNABLE TO CREATE A NEW TICKET: An existing ticket is currently open.', True) return sqlObj = self.mysqldb.query1("SELECT `user_id` FROM `tickets_user` WHERE `user_id` = {}".format(msg.chat.id)) (self.add_user if sqlObj is None else self.change_step)(msg.chat.id, custom_service_bot_class.SELECT_SECTION) msg.reply('You are creating a new ticket.\n\nPlease choose the correct department.', True, reply_markup=self.generate_section_pad()) def handle_cancel(self, client: Client, msg: Message): self.change_step(msg.chat.id, custom_service_bot_class.INIT_STATUS) msg.reply('Reset Successful', reply_markup=ReplyKeyboardRemove()) def handle_reply(self, client: Client, msg: Message): if self.flood_check(client, msg): return ticket_hash = self.get_hash_from_reply_msg(msg) sqlObj = self.mysqldb.query1("SELECT `status`, `section` FROM `tickets` WHERE `hash` = '{}' AND `user_id` = {}".format(ticket_hash, msg.chat.id)) if sqlObj is None or sqlObj['status'] == 'closed': msg.reply('TICKET NUMBER NOT FOUND or TICKET CLOSED. REPLY FUNCTION NO LONGER AVAILABLE.', True) return self.mysqldb.execute("UPDATE `tickets_user` SET `last_time` = CURRENT_TIMESTAMP() WHERE `user_id` = {}".format(msg.chat.id)) self.mysqldb.commit() client.send_message( self.help_group, 'NEW REPLY\n[ #{} ]:\nMESSAGE: {}'.format(ticket_hash, build_html_parse(msg).parsed_msg), 'html', reply_markup = self.generate_ticket_keyboard(ticket_hash, msg.chat.id, sqlObj['section'] != self.SECTION[0]) ) msg.reply('The new reply is added successfully!') def handle_msg(self, client: Client, msg: Message): sqlObj = self.query_status(msg.chat.id) if sqlObj is None or sqlObj['step'] not in (custom_service_bot_class.SELECT_SECTION, custom_service_bot_class.SEND_QUESTION): if self.flood_check(client, msg): return return msg.reply('Please use bot command to interact.') if sqlObj['step'] == custom_service_bot_class.SELECT_SECTION: if msg.text in self.SECTION: self.change_step(msg.chat.id, custom_service_bot_class.SEND_QUESTION, msg.text) msg.reply('Please describe your problem briefly(up to 500 characters)\n(Please use external links to send pictures.):\n\nATTENTION: Receiving a confirmation message in return indicates that the ticket is created successfully.\n\nUse /cancel to cancel creating the ticket. ', True, reply_markup = ReplyKeyboardRemove()) else: msg.reply('Please use the menu below to choose the correct department.', True) elif sqlObj['step'] == custom_service_bot_class.SEND_QUESTION: if len(msg.text) > 500: msg.reply('The number of characters you have entered is larger than 500. Please re-enter.', True) return ticket_hash = self.hash_msg(msg) self.mysqldb.execute(ticket(msg, sqlObj['section'], 'open').sql) self.mysqldb.commit() self.change_step(msg.chat.id, custom_service_bot_class.INIT_STATUS) msg.reply( 'The ticket is created successfully!\n[ #{ticket_id} ]\nDepartment: {section}\nMessage: \n{text}\n\nReply to this message to add a new reply to the ticket.'.format( ticket_id = ticket_hash, text = build_html_parse(msg).parsed_msg, section = sqlObj['section'] ), parse_mode = 'html' ) msg_id = client.send_message( self.help_group, 'NEW TICKET\n[ #{} ]\nClick {} to check the user profile\nDepartment: {}\nMessage: \n{}'.format( ticket_hash, build_html_parse.parse_user_ex(msg.chat.id, 'Here'), sqlObj['section'], build_html_parse(msg).parsed_msg ), 'html', reply_markup = self.generate_ticket_keyboard( ticket_hash, msg.chat.id, other = sqlObj['section'] != custom_service_bot_class.SECTION[0] ) ).message_id if sqlObj['section'] == custom_service_bot_class.SECTION[0]: client.send_message( self.help_group, self.generate_user_status(msg.chat.id), 'markdown', reply_to_message_id = msg_id ) else: print("throw! user_id: {}, sqlObj = {}".format(msg.chat.id, repr(sqlObj))) def generate_user_status(self, user_id: int): user_status = self.query_user_exam_status(user_id) return 'User {5} status:\nPassed exam: {0}\nBan status: {1}\nBypass: {2}\nUnlimited: {3}\nRetries: {4}'.format( self.returnYNemoji(user_status['passed']), self.returnYNemoji(user_status['baned']), self.returnYNemoji(user_status['bypass']), self.returnYNemoji(user_status['unlimited']), user_status['retries'], build_html_parse.parse_user(user_id) ) if user_status is not None else '**WARNING: THIS USER HAS NEVER USED THE BOT BEFORE.**' def handle_other(self, client: Client, msg: Message): q = self.mysqldb.query1("SELECT `last_msg_sent` FROM `tickets_user` WHERE `user_id` = {}".format(msg.chat.id)) if (datetime.now() - q['last_msg_sent']).total_seconds() < 120: return msg.reply('Please use bot command to interact. TEXT ONLY.') def handle_group(self, client: Client, msg: Message): #print(msg) if msg.reply_to_message.from_user.id != self.bot_id or (msg.text and msg.text.startswith('/')): return ticket_hash = self.get_hash_from_reply_msg(msg) sqlObj = self.mysqldb.query1("SELECT * FROM `tickets` WHERE `hash` = '{}'".format(ticket_hash)) if sqlObj is None: return msg.reply('ERROR: TICKET NOT FOUND') if sqlObj['status'] == 'closed': return msg.reply('This ticket is already closed.') msg_reply = client.send_message(sqlObj['user_id'], 'NEW UPDATE!\n[ #{} ]\nMessage: \n{}\n\nReply to this message to add a new reply to the ticket.'.format(ticket_hash, build_html_parse(msg).parsed_msg), 'html') msg.reply('REPLY SUCCESSFUL', reply_markup = InlineKeyboardMarkup(inline_keyboard = [ [ InlineKeyboardButton( text = 'recall', callback_data = ' '.join(('del', str(msg_reply.chat.id), str(msg_reply.message_id))).encode()) ] ])) sqlObj = self.mysqldb.query1("SELECT `last_time`, `user_id` FROM `tickets_user` WHERE user_id = {}".format(sqlObj['user_id'])) if (datetime.now() - sqlObj['last_time']).total_seconds() < 120: self.mysqldb.execute("UPDATE `tickets_user` SET `last_time` = DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 3 minute) WHERE `user_id` = %s", (sqlObj['user_id'],)) def handle_manual_add_blacklist(self, client: Client, msg: Message): pass @staticmethod def generate_confirm_keyboard(first: str, last: str): if isinstance(last, list) or isinstance(last, tuple): lastg = last else: lastg = (str(last),) return InlineKeyboardMarkup(inline_keyboard = [ [ InlineKeyboardButton(text = 'Yes', callback_data = ' '.join((first, 'confirm', *lastg)).encode()), InlineKeyboardButton(text = 'No', callback_data = b'cancel') ] ]) def generate_superuser_text(self, user_id: str or int): return '\n\n'.join(('Please choose the section below.', self.generate_user_status(user_id), ' '.join(('Last refresh:', time.strftime('%Y-%m-%d %H:%M:%S'))))) def generate_superuser_detail(self, user_id: str or int): return { 'text': self.generate_superuser_text(user_id), 'reply_markup': InlineKeyboardMarkup( inline_keyboard = [ [ InlineKeyboardButton( text = 'BYPASS', callback_data = 'bypass {}'.format(user_id).encode()), InlineKeyboardButton( text = 'UNLIMITED RETRIES', callback_data = 'unlimited {}'.format(user_id).encode()), InlineKeyboardButton( text = 'REFRESH', callback_data = 'refresh {}'.format(user_id).encode()) ], [ InlineKeyboardButton( text = 'PASS', callback_data = 'setpass {}'.format(user_id).encode()), InlineKeyboardButton( text = 'RESET TIMES', callback_data = 'reset {}'.format(user_id).encode()) ], [ InlineKeyboardButton( text = 'RESET USER STATUS', callback_data = 'renew {}'.format(user_id).encode()) ], [ InlineKeyboardButton( text = 'Cancel', callback_data = b'cancel') ] ] ) } def call_superuser_function(self, client: Client, msg: Message): sqlObj = self.mysqldb.query1("SELECT `user_id`, `section` FROM `tickets` WHERE `hash` = '{}'".format(self.get_hash_from_reply_msg(msg))) if sqlObj['section'] != self.SECTION[0]: return msg.reply('This ticket doesn\'t support admin menus for now.', True) user_id = sqlObj['user_id'] client.send_message( self.help_group, parse_mode = 'markdown', reply_to_message_id = msg.reply_to_message.message_id, **self.generate_superuser_detail(user_id) ) def confirm_dialog(self, msg: Message, additional_msg: str, callback_prefix: str, user_id: int = None, ticket_id: str = None): if user_id is not None: self.bot.send_message( self.help_group, 'Do you really want to {} {}?'.format(additional_msg, build_html_parse.parse_user(user_id)), 'markdown', reply_markup = self.generate_confirm_keyboard(callback_prefix, user_id) ) else: self.bot.send_message( self.help_group, 'Do you really want to {} #{}?'.format(additional_msg, ticket_id), reply_markup = self.generate_confirm_keyboard(callback_prefix, ticket_id) ) def confirm(self, client: Client, msg: CallbackQuery): if time.time() - msg.message.date > 15: raise TimeoutError() if msg.data.startswith('close'): ticket_id = msg.data.split()[-1] q = self.mysqldb.query1("SELECT `user_id`, `status` FROM `tickets` WHERE `hash` = '{}'".format(ticket_id)) if q is None: return msg.answer('TICKET NOT FOUND', True) if q['status'] == 'closed': return msg.answer('TICKET CLOSED') self.mysqldb.execute("UPDATE `tickets` SET `status` = 'closed' WHERE `hash` = '{}'".format(ticket_id)) msg.answer('This ticket is closed.') client.send_message( self.help_group, "UPDATE\n[ #{} ]\nThis ticket is closed by {}.".format( ticket_id, tg_tools.build_html_parse.parse_user( msg.from_user.id, tg_tools.build_html_parse.user_name(msg.from_user).full_name ) ), 'markdown', reply_markup = self.generate_ticket_keyboard(ticket_id, q['user_id'], True) ) client.send_message(q['user_id'], "Your ticket [ #{} ] is closed".format(ticket_id)) elif msg.data.startswith('block'): self.mysqldb.execute("UPDATE `tickets_user` SET `baned` = 1 WHERE `user_id` = {}".format(msg.data.split()[-1])) msg.answer('DONE!') self.bot.send_message( self.help_group, 'blocked {}'.format(build_html_parse.parse_user(msg.data.split()[-1], msg.data.split()[-1])), parse_mode = 'markdown', reply_markup = InlineKeyboardMarkup( inline_keyboard = [ [InlineKeyboardButton(text = 'UNBAN', callback_data = 'unban {}'.format(msg.data.split()[-1]).encode())] ]) ) elif msg.data.startswith('send'): try: self.send_link_callback(int(msg.data.split()[-1]), True) msg.answer('The invitation link is sent successfully.') except: client.send_message(self.help_group, traceback.format_exc(), disable_web_page_preview = True) msg.answer('Failed to send the invitation link. Please check the console.\n{}'.format(traceback.format_exc().splitlines()[-1]), True) elif msg.data.startswith('reset'): self.mysqldb.execute('UPDATE `exam_user_session` SET `retries` = 0 WHERE `user_id` = {}'.format(msg.data.split()[-1])) msg.answer('Retry times has been reset') elif msg.data.startswith('del'): try: client.delete_messages(int(msg.data.split()[-2]), int(msg.data.split()[-1])) msg.answer('message has been deleted') except: client.send_message(self.help_group, traceback.format_exc(), disable_web_page_preview = True) msg.answer('Failed to delete the message. Please check the console.\n{}'.format(traceback.format_exc().splitlines()[-1]), True) elif msg.data.startswith('renew'): self.mysqldb.execute('DELETE FROM `exam_user_session` WHERE `user_id` = {}'.format(msg.data.split()[-1])) msg.answer('User Profile Deleted') elif msg.data.startswith('bypass'): self.mysqldb.execute('UPDATE `exam_user_session` SET `bypass` = 1 WHERE `user_id` = {}'.format(msg.data.split()[-1])) msg.answer('BYPASS SET SUCCESSFULLY') elif msg.data.startswith('setpass'): self.mysqldb.execute('UPDATE `exam_user_session` SET `passed` = 1 WHERE `user_id` = {}'.format(msg.data.split()[-1])) msg.answer('PASS SET SUCCESSFULLY') elif msg.data.startswith('unlimited'): self.mysqldb.execute('UPDATE `exam_user_session` SET `unlimited` = 1 WHERE `user_id` = {}'.format(msg.data.split()[-1])) msg.answer('UNLIMITED RETRIES SET SUCCESSFULLY') self.mysqldb.commit() client.delete_messages(msg.message.chat.id, msg.message.message_id) def send_confirm(self, client: Client, msg: CallbackQuery): if msg.data.startswith('close'): self.confirm_dialog(msg, 'close this ticket', 'close',ticket_id = msg.data.split()[-1]) elif msg.data.startswith('block'): self.confirm_dialog(msg, 'block this user', 'block', user_id = int(msg.data.split()[-1])) elif msg.data.startswith('send'): self.confirm_dialog(msg, 'send the link to', 'send', user_id = int(msg.data.split()[-1])) elif msg.data.startswith('reset'): self.confirm_dialog(msg, 'reset retry times for', 'reset', user_id = int(msg.data.split()[-1])) elif msg.data.startswith('del'): msg.answer('Please press again to make sure. If you really want to delete this reply', True) self.bot.send_message( self.help_group, 'Do you want to delete reply message to {}?'.format(build_html_parse.parse_user(msg.data.split()[-2])), 'markdown', reply_markup = self.generate_confirm_keyboard('del', msg.data[4:]) ) elif msg.data.startswith('bypass'): self.confirm_dialog(msg, 'set bypass for', 'bypass', int(msg.data.split()[-1])) elif msg.data.startswith('renew'): self.confirm_dialog(msg, 'reset user status', 'renew', int(msg.data.split()[-1])) elif msg.data.startswith('setpass'): self.confirm_dialog(msg, 'set pass', 'setpass', int(msg.data.split()[-1])) elif msg.data.startswith('unlimited'): self.confirm_dialog(msg, 'set unlimited retries for', 'unlimited', int(msg.data.split()[-1])) msg.answer() def answer(self, client: Client, msg: CallbackQuery): msg.data = msg.data.decode(errors = 'ignore') if msg.data.startswith('cancel'): client.edit_message_reply_markup(msg.message.chat.id, msg.message.message_id) msg.answer('Canceled') elif msg.data.startswith('unban'): self.mysqldb.execute("UPDATE `tickets_user` SET `baned` = 0 WHERE `user_id` = {}".format(msg.data.split()[-1])) msg.answer('UNBANED') client.edit_message_reply_markup(msg.message.chat.id, msg.message.message_id) elif msg.data.startswith('refresh'): try: client.edit_message_text( msg.message.chat.id, msg.message.message_id, self.generate_superuser_text(msg.data.split()[-1]), 'markdown', reply_markup = msg.message.reply_markup ) except api.errors.exceptions.bad_request_400.MessageNotModified: pass msg.answer('refreshed') elif 'confirm' in msg.data: try: self.confirm(client, msg) except TimeoutError: msg.answer('Confirmation time out') client.edit_message_reply_markup(msg.message.chat.id, msg.message.message_id) elif any(msg.data.startswith(x) for x in ('close', 'block', 'send', 'bypass', 'reset', 'unlimited', 'del', 'renew', 'setpass')): self.send_confirm(client, msg) else: try: raise ValueError(msg.data) except: client.send_message(self.help_group, traceback.format_exc(), disable_web_page_preview = True) def flood_check(self, client: Client, msg: Message): sq = self.mysqldb.query1("SELECT `last_time`, `last_msg_sent`, `baned` FROM `tickets_user` WHERE `user_id` = {}".format(msg.chat.id)) if sq and (datetime.now() - sq['last_time']).total_seconds() < 120: if msg.text: print('Caught flood {}: {}'.format(msg.chat.id, msg.text)) self.mysqldb.execute("UPDATE `tickets_user` SET `last_msg_sent` = CURRENT_TIMESTAMP() WHERE `user_id` = {}".format(msg.chat.id)) self.mysqldb.commit() if sq['baned']: return msg.reply('Due to privacy settings, you are temporarily unable to operate.') is not None msg.reply("You are driving too fast. Please try again later.") return True return False
class bot_class: bot_self = None def __init__(self): logger.debug('Enter bot_class.__init__()') config = ConfigParser() config.read('data/config.ini') self.bot = Client(config.get('bot', 'bot_token').split(':')[0], config.get('bot', 'api_id'), config.get('bot', 'api_hash'), bot_token=config.get('bot', 'bot_token')) self._bot_id = int(self.bot.session_name) self.conn = mysqldb(config.get('database', 'host'), config.get('database', 'user'), config.get('database', 'password'), config.get('database', 'db'), autocommit=True) self._bot_name = None self.loaddatetime = datetime.datetime.now().replace(microsecond=0) self.groups = group_cache(self.conn, self.bot) self.error_message = config.get('bot', 'error_message', fallback='') self.init_receiver() def run(self): self.bot.start() try: self.bot.idle() except InterruptedError: logger.debug('Catch!') def stop(self): self.bot.stop() self.conn.close() @property def bot_id(self) -> int: return self._bot_id @property def bot_name(self) -> str: if self._bot_name is None: self._bot_name = self.bot.get_me().username logger.debug('Fetched bot username => %s', self._bot_name) return self._bot_name def new_chat_member(self, client: Client, msg: Message): if self.bot_id in msg.new_chat_members: self.groups.insert_group(msg.chat.id) msg.reply('Please use /setwelcome to set welcome message') #msg.reply('This bot is refactoring code, feature may not available during this time') else: group_setting = self.groups[msg.chat.id] if group_setting is None: group_setting = self.groups.insert_group(msg.chat.id) welcome_text = group_setting.welcome_text if welcome_text is not None: try: last_msg = msg.reply( welcome_text.replace('$name', parse_user_name(msg.from_user)), parse_mode='markdown', disable_web_page_preview=True).message_id except pyrogram.errors.ChatWriteForbidden: logger.error('Got ChatWriterForbidden in %d', msg.chat.id) msg.chat.leave() self.groups.delete_group(msg.chat.id) return previous_msg = self.conn.query_last_message_id(msg.chat.id) self.conn.insert_last_message_id(msg.chat.id, last_msg) if self.groups[msg.chat.id].no_welcome: if previous_msg is not None: client.delete_messages(msg.chat.id, previous_msg) def left_chat_member(self, _client: Client, msg: Message): if self.bot_id in msg.left_chat_member: self.groups.delete_group(msg.chat.id) def privileges_control(self, client: Client, msg: Message): bot_name = re.match( r'^\/(setwelcome|clear|status|setflag)(@[a-zA-Z_]*bot)?\s?', msg.text).group(2) if bot_name is not None and bot_name[1:] != self.bot_name: return group_info = self.groups[msg.chat.id] if group_info.admins is None: admins = client.get_chat_members(msg.chat.id, filter='administrators') group_info.admins = [x.user.id for x in admins] self.groups.update_group(msg.chat.id, group_info) logger.info('Updated administrator list in %d, new list is => %s', msg.chat.id, group_info.admins) if msg.from_user.id in group_info.admins: raise ContinuePropagation else: if not group_info.ignore_err and self.error_message != '': msg.reply(self.error_message) try: client.restrict_chat_member( msg.chat.id, msg.from_user.id, ChatPermissions(can_send_messages=False), msg.date + 60) except: pass def set_welcome_message(self, _client: Client, msg: Message): result = setcommand_match.match(msg.text) welcomemsg = str(result.group(2)) result = gist_match.match(welcomemsg) if result: r = requests.get(welcomemsg) r.raise_for_status() welcomemsg = r.text if len(welcomemsg) > 2048: msg.reply( "**Error**:Welcome message is too long.(len() must smaller than 2048)", parse_mode='markdown') return p = self.groups[msg.chat.id] p.welcome_text = welcomemsg self.groups.update_group(msg.chat.id, p) msg.reply(f"**Set welcome message to:**\n{welcomemsg}", parse_mode='markdown', disable_web_page_preview=True) def clear_welcome_message(self, _client: Client, msg: Message): p = self.groups[msg.chat.id] p.welcome_text = '' self.groups.update_group(msg.chat.id, p) msg.reply("**Clear welcome message completed!**", parse_mode='markdown') def generate_status_message(self, _client: Client, msg: Message): info = self.groups[msg.chat.id] send_and_delete( msg, 'Current welcome messsage: {}'.format(info.welcome_text), 10) def response_ping_command(self, _client: Client, msg: Message): send_and_delete( msg, '**Current chat_id:** `{}`\n**Your id:** `{}`\n**Bot runtime**: `{}`\n**System load avg**: `{}`' .format(msg.chat.id, msg.from_user.id, self.get_runtime(), getloadavg()), 10) def set_group_prop(self, _client: Client, msg: Message): r = setflag_match.match(msg.text) if r is None: return send_and_delete( msg, 'Please read manual to use this command properly', 10) value = r.group(3) == '1' group_info = self.groups[msg.chat.id] if r.group(2) == 'no_welcome': group_info.no_welcome = value elif r.group(2) == 'no_blue': group_info.no_blue = value elif r.group(2) == 'ignore_err': group_info.ignore_err = value elif r.group(2) == 'no_service_msg': group_info.no_service_msg = value elif r.group(2) == 'no_new_member': group_info.no_new_member = value self.groups.update_group(msg.chat.id, group_info) send_and_delete(msg, f'Set {r.group(2)} flag to **{value}** successfully!', 10) def init_receiver(self): self.bot.add_handler( MessageHandler(self.new_chat_member, Filters.new_chat_members)) self.bot.add_handler( MessageHandler(self.left_chat_member, Filters.left_chat_member)) self.bot.add_handler( MessageHandler( self.privileges_control, Filters.group & Filters.regex( r'^\/(setwelcome|clear|status|setflag)(@[a-zA-Z_]*bot)?\s?' ))) self.bot.add_handler( MessageHandler( self.set_welcome_message, Filters.group & Filters.regex(r'^\/setwelcome(@[a-zA-Z_]*bot)?\s((.|\n)*)$'))) self.bot.add_handler( MessageHandler( self.clear_welcome_message, Filters.group & Filters.regex(r'^\/clear(@[a-zA-Z_]*bot)?$'))) self.bot.add_handler( MessageHandler( self.generate_status_message, Filters.group & Filters.regex(r'^\/status(@[a-zA-Z_]*bot)?$'))) self.bot.add_handler( MessageHandler( self.response_ping_command, Filters.group & Filters.regex(r'^\/ping(@[a-zA-Z_]*bot)?$'))) self.bot.add_handler( MessageHandler( self.set_group_prop, Filters.group & Filters.regex(r'^\/setflag(@[a-zA-Z_]*bot)?\s?'))) def get_runtime(self): return str(datetime.datetime.now().replace(microsecond=0) - self.loaddatetime)
class bot_controller(object): def __init__(self): self.problems_load() self.target_group = int(config['fuduji']['target_group']) self.fudu_group = int(config['fuduji']['fudu_group']) self.bot_id = int(config['account']['api_key'].split(':')[0]) self.emerg_contact = eval(config['account']['emerg_contact']) \ if config.has_option('account', 'emerg_contact') and config['account']['emerg_contact'] != '' else \ int(config['account']['owner']) self.app = Client(session_name='session', api_id=config['account']['api_id'], api_hash=config['account']['api_hash'], app_version='repeater') self.botapp = Client(session_name=config['account']['api_key'], api_id=config['account']['api_id'], api_hash=config['account']['api_hash']) self.conn = mysqldb(config['database']['host'], config['database']['user'], config['database']['passwd'], config['database']['db_name'], self.emerg_contact) self.media_sender = mediaSender(self.app.send_message, self.conn) self.join_group_verify = join_group_verify_class( self.conn, self.botapp, self.target_group, extern_load_problem_set) self.revoke_tracker_thread = self.join_group_verify.get_revoke_tracker_thread( ) self.custom_service = custom_service_bot_class( config, self.conn, self.revoke_tracker_thread.send_link) self.db_keepAlive = Thread(target=self.conn.keep_alive, daemon=True) self.db_keepAlive.start() def init(self): global bot_username bot_username = self.botapp.get_me().username def problems_load(self): self.problem_set = extern_load_problem_set() def idle(self): return self.app.idle() def start(self): self.app.add_handler( MessageHandler( self.handle_edit, Filters.chat(self.target_group) & ~Filters.user(self.bot_id) & Filters.edited)) self.app.add_handler( MessageHandler( self.handle_new_member, Filters.chat(self.target_group) & Filters.new_chat_members)) self.app.add_handler( MessageHandler( self.handle_document, Filters.chat(self.target_group) & ~Filters.user(self.bot_id) & Filters.document)) self.app.add_handler( MessageHandler( self.handle_photo, Filters.chat(self.target_group) & ~Filters.user(self.bot_id) & Filters.photo)) self.app.add_handler( MessageHandler( self.handle_sticker, Filters.chat(self.target_group) & ~Filters.user(self.bot_id) & Filters.sticker)) self.app.add_handler( MessageHandler( self.handle_gif, Filters.chat(self.target_group) & ~Filters.user(self.bot_id) & Filters.animation)) self.app.add_handler( MessageHandler( self.handle_video, Filters.chat(self.target_group) & ~Filters.user(self.bot_id) & Filters.video)) self.app.add_handler( MessageHandler( self.handle_speak, Filters.chat(self.target_group) & ~Filters.user(self.bot_id) & Filters.text)) self.app.add_handler( MessageHandler(self.handle_incoming, Filters.incoming & Filters.chat(self.fudu_group))) self.botapp.add_handler(CallbackQueryHandler(self.handle_callback)) self.join_group_verify.init() self.app.start() self.botapp.start() self.init() self.custom_service.start() def stop(self): self.revoke_tracker_thread.set_stop() self.revoke_tracker_thread.join(1.5) if self.revoke_tracker_thread.is_alive(): print('[WARN] revoke_tracker_thread still running!') self.custom_service.stop() self.botapp.stop() self.app.stop() def emerg_send_message(self, msg_str: str): ''' Send message to emergancy contacts. ''' if isinstance(self.emerg_contact, int): self.app.send_message(self.emerg_contact, msg_str, 'html') else: for user_id in self.emerg_contact: self.app.send_message(user_id, msg_str, 'html') def process_imcoming_command(self, client: Client, msg: Message): r = re.match(r'^\/bot (on|off)$', msg.text) if r is None: r = re.match(r'^\/b?(on|off)$', msg.text) if r: if not auth_system.check_ex( msg.reply_to_message.from_user.id if msg. reply_to_message else msg.from_user.id): return auth_system.mute_or_unmute( r.group(1), msg.reply_to_message.from_user.id if msg.reply_to_message else msg.from_user.id) client.delete_messages(msg.chat.id, msg.message_id) if msg.text == '/status': user_id = msg.reply_to_message.from_user.id if msg.reply_to_message else msg.from_user.id status = [ str(user_id), ' summary:\n\n', 'A' if auth_system.check_ex(user_id) else 'Una', 'uthorized user\nBot status: ', '✅' if not auth_system.check_muted(user_id) else '❌' ] sleep_to_delete( client, msg.chat.id, (msg.message_id, msg.reply(''.join(status), True).message_id)) del status elif msg.text.startswith('/p'): if msg.text.startswith('/promote'): if len(msg.text.split()) == 1: if msg.reply_to_message is None or not auth_system.check_ex( msg.reply_to_message.from_user.id): self.botapp.send_message( msg.chat.id, 'Please reply to an Authorized user.', reply_to_message_id=msg.message_id) return user_id = msg.reply_to_message.from_user.id else: user_id = int(msg.text.split()[1]) self.botapp.send_message( msg.chat.id, 'Please use bottom to make sure you want to add {} to Administrators' .format(build_html_parse.parse_user(user_id)), parse_mode='markdown', reply_to_message_id=msg.message_id, reply_markup=InlineKeyboardMarkup( inline_keyboard=[[ InlineKeyboardButton(text='Yes, confirm', callback_data='promote {}'. format(user_id).encode()) ], [ InlineKeyboardButton( text='Cancel', callback_data=b'cancel d') ]])) else: if not auth_system.check_ex(msg.from_user.id): return self.botapp.promote_chat_member(self.target_group, int(msg.from_user.id), True, can_delete_messages=True, can_restrict_members=True, can_invite_users=True, can_pin_messages=True, can_promote_members=True) self.botapp.send_message( msg.chat.id, '[Emergency]: Privileges has been promoted', reply_to_message_id=msg.message_id) return if msg.reply_to_message: if msg.text == '/del': try: client.forward_messages( msg.chat.id, self.target_group, self.conn.get_reply_id_Reverse(msg)) self.botapp.delete_messages( self.target_group, self.conn.get_reply_id_Reverse(msg)) except: client.send_message(msg.chat.id, traceback.format_exc(), disable_web_page_preview=True) try: client.delete_messages( int(config['fuduji']['fudu_group']), [msg.message_id, msg.reply_to_message.message_id]) except: pass elif msg.text == '/getid': user_id = self.conn.get_user_id(msg) client.send_message( msg.chat.id, 'user_id is `{}`'.format( user_id['user_id'] if user_id is not None and user_id['user_id'] != 0 else 'ERROR_INVALID_USER_ID'), parse_mode='markdown', reply_to_message_id=msg.reply_to_message.message_id) elif msg.text == '/get' and self.conn.get_reply_id_Reverse(msg): try: client.forward_messages( int(config['fuduji']['fudu_group']), self.target_group, self.conn.get_reply_id_Reverse(msg)) except: client.send_message( msg.chat.id, traceback.format_exc().splitlines()[-1]) elif msg.text == '/getn': pass elif msg.text == '/fw': self.conn.insert_ex( self.botapp.forward_messages( self.target_group, self.target_group, self.conn.get_reply_id_Reverse(msg)).message_id, msg.message_id) elif msg.text.startswith('/ban'): user_id = self.conn.get_user_id(msg) if len(msg.text) == 4: restrict_time = 0 else: r = re.match(r'^([1-9]\d*)(s|m|h|d)$', msg.text[5:]) if r is not None: restrict_time = int(r.group(1)) * { 's': 1, 'm': 60, 'h': 60 * 60, 'd': 60 * 60 * 24 }.get(r.group(2)) else: self.botapp.send_message( msg.chat.id, 'Usage: `/ban` or `/ban <Duration>`', reply_to_message_id=msg.message_id, parse_mode='markdown') if user_id is not None and user_id['user_id'] != 0: if user_id['user_id'] not in auth_system.whitelist: self.botapp.send_message( msg.chat.id, 'What can {} only do? Press the button below.\nThis confirmation message will expire after 20 seconds.' .format( build_html_parse.parse_user( user_id['user_id'])), reply_to_message_id=msg.message_id, parse_mode='markdown', reply_markup=InlineKeyboardMarkup(inline_keyboard=[ [ InlineKeyboardButton( text='READ', callback_data='res {} read {}'.format( restrict_time, user_id['user_id']).encode()) ], [ InlineKeyboardButton( text='SEND_MESSAGES', callback_data='res {} write {}'.format( restrict_time, user_id['user_id']).encode()), InlineKeyboardButton( text='SEND_MEDIA', callback_data='res {} media {}'.format( restrict_time, user_id['user_id']).encode()) ], [ InlineKeyboardButton( text='SEND_STICKERS', callback_data='res {} stickers {}'. format(restrict_time, user_id['user_id']).encode()), InlineKeyboardButton( text='EMBED_LINKS', callback_data='res {} link {}'.format( restrict_time, user_id['user_id']).encode()) ], [ InlineKeyboardButton( text='Cancel', callback_data=b'cancel') ] ])) else: self.botapp.send_message( msg.chat.id, 'ERROR_WHITELIST_USER_ID', reply_to_message_id=msg.message_id) else: self.botapp.send_message( msg.chat.id, 'ERROR_INVALID_USER_ID', reply_to_message_id=msg.message_id) elif msg.text == '/kick': user_id = self.conn.get_user_id(msg) if user_id is not None and user_id['user_id'] != 0: if user_id['user_id'] not in auth_system.whitelist: self.botapp.send_message( msg.chat.id, 'Do you really want to kick {}?\nIf you really want to kick this user, press the button below.\nThis confirmation message will expire after 15 seconds.' .format( build_html_parse.parse_user( user_id['user_id'])), reply_to_message_id=msg.message_id, parse_mode='markdown', reply_markup=InlineKeyboardMarkup(inline_keyboard=[ [ InlineKeyboardButton( text='Yes, kick it', callback_data=b' '.join(( b'kick', str(msg.from_user.id).encode(), str(user_id['user_id']).encode()))) ], [ InlineKeyboardButton( text='No', callback_data=b'cancel') ], ])) else: self.botapp.send_message( msg.chat.id, 'ERROR_WHITELIST_USER_ID', reply_to_message_id=msg.message_id) else: self.botapp.send_message( msg.chat.id, 'ERROR_INVALID_USER_ID', reply_to_message_id=msg.message_id) else: # Not reply message if msg.text == '/ban': client.send_message( msg.chat.id, 'Reply to the user you wish to restrict, if you want to kick this user, please use the /kick command.' ) elif msg.text == '/join': pass elif msg.text.startswith('/set'): auth_system.user_suffix[ msg.from_user.id] = msg.text.split()[-1] client.send_message(msg.chat.id, 'Set suffix to `{}`'.format( msg.text.split()[-1]), 'markdown', reply_to_message_id=msg.message_id) def func_auth_process(self, client: Client, msg: Message): if not auth_system.check_ex(msg.from_user.id): msg.reply('Permission denied') return if msg.reply_to_message.from_user: if auth_system.check_ex(msg.reply_to_message.from_user.id): msg.reply('Authorized') else: self.botapp.send_message( msg.chat.id, 'Do you want to authorize {} ?\nThis confirmation message will expire after 20 seconds.' .format( build_html_parse.parse_user( msg.reply_to_message.from_user.id)), reply_to_message_id=msg.message_id, parse_mode='markdown', reply_markup=InlineKeyboardMarkup(inline_keyboard=[[ InlineKeyboardButton( text='Yes', callback_data='auth {} add'.format( msg.reply_to_message.from_user.id).encode()), InlineKeyboardButton(text='No', callback_data=b'cancel') ]])) else: client.send_message(msg.chat.id, 'Unexpected error.', reply_to_message_id=msg.message_id) def cross_group_forward_request(self, msg: Message): kb = [[ InlineKeyboardButton(text='Yes, I know what I\'m doing.', callback_data=b'fwd original') ], [ InlineKeyboardButton(text='Yes, but don\'t use forward.', callback_data=b'fwd text') ], [ InlineKeyboardButton(text='No, please don\'t.', callback_data=b'cancel d') ]] if msg.text is None: kb.pop(1) self.botapp.send_message( msg.chat.id, '<b>Warning:</b> You are requesting forwarding an authorized user\'s message to the main group, please comfirm your action.', 'html', reply_to_message_id=msg.message_id, reply_markup=InlineKeyboardMarkup(inline_keyboard=kb)) del kb def handle_new_member(self, client: Client, msg: Message): for new_user_id in (x.id for x in msg.new_chat_members): # Exam check goes here try: if not self.join_group_verify.query_user_passed(new_user_id): self.botapp.kick_chat_member(self.target_group, new_user_id) self.botapp.send_message( self.fudu_group, 'Kicked challenge failure user {}'.format( build_html_parse.parse_user(new_user_id)), 'markdown', ) except: traceback.print_exc() self.conn.insert( msg, client.send_message( self.fudu_group, '`{}` invite `{}` joined the group'.format( build_html_parse.user_name(msg.from_user).full_name, '`,`'.join( build_html_parse.user_name(user).full_name for user in msg.new_chat_members ) ), 'markdown' ) \ if msg.new_chat_members[0].id != msg.from_user.id else \ client.send_message( self.fudu_group, '`{}` joined the group'.format( '`,`'.join( build_html_parse.user_name(user).full_name for user in msg.new_chat_members ) ), 'markdown' ) ) def handle_edit(self, client: Client, msg: Message): if msg.via_bot and msg.via_bot.id == 166035794: return if self.conn.get_id(msg.message_id) is None: time.sleep(3) if self.conn.get_id(msg.message_id) is None: print(msg) return print('Editing Failure: get_id return None') try: (client.edit_message_text if msg.text else client.edit_message_caption)(self.fudu_group, self.conn.get_id(msg.message_id), build_html_parse(msg).call(), 'html') except: traceback.print_exc() def handle_document(self, client: Client, msg: Message): self.media_sender.put((client.send_document, msg, msg.document, False)) def handle_photo(self, client: Client, msg: Message): self.media_sender.put( (client.send_photo, msg, msg.photo.sizes[0], False)) def handle_sticker(self, client: Client, msg: Message): self.conn.insert( msg, client.send_message( self.fudu_group, '{} {} sticker'.format( build_html_parse(msg).call(), msg.sticker.emoji), 'html', True, reply_to_message_id=self.conn.get_reply_id(msg), )) def handle_gif(self, client: Client, msg: Message): self.media_sender.put( (client.send_animation, msg, msg.animation, False)) def handle_video(self, client: Client, msg: Message): self.media_sender.put((client.send_video, msg, msg.video, False)) def handle_speak(self, client: Client, msg: Message): if msg.text.startswith('/') and re.match(r'^\/\w+(@\w*)?$', msg.text): return self.conn.insert( msg, client.send_message( self.fudu_group, build_html_parse(msg).call(), 'html', reply_to_message_id=self.conn.get_reply_id(msg), disable_web_page_preview=True)) def handle_incoming(self, client: Client, msg: Message): client.send( api.functions.channels.ReadHistory( client.resolve_peer(msg.chat.id), msg.message_id)) if msg.text == '/auth' and msg.reply_to_message: return self.func_auth_process(client, msg) if not auth_system.check_ex(msg.from_user.id): return if msg.text and re.match( r'^\/(bot (on|off)|del|getn?|fw|ban( (([1-9]\d*)(s|m|h|d)|f))?|kick( confirm| -?\d+)?|status|b?o(n|ff)|join|p(romote( \d+)?)?|set [a-zA-Z])$', msg.text): return self.process_imcoming_command(client, msg) if msg.text and msg.text.startswith('/') and re.match( r'^\/\w+(@\w*)?$', msg.text): return if auth_system.check_muted(msg.from_user.id) or ( msg.text and msg.text.startswith('//')) or ( msg.caption and msg.caption.startswith('//')): return if msg.forward_from or msg.forward_from_chat: if msg.forward_from: if msg.forward_from.is_self: return elif auth_system.check_ex(msg.forward_from.id): return self.cross_group_forward_request(msg) self.conn.insert_ex( self.botapp.forward_messages(self.target_group, self.fudu_group, msg.message_id).message_id, msg.message_id) elif msg.text and (not msg.edit_date or (msg.edit_date and self.conn.get_id(msg.message_id, True) is None)): self.conn.insert_ex( self.botapp.send_message( self.target_group, build_html_parse(msg).split_offset(), 'html', True, reply_to_message_id=self.conn.get_reply_id_Reverse(msg), ).message_id, msg.message_id) elif msg.photo: self.media_sender.Locker.acquire() msg.download('tmp.jpg') self.media_sender.put((self.botapp.send_photo, msg, media_path('downloads/tmp.jpg'), True), True) elif msg.video: self.media_sender.put( (self.botapp.send_video, msg, msg.video, True), True) elif msg.document: self.media_sender.put( (self.botapp.send_document, msg, msg.document, True), True) elif msg.edit_date: try: (self.botapp.edit_message_text if msg.text else self.botapp.edit_message_caption)( self.target_group, self.conn.get_id(msg.message_id, True), build_html_parse(msg).split_offset(), parse_mode='html', disable_web_page_preview=True) except: traceback.print_exc() elif msg.sticker: self.media_sender.put( (self.botapp.send_sticker, msg, msg.sticker, True), True) def handle_callback(self, client: Client, msg: CallbackQuery): msg.data = msg.data.decode(errors='ignore') try: if msg.data.startswith('cancel') or msg.data == 'rm': msg.answer( msg.id, 'Canceled' if not msg.data == 'rm' else 'Button removed') if msg.data.endswith('d'): client.delete_messages(msg.message.chat.id, msg.message.message_id) else: client.edit_message_reply_markup(msg.message.chat.id, msg.message.message_id) if self.join_group_verify is not None and self.join_group_verify.click_to_join( client, msg): return if msg.data.startswith('res'): if time.time() - msg.message.date > 20: raise OperationTimeoutError() _, dur, _type, _user_id = msg.data.split() if client.restrict_chat_member( self.target_group, int(_user_id), int(time.time()) + int(dur), **({ 'write': { 'can_send_messages': True }, 'media': { 'can_send_media_messages': True }, 'stickers': { 'can_send_other_messages': True }, 'link': { 'can_add_web_page_previews': True }, 'read': {} }.get(_type))): msg.answer('The user is restricted successfully.') client.edit_message_text( msg.message.chat.id, msg.message.message_id, 'Restrictions applied to {} Duration: {}'.format( build_html_parse.parse_user(_user_id), '{}s'.format(dur) if int(dur) else 'Forever'), parse_mode='markdown', reply_markup=InlineKeyboardMarkup([[ InlineKeyboardButton( text='UNBAN', callback_data='unban {}'.format( _user_id).encode()) ]])) elif msg.data.startswith('unban'): if client.restrict_chat_member(self.target_group, int(msg.data.split()[-1]), 0, True, True, True, True): msg.answer('Unban successfully') client.edit_message_reply_markup(msg.message.chat.id, msg.message.message_id) elif msg.data.startswith('auth'): if time.time() - msg.message.date > 20: raise OperationTimeoutError() auth_system.add_user(msg.data.split()[1]) msg.answer('{} added to the authorized group'.format( msg.data.split()[1])) client.edit_message_text( msg.message.chat.id, msg.message.message_id, '{} added to the authorized group'.format( msg.data.split()[1])) with open('config.ini', 'w') as fout: config.write(fout) elif msg.data.startswith('fwd'): if time.time() - msg.message.date > 30: raise OperationTimeoutError() if 'original' in msg.data: self.conn.insert_ex( client.forward_messages( self.target_group, msg.message.chat.id, msg. message.reply_to_message.message_id).message_id, msg.message.reply_to_message.message_id) else: self.conn.insert_ex( client.send_message( self.target_group, build_html_parse( msg.message.reply_to_message).split_offset(), 'html').message_id, msg.message.reply_to_message.message_id) msg.answer('Forward successfully') client.delete_messages(msg.message.chat.id, msg.message.message_id) elif msg.data.startswith('kick'): if not msg.data.startswith( 'kickc') and msg.from_user.id != int( msg.data.split()[-2]): raise OperatorError() if 'true' not in msg.data: if not msg.data.startswith( 'kickc') and time.time() - msg.message.date > 15: raise OperationTimeoutError() args = [ msg.message.chat.id, msg.message.message_id, 'Press the button again to kick {}\nThis confirmation message will expire after 10 seconds.' .format( build_html_parse.parse_user(msg.data.split()[-1])), ] if msg.data.startswith('kickc'): args.pop(1) r = msg.data.split() r.insert(1, msg.from_user.id) msg.data = ' '.join(str(x) for x in r) del r kwargs = { 'parse_mode': 'markdown', 'reply_markup': InlineKeyboardMarkup( inline_keyboard=[[ InlineKeyboardButton( text='Yes, please.', callback_data=b' '.join(( b'kick true', ' '.join( msg.data.split()[1:]).encode()))) ], [ InlineKeyboardButton( text='Cancel', callback_data=b'cancel') ]]) } (client.send_message if msg.data.startswith('kickc') else client.edit_message_text)(*args, **kwargs) msg.answer( 'Please press again to make sure. Do you really want to kick {} ?' .format(msg.data.split()[-1]), True) else: if msg.message.edit_date: if time.time() - msg.message.edit_date > 10: raise OperationTimeoutError() else: if time.time() - msg.message.date > 10: raise OperationTimeoutError() client.kick_chat_member(self.target_group, int(msg.data.split()[-1])) msg.answer('Kicked {}'.format(msg.data.split()[-1])) client.edit_message_text( msg.message.chat.id, msg.message.message_id, 'Kicked {}'.format( build_html_parse.parse_user(msg.data.split()[-1]))) #app.send_message(self.fudu_group, 'Kicked {}'.format(msg.message.entities[0].user.id)) #client.delete_messages(msg.message.chat.id, msg.message.message_id) elif msg.data.startswith('promote'): if not msg.data.endswith('undo'): if time.time() - msg.message.date > 10: raise OperationTimeoutError() self.botapp.promote_chat_member(self.target_group, int(msg.data.split()[1]), True, can_delete_messages=True, can_restrict_members=True, can_invite_users=True, can_pin_messages=True, can_promote_members=True) msg.answer('Promote successfully') client.edit_message_text( msg.message.chat.id, msg.message.message_id, 'Promoted {}'.format( build_html_parse.parse_user( int(msg.data.split()[1]))), parse_mode='markdown', reply_markup=InlineKeyboardMarkup(inline_keyboard=[ [ InlineKeyboardButton(text='UNDO', callback_data=' '.join(( msg.data, 'undo')).encode()) ], [ InlineKeyboardButton(text='remove button', callback_data=b'rm') ] ])) else: self.botapp.promote_chat_member(self.target_group, int(msg.data.split()[1]), False, can_delete_messages=False, can_invite_users=False, can_restrict_members=False) msg.answer('Undo Promote successfully') client.edit_message_text( msg.message.chat.id, msg.message.message_id, 'Unpromoted {}'.format( build_html_parse.parse_user( int(msg.data.split()[1]))), parse_mode='markdown') except OperationTimeoutError: msg.answer('Confirmation time out') client.edit_message_reply_markup(msg.message.chat.id, msg.message.message_id) except OperatorError: msg.answer( 'The operator should be {}.'.format(msg.data.split()[-2]), True) except: self.app.send_message(int(config['fuduji']['help_group']), traceback.format_exc().splitlines()[-1]) traceback.print_exc()
def main(): load_modules() client = Client(session_name="userbot") client.set_update_handler(update_handler) client.start() client.idle()
class _BotClient: def __init__(self): self.config = ConfigParser() self.config.read('data/server_config.ini') self.client_pool = {} self.botapp = Client('distributed_vps_control_bot', self.config['account']['api_id'], self.config['account']['api_key'], bot_token=self.config['account']['bot_key']) self.conn = mysqldb.init_instance(self.config['mysql']['host'], self.config['mysql']['user'], self.config['mysql']['password'], self.config['mysql']['database']) self.owner = self.config.getint('account', 'owner') self.http_server = HTTPServer( (self.config['http']['addr'], self.config['http']['port']), RewritedServer) self.http_thread = None self._basic_filter = Filters.chat(self.owner) def init_handle(self): self.botapp.add_handler( MessageHandler(self.handle_status, self._basic_filter)) self.botapp.add_handler( CallbackQueryHandler(self.handle_callback_query)) def idle(self): try: self.botapp.idle() except InterruptedError: pass def handle_status(self, _client: Client, _msg: Message): pass def request_confirm(self, cid: int, payload: dict): self.botapp.send_message( self.owner, 'Do you want to approve this machine\n**Username**: `{}`\nIP Address:`{}`' .format(payload.get('username'), payload.get('ip')), 'markdown', reply_markup=InlineKeyboardMarkup(inline_keyboard=[[ InlineKeyboardButton('approve', callback_data=f'approve {cid}') ]])) def start(self): self.http_thread = threading.Thread( target=self.http_server.serve_forever, daemon=True) self.http_thread.start() self.botapp.start() def handle_callback_query(self, client: Client, msg: CallbackQuery): data = msg.data.split() if data[0] == 'approve': self.conn.approve_new_client(data[1]) def stop(self): self.botapp.stop() self.conn.close()
class TelegramBot(): def __init__(self): self.client = Client("Listener") self.client.add_handler(RawUpdateHandler(self.processUpdate)) def run(self): self.config = configparser.ConfigParser() try: self.config.read("config.ini") except: self.logError("Error while loading the config file, exiting", True) self.setupDBConnection() print("\nStarting Telegram API connection\n") self.client.start() print("API connection started") self.listening = False self.chats = self.getChats() self.monitoredChats = self.loadMonitoredChatsTable() self.menu() self.client.idle() def menu(self): help = ''' - COMMANDS - all - show a list of joined chats/channels/groups in the account listening - show a list of joined chats/channels/groups we are listening to for updates add - add hats/channels/groups to the listening list, pass comma-separated list of usernames or ids remove - remove chats/channels/groups from the listening list, pass comma-separated list of usernames or ids start - start listening for updates ''' print(help) while (True): userInput = input("\nPlease enter command: ") try: inputSplit = userInput.split(" ", 1) command = inputSplit[0].strip() if (command == "start"): print("\nStarted listening for updates\n") self.listening = True return elif (command == "all"): print("\nTITLE - USERNAME - ID") for chatID in self.chats: chat = self.chats[chatID] print(chat[0] + " - " + chat[1] + " - " + str(chatID)) elif (command == "listening"): if len(self.monitoredChats) > 0: print("TITLE - USERNAME - ID") for chatID in self.monitoredChats: chat = self.monitoredChats[chatID] print(chat[0] + " - " + chat[1] + " - " + str(chatID)) else: print( "We're not listening to any chats/channels/groups yet" ) elif (command == "add"): if len(inputSplit) == 1: print("No arguments provided") continue items = inputSplit[1].split(",") items = [i.strip() for i in items if i.strip() != ""] self.addChats(items) elif (command == "remove"): if len(inputSplit) == 1: print("No arguments provided") continue items = inputSplit[1].split(",") items = [i.strip() for i in items if i.strip() != ""] self.removeChats(items) else: print("Sorry, the command was not recognized") except: self.logError("Sorry, we've encountered an error") continue def setupDBConnection(self): host = self.config["database"]["host"] user = self.config["database"]["user"] password = self.config["database"]["password"] db = self.config["database"]["db"] charset = self.config["database"]["charset"] dbsettings = { "host": host, "user": user, "password": password, "db": db, "charset": charset } try: self.pool = pymysql_pool.ConnectionPool(size=1, name='pool', **dbsettings) except: self.logError( "Error while attempting to connect to database, exiting\n", True) print("Database connection established") self.checkTables() def checkTables(self): self.chatTable = self.config["database"]["chat_table"] self.messageTable = self.config["database"]["message_table"] tables = {} tables["chat"] = { "name": self.chatTable, "statement": "(ID int unsigned not null, Title varchar(255), Username varchar(255), PRIMARY KEY (ID))" } tables["message"] = { "name": self.messageTable, "statement": "(ID int unsigned not null auto_increment, Time datetime, Type varchar(255), Chat int unsigned not null, Sender varchar(255), Message text, PRIMARY KEY(ID), FOREIGN KEY (Chat) REFERENCES " + self.chatTable + "(ID))" } connection = self.pool.get_connection() c = connection.cursor() for tableType in tables: table = tables[tableType] try: c.execute("SHOW TABLES LIKE '" + table["name"] + "'") result = c.fetchone() except: self.logError( "Error while looking for " + tableType + " table (" + table["name"] + ") in database\n", True) if result: print("Found " + tableType + " table (" + table["name"] + ")") else: print("Creating " + tableType + " table (" + table["name"] + ")") try: c.execute("CREATE TABLE " + table["name"] + " " + table["statement"]) connection.commit() except: self.logError( "Error while creating " + tableType + " table (" + table["name"] + ")\n", True) connection.close() def loadMonitoredChatsTable(self): try: connection = self.pool.get_connection() c = connection.cursor() c.execute("SELECT * FROM " + self.chatTable) chats = list(c) self.monitoredChats = { chat[0]: [chat[1], chat[2]] for chat in chats } connection.close() except: self.logError( "Error while getting list of monitored chats/channels/groups from database" ) self.cleanUpMonitored() return self.monitoredChats def cleanUpMonitored(self): delete = [] for monitored in self.monitoredChats: if monitored not in self.chats: delete.append(monitored) if len(delete) > 0: try: connection = self.pool.get_connection() c = connection.cursor() for id in delete: c.execute("DELETE FROM " + self.chatTable + " WHERE ID=" + str(id)) del self.monitoredChats[id] connection.commit() connection.close() except: self.logError( "Error while clearing a monitored chat we no longer are a member of" ) def getChats(self): chats = self.client.send(functions.messages.GetAllChats([])) self.chats = chats.chats self.supergroupIDs = [ chat.id for chat in self.chats if isinstance(chat, types.Channel) and chat.megagroup == True ] self.chats = { chat.id: [ str(chat.title), ("@" if hasattr(chat, "username") and chat.username else "") + (str(chat.username) if hasattr(chat, "username") else "None") ] for chat in self.chats } return self.chats def addChats(self, items): new = [] for item in items: print("Adding to monitored: " + item) if (item[0] == "@"): item = next( (key for key, value in self.chats.items() if value[1] == item), None) elif not item.isdigit(): print("Invalid format for: " + item) continue item = int(item) if not item or not item in self.chats: print("You haven't joined this channel yet") continue if item in self.monitoredChats: print("You've already added this to listening list") continue new.append(item) if len(new) > 0: self.updateMonitoredChatsList(new, "add") def removeChats(self, items): removed = [] for item in items: print("Removing from monitored: " + item) if (item[0] == "@"): item = next( (key for key, value in self.chats.items() if value[1] == item), None) if not item: print( "You haven't even joined this channel , check for typing errors" ) continue elif item.isdigit(): if not int(item) in self.chats: print( "You haven't even joined this channel, check for typing errors" ) continue item = int(item) else: print("Invalid format for: " + item) continue if not item in self.monitoredChats: print("Already not monitored") continue removed.append(item) if len(removed) > 0: self.updateMonitoredChatsList(removed, "remove") def updateMonitoredChatsList(self, modified, action): try: connection = self.pool.get_connection() c = connection.cursor() for id in modified: chat = self.chats[id] if action == "add": c.execute( "INSERT INTO " + self.chatTable + "(ID, Title, Username) VALUES (%s, %s, %s)", (id, chat[0], chat[1])) elif action == "remove": sql = "DELETE FROM " + self.chatTable + " WHERE ID=" + str( id) c.execute(sql) connection.commit() connection.close() for id in modified: if action == "remove": del self.monitoredChats[id] elif action == "add": self.monitoredChats[id] = self.chats[id] except: self.logError("Error while updating monitored list in database") def getAdmins(self): self.admins = {} for group in self.supergroupIDs: print("Getting admins for: " + str(group)) groupAdmins = [] limit = 200 offset = 0 filter = types.ChannelParticipantsAdmins() while True: try: participants = self.client.send( functions.channels.GetParticipants( channel=self.client.resolve_peer(group), filter=filter, offset=offset, limit=limit, hash=0)) except FloodWait as e: time.sleep(e.x) continue if isinstance(participants, types.channels.ChannelParticipantsNotModified): print("No admin changes") pass if not participants.participants: break groupAdmins.extend(participants.participants) offset += limit self.admins[group] = [admin.user_id for admin in groupAdmins] for group in self.admins: print(" - " + str(group) + " - ") for admin in self.admins[group]: print(admin) print() return self.admins def updateAdmins(self): while True: time.sleep(20) print("Admin list refresh") self.admins = self.getAdmins() def checkIfAdmin(self, channelID, senderID): admins = self.admins[channelID] if senderID in admins: return True else: return False def checkIfChannelAdmin(self, channelID, senderID): participant = self.client.send( functions.channels.GetParticipant( channel=self.client.resolve_peer(channelID), user_id=self.client.resolve_peer(senderID))) sender = participant.participant if isinstance(sender, types.ChannelParticipantCreator) or isinstance( sender, types.ChannelParticipantAdmin): return True else: return False def checkIfGroupAdmin(self, groupID, senderID): chat = self.client.send(functions.messages.GetFullChat(groupID)) participants = chat.full_chat.participants.participants for participant in participants: if participant.user_id == senderID: if isinstance(participant, types.ChatParticipantCreator) or isinstance( participant, types.ChatParticipantAdmin): return True else: return False def processUpdate(self, client, update, users, chats): if self.listening: if isinstance(update, types.UpdateNewChannelMessage): if isinstance(update.message, types.MessageService): return chat = chats[update.message.to_id.channel_id] chatInfo = self.extractChatInfo(chat) if int(chatInfo["id"]) not in self.monitoredChats: return sender = update.message.from_id if sender: sender = users[sender] senderInfo = self.extractSenderInfo(sender) else: senderInfo = None if chat.megagroup == True: if self.checkIfChannelAdmin(chatInfo["id"], senderInfo["id"]): timestamp = update.message.date message = update.message.message print("Supergroup admin message - " + chatInfo["string"] + (" - Sender: " + senderInfo["string"] if sender else "") + ": " + message) self.recordToDatabase(timestamp, "admin", chatInfo, senderInfo, message) self.sendNotification("admin", chatInfo, senderInfo, message) else: print("Supergroup message not from admin - " + chatInfo["string"] + (" - Sender: " + senderInfo["string"] if sender else "") + ": " + update.message.message) else: timestamp = update.message.date message = update.message.message print("Channel message - " + chatInfo["string"] + (" - Sender: " + senderInfo["string"] if sender else "") + ": " + message) self.recordToDatabase(timestamp, "channel", chatInfo, senderInfo, message) self.sendNotification("channel", chatInfo, "", message) elif isinstance(update, types.UpdateChannelPinnedMessage): if update.id != 0: chat = chats[update.channel_id] chatInfo = self.extractChatInfo(chat) if int(chatInfo["id"]) not in self.monitoredChats: return messageInfo = client.get_messages(update.channel_id, update.id) sender = messageInfo.from_user if sender: senderInfo = self.extractSenderInfo(sender) else: senderInfo = None timestamp = messageInfo.date message = messageInfo.text print("New pinned message - " + chatInfo["string"] + (" - Sender: " + senderInfo["string"] if sender else "") + ": " + message) self.recordToDatabase(timestamp, "pinned", chatInfo, senderInfo, message) self.sendNotification("pinned", chatInfo, senderInfo if sender else "", message) elif isinstance(update, types.UpdateNewMessage): if isinstance(update.message, types.MessageService): return chat = chats[update.message.to_id.chat_id] chatInfo = self.extractChatInfo(chat) if int(chatInfo["id"]) not in self.monitoredChats: return sender = users[update.message.from_id] senderInfo = self.extractSenderInfo(sender) timestamp = update.message.date message = update.message.message if self.checkIfGroupAdmin(chatInfo["id"], senderInfo["id"]): print("Group admin message - " + chatInfo["string"] + (" - Sender: " + senderInfo["string"] if sender else "") + ": " + message) self.recordToDatabase(timestamp, "admin", chatInfo, senderInfo, message) self.sendNotification("admin", chatInfo, senderInfo, message) else: print("Group message not from admin - " + chatInfo["string"] + (" - Sender: " + senderInfo["string"] if sender else "") + ": " + message) elif isinstance(update, types.UpdateChannel): #print("Channel list changed") self.chats = self.getChats() self.cleanUpMonitored() def extractChatInfo(self, chat): chatInfo = {} chatInfo["title"] = chat.title chatInfo["id"] = chat.id if hasattr(chat, "username"): chatInfo["username"] = ("@" if chat.username else "") + str( chat.username) else: chatInfo["username"] = "******" chatInfo[ "string"] = chatInfo["title"] + "(" + chatInfo["username"] + ")" return chatInfo def extractSenderInfo(self, sender): senderInfo = {} senderInfo["id"] = sender.id senderInfo["name"] = sender.first_name + (" " + str(sender.last_name) if sender.last_name else "") if hasattr(sender, "username"): senderInfo["username"] = ("@" if sender.username else "") + str( sender.username) else: senderInfo["username"] = "******" senderInfo[ "string"] = senderInfo["name"] + "(" + senderInfo["username"] + ")" return senderInfo def recordToDatabase(self, timestamp, type, chat, sender, message): time = datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S") chat = chat["id"] if sender: sender = sender["string"] else: sender = "" try: connection = self.pool.get_connection() c = connection.cursor() c.execute( "INSERT INTO " + self.messageTable + "(Time, Type, Chat, Sender, Message) VALUES (%s, %s, %s, %s, %s)", (time, type, chat, sender, message)) connection.commit() connection.close() except: self.logError("Error while writing update to the database") def sendNotification(self, type, chat, sender, message): URL = self.config["IFTTT"]["URL"] if URL != "": text = "New " + type + " message in " + chat["string"] + ( " from " + sender["string"] if sender else "") + "\n\n" + message #print(text) data = {"value1": text} try: response = requests.post(URL, data=data) print(response.text) except: self.logError("Error while sending notification to phone") def logError(self, message, fatal=False): print(message) error = str(sys.exc_info()[0]) + "\n\n" + str(sys.exc_info()[1]) print(error) with open("errors.log", 'a') as logfile: logfile.write("\n" + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " - " + error + "\n\n" + str(traceback.format_exc()) + "\n") logfile.write( "---------------------------------------------------------------" ) if (fatal): #sprint ("\n" + str(traceback.format_exc())) raise SystemExit
# pyrogram version => 0.11.0 # this is only useful to fill the session file import sys from pyrogram import ChatAction, Client print("BEGIN") bot_api_key = open("bot_api_key.txt", "r").read() print(bot_api_key) if bot_api_key is None or bot_api_key == "": print("MISSING TELEGRAM API KEY") sys.exit() bot_api_key = str(bot_api_key).strip() app = Client(session_name=bot_api_key, workers=1) app.start() app.idle()
def main(): client = Client("example") client.set_update_handler(update_handler) client.start() client.idle()