Exemplo n.º 1
0
def connect():
    module_id = ModulesLoader.get_module_id("welcome_message")

    bot_manager = ModulesLoader.load_manager("bot")

    dispatcher = bot_manager.updater.dispatcher

    dispatcher.add_handler(MessageHandler(
        Filters.status_update.new_chat_members, welcome_message_handler),
                           group=module_id)
Exemplo n.º 2
0
def connect():
    # Connect modules
    logging.info("Connecting modules...")

    modules = os.listdir("modules")
    modules.remove("pytg")

    for module_name in modules:
        logging.info("Dynamically connecting module {}...".format(module_name))

        ModulesLoader.connect_module(module_name)
Exemplo n.º 3
0
def animation_message_handler(update, context):
    bot = context.bot

    message = update.message

    if not message or not message.chat or not message.animation:
        return

    chat_id = message.chat.id
    message_id = message.message_id

    username = message.from_user.username
    user_id = message.from_user.id

    logging.info(
        "Received animation message update from {} ({}) in chat {}".format(
            username, user_id, chat_id))

    data_manager = ModulesLoader.load_manager("data")

    # Check if the bot is waiting for a form input
    if data_manager.has_data("forms", chat_id, module="forms"):
        current_user_form_id = chat_id
        forms_manager = ModulesLoader.load_manager("forms")

        form_data = data_manager.load_data("forms",
                                           current_user_form_id,
                                           module="forms")

        if form_data["digested"]:
            return

        form_name = form_data["form_name"]
        form_steps = forms_manager.load_form_steps(form_name)

        step_data = form_steps[form_data["current_step"]]

        if step_data["type"] != "animation_field":
            return

        animation = message.animation
        animation_id = animation.file_id
        animation_url = bot.getFile(animation_id).file_path

        input_data = {
            "animation_id": animation_id,
            "animation_url": animation_url
        }

        forms_manager = ModulesLoader.load_manager("forms")
        forms_manager.handle_input(bot, chat_id, message_id, form_name,
                                   form_data["current_step"], input_data)
Exemplo n.º 4
0
def initialize():
    logging.info("Initializing pytg module...")

    # Initialize modules
    logging.info("Dynamically loading all modules...")

    modules = os.listdir("modules")
    modules.remove("pytg")

    for module_name in modules:
        logging.info("Dynamically loading module {}...".format(module_name))

        ModulesLoader.initialize_module(module_name)
Exemplo n.º 5
0
    def load_form_steps(self, form_name, lang=None):
        module_folder = ModulesLoader.get_module_content_folder("forms")

        if not lang:
            config_manager = ModulesLoader.load_manager("config")
            lang_settings = config_manager.load_settings_file("forms", "lang")
            lang = lang_settings["default"]

        return yaml.safe_load(
            open("{}/formats/{}/{}/steps.yaml".format(module_folder, lang,
                                                      form_name),
                 "r",
                 encoding="utf8"))
Exemplo n.º 6
0
    def start_form(self, bot, chat_id, form_name, form_meta={}):
        logging.info("Starting form {} for {}".format(form_name, chat_id))

        data_manager = ModulesLoader.load_manager("data")

        # Update user data
        self.clear_user_form_data(bot, chat_id)

        form_id = chat_id
        data_manager.create_data("forms", form_id, module="forms")

        # Show form to user
        steps = self.load_form_steps(form_name)

        first_step = steps["meta"]["first_step"]

        form_data = data_manager.load_data("forms", form_id, module="forms")

        form_data["form_name"] = form_name
        form_data["current_step"] = first_step
        form_data["form_meta"] = form_meta

        # Set default entries
        if "default_entries" in steps["meta"].keys():
            default_entries = steps["meta"]["default_entries"]

            for entry in default_entries.keys():
                form_data["form_entries"][entry] = default_entries[entry]

        data_manager.save_data("forms", form_id, form_data, module="forms")

        self.show_current_step(bot, chat_id)
