wechaty / python-wechaty

Python Wechaty is a Conversational RPA SDK for Chatbot Makers written in Python
https://wechaty.readthedocs.io/zh_CN/latest/
Apache License 2.0
1.55k stars 229 forks source link

Message Wrapper, Status File Saver and Database Manager added in WechatyPlugin #363

Open profthecopyright opened 1 year ago

profthecopyright commented 1 year ago

Is your feature request related to a problem? Please describe. Sometimes I what to implement complicated logic with wechaty, e.g. acting as a judge to host an Avalon: Resistance or a Werewolf game in multiple groups. Application scenarios like this require at least following features:

  1. Send multiple messages in response to one user input. The recipient of any message may be different from the sender who triggers it, and the type of each message (text, image, etc) could be different. For instance, when the last person votes, the system need to send out different messages to different player, and also public message to the group.

  2. Use files (json, for example) to save the complete status of each game, for making game record and also for reloading after unexpected crash happens

  3. Work with some DBMS to manage long-lasting user data (for instance, # of wins and loses of every user)

It is important to notice that the strength these features are not limited to party games. Most complicated, group-based, interactive (instead of one-to-one) applications would likely use them. However, in current version of wechaty, 1-3 can only be done manually with basic API.

Describe the solution you'd like I volunteer to take care of this. What I am going to do is to INTEGRATE the features 1-3 into WechatyPlugin (as some helper methods). The details would be abstracted out. The final outcome would look like this:


class AvalonPlugin(WeChatyPlugin):
    def __init__(self):
        super().__init__()
        self.load()
        # self.state is accessible after loading

    async def on_message(self, msg):

    # some complicated logic

    self.save()
    """
    Each plugin object has an automatically generated "inner state" as a serializable dict.
    The dict is associated with an automatically generated json file named by the class name of the plugin
    Users in this layer only need to take care of self.state and use self.load() and self.save()
    """

    if self.game_ended():    # write the result to database
        self.update_database(some_info)
        # third-party libs like sqlalchemy could be integrated into the plugin, just like what was done to Quart
    else:
        pass

    """
    Each send_to method returns a list object, with each element as a dict like
    {"type": "TEXT", "content": "hello", "recipient": "user_id_123"}
    or {type: "IMAGE", "file_name": "/path/to/file.jpg", "recipient": "room_id_456"}. 

    Each dict object is a representation of a message to be sent. Since each response is a list, they can be concatenated at liberty
    with operator+.

    Note that different response item maybe generated by different part of code implementing the logic, 
    and messages are not always be supposed to be SENT in the exact order in which they are GENERATED.

    If one has to call msg.say() directly whenever a part of the entire response is generated, there may be some extra efforts required.
    """

    response1 = self.send_to_group(some_text)
    response2 = self.send_to_player0(some_text)
    response3 = self.send_to_player1(some_text) + self.send_to_player1(some_image)

    response = response1 + response2 + response3

    await self.send(response)    # the msg.say() methods are encapsulated here

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Additional context Add any other context or screenshots about the feature request here.