예제 #1
0
def run_message_handler_for_bot(
    lib_module: Any,
    quiet: bool,
    config_file: str,
    bot_config_file: str,
    bot_name: str,
) -> Any:
    """
    lib_module is of type Any, since it can contain any bot's
    handler class. Eventually, we want bot's handler classes to
    inherit from a common prototype specifying the handle_message
    function.

    Set default bot_details, then override from class, if provided
    """
    bot_details = {
        'name': bot_name.capitalize(),
        'description': "",
    }
    bot_details.update(getattr(lib_module.handler_class, 'META', {}))
    # Make sure you set up your ~/.zuliprc

    client_name = "Zulip{}Bot".format(bot_name.capitalize())

    try:
        client = Client(config_file=config_file, client=client_name)
    except configparser.Error as e:
        display_config_file_errors(str(e), config_file)
        sys.exit(1)

    bot_dir = os.path.dirname(lib_module.__file__)
    restricted_client = ExternalBotHandler(client, bot_dir, bot_details, bot_config_file)

    message_handler = prepare_message_handler(bot_name, restricted_client, lib_module)

    if not quiet:
        print("Running {} Bot:".format(bot_details['name']))
        if bot_details['description'] != "":
            print("\n\t{}".format(bot_details['description']))
        print(message_handler.usage())

    def handle_message(message: Dict[str, Any], flags: List[str]) -> None:
        logging.info('waiting for next message')
        # `mentioned` will be in `flags` if the bot is mentioned at ANY position
        # (not necessarily the first @mention in the message).
        is_mentioned = 'mentioned' in flags
        is_private_message = is_private_message_from_another_user(message, restricted_client.user_id)

        # Provide bots with a way to access the full, unstripped message
        message['full_content'] = message['content']
        # Strip at-mention botname from the message
        if is_mentioned:
            # message['content'] will be None when the bot's @-mention is not at the beginning.
            # In that case, the message shall not be handled.
            message['content'] = extract_query_without_mention(message=message, client=restricted_client)
            if message['content'] is None:
                return

        if is_private_message or is_mentioned:
            message_handler.handle_message(
                message=message,
                bot_handler=restricted_client
            )

    signal.signal(signal.SIGINT, exit_gracefully)

    logging.info('starting message handling...')

    def event_callback(event: Dict[str, Any]) -> None:
        if event['type'] == 'message':
            handle_message(event['message'], event['flags'])

    client.call_on_each_event(event_callback, ['message'])
예제 #2
0
def run_message_handler_for_bot(
    lib_module: Any,
    quiet: bool,
    config_file: str,
    bot_config_file: str,
    bot_name: str,
    bot_source: str,
) -> Any:
    """
    lib_module is of type Any, since it can contain any bot's
    handler class. Eventually, we want bot's handler classes to
    inherit from a common prototype specifying the handle_message
    function.

    Set default bot_details, then override from class, if provided
    """
    bot_details = {
        "name": bot_name.capitalize(),
        "description": "",
    }
    bot_details.update(getattr(lib_module.handler_class, "META", {}))
    # Make sure you set up your ~/.zuliprc

    client_name = f"Zulip{bot_name.capitalize()}Bot"

    try:
        client = Client(config_file=config_file, client=client_name)
    except configparser.Error as e:
        display_config_file_errors(str(e), config_file)
        sys.exit(1)

    bot_dir = os.path.dirname(lib_module.__file__)
    restricted_client = ExternalBotHandler(client, bot_dir, bot_details,
                                           bot_config_file)

    message_handler = prepare_message_handler(bot_name, restricted_client,
                                              lib_module)

    if not quiet:
        print("Running {} Bot (from {}):".format(bot_details["name"],
                                                 bot_source))
        if bot_details["description"] != "":
            print("\n\t{}".format(bot_details["description"]))
        if hasattr(message_handler, "usage"):
            print(message_handler.usage())
        else:
            print(
                f"WARNING: {bot_name} is missing usage handler, please add one eventually"
            )

    def handle_message(message: Dict[str, Any], flags: List[str]) -> None:
        logging.info("waiting for next message")
        # `mentioned` will be in `flags` if the bot is mentioned at ANY position
        # (not necessarily the first @mention in the message).
        is_mentioned = "mentioned" in flags
        is_private_message = is_private_message_but_not_group_pm(
            message, restricted_client)

        # Provide bots with a way to access the full, unstripped message
        message["full_content"] = message["content"]
        # Strip at-mention botname from the message
        if is_mentioned:
            # message['content'] will be None when the bot's @-mention is not at the beginning.
            # In that case, the message shall not be handled.
            message["content"] = extract_query_without_mention(
                message=message, client=restricted_client)
            if message["content"] is None:
                return

        if is_private_message or is_mentioned:
            message_handler.handle_message(message=message,
                                           bot_handler=restricted_client)

    signal.signal(signal.SIGINT, exit_gracefully)

    logging.info("starting message handling...")

    def event_callback(event: Dict[str, Any]) -> None:
        if event["type"] == "message":
            handle_message(event["message"], event["flags"])

    client.call_on_each_event(event_callback, ["message"])