Exemplo n.º 7
0
    def set_next_step(self, bot, chat_id, message_id, next_step=None):
        data_manager = ModulesLoader.load_manager("data")

        form_id = chat_id

        form_data = data_manager.load_data("forms", form_id, module="forms")
        form_name = form_data["form_name"]
        form_steps = self.load_form_steps(form_name)

        current_step_data = form_steps[form_data["current_step"]]

        # Delete previous message if 'clear' is true
        if "clear" in current_step_data and current_step_data["clear"]:
            bot.deleteMessage(chat_id=chat_id, message_id=message_id)

        if next_step == None:
            next_step = current_step_data["next_step"]

        logging.info("Showing next step to {} ({} {})".format(
            chat_id, form_id, next_step))

        if next_step and next_step != "None":
            if next_step == "_RESET":
                self.clear_user_form_data(bot, chat_id, False)
                return

            form_data["current_step"] = next_step
            data_manager.save_data("forms", form_id, form_data, module="forms")
            self.show_current_step(bot, chat_id)
        else:
            if "void" in form_steps["meta"] and form_steps["meta"]["void"]:
                return

            self.digest_form(bot, chat_id, form_id)
Exemplo n.º 8
0
def connect():
    logging.info("Connecting forms module...")

    bot_manager = ModulesLoader.load_manager("bot")

    load_callback_handlers(bot_manager.updater.dispatcher)
    load_messages_handlers(bot_manager.updater.dispatcher)
Exemplo n.º 9
0
def blacklist_message_handler(update, context):
    bot = context.bot

    message = update.message

    chat_id = message.chat.id

    user_id = message.from_user.id
    username = message.from_user.username

    text = message.text

    tags_manager = ModulesLoader.load_manager("tags")

    if username:
        if tags_manager.has_tag(username, "no_words_filter", "users"):
            return

    config_manager = ModulesLoader.load_manager("config")
    blacklist_settings = config_manager.load_settings_file(
        "message_filter", "blacklist")

    text_lower = text.lower()

    for kickable_word in blacklist_settings["kickable_words"]:
        if kickable_word in text_lower:
            logger.info(
                "Deleting message '{}' from chat {} as it contains the kickable word '{}'"
                .format(text, chat_id, kickable_word))

            bot.deleteMessage(chat_id=chat_id, message_id=message.message_id)

    bannable_words = 0

    for bannable_word in blacklist_settings["bannable_words"]:
        if bannable_word in text_lower:
            bannable_words += 1

            if bannable_words == 3:
                logger.info(
                    "Deleting message '{}' from chat {} and kicking its author as it contains enough bannable words"
                    .format(text, chat_id))

                bot.deleteMessage(chat_id=chat_id,
                                  message_id=message.message_id)

                bot.kickChatMember(chat_id=chat_id, user_id=user_id)
Exemplo n.º 10
0
    def save_settings_file(self,
                           settings,
                           module="config",
                           file_name="settings"):
        module_folder = ModulesLoader.get_module_content_folder(module)

        yaml.safe_dump(
            settings,
            open("{}/config/{}.yaml".format(module_folder, file_name), "w"))
Exemplo n.º 11
0
    def save_data(self, table, object_id, data, module="data"):
        module_folder = ModulesLoader.get_module_content_folder(module)

        yaml.safe_dump(
            data,
            open("{}/data/{}/{}.yaml".format(module_folder, table, object_id),
                 "w"))

        return data
Exemplo n.º 12
0
    def __init__(self):
        config_manager = ModulesLoader.load_manager("config")

        settings = config_manager.load_settings_file("bot", "token")

        self.bot = telegram.Bot(settings["token"])
        self.updater = Updater(settings["token"], use_context=True)

        return
Exemplo n.º 13
0
    def download_media(self, media_id, media_url, folder="uncategorized"):
        module_folder = ModulesLoader.get_module_content_folder("cache")

        media_data = urllib.request.urlopen(media_url).read()

        with open("{}/{}/{}".format(module_folder, folder, media_id),
                  "wb") as media_file:
            media_file.write(media_data)

        return media_data
Exemplo n.º 14
0
def load_message_handlers(dispatcher):
    module_id = ModulesLoader.get_module_id("message_filter")

    dispatcher.add_handler(MessageHandler(Filters.text,
                                          blacklist_message_handler),
                           group=module_id)
    dispatcher.add_handler(MessageHandler(
        Filters.text & (Filters.entity(MessageEntity.URL)
                        | Filters.entity(MessageEntity.TEXT_LINK)),
        links_block_message_handler),
                           group=module_id + 1)
Exemplo n.º 15
0
def start_cmd_handler(update, context):
    bot = context.bot

    message = update.message
    chat_id = message.chat.id

    username = message.from_user.username
    user_id = message.from_user.id

    logging.info("Received start command update from {} ({}) in chat {}".format(username, user_id, chat_id))
    forms_manager = ModulesLoader.load_manager("forms")
    forms_manager.start_form(bot,chat_id,"send_photo")
