async def add_mapping(mapping: BotInstanceMapping, guildId: str): if mapping.bot_instance is not None: data.add_bot_instance(guildId, mapping.bot_instance) task = { 'kwargs': { 'bot_token': mapping.bot_instance }, 'function': 'start_new_bot_instance' } data.add_task(task) bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") return { "bot_instance": bot_instance[BOT_TOKEN_KEY], "bot_avatar": bot_instance[BOT_AVATAR_KEY], "bot_name": bot_instance[BOT_NAME_KEY], 'avatar_timout': bot_instance[AVATAR_TIMEOUT_KEY], 'name_timeout': bot_instance[NAME_TIMEOUT_KEY], 'activity_type': bot_instance[BOT_ACTIVITY_TYPE_KEY], 'activity_text': bot_instance[BOT_ACTIVITY_TEXT_KEY], 'bot_id': bot_instance[BOT_ID_KEY], "guildId": guildId }
async def add_mapping(mapping: BotInstanceMapping, guildId: str): if mapping.bot_instance is not None: data.add_bot_instance(guildId, mapping.bot_instance) running_bot_instances.append(mapping.bot_instance) asyncio.create_task(UpdateTask.start_bot_instance(mapping.bot_instance)) bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") # set default avatar await update_avatar(bot_instance) return { "bot_instance": bot_instance[BOT_TOKEN_KEY], "bot_avatar": bot_instance[BOT_AVATAR_KEY], "bot_name": bot_instance[BOT_NAME_KEY], 'avatar_timout': bot_instance[AVATAR_TIMEOUT_KEY], 'name_timeout': bot_instance[NAME_TIMEOUT_KEY], 'activity_type': bot_instance[BOT_ACTIVITY_TYPE_KEY], 'activity_text': bot_instance[BOT_ACTIVITY_TEXT_KEY], 'bot_id': bot_instance[BOT_ID_KEY], "guildId": guildId }
async def read_mapping(guildId: str): bot_instance = data.get_bot_instance(int(guildId)) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") bot_object = running_bots[bot_instance[BOT_ID_KEY]]['bot'] if bot_object: bot_avatar_url = str(bot_object.user.avatar_url) bot_name = str(bot_object.user.name) if bot_avatar_url != bot_instance[BOT_AVATAR_KEY]: data.set_bot_avatar(guildId, bot_avatar_url) bot_instance[BOT_AVATAR_KEY] = bot_avatar_url if bot_name != bot_instance[BOT_NAME_KEY]: data.set_bot_avatar(guildId, bot_name) bot_instance[BOT_NAME_KEY] = bot_name # bot isnt running, start it back up if bot_instance[BOT_TOKEN_KEY] not in running_bot_instances: running_bot_instances.append(bot_instance[BOT_TOKEN_KEY]) asyncio.create_task(UpdateTask.start_bot_instance(bot_instance[BOT_TOKEN_KEY])) return { "bot_instance": bot_instance[BOT_TOKEN_KEY], "bot_avatar": bot_instance[BOT_AVATAR_KEY], "bot_name": bot_instance[BOT_NAME_KEY], 'avatar_timout': bot_instance[AVATAR_TIMEOUT_KEY], 'name_timeout': bot_instance[NAME_TIMEOUT_KEY], 'activity_type': bot_instance[BOT_ACTIVITY_TYPE_KEY], 'activity_text': bot_instance[BOT_ACTIVITY_TEXT_KEY], 'bot_id': bot_instance[BOT_ID_KEY], "guildId": guildId }
async def add_mapping(mapping: BotAvatarMapping, guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") # avatar timout if bot_instance[AVATAR_TIMEOUT_KEY] and int( bot_instance[AVATAR_TIMEOUT_KEY]) <= time.time(): data.set_avatar_timout(bot_instance[GUILD_ID_KEY], 0) bot_instance[AVATAR_TIMEOUT_KEY] = 0 bot_object = update_cog.running_bots[bot_instance[BOT_ID_KEY]]['bot'] if mapping.bot_avatar is not None and not bot_instance[AVATAR_TIMEOUT_KEY]: # get image from base64 ext, image_data = re.findall('/(.*);base64,(.*)', mapping.bot_avatar)[0] new_avatar = base64.decodebytes(image_data.encode('utf-8')) error = await update_cog.update_avatar(bot_instance, new_avatar) if error: raise HTTPException(status_code=500, detail="Error changing bot avatar") return { "bot_avatar": str(bot_object.user.avatar_url), 'guildId': guildId, 'avatar_timeout': int(bool(bot_instance[AVATAR_TIMEOUT_KEY])) }
async def start_daily_stats_timers(guild_id: int, timezone, channel: str): """ Start daily_stats timer for provided guild and channel @param guild_id: id of guild @param timezone: number from -12 to +12, set by users to tell the bot when to send the message in relation to the utc timezone @param channel: name of channel where message will be sent """ # get bot instance, if it isn't set, assume the bot being used is the main one bot_instance = data.get_bot_instance(guild_id) bot_object = main.main_bot if not bot_instance else main.running_bots[ bot_instance[BOT_ID_KEY]]['bot'] try: # get guild to see if bot has permission to manage webhooks guild_object = bot_object.get_guild(guild_id) if not guild_object: guild_object = await bot_object.fetch_guild(guild_id) if not guild_object: return has_permission = guild_object.me.guild_permissions.is_superset( discord.Permissions(536870912)) if not has_permission: return except: # just in case no guild can be gotten return # set timezone to a default 0 if needed if not timezone: timezone = '0' try: # get time relative to user timezone dt = datetime.datetime.utcnow() + datetime.timedelta( hours=int(timezone)) except: return # get time until midnight time_midnight = time.time() + (((24 - dt.hour - 1) * 60 * 60) + ((60 - dt.minute - 1) * 60) + (60 - dt.second)) # start new timer for instance bot_object.timers.create( guild_id=guild_id, expires=time_midnight, event='daily_stats', extras={ 'channel_name': channel, 'timezone': timezone }, bot_id=bot_object.user.id, )
async def read_mapping(guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: return {} activity_text = bot_instance[BOT_ACTIVITY_TEXT_KEY] activity_type = bot_instance[BOT_ACTIVITY_TYPE_KEY] return {"activity_text": activity_text, "activity_type": activity_type}
async def delete_mapping(guildId: str): old_bot_instance = data.get_bot_instance(guildId) if guildId is not None: data.remove_bot_instance(guildId) bot_instance = data.get_bot_instance(guildId) if not bot_instance: try: running_bot_instances.remove(old_bot_instance[BOT_TOKEN_KEY]) to_be_removed = [b for b in running_bots if running_bots[b]['token'] == old_bot_instance[BOT_TOKEN_KEY]] if to_be_removed: await running_bots[to_be_removed[0]]['bot'].close() del running_bots[to_be_removed[0]] except: raise HTTPException(status_code=500, detail="Error stopping bot") return {"deleted": True} raise HTTPException(status_code=404, detail="Bot config not found")
async def read_mapping(guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: return {"bot_avatar": DEFAULT_BOT_AVATAR_URL, "guildId": guildId} avatar = bot_instance[BOT_AVATAR_KEY] return { "bot_avatar": avatar, "avatar_timeout": int(bool(bot_instance[AVATAR_TIMEOUT_KEY])), "guildId": guildId }
async def add_mapping(mapping: BotActivityMapping, guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") error = await update_activity(bot_instance, mapping.activity_type, mapping.activity_text) if error: raise HTTPException(status_code=500, detail="Error changing bot activity") return {"success": 1}
async def delete_mapping(guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") if guildId is not None: task = { 'kwargs': { 'guild_id': int(guildId) }, 'function': 'delete_bot_instance' } data.add_task(task)
async def read_mapping(guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: return {"guildId": guildId, "bot_name": "rallybot"} # set name in db to current bot name if name is empty if not bot_instance[BOT_NAME_KEY]: bot_object = update_cog.running_bots[bot_instance[BOT_ID_KEY]]['bot'] bot_instance[BOT_NAME_KEY] = bot_object.user.name data.set_bot_name(guildId, bot_object.user.name) return { "guildId": guildId, "bot_name": bot_instance[BOT_NAME_KEY], 'name_timeout': int(bool(bot_instance[NAME_TIMEOUT_KEY])) }
async def read_mapping(guildId: str): bot_instance = data.get_bot_instance(int(guildId)) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") return { "bot_instance": bot_instance[BOT_TOKEN_KEY], "bot_avatar": bot_instance[BOT_AVATAR_KEY], "bot_name": bot_instance[BOT_NAME_KEY], 'avatar_timout': bot_instance[AVATAR_TIMEOUT_KEY], 'name_timeout': bot_instance[NAME_TIMEOUT_KEY], 'activity_type': bot_instance[BOT_ACTIVITY_TYPE_KEY], 'activity_text': bot_instance[BOT_ACTIVITY_TEXT_KEY], 'bot_id': bot_instance[BOT_ID_KEY], "guildId": guildId }
async def delete_bot_instance(guild_id: int): """ Delete a bot instance and stop it @param guild_id: id of guild """ bot_instance = data.get_bot_instance(guild_id) try: data.remove_bot_instance(guild_id) main.running_bot_instances.remove(bot_instance[BOT_TOKEN_KEY]) to_be_removed = main.running_bots[bot_instance[BOT_ID_KEY]] if to_be_removed: await to_be_removed['bot'].close() del main.running_bots[bot_instance[BOT_ID_KEY]] except: pass
async def read_mapping(guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: return {"bot_avatar": DEFAULT_BOT_AVATAR_URL, "guildId": guildId} avatar = bot_instance[BOT_AVATAR_KEY] # set avatar in db to current bot avatar_url if name is empty if not avatar: bot_object = update_cog.running_bots[bot_instance[BOT_ID_KEY]]['bot'] avatar = bot_object.user.avatar_url data.set_bot_avatar(guildId, str(bot_object.user.avatar_url)) return { "bot_avatar": avatar, "avatar_timeout": int(bool(bot_instance[AVATAR_TIMEOUT_KEY])), "guildId": guildId }
async def add_mapping(mapping: BotActivityMapping, guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") task = { 'kwargs': { 'guild_id': int(guildId), 'bot_id': int(bot_instance[BOT_ID_KEY]), 'activity_type_str': mapping.activity_type, 'activity_text': mapping.activity_text }, 'function': 'update_activity' } data.add_task(task) return {"success": 1}
async def add_mapping(mapping: BotAvatarMapping, guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") # avatar timout if bot_instance[AVATAR_TIMEOUT_KEY] and int( bot_instance[AVATAR_TIMEOUT_KEY]) <= time.time(): data.set_avatar_timout(bot_instance[GUILD_ID_KEY], 0) bot_instance[AVATAR_TIMEOUT_KEY] = 0 if not bot_instance[AVATAR_TIMEOUT_KEY]: # read new avatar data and decode the base64 form ext, image_data = re.findall('/(.*);base64,(.*)', mapping.bot_avatar)[0] new_avatar = base64.decodebytes(image_data.encode('utf-8')) # get path to tmp folder where avatars will be stored temporarily tmp_folder = os.path.abspath('tmp/') if not os.path.exists(tmp_folder): os.mkdir(tmp_folder) # get path to new file and write bytes to it file_path = os.path.join(os.path.abspath('tmp/'), f'{guildId}_tmp_bot_avatar.{ext}') with open(file_path, 'wb+') as file: file.write(new_avatar) task = { 'kwargs': { 'guild_id': int(guildId), 'bot_id': int(bot_instance[BOT_ID_KEY]), 'new_avatar_path': file_path, }, 'function': 'update_avatar' } data.add_task(task) return { "bot_avatar": mapping.bot_avatar, 'guildId': guildId, 'avatar_timeout': int(bool(bot_instance[AVATAR_TIMEOUT_KEY])) }
async def get_webhook_url(guild_id: str, channel_name: str) -> Optional[str]: """ Gets or creates webhook url. @param guild_id: guild id of webhook @param channel_name: channel name of webhook @return: webhook url or None if error occurred """ # get bot object bot_instance = data.get_bot_instance(guild_id) bot_object = main.main_bot if not bot_instance else main.running_bots[bot_instance[BOT_ID_KEY]]['bot'] # wait until bot is ready, just in case await bot_object.wait_until_ready() # get guild object, fetch if needed, if bot cant access guild, return guild_object = bot_object.get_guild(int(guild_id)) if not guild_object: guild_object = await bot_object.fetch_guild(int(guild_id)) if not guild_object: return # get channel channel_object = discord.utils.get(guild_object.channels, name=channel_name) if not channel_object: return # get webhook webhook = data.get_webhook(guild_id, channel_object.id) if not webhook: # if webhook doesnt exist, create new one and add it to the webhooks database try: webhook_object = await channel_object.create_webhook(name='RallyBotAlerts', avatar=default_avatar) data.add_webhook(guild_id, channel_object.id, webhook_object.url, webhook_object.id, webhook_object.token) webhook_url = webhook_object.url except: return else: webhook_url = webhook[WEBHOOK_URI] return webhook_url
async def add_mapping(mapping: BotNameMapping, guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") # name timout if bot_instance[NAME_TIMEOUT_KEY] and int(bot_instance[NAME_TIMEOUT_KEY]) <= time.time(): data.set_name_timeout(bot_instance[GUILD_ID_KEY], 0) bot_instance[NAME_TIMEOUT_KEY] = 0 if mapping.bot_name and not bot_instance[NAME_TIMEOUT_KEY]: task = { 'kwargs': { 'guild_id': int(guildId), 'bot_id': int(bot_instance[BOT_ID_KEY]), 'new_name': mapping.bot_name, }, 'function': 'update_name' } data.add_task(task) return {"guildId": guildId, "bot_name": mapping.bot_name, 'name_timeout': int(bool(bot_instance[NAME_TIMEOUT_KEY]))}
async def add_mapping(mapping: BotNameMapping, guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: raise HTTPException(status_code=404, detail="Bot config not found") # name timout if bot_instance[NAME_TIMEOUT_KEY] and int( bot_instance[NAME_TIMEOUT_KEY]) <= time.time(): data.set_name_timeout(bot_instance[GUILD_ID_KEY], 0) bot_instance[NAME_TIMEOUT_KEY] = 0 bot_object = update_cog.running_bots[bot_instance[BOT_ID_KEY]]['bot'] if mapping.bot_name and not bot_instance[NAME_TIMEOUT_KEY]: data.set_bot_name(guildId, mapping.bot_name) # name change try: if mapping.bot_name != bot_object.user.name: await bot_object.user.edit(username=mapping.bot_name) data.set_bot_name(guildId, mapping.bot_name) except discord.HTTPException: # user is editing name too many times, set 1h timeout timout = round(time.time() + 3600) data.set_name_timeout(bot_instance[GUILD_ID_KEY], timout) bot_instance[NAME_TIMEOUT_KEY] = timout except: raise HTTPException(status_code=500, detail="Error changing bot name") return { "guildId": guildId, "bot_name": bot_object.user.name, 'name_timeout': int(bool(bot_instance[NAME_TIMEOUT_KEY])) }
async def read_mapping(guildId: str): bot_instance = data.get_bot_instance(guildId) if not bot_instance: return {"guildId": guildId, "bot_name": "rallybot"} return {"guildId": guildId, "bot_name": bot_instance[BOT_NAME_KEY], 'name_timeout': int(bool(bot_instance[NAME_TIMEOUT_KEY]))}