Example #1
0
def rem_plant_cmd(bot, update, job_queue, args=None):
    chat_id, chat_type, user_id, text, message = support.extract_update_info(
        update)
    support.delete_message(chat_id, message.message_id, bot)

    if are_banned(chat_id,
                  user_id) or not support.is_admin(chat_id, user_id, bot):
        return

    user = get_real_user(user_id)
    if user is None:
        bot.sendMessage(chat_id=chat_id,
                        text="❌ Debes registrarte para usar este comando.",
                        parse_mode=telegram.ParseMode.MARKDOWN)
        return

    if args is not None and len(args) != 0:
        if re.match(r"^[0-9]{0,10}$", args[0]):
            try:
                alert15PlantJob = job_queue.get_jobs_by_name(
                    "{}_plantJob15".format(args[0]))
                alert15PlantJob[0].schedule_removal()
            except:
                pass
            try:
                alertPlantJob = job_queue.get_jobs_by_name(
                    "{}_plantJob".format(args[0]))
                alertPlantJob[0].schedule_removal()
            except:
                pass
            try:
                deletePlantJob = job_queue.get_jobs_by_name(
                    "{}_plantJobDelete".format(args[0]))
                deletePlantJob[0].schedule_removal()
            except:
                pass

            support.save_jobs(job_queue)

            if delete_plant(plant_id=args[0], group_id=chat_id):
                text = "Plantación eliminada correctamente."
            else:
                text = "❌ No se pudo eliminar la plantación."
            bot.sendMessage(chat_id=chat_id,
                            text=text,
                            parse_mode=telegram.ParseMode.MARKDOWN)
        elif args[0] == "all":
            plants = delete_plant(group_id=chat_id, group=True)
            for plant in plants:
                try:
                    alert15PlantJob = job_queue.get_jobs_by_name(
                        "{}_plantJob15".format(plant.id))
                    alert15PlantJob[0].schedule_removal()
                except:
                    continue
                try:
                    alertPlantJob = job_queue.get_jobs_by_name(
                        "{}_plantJob".format(plant.id))
                    alertPlantJob[0].schedule_removal()
                except:
                    continue
                try:
                    deletePlantJob = job_queue.get_jobs_by_name(
                        "{}_plantJobDelete".format(plant.id))
                    deletePlantJob[0].schedule_removal()
                except:
                    continue

            support.save_jobs(job_queue)
            bot.sendMessage(
                chat_id=chat_id,
                text="Todas las plantaciones eliminadas correctamente.",
                parse_mode=telegram.ParseMode.MARKDOWN)