Exemplo n.º 16
0
def main():
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        level=logging.INFO,
        # filename="pytg-bot.log"
    )

    logging.info(" ### Launching Bot... ### ")
    logging.info(str(datetime.datetime.now()))

    parser = argparse.ArgumentParser(description='PyTG command line launcher')
    parser.add_argument("--main-module")

    args = parser.parse_args()

    main_module = args.main_module

    if not main_module:
        logging.error("No main module specified")
        return

    # Initialize PyTG module (initializes all modules)
    ModulesLoader.initialize_module("pytg")

    # Connect PyTG module (connects all modules)
    ModulesLoader.connect_module("pytg")

    # Launch main module
    ModulesLoader.launch_main_module(main_module)
Exemplo n.º 17
0
def links_block_message_handler(update, context):
    bot = context.bot

    message = update.message

    chat_id = message.chat.id

    username = message.from_user.username

    config_manager = ModulesLoader.load_manager("config")
    settings = config_manager.load_settings_file("message_filter", "links_block")

    if not settings["block_links"]:
        return

    chat_admins = message.chat.get_administrators()

    if settings["admins_authorized"]:
        for chat_admin in chat_admins:
            if message.from_user.id == chat_admin.user.id:
                logging.info("User is an administrator of the chat")
                return

    logger.info("Detected message with link")

    tags_manager = ModulesLoader.load_manager("tags")
    
    if username:
        if tags_manager.has_tag(username, "can_post_links", "users"):
            logger.info("User is allowed to post links")
            return

    logger.info("Deleting message with link")

    bot.deleteMessage(
        chat_id = chat_id,
        message_id = message.message_id
    )
Exemplo n.º 18
0
    def find_entry_by_field(self, table, field, value, module="data"):
        module_folder = ModulesLoader.get_module_content_folder(module)

        files = os.listdir("{}/data/{}".format(module_folder, table))
        files.remove("__default.yaml")

        for f in files:
            entry_id = f.replace(".yaml", "")

            data = self.load_data(table, entry_id)

            if data[field] == value:
                return data

        return None
Exemplo n.º 19
0
def load_messages_handlers(dispatcher):
    module_id = ModulesLoader.get_module_id("forms")

    dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command,
                                          text_message_handler),
                           group=module_id)
    dispatcher.add_handler(MessageHandler(Filters.photo,
                                          photo_message_handler),
                           group=module_id)
    dispatcher.add_handler(MessageHandler(Filters.video,
                                          video_message_handler),
                           group=module_id)
    dispatcher.add_handler(MessageHandler(Filters.animation,
                                          animation_message_handler),
                           group=module_id)
Exemplo n.º 20
0
    def load_table_entries(self, table, module="data"):
        module_folder = ModulesLoader.get_module_content_folder(module)

        entries = []

        files = os.listdir("{}/data/{}".format(module_folder, table))
        files.remove("__default.yaml")

        for f in files:
            entry_id = f.replace(".yaml", "")

            data = self.load_data(table, entry_id)

            entries.append(data)

        return entries
Exemplo n.º 21
0
    def digest_form(self, bot, chat_id, form_id):
        logging.info("Digesting form for {}".format(chat_id))

        data_manager = ModulesLoader.load_manager("data")

        # Load form's data
        form_data = data_manager.load_data("forms", form_id, module="forms")
        form_name = form_data["form_name"]

        # Update digestion flag
        form_data["digested"] = True
        data_manager.save_data("forms", form_id, form_data, module="forms")

        # Digest the form
        digester = self.digesters[form_name]
        digester(bot, chat_id, form_data["form_entries"],
                 form_data["form_meta"])
Exemplo n.º 22
0
    def clear_user_form_data(self, bot, chat_id, delete_messages=True):
        logging.info("Clearing form data for user {}".format(chat_id))

        data_manager = ModulesLoader.load_manager("data")

        form_id = chat_id
        if not data_manager.has_data("forms", form_id, module="forms"):
            return

        form_data = data_manager.load_data("forms", form_id, module="forms")

        # Clear form messages
        if delete_messages:  # (not form_data["digested"]) and delete_messages:
            for form_message_id in form_data["messages"]:
                try:
                    bot.deleteMessage(chat_id=chat_id,
                                      message_id=form_message_id)
                except:
                    logging.info(
                        "Unable to delete message {}".format(form_message_id))

        # Update form data
        data_manager.delete_data("forms", form_id, module="forms")
