From 8ebc8894de07a27816164f1ef8bb927b8a7f5f42 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sun, 11 Jan 2026 16:57:15 +0000 Subject: [PATCH] bots api: fix typescript code, add start/stop commands (#6565) --- bots/api/COMMANDS.md | 162 ++++++++++++------ bots/api/EVENTS.md | 2 +- bots/api/TYPES.md | 2 +- bots/src/API/Docs/Commands.hs | 20 ++- bots/src/API/Docs/Events.hs | 2 +- bots/src/API/Docs/Generate.hs | 2 +- bots/src/API/Docs/Generate/TypeScript.hs | 12 +- bots/src/API/Docs/Responses.hs | 8 +- bots/src/API/Docs/Syntax.hs | 6 +- .../types/typescript/package.json | 2 +- .../types/typescript/src/commands.ts | 53 ++++-- .../types/typescript/src/responses.ts | 18 ++ .../types/typescript/src/types.ts | 2 +- 13 files changed, 200 insertions(+), 91 deletions(-) diff --git a/bots/api/COMMANDS.md b/bots/api/COMMANDS.md index f3bb915665..b408d8eb30 100644 --- a/bots/api/COMMANDS.md +++ b/bots/api/COMMANDS.md @@ -60,6 +60,10 @@ This file is generated automatically. - [APIUpdateProfile](#apiupdateprofile) - [APISetContactPrefs](#apisetcontactprefs) +[Chat management](#chat-management) +- [StartChat](#startchat) +- [APIStopChat](#apistopchat) + --- @@ -98,7 +102,7 @@ UserContactLinkCreated: User contact address created. - user: [User](./TYPES.md#user) - connLinkContact: [CreatedConnLink](./TYPES.md#createdconnlink) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -134,7 +138,7 @@ UserContactLinkDeleted: User contact address deleted. - type: "userContactLinkDeleted" - user: [User](./TYPES.md#user) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -171,7 +175,7 @@ UserContactLink: User contact address. - user: [User](./TYPES.md#user) - contactLink: [UserContactLink](./TYPES.md#usercontactlink) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -211,7 +215,7 @@ UserProfileUpdated: User profile updated. - toProfile: [Profile](./TYPES.md#profile) - updateSummary: [UserProfileUpdateSummary](./TYPES.md#userprofileupdatesummary) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -249,7 +253,7 @@ UserContactLinkUpdated: User contact address updated. - user: [User](./TYPES.md#user) - contactLink: [UserContactLink](./TYPES.md#usercontactlink) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -280,7 +284,7 @@ Send messages. ``` ```javascript -'/_send ' + sendRef.toString() + (liveMessage ? ' live=on' : '') + (ttl ? ' ttl=' + ttl : '') + ' json ' + JSON.stringify(composedMessages) // JavaScript +'/_send ' + ChatRef.cmdString(sendRef) + (liveMessage ? ' live=on' : '') + (ttl ? ' ttl=' + ttl : '') + ' json ' + JSON.stringify(composedMessages) // JavaScript ``` ```python @@ -294,7 +298,7 @@ NewChatItems: New messages. - user: [User](./TYPES.md#user) - chatItems: [[AChatItem](./TYPES.md#achatitem)] -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -320,7 +324,7 @@ Update message. ``` ```javascript -'/_update item ' + chatRef.toString() + ' ' + chatItemId + (liveMessage ? ' live=on' : '') + ' json ' + JSON.stringify(updatedMessage) // JavaScript +'/_update item ' + ChatRef.cmdString(chatRef) + ' ' + chatItemId + (liveMessage ? ' live=on' : '') + ' json ' + JSON.stringify(updatedMessage) // JavaScript ``` ```python @@ -339,7 +343,7 @@ ChatItemNotChanged: Message not changed. - user: [User](./TYPES.md#user) - chatItem: [AChatItem](./TYPES.md#achatitem) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -367,7 +371,7 @@ Delete message. ``` ```javascript -'/_delete item ' + chatRef.toString() + ' ' + chatItemIds.join(',') + ' ' + deleteMode // JavaScript +'/_delete item ' + ChatRef.cmdString(chatRef) + ' ' + chatItemIds.join(',') + ' ' + deleteMode // JavaScript ``` ```python @@ -383,7 +387,7 @@ ChatItemsDeleted: Messages deleted. - byUser: bool - timed: bool -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -423,7 +427,7 @@ ChatItemsDeleted: Messages deleted. - byUser: bool - timed: bool -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -449,7 +453,7 @@ Add/remove message reaction. ``` ```javascript -'/_reaction ' + chatRef.toString() + ' ' + chatItemId + ' ' + (add ? 'on' : 'off') + ' ' + JSON.stringify(reaction) // JavaScript +'/_reaction ' + ChatRef.cmdString(chatRef) + ' ' + chatItemId + ' ' + (add ? 'on' : 'off') + ' ' + JSON.stringify(reaction) // JavaScript ``` ```python @@ -464,7 +468,7 @@ ChatItemReaction: Message reaction. - added: bool - reaction: [ACIReaction](./TYPES.md#acireaction) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -515,7 +519,7 @@ RcvFileAcceptedSndCancelled: File accepted, but no longer sent. - user: [User](./TYPES.md#user) - rcvFileTransfer: [RcvFileTransfer](./TYPES.md#rcvfiletransfer) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -560,7 +564,7 @@ RcvFileCancelled: Cancelled receiving file. - chatItem_: [AChatItem](./TYPES.md#achatitem)? - rcvFileTransfer: [RcvFileTransfer](./TYPES.md#rcvfiletransfer) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -609,7 +613,7 @@ SentGroupInvitation: Group invitation sent. - contact: [Contact](./TYPES.md#contact) - member: [GroupMember](./TYPES.md#groupmember) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -647,7 +651,7 @@ UserAcceptedGroupSent: User accepted group invitation. - groupInfo: [GroupInfo](./TYPES.md#groupinfo) - hostContact: [Contact](./TYPES.md#contact)? -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -687,7 +691,7 @@ MemberAccepted: Member accepted to group. - groupInfo: [GroupInfo](./TYPES.md#groupinfo) - member: [GroupMember](./TYPES.md#groupmember) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -731,7 +735,7 @@ MembersRoleUser: Members role changed by user. - members: [[GroupMember](./TYPES.md#groupmember)] - toRole: [GroupMemberRole](./TYPES.md#groupmemberrole) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -772,7 +776,7 @@ MembersBlockedForAllUser: Members blocked for all by admin. - members: [[GroupMember](./TYPES.md#groupmember)] - blocked: bool -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -813,7 +817,7 @@ UserDeletedMembers: Members deleted. - members: [[GroupMember](./TYPES.md#groupmember)] - withMessages: bool -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -853,7 +857,7 @@ LeftMemberUser: User left group. - user: [User](./TYPES.md#user) - groupInfo: [GroupInfo](./TYPES.md#groupinfo) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -890,7 +894,7 @@ GroupMembers: Group members. - user: [User](./TYPES.md#user) - group: [Group](./TYPES.md#group) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -929,7 +933,7 @@ GroupCreated: Group created. - user: [User](./TYPES.md#user) - groupInfo: [GroupInfo](./TYPES.md#groupinfo) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -969,7 +973,7 @@ GroupUpdated: Group updated. - toGroup: [GroupInfo](./TYPES.md#groupinfo) - member_: [GroupMember](./TYPES.md#groupmember)? -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1013,7 +1017,7 @@ GroupLinkCreated: Group link created. - groupInfo: [GroupInfo](./TYPES.md#groupinfo) - groupLink: [GroupLink](./TYPES.md#grouplink) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1052,7 +1056,7 @@ GroupLink: Group link. - groupInfo: [GroupInfo](./TYPES.md#groupinfo) - groupLink: [GroupLink](./TYPES.md#grouplink) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1089,7 +1093,7 @@ GroupLinkDeleted: Group link deleted. - user: [User](./TYPES.md#user) - groupInfo: [GroupInfo](./TYPES.md#groupinfo) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1127,7 +1131,7 @@ GroupLink: Group link. - groupInfo: [GroupInfo](./TYPES.md#groupinfo) - groupLink: [GroupLink](./TYPES.md#grouplink) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1171,7 +1175,7 @@ Invitation: One-time invitation. - connLinkInvitation: [CreatedConnLink](./TYPES.md#createdconnlink) - connection: [PendingContactConnection](./TYPES.md#pendingcontactconnection) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1210,7 +1214,7 @@ ConnectionPlan: Connection link information. - connLink: [CreatedConnLink](./TYPES.md#createdconnlink) - connectionPlan: [ConnectionPlan](./TYPES.md#connectionplan) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1219,7 +1223,7 @@ ChatCmdError: Command error. ### APIConnect -Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link +Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link. *Network usage*: interactive. @@ -1235,7 +1239,7 @@ Connect via prepared SimpleX link. The link can be 1-time invitation link, conta ``` ```javascript -'/_connect ' + userId + (preparedLink_ ? ' ' + preparedLink_.toString() : '') // JavaScript +'/_connect ' + userId + (preparedLink_ ? ' ' + CreatedConnLink.cmdString(preparedLink_) : '') // JavaScript ``` ```python @@ -1261,7 +1265,7 @@ SentInvitation: Invitation sent to contact address. - connection: [PendingContactConnection](./TYPES.md#pendingcontactconnection) - customUserProfile: [Profile](./TYPES.md#profile)? -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1311,7 +1315,7 @@ SentInvitation: Invitation sent to contact address. - connection: [PendingContactConnection](./TYPES.md#pendingcontactconnection) - customUserProfile: [Profile](./TYPES.md#profile)? -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1348,7 +1352,7 @@ AcceptingContactRequest: Contact request accepted. - user: [User](./TYPES.md#user) - contact: [Contact](./TYPES.md#contact) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1386,7 +1390,7 @@ ContactRequestRejected: Contact request rejected. - contactRequest: [UserContactRequest](./TYPES.md#usercontactrequest) - contact_: [Contact](./TYPES.md#contact)? -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1428,7 +1432,7 @@ ContactsList: Contacts. - user: [User](./TYPES.md#user) - contacts: [[Contact](./TYPES.md#contact)] -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1467,7 +1471,7 @@ GroupsList: Groups. - user: [User](./TYPES.md#user) - groups: [[GroupInfo](./TYPES.md#groupinfo)] -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1491,7 +1495,7 @@ Delete chat. ``` ```javascript -'/_delete ' + chatRef.toString() + ' ' + chatDeleteMode.toString() // JavaScript +'/_delete ' + ChatRef.cmdString(chatRef) + ' ' + ChatDeleteMode.cmdString(chatDeleteMode) // JavaScript ``` ```python @@ -1515,7 +1519,7 @@ GroupDeletedUser: User deleted group. - user: [User](./TYPES.md#user) - groupInfo: [GroupInfo](./TYPES.md#groupinfo) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1529,7 +1533,7 @@ Most bots don't need to use these commands, as bot profile can be configured man ### ShowActiveUser -Get active user profile +Get active user profile. *Network usage*: no. @@ -1545,7 +1549,7 @@ ActiveUser: Active user profile. - type: "activeUser" - user: [User](./TYPES.md#user) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1554,7 +1558,7 @@ ChatCmdError: Command error. ### CreateActiveUser -Create new user profile +Create new user profile. *Network usage*: no. @@ -1581,7 +1585,7 @@ ActiveUser: Active user profile. - type: "activeUser" - user: [User](./TYPES.md#user) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1594,7 +1598,7 @@ ChatCmdError: Command error. ### ListUsers -Get all user profiles +Get all user profiles. *Network usage*: no. @@ -1610,7 +1614,7 @@ UsersList: Users. - type: "usersList" - users: [[UserInfo](./TYPES.md#userinfo)] -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1619,7 +1623,7 @@ ChatCmdError: Command error. ### APISetActiveUser -Set active user profile +Set active user profile. *Network usage*: no. @@ -1647,7 +1651,7 @@ ActiveUser: Active user profile. - type: "activeUser" - user: [User](./TYPES.md#user) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1688,7 +1692,7 @@ CmdOk: Ok. - type: "cmdOk" - user_: [User](./TYPES.md#user)? -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1732,7 +1736,7 @@ UserProfileNoChange: User profile was not changed. - type: "userProfileNoChange" - user: [User](./TYPES.md#user) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) @@ -1771,8 +1775,60 @@ ContactPrefsUpdated: Contact preferences updated. - fromContact: [Contact](./TYPES.md#contact) - toContact: [Contact](./TYPES.md#contact) -ChatCmdError: Command error. +ChatCmdError: Command error (only used in WebSockets API). - type: "chatCmdError" - chatError: [ChatError](./TYPES.md#chaterror) --- + + +## Chat management + +These commands should not be used with CLI-based bots + + +### StartChat + +Start chat controller. + +*Network usage*: no. + +**Parameters**: +- mainApp: bool +- enableSndFiles: bool + +**Syntax**: + +``` +/_start +``` + +**Responses**: + +ChatStarted: Chat started. +- type: "chatStarted" + +ChatRunning: Chat running. +- type: "chatRunning" + +--- + + +### APIStopChat + +Stop chat controller. + +*Network usage*: no. + +**Syntax**: + +``` +/_stop +``` + +**Response**: + +ChatStopped: Chat stopped. +- type: "chatStopped" + +--- diff --git a/bots/api/EVENTS.md b/bots/api/EVENTS.md index a77747482f..84f59e7405 100644 --- a/bots/api/EVENTS.md +++ b/bots/api/EVENTS.md @@ -705,7 +705,7 @@ Message error. ### ChatError -Chat error. +Chat error (only used in WebSockets API). **Record type**: - type: "chatError" diff --git a/bots/api/TYPES.md b/bots/api/TYPES.md index 62c5dff3b5..1aaa291204 100644 --- a/bots/api/TYPES.md +++ b/bots/api/TYPES.md @@ -1309,7 +1309,7 @@ Used in API commands. Chat scope can only be passed with groups. ``` ```javascript -chatType.toString() + chatId + (chatScope ? chatScope.toString() : '') // JavaScript +ChatType.cmdString(chatType) + chatId + (chatScope ? GroupChatScope.cmdString(chatScope) : '') // JavaScript ``` ```python diff --git a/bots/src/API/Docs/Commands.hs b/bots/src/API/Docs/Commands.hs index 41e8cdf019..35745f9b42 100644 --- a/bots/src/API/Docs/Commands.hs +++ b/bots/src/API/Docs/Commands.hs @@ -72,7 +72,7 @@ instance IsString ErrorTypeDoc where fromString s = TD s "" -- category name, category description, commands --- inner: constructor, description, responses, errors (ChatErrorType constructors), network usage, syntax +-- inner: constructor, hidden params, description, responses, errors (ChatErrorType constructors), network usage, syntax chatCommandsDocsData :: [(String, String, [(ConsName, [String], Text, [ConsName], [ErrorTypeDoc], Maybe UsesNetwork, Expr)])] chatCommandsDocsData = [ ( "Address commands", @@ -132,7 +132,7 @@ chatCommandsDocsData = "These commands may be used to create connections. Most bots do not need to use them - bot users will connect via bot address with auto-accept enabled.", [ ("APIAddContact", [], "Create 1-time invitation link.", ["CRInvitation", "CRChatCmdError"], [], Just UNInteractive, "/_connect " <> Param "userId" <> OnOffParam "incognito" "incognito" (Just False)), ("APIConnectPlan", [], "Determine SimpleX link type and if the bot is already connected via this link.", ["CRConnectionPlan", "CRChatCmdError"], [], Just UNInteractive, "/_connect plan " <> Param "userId" <> " " <> Param "connectionLink"), - ("APIConnect", [], "Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link", ["CRSentConfirmation", "CRContactAlreadyExists", "CRSentInvitation", "CRChatCmdError"], [], Just UNInteractive, "/_connect " <> Param "userId" <> Optional "" (" " <> Param "$0") "preparedLink_"), + ("APIConnect", [], "Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link.", ["CRSentConfirmation", "CRContactAlreadyExists", "CRSentInvitation", "CRChatCmdError"], [], Just UNInteractive, "/_connect " <> Param "userId" <> Optional "" (" " <> Param "$0") "preparedLink_"), ("Connect", [], "Connect via SimpleX link as string in the active user profile.", ["CRSentConfirmation", "CRContactAlreadyExists", "CRSentInvitation", "CRChatCmdError"], [], Just UNInteractive, "/connect" <> Optional "" (" " <> Param "$0") "connLink_"), ("APIAcceptContact", ["incognito"], "Accept contact request.", ["CRAcceptingContactRequest", "CRChatCmdError"], [], Just UNInteractive, "/_accept " <> Param "contactReqId"), ("APIRejectContact", [], "Reject contact request. The user who sent the request is **not notified**.", ["CRContactRequestRejected", "CRChatCmdError"], [], Nothing, "/_reject " <> Param "contactReqId") @@ -163,21 +163,27 @@ chatCommandsDocsData = ), ( "User profile commands", "Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents).", - [ ("ShowActiveUser", [], "Get active user profile", ["CRActiveUser", "CRChatCmdError"], [], Nothing, "/user"), + [ ("ShowActiveUser", [], "Get active user profile.", ["CRActiveUser", "CRChatCmdError"], [], Nothing, "/user"), ( "CreateActiveUser", [], - "Create new user profile", + "Create new user profile.", ["CRActiveUser", "CRChatCmdError"], [TD "CEUserExists" "User or contact with this name already exists", TD "CEInvalidDisplayName" "Invalid user display name"], Nothing, "/_create user " <> Json "newUser" ), - ("ListUsers", [], "Get all user profiles", ["CRUsersList", "CRChatCmdError"], [], Nothing, "/users"), - ("APISetActiveUser", [], "Set active user profile", ["CRActiveUser", "CRChatCmdError"], ["CEChatNotStarted"], Nothing, "/_user " <> Param "userId" <> Optional "" (" " <> Json "$0") "viewPwd"), + ("ListUsers", [], "Get all user profiles.", ["CRUsersList", "CRChatCmdError"], [], Nothing, "/users"), + ("APISetActiveUser", [], "Set active user profile.", ["CRActiveUser", "CRChatCmdError"], ["CEChatNotStarted"], Nothing, "/_user " <> Param "userId" <> Optional "" (" " <> Json "$0") "viewPwd"), ("APIDeleteUser", [], "Delete user profile.", ["CRCmdOk", "CRChatCmdError"], [], Just UNBackground, "/_delete user " <> Param "userId" <> OnOffParam "del_smp" "delSMPQueues" Nothing <> Optional "" (" " <> Json "$0") "viewPwd"), ("APIUpdateProfile", [], "Update user profile.", ["CRUserProfileUpdated", "CRUserProfileNoChange", "CRChatCmdError"], [], Just UNBackground, "/_profile " <> Param "userId" <> " " <> Json "profile"), ("APISetContactPrefs", [], "Configure chat preference overrides for the contact.", ["CRContactPrefsUpdated", "CRChatCmdError"], [], Just UNBackground, "/_set prefs @" <> Param "contactId" <> " " <> Json "preferences") ] + ), + ( "Chat management", + "These commands should not be used with CLI-based bots", + [ ("StartChat", [], "Start chat controller.", ["CRChatStarted", "CRChatRunning"], [], Nothing, "/_start"), + ("APIStopChat", [], "Stop chat controller.", ["CRChatStopped"], [], Nothing, "/_stop") + ] ) ] @@ -396,7 +402,6 @@ undocumentedCommands = "APISetUserServers", "APISetUserUIThemes", "APIStandaloneFileInfo", - "APIStopChat", "APIStorageEncryption", "APISuspendChat", "APISwitchContact", @@ -453,7 +458,6 @@ undocumentedCommands = "SetTempFolder", "SetUserProtoServers", "SlowSQLQueries", - "StartChat", "StartRemoteHost", "StopRemoteCtrl", "StopRemoteHost", diff --git a/bots/src/API/Docs/Events.hs b/bots/src/API/Docs/Events.hs index 4a49551a54..ecb8a5ba04 100644 --- a/bots/src/API/Docs/Events.hs +++ b/bots/src/API/Docs/Events.hs @@ -143,7 +143,7 @@ chatEventsDocsData = \or because messages may be delivered to deleted chats for a short period of time \ \(they will be ignored).", [ ("CEvtMessageError", ""), - ("CEvtChatError", ""), -- only used in WebSockets API, Haskell code uses Either, with error in Left + ("CEvtChatError", "Chat error (only used in WebSockets API)."), -- Haskell code uses Either, with error in Left ("CEvtChatErrors", "") ], [] diff --git a/bots/src/API/Docs/Generate.hs b/bots/src/API/Docs/Generate.hs index 334ad93bad..99886bf222 100644 --- a/bots/src/API/Docs/Generate.hs +++ b/bots/src/API/Docs/Generate.hs @@ -73,7 +73,7 @@ syntaxText :: TypeAndFields -> Expr -> Text syntaxText r syntax = "\n**Syntax**:\n" <> "\n```\n" <> docSyntaxText r syntax <> "\n```\n" - <> (if isConst syntax then "" else "\n```javascript\n" <> jsSyntaxText False r syntax <> " // JavaScript\n```\n") + <> (if isConst syntax then "" else "\n```javascript\n" <> jsSyntaxText False "" r syntax <> " // JavaScript\n```\n") <> (if isConst syntax then "" else "\n```python\n" <> pySyntaxText r syntax <> " # Python\n```\n") camelToSpace :: String -> String diff --git a/bots/src/API/Docs/Generate/TypeScript.hs b/bots/src/API/Docs/Generate/TypeScript.hs index b69635086e..c3049c100d 100644 --- a/bots/src/API/Docs/Generate/TypeScript.hs +++ b/bots/src/API/Docs/Generate/TypeScript.hs @@ -49,7 +49,7 @@ commandsCodeText = <> "}\n\n" <> ("export namespace " <> T.pack constrName <> " {\n") <> (" export type Response = " <> constrsCode " " "CR" (("CR." <> ) . T.pack . fstToUpper . memberTag) (map responseType responses)) - <> (if syntax == "" then "" else funcCode APITypeDef {typeName' = constrName, typeDef = ATDRecord params} syntax) + <> (if syntax == "" then "" else funcCode APITypeDef {typeName' = constrName, typeDef = ATDRecord params} "T." syntax) <> "}\n" where constrName = fstToUpper tag @@ -86,7 +86,7 @@ typesCodeText = ("// API Types\n// " <> autoGenerated <> "\n") <> foldMap typeCo "ConnectionMode" -> T.pack $ map toUpper tag "FileProtocol" -> T.pack $ map toUpper tag _ -> T.replace "-" "_" $ T.pack $ fstToUpper tag - namespaceFuncCode = "\nexport namespace " <> name' <> " {" <> funcCode td typeSyntax <> "}\n" + namespaceFuncCode = "\nexport namespace " <> name' <> " {" <> funcCode td "" typeSyntax <> "}\n" typeDefCode = case typeDef of ATDRecord fields -> ("\nexport interface " <> name' <> " {\n") @@ -107,7 +107,7 @@ unionTypeCode unionNamespace typesNamespace td@APITypeDef {typeName' = name} cs <> (" export type Tag = " <> constrsCode " " name' constrTag (L.toList cs) <> "\n") <> (" interface Interface {\n type: Tag\n }\n") <> foldMap constrType cs - <> (if cmdSyntax == "" then "" else funcCode td cmdSyntax) + <> (if cmdSyntax == "" then "" else funcCode td typesNamespace cmdSyntax) <> "}\n" where name' = T.pack name @@ -128,9 +128,9 @@ constrsCode indent name' constr cs line = T.intercalate " | " cs' cs' = map constr cs -funcCode :: APITypeDef -> Expr -> Text -funcCode td@APITypeDef {typeName' = name, typeDef} cmdSyntax = - "\n export function cmdString(" <> param <> ": " <> T.pack name <> "): string {\n return " <> jsSyntaxText True (name, self : typeFields) cmdSyntax <> "\n }\n" +funcCode :: APITypeDef -> String -> Expr -> Text +funcCode td@APITypeDef {typeName' = name, typeDef} typeNamespace cmdSyntax = + "\n export function cmdString(" <> param <> ": " <> T.pack name <> "): string {\n return " <> jsSyntaxText True typeNamespace (name, self : typeFields) cmdSyntax <> "\n }\n" where param = if hasParams cmdSyntax then "self" else "_self" self = APIRecordField "self" (ATDef td) diff --git a/bots/src/API/Docs/Responses.hs b/bots/src/API/Docs/Responses.hs index c52b288603..60fe129cdb 100644 --- a/bots/src/API/Docs/Responses.hs +++ b/bots/src/API/Docs/Responses.hs @@ -51,8 +51,11 @@ chatResponsesDocsData = ("CRChatItemReaction", "Message reaction"), ("CRChatItemUpdated", "Message updated"), ("CRChatItemsDeleted", "Messages deleted"), + ("CRChatRunning", ""), + ("CRChatStarted", ""), + ("CRChatStopped", ""), ("CRCmdOk", "Ok"), - ("CRChatCmdError", "Command error"), -- only used in WebSockets API, Haskell code uses Either, with error in Left + ("CRChatCmdError", "Command error (only used in WebSockets API)"), -- Haskell code uses Either, with error in Left ("CRConnectionPlan", "Connection link information"), ("CRContactAlreadyExists", ""), ("CRContactConnectionDeleted", "Connection deleted"), @@ -127,10 +130,7 @@ undocumentedResponses = "CRChatItemInfo", "CRChatItems", "CRChatItemTTL", - "CRChatRunning", "CRChats", - "CRChatStarted", - "CRChatStopped", "CRConnectionsDiff", "CRChatTags", "CRConnectionAliasUpdated", diff --git a/bots/src/API/Docs/Syntax.hs b/bots/src/API/Docs/Syntax.hs index 83fa2bf6a2..f96ec03b02 100644 --- a/bots/src/API/Docs/Syntax.hs +++ b/bots/src/API/Docs/Syntax.hs @@ -99,8 +99,8 @@ withOptBoolParam r param p f = (ATOptional (ATPrim (PT TBool))) -> f True _ -> paramError r param p "is not [optional] boolean" -jsSyntaxText :: Bool -> TypeAndFields -> Expr -> Text -jsSyntaxText useSelf r = T.replace "' + '" "" . T.pack . go Nothing True +jsSyntaxText :: Bool -> String -> TypeAndFields -> Expr -> Text +jsSyntaxText useSelf typeNamespace r = T.replace "' + '" "" . T.pack . go Nothing True where go param top = \case Concat exs -> intercalate " + " $ map (go param False) $ L.toList exs @@ -112,7 +112,7 @@ jsSyntaxText useSelf r = T.replace "' + '" "" . T.pack . go Nothing True _ -> paramName' useSelf param p where toStringSyntax (APITypeDef typeName _) - | typeHasSyntax typeName = paramName' useSelf param p <> ".toString()" + | typeHasSyntax typeName = typeNamespace <> typeName <> ".cmdString(" <> paramName' useSelf param p <> ")" | otherwise = paramName' useSelf param p Optional exN exJ p -> open <> n <> " ? " <> go (Just p) False exJ <> " : " <> nothing <> close where diff --git a/packages/simplex-chat-client/types/typescript/package.json b/packages/simplex-chat-client/types/typescript/package.json index 1bf593b483..c24b93fbed 100644 --- a/packages/simplex-chat-client/types/typescript/package.json +++ b/packages/simplex-chat-client/types/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@simplex-chat/types", - "version": "0.1.0", + "version": "0.2.0", "description": "TypeScript types for SimpleX Chat bot libraries", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/simplex-chat-client/types/typescript/src/commands.ts b/packages/simplex-chat-client/types/typescript/src/commands.ts index de6a7a7ce1..66f4f6ec5f 100644 --- a/packages/simplex-chat-client/types/typescript/src/commands.ts +++ b/packages/simplex-chat-client/types/typescript/src/commands.ts @@ -96,7 +96,7 @@ export namespace APISendMessages { export type Response = CR.NewChatItems | CR.ChatCmdError export function cmdString(self: APISendMessages): string { - return '/_send ' + self.sendRef.toString() + (self.liveMessage ? ' live=on' : '') + (self.ttl ? ' ttl=' + self.ttl : '') + ' json ' + JSON.stringify(self.composedMessages) + return '/_send ' + T.ChatRef.cmdString(self.sendRef) + (self.liveMessage ? ' live=on' : '') + (self.ttl ? ' ttl=' + self.ttl : '') + ' json ' + JSON.stringify(self.composedMessages) } } @@ -113,7 +113,7 @@ export namespace APIUpdateChatItem { export type Response = CR.ChatItemUpdated | CR.ChatItemNotChanged | CR.ChatCmdError export function cmdString(self: APIUpdateChatItem): string { - return '/_update item ' + self.chatRef.toString() + ' ' + self.chatItemId + (self.liveMessage ? ' live=on' : '') + ' json ' + JSON.stringify(self.updatedMessage) + return '/_update item ' + T.ChatRef.cmdString(self.chatRef) + ' ' + self.chatItemId + (self.liveMessage ? ' live=on' : '') + ' json ' + JSON.stringify(self.updatedMessage) } } @@ -129,7 +129,7 @@ export namespace APIDeleteChatItem { export type Response = CR.ChatItemsDeleted | CR.ChatCmdError export function cmdString(self: APIDeleteChatItem): string { - return '/_delete item ' + self.chatRef.toString() + ' ' + self.chatItemIds.join(',') + ' ' + self.deleteMode + return '/_delete item ' + T.ChatRef.cmdString(self.chatRef) + ' ' + self.chatItemIds.join(',') + ' ' + self.deleteMode } } @@ -161,7 +161,7 @@ export namespace APIChatItemReaction { export type Response = CR.ChatItemReaction | CR.ChatCmdError export function cmdString(self: APIChatItemReaction): string { - return '/_reaction ' + self.chatRef.toString() + ' ' + self.chatItemId + ' ' + (self.add ? 'on' : 'off') + ' ' + JSON.stringify(self.reaction) + return '/_reaction ' + T.ChatRef.cmdString(self.chatRef) + ' ' + self.chatItemId + ' ' + (self.add ? 'on' : 'off') + ' ' + JSON.stringify(self.reaction) } } @@ -450,7 +450,7 @@ export namespace APIConnectPlan { } } -// Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link +// Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link. // Network usage: interactive. export interface APIConnect { userId: number // int64 @@ -462,7 +462,7 @@ export namespace APIConnect { export type Response = CR.SentConfirmation | CR.ContactAlreadyExists | CR.SentInvitation | CR.ChatCmdError export function cmdString(self: APIConnect): string { - return '/_connect ' + self.userId + (self.preparedLink_ ? ' ' + self.preparedLink_.toString() : '') + return '/_connect ' + self.userId + (self.preparedLink_ ? ' ' + T.CreatedConnLink.cmdString(self.preparedLink_) : '') } } @@ -553,14 +553,14 @@ export namespace APIDeleteChat { export type Response = CR.ContactDeleted | CR.ContactConnectionDeleted | CR.GroupDeletedUser | CR.ChatCmdError export function cmdString(self: APIDeleteChat): string { - return '/_delete ' + self.chatRef.toString() + ' ' + self.chatDeleteMode.toString() + return '/_delete ' + T.ChatRef.cmdString(self.chatRef) + ' ' + T.ChatDeleteMode.cmdString(self.chatDeleteMode) } } // User profile commands // Most bots don't need to use these commands, as bot profile can be configured manually via CLI or desktop client. These commands can be used by bots that need to manage multiple user profiles (e.g., the profiles of support agents). -// Get active user profile +// Get active user profile. // Network usage: no. export interface ShowActiveUser { } @@ -573,7 +573,7 @@ export namespace ShowActiveUser { } } -// Create new user profile +// Create new user profile. // Network usage: no. export interface CreateActiveUser { newUser: T.NewUser @@ -587,7 +587,7 @@ export namespace CreateActiveUser { } } -// Get all user profiles +// Get all user profiles. // Network usage: no. export interface ListUsers { } @@ -600,7 +600,7 @@ export namespace ListUsers { } } -// Set active user profile +// Set active user profile. // Network usage: no. export interface APISetActiveUser { userId: number // int64 @@ -660,3 +660,34 @@ export namespace APISetContactPrefs { return '/_set prefs @' + self.contactId + ' ' + JSON.stringify(self.preferences) } } + +// Chat management +// These commands should not be used with CLI-based bots + +// Start chat controller. +// Network usage: no. +export interface StartChat { + mainApp: boolean + enableSndFiles: boolean +} + +export namespace StartChat { + export type Response = CR.ChatStarted | CR.ChatRunning + + export function cmdString(_self: StartChat): string { + return '/_start' + } +} + +// Stop chat controller. +// Network usage: no. +export interface APIStopChat { +} + +export namespace APIStopChat { + export type Response = CR.ChatStopped + + export function cmdString(_self: APIStopChat): string { + return '/_stop' + } +} diff --git a/packages/simplex-chat-client/types/typescript/src/responses.ts b/packages/simplex-chat-client/types/typescript/src/responses.ts index ea49478b15..684aeec7af 100644 --- a/packages/simplex-chat-client/types/typescript/src/responses.ts +++ b/packages/simplex-chat-client/types/typescript/src/responses.ts @@ -10,6 +10,9 @@ export type ChatResponse = | CR.ChatItemReaction | CR.ChatItemUpdated | CR.ChatItemsDeleted + | CR.ChatRunning + | CR.ChatStarted + | CR.ChatStopped | CR.CmdOk | CR.ChatCmdError | CR.ConnectionPlan @@ -58,6 +61,9 @@ export namespace CR { | "chatItemReaction" | "chatItemUpdated" | "chatItemsDeleted" + | "chatRunning" + | "chatStarted" + | "chatStopped" | "cmdOk" | "chatCmdError" | "connectionPlan" @@ -140,6 +146,18 @@ export namespace CR { timed: boolean } + export interface ChatRunning extends Interface { + type: "chatRunning" + } + + export interface ChatStarted extends Interface { + type: "chatStarted" + } + + export interface ChatStopped extends Interface { + type: "chatStopped" + } + export interface CmdOk extends Interface { type: "cmdOk" user_?: T.User diff --git a/packages/simplex-chat-client/types/typescript/src/types.ts b/packages/simplex-chat-client/types/typescript/src/types.ts index 5e3309238b..bca0179a91 100644 --- a/packages/simplex-chat-client/types/typescript/src/types.ts +++ b/packages/simplex-chat-client/types/typescript/src/types.ts @@ -1552,7 +1552,7 @@ export interface ChatRef { export namespace ChatRef { export function cmdString(self: ChatRef): string { - return self.chatType.toString() + self.chatId + (self.chatScope ? self.chatScope.toString() : '') + return ChatType.cmdString(self.chatType) + self.chatId + (self.chatScope ? GroupChatScope.cmdString(self.chatScope) : '') } }