Example #2
0
def gh_btn(bot, update, job_queue):
    query = update.callback_query
    data = query.data
    user = update.effective_user
    user_id = query.from_user.id
    text = query.message.text
    chat_id = query.message.chat.id
    message_id = query.message.message_id
    name = query.message.venue.title
    lat = query.message.location.latitude
    lon = query.message.location.longitude
    coords = str(lat) + ", " + str(lon)

    if are_banned(user_id, chat_id):
        return

    queryData = data.split("_")
    userBtn = queryData[4]

    if userBtn == str(user_id) or support.is_admin(chat_id, user_id, bot):
        if queryData[1] == "addplant":
            bot.delete_message(chat_id=chat_id, message_id=message_id)

            poi_list = get_poi_list(chat_id, PortalType.GREENHOUSE.value)
            poi_sorted = sort_list(poi_list, coords)

            button_list = []
            if len(poi_sorted) >= 1:
                button_list.append([
                    InlineKeyboardButton(
                        poi_sorted[0].name,
                        callback_data='gh_addubi_{0}_{1}_{2}_{3}'.format(
                            poi_sorted[0].id, queryData[2], user_id,
                            queryData[3]))
                ])
            if len(poi_sorted) >= 2:
                button_list.append([
                    InlineKeyboardButton(
                        poi_sorted[1].name,
                        callback_data='gh_addubi_{0}_{1}_{2}_{3}'.format(
                            poi_sorted[1].id, queryData[2], user_id,
                            queryData[3]))
                ])
            if len(poi_sorted) >= 3:
                button_list.append([
                    InlineKeyboardButton(
                        poi_sorted[2].name,
                        callback_data='gh_addubi_{0}_{1}_{2}_{3}'.format(
                            poi_sorted[2].id, queryData[2], user_id,
                            queryData[3]))
                ])
            if len(poi_sorted) >= 4:
                button_list.append([
                    InlineKeyboardButton(
                        poi_sorted[3].name,
                        callback_data='gh_addubi_{0}_{1}_{2}_{3}'.format(
                            poi_sorted[3].id, queryData[2], user_id,
                            queryData[3]))
                ])
            if len(poi_sorted) >= 5:
                button_list.append([
                    InlineKeyboardButton(
                        poi_sorted[4].name,
                        callback_data='gh_addubi_{0}_{1}_{2}_{3}'.format(
                            poi_sorted[4].id, queryData[2], user_id,
                            queryData[3]))
                ])
            button_list.append([
                InlineKeyboardButton(
                    "❌ Cancelar",
                    callback_data='gh_cancel_._._{}'.format(user_id))
            ])

            plant = support.replace_plants(int(queryData[2]))

            bot.send_venue(chat_id=chat_id,
                           title=plant + " " + queryData[3],
                           address="¿En qué invernadero está plantado?",
                           latitude=lat,
                           longitude=lon,
                           reply_markup=InlineKeyboardMarkup(button_list))
            return
        elif queryData[1] == "addubi":
            userTime = datetime.strptime(queryData[5], '%H:%M')

            group = get_group(chat_id)
            group_tz = group.timezone
            tz = pytz.timezone(group_tz)

            userDatetime = datetime.now().replace(hour=userTime.hour,
                                                  minute=userTime.minute,
                                                  second=0)
            userAsLocal = tz.localize(userDatetime)
            userAsLocal = userAsLocal.astimezone(pytz.utc)
            '''
            if datetime.now(pytz.utc) > userAsLocal:
                userAsLocal = userAsLocal + timedelta(days=1)
            '''

            userAsLocal15 = userAsLocal - timedelta(minutes=15)
            userAsLocalDeletePlant = userAsLocal + timedelta(minutes=30)
            userAsLocal15 = userAsLocal15.time()
            userAsLocalTime = userAsLocal.time()
            userAsLocalDPTime = userAsLocalDeletePlant.time()

            plant = support.replace_plants(int(queryData[3]))

            setPlant = set_plant(queryData[2], queryData[3], chat_id,
                                 userDatetime, userAsLocalDeletePlant)
            thePlant = get_plant(setPlant)

            poi = get_poi(queryData[2])
            ap_object = support.AlertPlantContext(
                chat_id,
                "¡Magos de *{0}*, en 15 minutos se podrá recoger *{1}* en [{2}](https://maps.google.com/maps?q={3},{4})!"
                .format(query.message.chat.title, plant, poi.name,
                        poi.latitude, poi.longitude), False, thePlant.id)
            job_queue.run_once(support.callback_AlertPlant,
                               userAsLocal15,
                               context=ap_object,
                               name="{}_plantJob15".format(thePlant.id))

            ap_object = support.AlertPlantContext(
                chat_id,
                "¡Magos de *{0}*, ya se puede recoger *{1}* en [{2}](https://maps.google.com/maps?q={3},{4})!"
                .format(query.message.chat.title, plant, poi.name,
                        poi.latitude, poi.longitude), True, thePlant.id)
            job_queue.run_once(support.callback_AlertPlant,
                               userAsLocalTime,
                               context=ap_object,
                               name="{}_plantJob".format(thePlant.id))
            dp_object = support.DeletePlantContext(thePlant.id)
            job_queue.run_once(support.callback_DeletePlant,
                               userAsLocalDPTime,
                               context=dp_object,
                               name="{}_plantJobDelete".format(thePlant.id))

            bot.delete_message(chat_id=chat_id, message_id=message_id)
            success_message = bot.sendMessage(
                chat_id=chat_id,
                text="🌱 Plantación añadida correctamente.",
                parse_mode=telegram.ParseMode.MARKDOWN)
            delete_object = support.DeleteContext(chat_id,
                                                  success_message.message_id)
            job_queue.run_once(support.callback_delete,
                               10,
                               context=delete_object)
            support.save_jobs(job_queue)
            return
        elif queryData[1] == "cancel":
            bot.delete_message(chat_id=chat_id, message_id=message_id)
            return
    else:
        bot.answer_callback_query(
            callback_query_id=query.id,
            text=
            "Sólo un administrador o el usuario que ha creado el aviso puede pulsar ese botón.",
            show_alert=True)
Example #3
0
def save_jobs_job(job, context):
    support.save_jobs(context.job_queue)