Exemplo n.º 23
0
    def save_cache(self, cache):
        module_folder = ModulesLoader.get_module_content_folder("cache")

        yaml.safe_dump(cache, open("{}/cache.yaml".format(module_folder), "w"))
Exemplo n.º 24
0
    def load_cache(self):
        module_folder = ModulesLoader.get_module_content_folder("cache")

        return yaml.safe_load(open("{}/cache.yaml".format(module_folder), "r"))
Exemplo n.º 25
0
def connect():
    bot_manager = ModulesLoader.load_manager("bot")

    dispatcher = bot_manager.updater.dispatcher

    load_message_handlers(dispatcher)
Exemplo n.º 26
0
def forms_callback_handler(update, context):
    bot = context.bot

    forms_manager = ModulesLoader.load_manager("forms")

    query = update.callback_query
    query_data = query.data.split(",")
    user_id = query.from_user.id

    username = query.message.chat.username
    chat_id = query.message.chat_id
    message_id = query.message.message_id

    logging.info("Handling forms callback data from {}: {}".format(chat_id, query_data))

    if query_data[1] == "fixed_reply":
        data_manager = ModulesLoader.load_manager("data")

        form_data = data_manager.load_data("forms", chat_id, module="forms")

        step_name = form_data["current_step"]
        form_name = form_data["form_name"]

        # step_name = query_data[2]
        # form_name = query_data[3]

        input_data = {
            "action": query_data[2],
            "output_data": query_data[3]
        }

        bot.editMessageReplyMarkup(
            chat_id = chat_id,
            message_id = message_id,
            reply_markup = None
        )

        forms_manager.handle_input(bot, chat_id, message_id, form_name, step_name, input_data)
        return

    if query_data[1] == "jump":
        next_step_name = query_data[2]

        bot.editMessageReplyMarkup(
            chat_id = chat_id,
            message_id = message_id,
            reply_markup = None
        )

        forms_manager.set_next_step(bot, chat_id, message_id, next_step=next_step_name)
        return

    if query_data[1] == "show":
        form_name = query_data[2]

        forms_manager.start_form(bot, chat_id, form_name)

    if query_data[1] == "checkbox_click":
        entry = query_data[2]
        step_output = query_data[3]

        form_id = chat_id

        data_manager = ModulesLoader.load_manager("data")
        form_data = data_manager.load_data("forms", form_id, module="forms")

        if entry in form_data["form_entries"][step_output]:
            form_data["form_entries"][step_output].remove(entry)
        else:
            form_data["form_entries"][step_output].append(entry)

        data_manager.save_data("forms", form_id, form_data, module="forms")

        forms_manager.show_current_step(bot, chat_id, message_id)
Exemplo n.º 27
0
    def load_media(self, media_id, folder="uncategorized"):
        module_folder = ModulesLoader.get_module_content_folder("cache")

        return open("{}/{}/{}".format(module_folder, folder, media_id), "rb")
Exemplo n.º 28
0
    def handle_input(self, bot, chat_id, message_id, form_name, step_name,
                     input_data):
        logging.info(
            "Handling input of {} on form {} (step name = {}, input data = {})"
            .format(chat_id, form_name, step_name, input_data))

        data_manager = ModulesLoader.load_manager("data")

        next_step_name = None

        # Check if it's an action input
        if "action" in input_data.keys() and len(input_data["action"]) > 0:
            actions = input_data["action"].split(";")

            if actions[0] == "jump":
                next_step_name = actions[1]

        form_steps = self.load_form_steps(form_name)
        step_data = form_steps[step_name]

        if "output" in step_data.keys():
            if step_data["type"] == "text_field":
                step_output = input_data["text"]

            elif step_data["type"] == "fixed_reply":
                step_output = input_data["output_data"]

            elif step_data["type"] == "keyboard_reply":
                step_output = input_data["value"]

            elif step_data["type"] == "image_field":
                step_output = input_data["image_id"]

                if step_data["save_in_cache"]:
                    cache_manager = ModulesLoader.load_manager("cache")
                    cache_manager.download_image(input_data["image_id"],
                                                 input_data["image_url"])

            elif step_data["type"] == "video_field":
                step_output = input_data["video_id"]

                if step_data["save_in_cache"]:
                    cache_manager = ModulesLoader.load_manager("cache")
                    cache_manager.download_video(input_data["video_id"],
                                                 input_data["video_url"])

            elif step_data["type"] == "animation_field":
                step_output = input_data["animation_id"]

                if step_data["save_in_cache"]:
                    cache_manager = ModulesLoader.load_manager("cache")
                    cache_manager.download_animation(
                        input_data["animation_id"],
                        input_data["animation_url"])

            current_user_form_id = chat_id
            form_data = data_manager.load_data("forms",
                                               current_user_form_id,
                                               module="forms")
            form_data["form_entries"][step_data["output"]] = step_output
            data_manager.save_data("forms",
                                   current_user_form_id,
                                   form_data,
                                   module="forms")

        self.set_next_step(bot, chat_id, message_id, next_step=next_step_name)