예제 #3
0
def run_message_handler_for_bot(lib_module, quiet, config_file, bot_name):
    # type: (Any, bool, str, str) -> Any
    #
    # lib_module is of type Any, since it can contain any bot's
    # handler class. Eventually, we want bot's handler classes to
    # inherit from a common prototype specifying the handle_message
    # function.
    #
    # Make sure you set up your ~/.zuliprc
    client = Client(config_file=config_file,
                    client="Zulip{}Bot".format(bot_name.capitalize()))
    bot_dir = os.path.dirname(lib_module.__file__)
    restricted_client = ExternalBotHandler(client, bot_dir)

    message_handler = lib_module.handler_class()
    if hasattr(message_handler, 'initialize'):
        message_handler.initialize(bot_handler=restricted_client)

    # Set default bot_details, then override from class, if provided
    bot_details = {
        'name': bot_name.capitalize(),
        'description': "",
    }
    bot_details.update(getattr(lib_module.handler_class, 'META', {}))

    if not quiet:
        print("Running {} Bot:".format(bot_details['name']))
        if bot_details['description'] != "":
            print("\n\t{}".format(bot_details['description']))
        print(message_handler.usage())

    def handle_message(message, flags):
        # type: (Dict[str, Any], List[str]) -> None
        logging.info('waiting for next message')

        # `mentioned` will be in `flags` if the bot is mentioned at ANY position
        # (not necessarily the first @mention in the message).
        is_mentioned = 'mentioned' in flags
        is_private_message = is_private_message_from_another_user(
            message, restricted_client.user_id)

        # Strip at-mention botname from the message
        if is_mentioned:
            # message['content'] will be None when the bot's @-mention is not at the beginning.
            # In that case, the message shall not be handled.
            message['content'] = extract_query_without_mention(
                message=message, client=restricted_client)
            if message['content'] is None:
                return

        if is_private_message or is_mentioned:
            message_handler.handle_message(message=message,
                                           bot_handler=restricted_client)

    signal.signal(signal.SIGINT, exit_gracefully)

    logging.info('starting message handling...')

    def event_callback(event):
        # type: (Dict[str, Any]) -> None
        if event['type'] == 'message':
            handle_message(event['message'], event['flags'])

    client.call_on_each_event(event_callback, ['message'])
예제 #4
0
def run_message_handler_for_bot(
    lib_module: Any,
    quiet: bool,
    config_file: str,
    bot_config_file: str,
    bot_name: str,
) -> Any:
    """
    lib_module is of type Any, since it can contain any bot's
    handler class. Eventually, we want bot's handler classes to
    inherit from a common prototype specifying the handle_message
    function.

    Set default bot_details, then override from class, if provided
    """
    bot_details = {
        'name': bot_name.capitalize(),
        'description': "",
    }
    bot_details.update(getattr(lib_module.handler_class, 'META', {}))
    # Make sure you set up your ~/.zuliprc

    client_name = "Zulip{}Bot".format(bot_name.capitalize())

    try:
        client = Client(config_file=config_file, client=client_name)
    except configparser.Error as e:
        display_config_file_errors(str(e), config_file)
        sys.exit(1)

    bot_dir = os.path.dirname(lib_module.__file__)
    restricted_client = ExternalBotHandler(client, bot_dir, bot_details, bot_config_file)

    message_handler = prepare_message_handler(bot_name, restricted_client, lib_module)

    if not quiet:
        print("Running {} Bot:".format(bot_details['name']))
        if bot_details['description'] != "":
            print("\n\t{}".format(bot_details['description']))
        print(message_handler.usage())

    def handle_message(message: Dict[str, Any], flags: List[str]) -> None:
        logging.info('waiting for next message')
        # `mentioned` will be in `flags` if the bot is mentioned at ANY position
        # (not necessarily the first @mention in the message).
        is_mentioned = 'mentioned' in flags
        is_private_message = is_private_message_from_another_user(message, restricted_client.user_id)

        # Provide bots with a way to access the full, unstripped message
        message['full_content'] = message['content']
        # Strip at-mention botname from the message
        if is_mentioned:
            # message['content'] will be None when the bot's @-mention is not at the beginning.
            # In that case, the message shall not be handled.
            message['content'] = extract_query_without_mention(message=message, client=restricted_client)
            if message['content'] is None:
                return

        if is_private_message or is_mentioned:
            message_handler.handle_message(
                message=message,
                bot_handler=restricted_client
            )

    signal.signal(signal.SIGINT, exit_gracefully)

    logging.info('starting message handling...')

    def event_callback(event: Dict[str, Any]) -> None:
        if event['type'] == 'message':
            handle_message(event['message'], event['flags'])

    client.call_on_each_event(event_callback, ['message'])