Example #4
0
def start_bot():
    signal.signal(signal.SIGINT, support.cleanup)
    parser = argparse.ArgumentParser()

    parser.add_argument(
        '-c',
        '--cfg',
        default=config_file.get_default_config_path(),
        type=str,
        help='path to the Dumbledore bot config file (Default: %(default)s')

    parser.add_argument('--create-config',
                        default=False,
                        action='store_true',
                        help='')

    args = parser.parse_args()

    if args.create_config:
        config_file.create_default_config(args.cfg)
        sys.exit(0)

    config = config_file.get_config(args.cfg)
    support.create_needed_paths()
    model.create_databases()

    log = (os.path.expanduser(config['general'].get('log'))
           or os.path.join(os.getcwd(), 'debug.log'))

    log_handler = TimedRotatingFileHandler(log,
                                           when='d',
                                           interval=1,
                                           backupCount=5)

    logging.basicConfig(
        format=
        "%(asctime)s %(name)s %(module)s:%(funcName)s:%(lineno)s - %(message)s",
        handlers=[log_handler],
        level=logging.DEBUG)

    logging.info("--------------------- Starting bot! -----------------------")

    updater = Updater(token=config["telegram"]["token"],
                      workers=24,
                      request_kwargs={
                          'read_timeout': 15,
                          'connect_timeout': 15
                      })

    dispatcher = updater.dispatcher

    dispatcher.add_error_handler(support.error_callback)

    dispatcher.add_handler(
        CommandHandler('games',
                       games.game_spawn_cmd,
                       Filters.group,
                       pass_args=True))
    #dispatcher.add_handler(CommandHandler('duel', games.duel_cmd, Filters.group))
    dispatcher.add_handler(CallbackQueryHandler(games.btn, pattern=r"^g\*"))

    #Juego Cumple Nelu
    #dispatcher.add_handler(CommandHandler('nelu', nelu.nelu_cmd, Filters.user(int(config["telegram"]["saray"])), pass_job_queue=True))
    #dispatcher.add_handler(CallbackQueryHandler(nelu.nelu_btn, pattern=r"^nelu_"))

    dispatcher.add_handler(
        CommandHandler(['fort', 'fortaleza'],
                       fortress.fort_list_cmd,
                       Filters.group,
                       pass_args=True))
    #dispatcher.add_handler(CommandHandler(['fort_refloat', 'fortrefloat'], fortress.fort_refloat_cmd, Filters.group))
    #dispatcher.add_handler(CommandHandler(['fort_delete', 'fortremove', 'rm_fort'], fortress.fort_remove_cmd, Filters.group))
    dispatcher.add_handler(
        CallbackQueryHandler(fortress.fort_btn,
                             pattern=r"^fort_",
                             pass_job_queue=True))

    #TBRdispatcher.add_handler(CommandHandler('avistamiento', sighting.sighting_cmd, Filters.group))
    dispatcher.add_handler(
        CallbackQueryHandler(sighting.sighting_btn, pattern=r"^sighting_"))

    dispatcher.add_handler(
        CommandHandler(['add_plant', 'addplant'],
                       greenhouses.add_ingredients_cmd,
                       Filters.group,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler(['rm_plant', 'rmplant'],
                       greenhouses.rem_plant_cmd,
                       Filters.group,
                       pass_args=True,
                       pass_job_queue=True))
    dispatcher.add_handler(
        CommandHandler(['plantaciones', 'plant_list'],
                       greenhouses.plants_list_cmd, Filters.group))
    dispatcher.add_handler(
        CallbackQueryHandler(greenhouses.gh_btn,
                             pattern=r"^gh_",
                             pass_job_queue=True))

    dispatcher.add_handler(
        CommandHandler(['add_poi', 'addpoi'],
                       profdumbledorebot.add_poi_cmd,
                       Filters.group,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler(['rm_poi', 'rmpoi'],
                       profdumbledorebot.rem_poi_cmd,
                       Filters.group,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler(['poi_list', 'poilist'], profdumbledorebot.poi_list_cmd,
                       Filters.group))
    dispatcher.add_handler(
        CallbackQueryHandler(profdumbledorebot.poi_btn, pattern=r"^poi_"))

    dispatcher.add_handler(
        CommandHandler(
            ['midepollas', 'flipaos'], profdumbledorebot.ranking_spain_cmd,
            Filters.chat(int(config["telegram"]["spain_id"]))
            & Filters.user(int(config["telegram"]["ranking_admin_id"]))))
    #TBRdispatcher.add_handler(CommandHandler('puntos', profdumbledorebot.points_cmd, Filters.private))
    dispatcher.add_handler(
        CommandHandler('ranking', profdumbledorebot.private_ranking_cmd,
                       Filters.group))

    dispatcher.add_handler(CommandHandler('ping', profdumbledorebot.ping_cmd))
    dispatcher.add_handler(
        CommandHandler(['fclist', 'fc'], profdumbledorebot.fclist_cmd,
                       Filters.group))
    dispatcher.add_handler(
        CommandHandler(['help', 'start'],
                       profdumbledorebot.start_cmd,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler(['whois', 'informe', 'info'],
                       profdumbledorebot.whois_cmd,
                       pass_args=True))

    dispatcher.add_handler(
        CallbackQueryHandler(profdumbledorebot.register_btn, pattern=r"^reg_"))
    dispatcher.add_handler(
        CallbackQueryHandler(profdumbledorebot.passport_btn,
                             pattern=r"^profile_"))
    dispatcher.add_handler(
        CommandHandler(['passport', 'pasaporte', 'profile', 'perfil'],
                       profdumbledorebot.passport_cmd, Filters.private))
    dispatcher.add_handler(
        CommandHandler('set_friendid',
                       profdumbledorebot.set_friendid_cmd,
                       Filters.private,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler(['register', 'registro', 'cucuruchodecucarachas'],
                       profdumbledorebot.register_cmd, Filters.private))
    '''
    dispatcher.add_handler(CommandHandler('rm_cmd', rm_cmd_cmd, Filters.group))
    dispatcher.add_handler(CommandHandler('new_cmd', new_cmd_cmd, Filters.group))
    dispatcher.add_handler(CommandHandler('list_cmds', list_cmds_cmd, Filters.group))
    '''
    dispatcher.add_handler(
        CommandHandler('rm_admin', admin.rm_admin_cmd, Filters.group))
    dispatcher.add_handler(
        CommandHandler('create_admin', admin.create_admin_cmd, Filters.group))
    dispatcher.add_handler(
        CommandHandler('settings_admin', admin.settings_admin_cmd,
                       Filters.group))

    dispatcher.add_handler(
        CommandHandler('rm_link', admin.rm_link_cmd, Filters.group))
    dispatcher.add_handler(
        CommandHandler('add_tag',
                       admin.add_tag_cmd,
                       Filters.group,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler('add_url',
                       admin.add_url_cmd,
                       Filters.group,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler('create_link',
                       admin.create_link_cmd,
                       Filters.group,
                       pass_args=True))

    dispatcher.add_handler(
        CommandHandler(['groups', 'grupos'], admin.groups_cmd, Filters.group))

    dispatcher.add_handler(
        CommandHandler('ban', admin.ban_cmd, Filters.group, pass_args=True))
    dispatcher.add_handler(
        CommandHandler('kick', admin.kick_cmd, Filters.group, pass_args=True))
    dispatcher.add_handler(
        CommandHandler('warn', admin.warn_cmd, Filters.group, pass_args=True))
    dispatcher.add_handler(
        CommandHandler('unban', admin.unban_cmd, Filters.group,
                       pass_args=True))
    #dispatcher.add_handler(CommandHandler('mute', admin.mute_cmd, Filters.group, pass_args=True))
    #dispatcher.add_handler(CommandHandler('unwarn', unwarn_cmd, Filters.group, pass_args=True))

    #TBRdispatcher.add_handler(CommandHandler('dumbleuv', admin.uv_cmd, Filters.group, pass_args=True))
    #TBRdispatcher.add_handler(CommandHandler('dumblekickuv', admin.kickuv_cmd, Filters.group, pass_args=True))
    #TBRdispatcher.add_handler(CommandHandler('dumblekickmsg', admin.kickmsg_cmd, Filters.group, pass_args=True))
    #TBRdispatcher.add_handler(CommandHandler('dumblekickold', admin.kickold_cmd, Filters.group, pass_args=True))

    dispatcher.add_handler(CommandHandler('rules', rules.rules, Filters.group))
    dispatcher.add_handler(
        CommandHandler('set_rules', rules.set_rules, Filters.group))
    dispatcher.add_handler(
        CommandHandler('clear_rules', rules.clear_rules, Filters.group))

    dispatcher.add_handler(
        CommandHandler('list', lists.list_cmd, Filters.group))
    dispatcher.add_handler(
        CallbackQueryHandler(lists.list_btn, pattern=r"^list_"))
    dispatcher.add_handler(
        CommandHandler('listopen', lists.listopen_cmd, Filters.group))
    dispatcher.add_handler(
        CommandHandler('listclose', lists.listclose_cmd, Filters.group))
    dispatcher.add_handler(
        CommandHandler('listrefloat', lists.listrefloat_cmd, Filters.group))

    dispatcher.add_handler(
        CommandHandler('settings', settings.settings, Filters.group))
    dispatcher.add_handler(
        CommandHandler('set_pince', nanny.set_nanny, Filters.group))
    dispatcher.add_handler(
        CommandHandler('set_welcome', settings.set_welcome, Filters.group))
    #TBRdispatcher.add_handler(CommandHandler('test_welcome', welcome.test_welcome, Filters.group))
    dispatcher.add_handler(
        CommandHandler('set_zone',
                       settings.set_zone,
                       Filters.group,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler('set_cooldown',
                       settings.set_cooldown,
                       Filters.group,
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler('set_maxmembers',
                       settings.set_maxmembers,
                       Filters.group,
                       pass_args=True))

    dispatcher.add_handler(InlineQueryHandler(tablas.inline_tablas))
    dispatcher.add_handler(
        CallbackQueryHandler(tablas.tablas_btn, pattern=r"^tabla_"))
    dispatcher.add_handler(
        CommandHandler('tablas',
                       tablas.list_pics,
                       Filters.chat(int(config["telegram"]["staff_id"])),
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler('nueva_tabla',
                       tablas.new_pic,
                       Filters.chat(int(config["telegram"]["staff_id"])),
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler('borrar_tabla',
                       tablas.rm_pic,
                       Filters.chat(int(config["telegram"]["staff_id"])),
                       pass_args=True))
    dispatcher.add_handler(
        CommandHandler('editar_tabla',
                       tablas.edit_pic,
                       Filters.chat(int(config["telegram"]["staff_id"])),
                       pass_args=True))

    dispatcher.add_handler(
        CommandHandler('list_news', news.list_news, Filters.group))
    dispatcher.add_handler(
        CommandHandler('rm_news', news.rm_news, Filters.group, pass_args=True))
    dispatcher.add_handler(
        CommandHandler('add_news',
                       news.add_news,
                       Filters.group,
                       pass_args=True))

    dispatcher.add_handler(
        CommandHandler('add_staff', staff.add_staff_cmd, pass_args=True))
    dispatcher.add_handler(
        CommandHandler('rm_staff', staff.rm_staff_cmd, pass_args=True))

    dispatcher.add_handler(
        MessageHandler(Filters.group & Filters.status_update.new_chat_members,
                       group.joined_chat,
                       pass_job_queue=True))

    dispatcher.add_handler(
        MessageHandler(Filters.command, nanny.process_cmd,
                       pass_job_queue=True))
    dispatcher.add_handler(
        MessageHandler(Filters.group & Filters.all,
                       group.process_group_message,
                       pass_job_queue=True))

    dispatcher.add_handler(MessageHandler(Filters.all, news.send_news))
    dispatcher.add_handler(CallbackQueryHandler(settings.settingsbutton))

    job_queue = updater.job_queue
    job_queue.run_repeating(save_jobs_job, timedelta(minutes=5))
    try:
        support.load_jobs(job_queue)

    except FileNotFoundError:
        # First run
        pass

    updater.start_polling(timeout=25)

    support.save_jobs(job_queue)

    sys.exit(0)
Example #5
0
def fort_btn(bot, update, job_queue):
    query = update.callback_query
    data = query.data
    user = update.effective_user
    username = query.from_user.username
    user_id = query.from_user.id
    text = query.message.text
    chat_id = query.message.chat.id
    message_id = query.message.message_id
    message = query.message
    markdown_text = query.message.text_markdown_urled

    if are_banned(user_id, chat_id):
        return

    user = get_user(user_id)
    if user is None:
        bot.answer_callback_query(
            query.id,
            "❌ Debes registrarte para usar esta función.",
            show_alert=True)
        return

    queryData = data.split("_")

    if len(queryData) == 5:
        if queryData[3] == str(user_id) or support.is_admin(
                chat_id, user_id, bot):
            if queryData[1] == "addubi":
                group = get_group(chat_id)
                group_tz = group.timezone
                tz = pytz.timezone(group_tz)

                try:
                    userTime = datetime.strptime(queryData[4], '%d/%H:%M')
                    userDatetime = datetime.now().replace(
                        day=userTime.day,
                        hour=userTime.hour,
                        minute=userTime.minute,
                        second=0)
                    dateText = f"el *{userDatetime.day}/{userDatetime.month}* a las *{userDatetime.hour:02}:{userDatetime.minute:02}*"
                except:
                    userTime = datetime.strptime(queryData[4], '%H:%M')
                    userDatetime = datetime.now().replace(
                        hour=userTime.hour, minute=userTime.minute, second=0)
                    dateText = f"a las *{userDatetime.hour:02}:{userDatetime.minute:02}*"

                userAsLocal = tz.localize(userDatetime)
                userAsLocal = userAsLocal.astimezone(pytz.utc)

                if datetime.now(pytz.utc) > userAsLocal:
                    userAsLocal = userAsLocal + timedelta(days=1)
                    userDatetime = userDatetime + timedelta(days=1)
                    dateText = f"el *{userDatetime.day}/{userDatetime.month}* a las *{userDatetime.hour:02}:{userDatetime.minute:02}*"

                userAsLocal30 = userAsLocal - timedelta(minutes=30)
                #userAsLocal30 = userAsLocal30.time()
                #userAsLocalTime = userAsLocal.time()

                userAsLocal = userAsLocal.replace(tzinfo=None)

                poi = get_poi(queryData[2])
                lat = poi.latitude
                lon = poi.longitude

                button_list = [[
                    (InlineKeyboardButton("🙋‍♀️ Voy",
                                          callback_data=f'fort_yes_{poi.id}')),
                    (InlineKeyboardButton(
                        "🕒 Tardo", callback_data=f'fort_late_{poi.id}')),
                    (InlineKeyboardButton("❌ No voy",
                                          callback_data=f'fort_no_{poi.id}'))
                ],
                               [(InlineKeyboardButton(
                                   "✅ Estoy",
                                   callback_data=f'fort_here_{poi.id}')),
                                (InlineKeyboardButton(
                                    "📍 Ubicación",
                                    callback_data=f'fort_ubi_{poi.id}')),
                                (InlineKeyboardButton(
                                    "⚠️ Aviso",
                                    callback_data=f'fort_alert_{poi.id}'))]]

                text = "Fortaleza en [{0}](https://maps.google.com/maps?q={1},{2}) {3}\n\nLista:".format(
                    poi.name, lat, lon, dateText)

                fort_msg = bot.sendMessage(
                    chat_id=chat_id,
                    text=text,
                    parse_mode=telegram.ParseMode.MARKDOWN,
                    disable_web_page_preview=True,
                    reply_markup=InlineKeyboardMarkup(button_list))

                chat_url = support.message_url(message, fort_msg.message_id,
                                               "desafío")

                f_object = support.AlertFortressContext(
                    chat_id,
                    f"¡Mago de *{message.chat.title}*, en 30 minutos tendrá lugar un {chat_url} que pondrá a prueba tus habilidades como mago en [{poi.name}](https://maps.google.com/maps?q={lat},{lon})!",
                    fort_msg.message_id, poi.id)
                job_queue.run_once(support.callback_AlertFortress,
                                   userAsLocal,
                                   context=f_object)

                support.save_jobs(job_queue)

                bot.delete_message(chat_id=chat_id, message_id=message_id)
                return

        else:
            bot.answer_callback_query(
                callback_query_id=query.id,
                text=
                "Sólo un administrador o el usuario que ha creado el aviso puede pulsar ese botón.",
                show_alert=True)
            return
    if queryData[1] == "cancel":
        if queryData[2] == str(user_id) or support.is_admin(
                chat_id, user_id, bot):
            bot.delete_message(chat_id=chat_id, message_id=message_id)
            return
        else:
            bot.answer_callback_query(
                callback_query_id=query.id,
                text=
                "Sólo un administrador o el usuario que ha creado el aviso puede pulsar ese botón.",
                show_alert=True)
            return

    poi_id = queryData[2]
    poi = get_poi(poi_id)
    lat = poi.latitude
    lon = poi.longitude

    button_list = [
        [(InlineKeyboardButton("🙋‍♀️ Voy",
                               callback_data=f'fort_yes_{poi.id}')),
         (InlineKeyboardButton("🕒 Tardo",
                               callback_data=f'fort_late_{poi.id}')),
         (InlineKeyboardButton("❌ No voy",
                               callback_data=f'fort_no_{poi.id}'))],
        [(InlineKeyboardButton("✅ Estoy",
                               callback_data=f'fort_here_{poi.id}')),
         (InlineKeyboardButton("📍 Ubicación",
                               callback_data=f'fort_ubi_{poi.id}')),
         (InlineKeyboardButton("⚠️ Aviso",
                               callback_data=f'fort_alert_{poi.id}'))]
    ]

    string = r'\n(🙋‍♀️|✅|🕒|❌) 🧙(\d|\d\d|\?\?) (🍮|⚔|🐾|📚)(\d|\d\d|\?\?) @{}'.format(
        username)

    if queryData[1] == "ubi":
        bot.send_venue(
            chat_id=user_id,
            title=poi.name,
            address=" ",
            latitude=lat,
            longitude=lon,
            reply_markup=InlineKeyboardMarkup([[
                InlineKeyboardButton(
                    text="📍 Google Maps",
                    url='https://maps.google.com/maps?q={0},{1}'.format(
                        lat, lon))
            ]]))
        return
    elif queryData[1] == "alert":
        if last_run(
                str(user_id) + str(chat_id) + str(message_id), 'fort_alert'):
            bot.answer_callback_query(
                callback_query_id=query.id,
                text=
                "Ya has enviado un ⚠️ Aviso, espera un rato para enviar otro.",
                show_alert=True)
            return
        if re.search(string, markdown_text):
            ent = message.parse_entities(["mention"])
            chat_url = support.message_url(message, message_id, "fortaleza")
            for mention in ent:
                username = message.parse_entity(mention)
                string = r'\n(🙋‍♀️|✅|🕒|❌) 🧙(\d|\d\d|\?\?) (🍮|⚔|🐾|📚)(\d|\d\d|\?\?) {}'.format(
                    username)
                search = re.search(string, markdown_text)
                if search.group(1) == "❌":
                    continue
                user = get_user_by_name(username[1:])
                btn_user = get_user(user_id)
                bot.sendMessage(
                    chat_id=user.id,
                    text=
                    f"Alerta para la {chat_url} en [{poi.name}](https://maps.google.com/maps?q={lat},{lon}) enviada por @{btn_user.alias}",
                    parse_mode=telegram.ParseMode.MARKDOWN,
                    disable_web_page_preview=True)
            bot.answer_callback_query(
                callback_query_id=query.id,
                text=
                "⚠️ Aviso enviado a todos los magos apuntados en la lista.",
                show_alert=True)
        else:
            bot.answer_callback_query(
                query.id,
                "❌ Debes apuntarte para poder enviar una alerta.",
                show_alert=True)
        return

    markdown_text = re.sub(string, "", markdown_text)

    if user is None or user.profession is Professions.NONE.value:
        text_prof = "🍮"
    elif user.profession is Professions.AUROR.value:
        text_prof = "⚔"
    elif user.profession is Professions.MAGIZOOLOGIST.value:
        text_prof = "🐾"
    elif user.profession is Professions.PROFESSOR.value:
        text_prof = "📚"

    text_level = ("{}".format(user.level) if user and user.level else "??")
    text_profession_level = ("{}".format(user.profession_level)
                             if user and user.profession_level else "??")

    if queryData[1] == "yes":
        text = markdown_text + f"\n🙋‍♀️ 🧙{text_level} {text_prof}{text_profession_level} @{username}"
    elif queryData[1] == "here":
        text = markdown_text + f"\n✅ 🧙{text_level} {text_prof}{text_profession_level} @{username}"
    elif queryData[1] == "late":
        text = markdown_text + f"\n🕒 🧙{text_level} {text_prof}{text_profession_level} @{username}"
    elif queryData[1] == "no":
        text = markdown_text + f"\n❌ 🧙{text_level} {text_prof}{text_profession_level} @{username}"

    bot.edit_message_text(text=text,
                          chat_id=chat_id,
                          message_id=message_id,
                          parse_mode=telegram.ParseMode.MARKDOWN,
                          reply_markup=InlineKeyboardMarkup(button_list),
                          disable_web_page_preview=True)