Exemplo n.º 29
0
    def show_current_step(self, bot, chat_id, message_id=None):
        data_manager = ModulesLoader.load_manager("data")

        form_id = chat_id

        form_data = data_manager.load_data("forms", form_id, module="forms")
        form_name = form_data["form_name"]
        form_steps = self.load_form_steps(form_name)

        step_name = form_data["current_step"]
        current_step_data = form_steps[step_name]

        if "externs" in current_step_data.keys():
            externs = current_step_data["externs"]

            for extern_key in externs.keys():
                extern_data = form_data["form_meta"][externs[extern_key]]

                current_step_data[extern_key] = extern_data

        reply_markup = None
        next_step = "__NULL"

        # Message
        if current_step_data["type"] == "message":
            step_text = current_step_data["text"]

            if "format" in current_step_data.keys(
            ) and current_step_data["format"]:
                form_entries = form_data["form_entries"]
                step_text = self.format_step_text(step_text, form_entries)

            # Check if the step requires a back button
            if "previous_step" in current_step_data.keys():
                menu_layout = []
                self.append_jump_button(menu_layout, "Back",
                                        current_step_data["previous_step"])
                reply_markup = InlineKeyboardMarkup(menu_layout)

            next_step = current_step_data["next_step"]

        # Text or image field
        if (current_step_data["type"] == "text_field"
                or current_step_data["type"] == "image_field"
                or current_step_data["type"] == "video_field"
                or current_step_data["type"] == "animation_field"):
            step_text = current_step_data["text"]

            if "format" in current_step_data.keys(
            ) and current_step_data["format"]:
                form_entries = form_data["form_entries"]
                step_text = self.format_step_text(step_text, form_entries)

            reply_markup = None

            # Check if the step requires a back button
            if "previous_step" in current_step_data.keys():
                menu_layout = []
                self.append_jump_button(menu_layout, "Back",
                                        current_step_data["previous_step"])
                reply_markup = InlineKeyboardMarkup(menu_layout)

        # Fixed reply
        if current_step_data["type"] == "fixed_reply":
            # Format step text (if necessary)
            step_text = current_step_data["text"]

            if "format" in current_step_data.keys(
            ) and current_step_data["format"]:
                form_entries = form_data["form_entries"]
                step_text = self.format_step_text(step_text, form_entries)

            options = current_step_data["options"]
            reply_markup = self.fixed_reply_reply_markup(
                options, form_data, current_step_data)

        # Keyboard reply
        if current_step_data["type"] == "keyboard_reply":
            # Format step text (if necessary)
            step_text = current_step_data["text"]

            if "format" in current_step_data.keys(
            ) and current_step_data["format"]:
                form_entries = form_data["form_entries"]
                step_text = self.format_step_text(step_text, form_entries)

            options = current_step_data["options"]
            reply_markup = self.keyboard_reply_reply_markup(
                options, form_data, current_step_data)

        # Checkbox list
        if current_step_data["type"] == "checkbox_list":
            step_text = current_step_data["text"]
            step_output = current_step_data["output"]

            if "format" in current_step_data.keys(
            ) and current_step_data["format"]:
                form_entries = form_data["form_entries"]
                step_text = self.format_step_text(step_text, form_entries)

            if step_output not in form_data["form_entries"].keys():
                form_data["form_entries"][step_output] = []
                data_manager.save_data("forms",
                                       form_id,
                                       form_data,
                                       module="forms")

            entries = current_step_data["entries"]
            reply_markup = self.checkbox_list_reply_markup(
                entries, form_data, current_step_data)

        # Replace macros in meta
        for meta in form_data["form_meta"].keys():
            macro = "[{}]".format(meta)

            step_text = step_text.replace(macro,
                                          str(form_data["form_meta"][meta]))

        # Disable web page preview option
        disable_web_page_preview = True
        if "disable_web_page_preview" in current_step_data.keys(
        ) and current_step_data["disable_web_page_preview"]:
            disable_web_page_preview = current_step_data[
                "disable_web_page_preview"]

        # Send or edit message
        if message_id:
            bot.editMessageText(
                chat_id=chat_id,
                message_id=message_id,
                text=step_text,
                parse_mode=telegram.ParseMode.MARKDOWN,
                reply_markup=reply_markup,
                disable_web_page_preview=disable_web_page_preview)
        else:
            # Load media data (if any)
            media_data = None
            if "media" in current_step_data.keys(
            ) and current_step_data["media"]:
                media_data = current_step_data["media"]

                for meta in form_data["form_meta"].keys():
                    macro = "[{}]".format(meta)

                    media_data["type"] = media_data["type"].replace(
                        macro, str(form_data["form_meta"][meta]))
                    media_data["path"] = media_data["path"].replace(
                        macro, str(form_data["form_meta"][meta]))

                if "format" in current_step_data.keys(
                ) and current_step_data["format"]:
                    for key in form_data["form_entries"].keys():
                        macro = "[{}]".format(key)

                        media_data["type"] = media_data["type"].replace(
                            macro, str(form_data["form_entries"][key]))
                        media_data["path"] = media_data["path"].replace(
                            macro, str(form_data["form_entries"][key]))

            # Send complete message
            if not media_data:
                sent_message = bot.sendMessage(
                    chat_id=chat_id,
                    text=step_text,
                    parse_mode=telegram.ParseMode.MARKDOWN,
                    reply_markup=reply_markup,
                    disable_web_page_preview=disable_web_page_preview)
            else:
                if media_data["type"] == "photo":
                    sent_message = bot.sendPhoto(
                        chat_id=chat_id,
                        caption=step_text,
                        photo=media_data["path"],
                        parse_mode=telegram.ParseMode.MARKDOWN,
                        reply_markup=reply_markup,
                        disable_web_page_preview=disable_web_page_preview)
                elif media_data["type"] == "video":
                    sent_message = bot.sendVideo(
                        chat_id=chat_id,
                        caption=step_text,
                        video=media_data["path"],
                        parse_mode=telegram.ParseMode.MARKDOWN,
                        reply_markup=reply_markup,
                        disable_web_page_preview=disable_web_page_preview)
                else:
                    logging.exception("Unknown media type")

            # Add new message IDs
            if data_manager.has_data("forms", form_id):
                form_data = data_manager.load_data("forms",
                                                   form_id,
                                                   module="forms")
                form_data["messages"].append(sent_message.message_id)
                data_manager.save_data("forms",
                                       form_id,
                                       form_data,
                                       module="forms")

        if next_step is not "__NULL":
            self.set_next_step(bot,
                               chat_id,
                               sent_message.message_id,
                               next_step=next_step)
