mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 23:46:41 +00:00
rfc: bot messages and buttons, core: command markdown, supported commands in profile preferences, chat sessions preference, peer type field in profile to identify bots (#5360)
* rfc: bot messages and buttons * update * update bot rfc * core: add bot commands to chat preferences and peer type to profile * update postgresql schema * update query plans * chat sessions preference * markdown for bot commands * schema * core: file preference, options to create bot from CLI * core: different command type * ios: commands menu * update types * update ios * improve command markdown * core, ios: update types * android, desktop: clickable commands in messages in chats with bots * android, desktop: commands menu * command menu button, bot icon * ios: connect flow for bots * android, desktop: connect flow for bots * icon * CLI commands to view and set commands, remove "hidden" property of command, bot api docs * corrections * fix inheriting profile preferences to business groups * note on business address * ios: export localizations * fix test * commands to set file preference on user/contact, tidy up layout and display of command and attachment buttons
This commit is contained in:
1 parent
9596029c30
commit
4811d663e6
93 files changed
+2810
-466
No files matched your search
@@ -20,11 +20,21 @@
|
||||
"format": "data URI format for base64 encoded image"
|
||||
}
|
||||
},
|
||||
"contactLink": {"ref": "connReqUri"},
|
||||
"preferences": {
|
||||
"shortDescr": {
|
||||
"type": "string",
|
||||
"metadata": {"comment": "profile bio (160 characters)"}
|
||||
},
|
||||
"contactLink": {"ref": "connReqUri"},
|
||||
"peerType": {"enum": ["human", "bot"]},
|
||||
"preferences": {
|
||||
"optionalProperties": {
|
||||
"commands": {
|
||||
"elements": {"ref": "command"}
|
||||
}
|
||||
},
|
||||
"additionalProperties": true,
|
||||
"metadata": {
|
||||
"format": "JSON encoded user preferences"
|
||||
"format": "an object with user or contact preferences"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -47,15 +57,59 @@
|
||||
"format": "data URI format for base64 encoded image"
|
||||
}
|
||||
},
|
||||
"groupPreferences": {
|
||||
"shortDescr": {
|
||||
"type": "string",
|
||||
"metadata": {"comment": "group purpose / short description (160 characters)"}
|
||||
},
|
||||
"groupPreferences": {
|
||||
"optionalProperties": {
|
||||
"commands": {
|
||||
"elements": {"ref": "command"}
|
||||
}
|
||||
},
|
||||
"additionalProperties": "true",
|
||||
"metadata": {
|
||||
"format": "JSON encoded user preferences"
|
||||
"format": "an object with group preferences"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
},
|
||||
"command": {
|
||||
"discriminator": "type",
|
||||
"mapping": {
|
||||
"command": {
|
||||
"properties": {
|
||||
"keyword": {
|
||||
"type": "string",
|
||||
"metadata": {"format": "Must start from / and consist from letters, digits and underscores only, no punctuation or spaces"}
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"metadata": {"comment": "shown to the user after command keyword in menus"}
|
||||
}
|
||||
},
|
||||
"optionalProperties": {
|
||||
"params": {
|
||||
"type": "string",
|
||||
"metadata": {"comment": "Params that can follow after keyword using command-line syntax. If params property is not present, command will be sent on selection"}}
|
||||
},
|
||||
"hidden": {
|
||||
"type": "bool",
|
||||
"metadata": {"comment": "Won't be shown in menu when true"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"properties": {
|
||||
"label": {"type": "string"},
|
||||
"commands": {
|
||||
"elements": {"ref": "command"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"msgContainer": {
|
||||
"properties": {
|
||||
"content": {"ref": "msgContent"}
|
||||
@@ -658,6 +712,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"x.grp.prefs": {
|
||||
"properties": {
|
||||
"msgId": {"ref": "base64url"},
|
||||
"params": {
|
||||
"properties": {
|
||||
"groupPreferences": {"ref": "groupPreferences"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x.grp.direct.inv": {
|
||||
"properties": {
|
||||
"msgId": {"ref": "base64url"},
|
||||
|
||||
@@ -8,7 +8,7 @@ When business uses a communication system for support and other business scenari
|
||||
|
||||
It's important for the business:
|
||||
- to have bot accept incoming requests.
|
||||
- to be able to add other people to the coversation, as transfer and as escalation.
|
||||
- to be able to add other people to the conversation, as transfer and as escalation.
|
||||
|
||||
This is how all messaging support system works, and how WeChat business accounts work, but no messenger provides it.
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# Chat bots UI
|
||||
|
||||
## Problem
|
||||
|
||||
Chat bots are a simple way to increase utility of the network, as it helps other people to create value by providing arbitrary services via chat interface.
|
||||
|
||||
Interacting with chat bots requires structured commands, which require entering them correctly, similarly how people do it in the terminal, and for most users it's hard.
|
||||
|
||||
## Solution
|
||||
|
||||
### Bot commands
|
||||
|
||||
As commands should be recognized based on their syntax, the same list of commands should be accepted irrespective of the conversation state. In cases commands cannot be executed, for any reason, bot would respond with the message.
|
||||
|
||||
The bot profile is probably the best place to include supported commands, in the form of a menu tree. See the schema.
|
||||
|
||||
The downside of communicating commands via profile is that they may change per contact or per group. The place to put commands would be chat preferences, which also makes sense - receiving commands is "the preference" of the bot. This preference would indicate that bot supports commands, and also which commands are supported with any additional information.
|
||||
|
||||
This menu will be shown to the end users in the app when they type "/" character in the first position of after several spaces. When the user chooses command from the menu, it will be inserted into the entry field for further editing. The placeholders for parameter should be inserted as "<name>". Clients may offer some interaction for filling parameters in, but in MVP it is sufficient to let users edit them directly.
|
||||
|
||||
When processing commands bots should ignore leading and trailing spaces in the user messages.
|
||||
|
||||
### Interactive dialogues with buttons
|
||||
|
||||
A special message sent by chat bot that would show a modal UI requiring to choose one of several presented options. These options should contain the text visible to the user with an optional emoji or action icon. The clients may automatically use icons for known words.
|
||||
|
||||
When this message is received, the compose area is either replaced with or complemented (if the context allows a free text entry in response) with one or several buttons, either located in a row, with wrapping, or in a column.
|
||||
|
||||
When the response is sent, the chosen text is sent, possibly as a reply to the original message, and the original message can be looked at to show which choices it offered in message information pane. There could be slightly different design or some marker to indicate that it was a message that offered multiple choices, and it could be updated to indicate it was replied to.
|
||||
|
||||
The clients probably should not show client messages as replies. There are 3 options here:
|
||||
- show as a normal reply. This avoids any ambiguity in the conversation history, and may protect customers from misbehaving bots - the message would be visually attached to the question.
|
||||
- simply do not show reply in the conversation, but use replies in the protocol.
|
||||
- use some other marker in the protocol.
|
||||
|
||||
I prefer sending and showing normal replies in these cases, as it avoids any ambiguity in the transcript about which question the choices were offered for. That means that bots should support replies, not only normal messages.
|
||||
|
||||
For protocol design we have three options:
|
||||
- a completely different message content constructor,
|
||||
- an extension to x.msg.new message instructing the bot to show button,
|
||||
- a normal message where all information would be present in the message text so it could be correctly presented by the old clients, with additional property that would be interpreted by the new clients so that it can parse the message text to present it as a multiple choice.
|
||||
- the bots can send a normal message to the old clients with a different message to the new clients, and it can be abstracted by the bot library.
|
||||
|
||||
The last option where the bot sends text message to the old clients and structured message to the new clients seems the most reasonable, as it avoids the need to parse texts, while preserves backward compatibility without complicating code for bot developers.
|
||||
|
||||
### Protocol
|
||||
|
||||
Add to message container an optional property `dialog`, an object with these properties:
|
||||
|
||||
- `choices`: required property with an array of choices presented as buttons, with required property `text` and optional properties `tag`, `role`, `icon`.
|
||||
- `layout`: "row" or "column" (default). "column" layout could use standard confirmation dialogue to present choices on iOS (although it should not be modal, and should allow scrolling the conversation, but not replying or sending messages).
|
||||
- `allow`: an object showing possible arbitrary message responses, currently only `text` property is allowed with `false` (default) or `true` value. Because button responses are just text messages, if free text is allowed, and user sends the same text as button, with or without surrounding spaces, the bots should interpret them in the same way.
|
||||
|
||||
See the schema in the protocol schema document.
|
||||
Reference in new issue
Block a user