def readonly_callback(update: Update, context: CallbackContext): user = update.message.reply_to_message.from_user days, reason = update.message.text.strip("/ro ").split(" ", 1) if days.isnumeric(): days = int(days) else: days = 1 seconds = days * 24 * 60 * 60 logger.info("Setting readonly for %s for %s seconds", user.id, seconds) context.bot.restrict_chat_member( chat_id=update.message.chat_id, user_id=user.id, permissions=ChatPermissions( can_send_messages=False, can_send_media_messages=False, can_send_polls=False, can_send_other_messages=False, can_add_web_page_previews=False, ), until_date=int(time.time() + seconds), ) message = f"{user.name} в ридонли на {days} {plural_days(days)}." if reason: message += f" по причине: {reason}" update.message.reply_to_message.reply_text(text=message, parse_mode=ParseMode.MARKDOWN, quote=True) update.message.delete()
async def load_modules(): logger.info("Started loading modules...") for module in ALL_MODULES: modulename = module.split(".")[0] importlib.import_module(f"bot.modules.{modulename}") logger.debug("Module %s imported", module) logger.info("All modules loaded!")
def handle_connection(): """Handle bot connections. Gets notifications when the bot is added to a flow in an organization for the firs time. """ contents = request.get_json() if not isinstance(contents, dict): raise BadRequest('No input data provided') data = contents.get('data') if not data or not isinstance(data, dict): raise BadRequest('Invalid payload, missed "data"') should_disconnect = path(contents, 'meta.disconnected') or False org_uid = path(data, 'relationships.organization.data.id') if not org_uid: raise ValidationError('Organization id is missed') logger.info( 'Received %s webhook for organization %s' % (('disconnect' if should_disconnect else 'connect'), org_uid) ) if should_disconnect: disconnect(org_uid) message = 'Organization disconnected.' else: connect(Organization.from_id(org_uid)) message = 'Organization connected.' response = {'message': f'{message}'} return response, HTTPStatus.OK
def register_user(message): reply_message = 'Welcome ' + \ str(message.from_user.first_name) + ' to F1 predictions!' try: cursor.execute("SELECT * FROM users WHERE username=?", (message.from_user.username, )) user = cursor.fetchall() except mariadb.Error as e: logger.error( f'Error SELECTING FROM users WHERE username... MariaDB output: {e}' ) if not user: try: cursor.execute( "INSERT IGNORE INTO users (username,user_id,points) VALUES (?, ?, ?)", (message.from_user.username, message.from_user.id, 0)) conn.commit() except mariadb.Error as e: logger.error(f'Error INSERTING username... MariaDB output: {e}') bot.reply_to(message, reply_message) logger.info('User created in database') return True bot.reply_to(message, "Wait, are you registered? I think so...")
async def on_guild_remove(self, guild): conn = await self.bot.connpool.acquire() await conn.execute( f"""DELETE FROM server_info WHERE server_id={guild.id}""") await self.bot.connpool.release(conn) logger.info(f"Bot left guild: {guild.id}")
async def logout(self, ctx): """Logout of bot""" await self.bot.http_session.close() await ctx.send("`Bot logging out... closing connections.`") logger.info("Logged out - all connections closed.") await self.bot.logout()
def open_predictions(message): if (message.from_user.id == int(os.getenv('ADMIN_ID'))): info.are_predictions_closed = False logger.info("Predictions were opened.") bot.send_message(message.chat.id, "[!] PIT LANE OPEN!!") else: logger.info("Someone tried to use an admin command: " + message.fro_user.id) bot.send_message(message.chat.id, "Sorry, you are not my boss! >:(")
async def on_guild_join(self, guild): conn = await self.bot.connpool.acquire() await conn.execute( f"""INSERT INTO server_info(server_id, prefix) VALUES({guild.id}, 'b!')""" ) await self.bot.connpool.release(conn) logger.info(f"Bot joined guild: {guild.id}")
def getServerInfo(bot, update, chat_data): user = update.message.from_user logger.info("User %s Is asking for ServerIP." % user.name) if 'isAdmin' in chat_data: nmyIP = get('http://ipinfo.io/ip').text message = "IP: " + nmyIP else: message = "Hey Giovane, mi sa che mi stai chiedendo troppo...." bot.send_message(chat_id=update.message.chat_id, text=message)
def imAdmin(bot, update, chat_data): user = update.message.from_user logger.info("User %s Has been marked as ADMIN." % user.name) chat_data['isAdmin'] = True bot.send_message( chat_id=update.message.chat_id, text= "Questa chat è stata marchiata come isAdmin (almeno fino al riavvio del bot)" )
async def check_next_run(self): while True: time_diff = self.dlRunTime.next_run_at - datetime.datetime.now() if time_diff.total_seconds( ) < -50 and self.dlRunTime.active is False: logger.info( "APScheduler failed to schedule run, forcing run now") self.dlRunTime.run_now = True await asyncio.sleep(60)
async def get_shortlink(link): url = Config.SHORT_LINK_API_URL params = {'api': Config.SHORT_LINK_API_KEY, 'url': link} async with aiohttp.ClientSession() as session: logger.info("Calling Short Links API") async with session.get(url, params=params, raise_for_status=True) as response: data = await response.json() return data
def signal_handler(signal, frame): """Signal handler takes process signal and handles them. Arguments: signal {???} -- ??? frame {???} -- ??? """ logger = logging.getLogger('telegrambot') logger.info("CTRL+C pressed. Closing TahmatassuBot") sys.exit(0)
def resource_setup(): """Handle resource fields setting.""" contents = request.get_json() logger.info('Received resource payload: %s' % contents) fields = parse_request(create_request(contents)) response = Response(fields) logger.info('Return response %s' % response) return response
def close_predictions(message): if (message.from_user.id == int(os.getenv('ADMIN_ID'))): info.are_predictions_closed = True logger.info("Predictions were closed") bot.send_message(message.chat.id, "[!] PIT LANE CLOSED!! Current predictions: ") get_predictions(message) else: logger.info("Someone tried to use an admin command: " + message.fro_user.id) bot.send_message(message.chat.id, "Sorry, you are not my boss! >:(")
async def get_shortlink(link): url = Config.SHORT_LINK_API_URL params = {'api': Config.SHORT_LINK_API_KEY, 'url': link} async with aiohttp.ClientSession() as session: logger.info( "Consiguiendo la API para generar enlaces cortos... Por favor, espere." ) async with session.get(url, params=params, raise_for_status=True) as response: data = await response.json() return data
def stop(self, stop): if not isinstance(stop, bool): self.runtime_error_options("stop", bool, type(stop)) return if self._stop == stop: return self._stop = stop frame = inspect.currentframe() logger.info("Value {} modified".format( inspect.getframeinfo(frame).function)) self.timeout_dump() self.handle_option_change('stop')
def last_run_at(self, value): if not isinstance(value, datetime.datetime): self.runtime_error_options("last_run_at", datetime.datetime, type(value)) return if self._last_run_at == value: return self._last_run_at = value frame = inspect.currentframe() logger.info("Value {} modified to {}".format( inspect.getframeinfo(frame).function, value)) self.timeout_dump()
def battle_calls(self, value): if not isinstance(value, dict): self.runtime_error_options("battle_calls", dict, type(value)) return if self._battle_calls == value: return self._battle_calls = value frame = inspect.currentframe() logger.info("Value {} modified".format( inspect.getframeinfo(frame).function)) self.timeout_dump() self.handle_option_change('battle_calls')
async def execute(self, ctx, *, query): conn = await self.bot.connpool.acquire() try: await conn.execute(f"""{query}""") await ctx.message.add_reaction('\U00002705') logger.info(f"Successfully executed query: '{query}' on PG DB") except Exception as e: await ctx.message.add_reaction('\U0000274c') logger.error( f"Failed execute of query: '{query}' on PG DB - Error: {e}") finally: await self.bot.connpool.release(conn)
def disconnect(org_id: str): rows = db.session.query(Organization).filter_by( organization_uid=org_id).delete() db.session.commit() status = bool(rows) if not status: raise exceptions.OrganizationDisconnect( status_code=404, message='Not Found', payload={'detail': 'Requested organization does not exist.'}) logger.info('Organization %s successfully disconnected' % org_id)
def run_now(self, value): if not isinstance(value, bool): self.runtime_error_options("run_now", bool, type(value)) return if self._run_now == value: return self._run_now = value # IMPLEMENTATION: Notify Scheduler to Run Now frame = inspect.currentframe() logger.info("Value {} modified".format( inspect.getframeinfo(frame).function)) self.timeout_dump() self.handle_option_change('run_now')
async def reload(self, ctx, cog: str): """Reload a cog""" try: self.bot.unload_extension(cog) except Exception as e: logger.error( f"Attempted to unload cog: {cog} which was never loaded on start up. Bypassing and attempting " f"to complete function.") self.bot.load_extension(cog) logger.info(f"Successfully reloaded extension: {cog}") await ctx.send(f"`{cog}` successfully reloaded.")
def next_run_at(self, value): if not isinstance(value, datetime.datetime): self.runtime_error_options("next_run_at", datetime.datetime, type(value)) return if self._next_run_at == value: return self._next_run_at = value # IMPLEMENTATION: Notify Scheduler of next run frame = inspect.currentframe() logger.info("Value {} modified to {}".format( inspect.getframeinfo(frame).function, value)) self.timeout_dump() self.handle_option_change('next_run_at')
def send_help_message(message): help_message = "ALL COMMANDS: \n" +\ "/register - to be registered in the game.\n" +\ "/list - See current standings username-points.\n" +\ "/predict MAZ MIC NOR - to make a prediction or modify one, of the current race.\n" +\ "/predictions - see all predictions of current race.\n" +\ "\nADMIN COMMANDS: \n" +\ "/close - close predictions.\n" +\ "/open - open predictions.\n" +\ "/result HAM VER BOT - result of last race\n" +\ "/setpoints user 5 - set points to an user\n" bot.send_message(message.chat.id, help_message) logger.info("Sending help message") return True
def event_handle(): """Gets all trigger related events.""" contents = request.get_json() logger.info('Received webhook. Event data: %s' % contents) if not isinstance(contents, dict): raise BadRequest('No input data provided') # TODO: # 1. Create processor # 2. Pass contents to processor # 3. Process the data # 4. Return value to views # 5. Create response return {}
def connect(organization: Organization) -> Organization: try: client_id = current_app.config.get('BOT_CLIENT_ID') client_secret = current_app.config.get('BOT_CLIENT_SECRET') identity = authenticate(organization.organization_uid, client_id, client_secret) organization.token = identity.token organization.domain = identity.domain organization.token_expires_at = identity.expires db.session.add(organization) db.session.flush() except ApiError as api_error: logger.error('Received error response from API: %s' % api_error.message) # Any 4xx errors at this stage means our error if 400 <= api_error.status < 500: message = ('Unable to connect organization due to internal ' ' error. Please contact bot developer.') raise exceptions.InternalServerError( payload={'detail': message}) from api_error else: raise exceptions.BadRequest(message='API Error', payload={'detail': api_error.message }) from api_error except exc.IntegrityError as integrity_error: logger.error(integrity_error) db.session.rollback() raise exceptions.OrganizationConnect( message='Already connected', payload={'detail': 'Requested organization already connected.'}) except (exc.SQLAlchemyError, RequestException) as internal_error: logger.error(internal_error) db.session.rollback() raise exceptions.InternalServerError( payload={'detail': 'Unable to connect organization.'}) else: db.session.commit() logger.info('Organization %s successfully connected' % organization.organization_uid) return organization
async def admin(self, ctx, user: discord.Member): """ Promotes a user to admin permissions in the current guild. (Only bot owners can promote users to admins) """ try: uid = user.id sid = ctx.guild.id core.promote(uid, sid) core.updateadmin(sid) logger.info( f'{ctx.author.name} promoted {user.name}{user.discriminator} to admin in {sid}.' ) return await ctx.send( f'{user.name}#{user.discriminator} has been promoted to an admin in this guild.' ) except sqlite3.IntegrityError: return await ctx.send( f'{user.name}#{user.discriminator} is already an admin in this guild.' )
async def send_photo(bot: Bot, repo: Repo, user_id: int, photo, caption: str, disable_notification: bool = False): """ Безопасная рассылка :param repo: :param bot: :param caption: :param photo: :param user_id: :param disable_notification: :return: """ try: await bot.send_photo(chat_id=user_id, photo=photo, caption=caption, disable_notification=disable_notification) except exceptions.BotBlocked: logger.error( f"Пользователь [ID:{user_id}]: Бот заблокирован пользователем") await repo.delete_customer(user_id) except exceptions.ChatNotFound: logger.error(f"Пользователь [ID:{user_id}]: Неверный ID пользователя") except exceptions.RetryAfter as e: logger.error( f"Пользователь [ID:{user_id}]: Достигнут лимит рассылки. Засыпаю на {e.timeout} секунд." ) await asyncio.sleep(e.timeout) return await send_photo(user_id=user_id, photo=photo, caption=caption) # Recursive call except exceptions.UserDeactivated: logger.error( f"Пользователь [ID:{user_id}]: Аккаунт деактивирован/удалён") except exceptions.TelegramAPIError: logger.exception(f"Пользователь [ID:{user_id}]: Провалено") except exceptions.BotKicked: logger.exception( f"Бот был удален из группы. Удаляю [ID:{user_id}] из базы") await repo.delete_customer(user_id) else: logger.info(f"Пользователь [ID:{user_id}]: Успешно")
def create_configuration_file(logger, args): """Generate initial configuration file Arguments: logger {Logger} -- logging object args {dict} -- Command line arguments """ if not args.force and os.path.exists(args.generate): return logger.info("File exist allready, use -f flag to overwrite the existing file") config = ConfigParser() config.set('DEFAULT', 'token', 'Telegram Bot API token here') config.set('DEFAULT', 'tahmatassuapi', 'http://puumuki.game-server.cc') config.set('DEFAULT', 'botname', 'Tahmatassubot') with open(args.generate, 'w') as filehandle: config.write(filehandle) logger.info("Writed configuration to file named: " + args.generate)