Exemplo n.º 30
0
def text_message_handler(update, context):
    bot = context.bot

    message = update.message

    if not message or not message.chat:
        return

    chat_id = message.chat.id
    message_id = message.message_id

    username = message.from_user.username
    user_id = message.from_user.id

    text = message.text

    logging.info(
        "Received text message update from {} ({}) in chat {}: {}".format(
            username, user_id, chat_id, text))

    data_manager = ModulesLoader.load_manager("data")

    # Check if the bot is waiting for a form input
    if data_manager.has_data("forms", chat_id, module="forms"):
        current_user_form_id = chat_id

        forms_manager = ModulesLoader.load_manager("forms")

        form_data = data_manager.load_data("forms",
                                           current_user_form_id,
                                           module="forms")

        if form_data["digested"]:
            return

        form_name = form_data["form_name"]
        form_steps = forms_manager.load_form_steps(form_name)

        step_data = form_steps[form_data["current_step"]]

        if step_data["type"] == "text_field":
            input_data = {"text": text}

        elif step_data["type"] == "keyboard_reply":
            replies_map = step_data["map"]

            if text not in replies_map.keys():
                return

            input_data = {"value": replies_map[text]}

        # elif step_data["type"] == "image_field":
        #     if not message.photo:
        #         return

        #     photos = message.photo

        #     input_data = {
        #         "image_url": None
        #     }
        else:
            return

        forms_manager.handle_input(bot, chat_id, message_id, form_name,
                                   form_data["current_step"], input_data)