bots: add APIs (#7494)

* docs: fix bot API surface

- Fix missing space in APIShareMyAddress syntax expression which
  resulted in parse errors

- Document missing `Connect` responses: `CRConnectionPlan`, `CRSentInvitationToContact`,
  `CRStartedConnectionToContact`, and `CRStartedConnectionToGroup` (relay channel links).

- Document missing `CRUserProfileNoChange` responsed returned when `APISetProfileAddress` doesn't change the profile.

- Expose remote control APIs to bots

* website: improve sign-up forms (#7484)

* website: improve sign-up forms

* name

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* rename field

* generic

---------

Co-authored-by: a1akris <alkrivitskiy@pm.me>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny
2026-09-12 14:13:11 +01:00
committed by GitHub
co-authored by Evgeny @ SimpleX Chat a1akris
parent 9631e0b1b9
commit 47d32b674a
17 changed files with 661 additions and 26 deletions
+118 -3
View File
@@ -79,6 +79,10 @@ This file is generated automatically.
- [StartChat](#startchat)
- [APIStopChat](#apistopchat)
[Remote control commands](#remote-control-commands)
- [ConnectRemoteCtrl](#connectremotectrl)
- [VerifyRemoteCtrlSession](#verifyremotectrlsession)
---
@@ -231,6 +235,10 @@ UserProfileUpdated: User profile updated.
- toProfile: [Profile](./TYPES.md#profile)
- updateSummary: [UserProfileUpdateSummary](./TYPES.md#userprofileupdatesummary)
UserProfileNoChange: User profile was not changed.
- type: "userProfileNoChange"
- user: [User](./TYPES.md#user)
ChatCmdError: Command error (only used in WebSockets API).
- type: "chatCmdError"
- chatError: [ChatError](./TYPES.md#chaterror)
@@ -505,15 +513,15 @@ Share user address card
**Syntax**:
```
/_share address<str(toSendRef)>
/_share address <str(toSendRef)>
```
```javascript
'/_share address' + ChatRef.cmdString(toSendRef) // JavaScript
'/_share address ' + ChatRef.cmdString(toSendRef) // JavaScript
```
```python
'/_share address' + ChatRef_cmd_string(toSendRef) # Python
'/_share address ' + ChatRef_cmd_string(toSendRef) # Python
```
**Response**:
@@ -1609,6 +1617,33 @@ SentInvitation: Invitation sent to contact address.
- connection: [PendingContactConnection](./TYPES.md#pendingcontactconnection)
- customUserProfile: [Profile](./TYPES.md#profile)?
ConnectionPlan: Connection link information.
- type: "connectionPlan"
- user: [User](./TYPES.md#user)
- connLink: [CreatedConnLink](./TYPES.md#createdconnlink)
- planSimplexName: [SimplexNameInfo](./TYPES.md#simplexnameinfo)?
- otherSimplexName: [SimplexNameInfo](./TYPES.md#simplexnameinfo)?
- connectionPlan: [ConnectionPlan](./TYPES.md#connectionplan)
SentInvitationToContact: Invitation sent to contact (when connecting via SimpleX name to a known contact address)..
- type: "sentInvitationToContact"
- user: [User](./TYPES.md#user)
- contact: [Contact](./TYPES.md#contact)
- customUserProfile: [Profile](./TYPES.md#profile)?
StartedConnectionToContact: Connection to contact started (when connecting via prepared contact)..
- type: "startedConnectionToContact"
- user: [User](./TYPES.md#user)
- contact: [Contact](./TYPES.md#contact)
- customUserProfile: [Profile](./TYPES.md#profile)?
StartedConnectionToGroup: Connection to channel started (when connecting via channel link)..
- type: "startedConnectionToGroup"
- user: [User](./TYPES.md#user)
- groupInfo: [GroupInfo](./TYPES.md#groupinfo)
- customUserProfile: [Profile](./TYPES.md#profile)?
- relayResults: [[RelayConnectionResult](./TYPES.md#relayconnectionresult)]
ChatCmdError: Command error (only used in WebSockets API).
- type: "chatCmdError"
- chatError: [ChatError](./TYPES.md#chaterror)
@@ -2370,3 +2405,83 @@ ChatStopped: Chat stopped.
- type: "chatStopped"
---
## Remote control commands
Allows a bot to accept an incoming remote control session from a SimpleX Desktop client, giving the desktop live access to the bot's SimpleX instance.
### ConnectRemoteCtrl
Connect to a remote controller using an OOB invitation link.
*Network usage*: interactive.
**Parameters**:
- remoteInvitation: string
**Syntax**:
```
/crc <remoteInvitation>
```
```javascript
'/crc ' + remoteInvitation // JavaScript
```
```python
'/crc ' + remoteInvitation # Python
```
**Responses**:
RemoteCtrlConnecting: Remote controller is connecting..
- type: "remoteCtrlConnecting"
- remoteCtrl_: [RemoteCtrlInfo](./TYPES.md#remotectrlinfo)?
- ctrlAppInfo: [CtrlAppInfo](./TYPES.md#ctrlappinfo)
- appVersion: string
ChatCmdError: Command error (only used in WebSockets API).
- type: "chatCmdError"
- chatError: [ChatError](./TYPES.md#chaterror)
---
### VerifyRemoteCtrlSession
Verify the remote controller session code to complete the connection.
*Network usage*: no.
**Parameters**:
- sessionCode: string
**Syntax**:
```
/verify remote ctrl <sessionCode>
```
```javascript
'/verify remote ctrl ' + sessionCode // JavaScript
```
```python
'/verify remote ctrl ' + sessionCode # Python
```
**Responses**:
RemoteCtrlConnected: Remote controller session connected..
- type: "remoteCtrlConnected"
- remoteCtrl: [RemoteCtrlInfo](./TYPES.md#remotectrlinfo)
- compression: bool
ChatCmdError: Command error (only used in WebSockets API).
- type: "chatCmdError"
- chatError: [ChatError](./TYPES.md#chaterror)
---
+35
View File
@@ -72,6 +72,10 @@ This file is generated automatically.
- [ServiceRequest](#servicerequest)
- [ServiceReplySent](#servicereplysent)
[Remote control events](#remote-control-events)
- [RemoteCtrlSessionCode](#remotectrlsessioncode)
- [RemoteCtrlStopped](#remotectrlstopped)
[Error events](#error-events)
- [MessageError](#messageerror)
- [ChatError](#chaterror)
@@ -793,6 +797,37 @@ Correlate `connectionId` with the connection ID from the response to [APISendSer
---
## Remote control events
Bots that act as remote control hosts receive these events during the remote control session lifecycle.
### RemoteCtrlSessionCode
Remote controller session code ready for verification.
Use [VerifyRemoteCtrlSession](./COMMANDS.md#verifyremotectrlsession) to complete the connection.
**Record type**:
- type: "remoteCtrlSessionCode"
- remoteCtrl_: [RemoteCtrlInfo](./TYPES.md#remotectrlinfo)?
- sessionCode: string
---
### RemoteCtrlStopped
Remote controller session stopped.
**Record type**:
- type: "remoteCtrlStopped"
- rcsState: [RemoteCtrlSessionState](./TYPES.md#remotectrlsessionstate)
- rcStopReason: [RemoteCtrlStopReason](./TYPES.md#remotectrlstopreason)
---
## Error events
Bots may log these events for debugging. There will be many error events - this does NOT indicate a malfunction - e.g., they may happen because of bad network connectivity, or because messages may be delivered to deleted chats for a short period of time (they will be ignored).
+94
View File
@@ -10,6 +10,7 @@ This file is generated automatically.
- [AgentCryptoError](#agentcryptoerror)
- [AgentErrorType](#agenterrortype)
- [AgentServiceError](#agentserviceerror)
- [AppVersionRange](#appversionrange)
- [AutoAccept](#autoaccept)
- [BadgeInfo](#badgeinfo)
- [BadgeProof](#badgeproof)
@@ -77,6 +78,7 @@ This file is generated automatically.
- [CreatedConnLink](#createdconnlink)
- [CryptoFile](#cryptofile)
- [CryptoFileArgs](#cryptofileargs)
- [CtrlAppInfo](#ctrlappinfo)
- [DroppedMsg](#droppedmsg)
- [E2EInfo](#e2einfo)
- [ErrorType](#errortype)
@@ -170,8 +172,12 @@ This file is generated automatically.
- [RcvGroupEvent](#rcvgroupevent)
- [RcvMsgError](#rcvmsgerror)
- [RelayCapabilities](#relaycapabilities)
- [RelayConnectionResult](#relayconnectionresult)
- [RelayProfile](#relayprofile)
- [RelayStatus](#relaystatus)
- [RemoteCtrlInfo](#remotectrlinfo)
- [RemoteCtrlSessionState](#remotectrlsessionstate)
- [RemoteCtrlStopReason](#remotectrlstopreason)
- [ReportReason](#reportreason)
- [RoleGroupPreference](#rolegrouppreference)
- [SMPAgentError](#smpagenterror)
@@ -386,6 +392,17 @@ BadSignature:
- type: "badSignature"
---
## AppVersionRange
Remote controller app version range (min and max as version strings).
**Record type**:
- minVersion: string
- maxVersion: string
---
## AutoAccept
@@ -1967,6 +1984,18 @@ connFullLink + ((' ' + connShortLink) if connShortLink is not None else '') # Py
- fileNonce: string
---
## CtrlAppInfo
Remote controller application info.
**Record type**:
- appVersionRange: [AppVersionRange](#appversionrange)
- deviceName: string
- compression: bool
---
## DroppedMsg
@@ -3558,6 +3587,15 @@ ParseError:
- webDomain: string?
---
## RelayConnectionResult
**Record type**:
- relayMember: [GroupMember](#groupmember)
- relayError: [ChatError](#chaterror)?
---
## RelayProfile
@@ -3583,6 +3621,62 @@ ParseError:
- "rejected"
---
## RemoteCtrlInfo
**Record type**:
- remoteCtrlId: int64
- ctrlDeviceName: string
- sessionState: [RemoteCtrlSessionState](#remotectrlsessionstate)?
---
## RemoteCtrlSessionState
**Discriminated union type**:
Starting:
- type: "starting"
Searching:
- type: "searching"
Connecting:
- type: "connecting"
PendingConfirmation:
- type: "pendingConfirmation"
- sessionCode: string
Connected:
- type: "connected"
- sessionCode: string
---
## RemoteCtrlStopReason
**Discriminated union type**:
DiscoveryFailed:
- type: "discoveryFailed"
- chatError: [ChatError](#chaterror)
ConnectionFailed:
- type: "connectionFailed"
- chatError: [ChatError](#chaterror)
SetupFailed:
- type: "setupFailed"
- chatError: [ChatError](#chaterror)
Disconnected:
- type: "disconnected"
---
## ReportReason
+10 -6
View File
@@ -80,7 +80,7 @@ chatCommandsDocsData =
[ ("APICreateMyAddress", ["server_"], "Create bot address.", ["CRUserContactLinkCreated", "CRChatCmdError"], [], Just UNInteractive, "/_address " <> Param "userId" <> OnOffParam "pq_ratchet" "pqRatchet" Nothing),
("APIDeleteMyAddress", [], "Delete bot address.", ["CRUserContactLinkDeleted", "CRChatCmdError"], [], Just UNBackground, "/_delete_address " <> Param "userId"),
("APIShowMyAddress", [], "Get bot address and settings.", ["CRUserContactLink", "CRChatCmdError"], [], Nothing, "/_show_address " <> Param "userId"),
("APISetProfileAddress", [], "Add address to bot profile.", ["CRUserProfileUpdated", "CRChatCmdError"], [], Just UNInteractive, "/_profile_address " <> Param "userId" <> " " <> OnOff "enable"),
("APISetProfileAddress", [], "Add address to bot profile.", ["CRUserProfileUpdated", "CRUserProfileNoChange", "CRChatCmdError"], [], Just UNInteractive, "/_profile_address " <> Param "userId" <> " " <> OnOff "enable"),
("APISetAddressSettings", [], "Set bot address settings.", ["CRUserContactLinkUpdated", "CRChatCmdError"], [], Just UNInteractive, "/_address_settings " <> Param "userId" <> OnOffParam "pq_ratchet" "pqRatchet" Nothing <> " " <> Json "settings")
]
),
@@ -98,7 +98,7 @@ chatCommandsDocsData =
("APIDeleteChatItem", [], "Delete message.", ["CRChatItemsDeleted", "CRChatCmdError"], [], Just UNBackground, "/_delete item " <> Param "chatRef" <> " " <> Join ',' "chatItemIds" <> " " <> Param "deleteMode"),
("APIDeleteMemberChatItem", [], "Moderate message. Requires Moderator role (and higher than message author's).", ["CRChatItemsDeleted", "CRChatCmdError"], [], Just UNBackground, "/_delete member item #" <> Param "groupId" <> " " <> Join ',' "chatItemIds"),
("APIChatItemReaction", [], "Add/remove message reaction.", ["CRChatItemReaction", "CRChatCmdError"], [], Just UNBackground, "/_reaction " <> Param "chatRef" <> " " <> Param "chatItemId" <> " " <> OnOff "add" <> " " <> Json "reaction"),
("APIShareMyAddress", [], "Share user address card", ["CRChatMsgContent"], [], Nothing, "/_share address" <> Param "toSendRef"),
("APIShareMyAddress", [], "Share user address card", ["CRChatMsgContent"], [], Nothing, "/_share address " <> Param "toSendRef"),
("APIShareChatMsgContent", [], "Share channel address", ["CRChatMsgContent"], [], Nothing, "/_share chat content " <> Param "shareChatRef" <> " " <> Param "toSendRef")
]
),
@@ -141,7 +141,7 @@ chatCommandsDocsData =
-- `Maybe` in `connectTarget :: Maybe ConnectTarget` is used to signal parse failure to the runtime (the handler returns CEInvalidConnReq on Nothing); it is NOT API-level optionality. The parameter is required from callers.
("APIConnectPlan", [], "Determine SimpleX link type and if the bot is already connected via this link or name.", ["CRConnectionPlan", "CRChatCmdError"], [], Just UNInteractive, "/_connect plan " <> Param "userId" <> " " <> Param "connectTarget"),
("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 or name as string in the active user profile.", ["CRSentConfirmation", "CRContactAlreadyExists", "CRSentInvitation", "CRChatCmdError"], [], Just UNInteractive, "/connect" <> Optional "" (" " <> Param "$0") "connTarget_"),
("Connect", [], "Connect via SimpleX link or name as string in the active user profile.", ["CRSentConfirmation", "CRContactAlreadyExists", "CRSentInvitation", "CRConnectionPlan", "CRSentInvitationToContact", "CRStartedConnectionToContact", "CRStartedConnectionToGroup", "CRChatCmdError"], [], Just UNInteractive, "/connect" <> Optional "" (" " <> Param "$0") "connTarget_"),
("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")
]
@@ -202,6 +202,12 @@ chatCommandsDocsData =
[ ("StartChat", [], "Start chat controller.", ["CRChatStarted", "CRChatRunning"], [], Nothing, "/_start" <> OnOffParam "main" "mainApp" Nothing <> OnOffParam "snd_files" "enableSndFiles" (Just True) <> OnOffParam "service_requests" "serviceRequests" (Just False)),
("APIStopChat", [], "Stop chat controller.", ["CRChatStopped"], [], Nothing, "/_stop")
]
),
( "Remote control commands",
"Allows a bot to accept an incoming remote control session from a SimpleX Desktop client, giving the desktop live access to the bot's SimpleX instance.",
[ ("ConnectRemoteCtrl", [], "Connect to a remote controller using an OOB invitation link.", ["CRRemoteCtrlConnecting", "CRChatCmdError"], [], Just UNInteractive, "/crc " <> Param "remoteInvitation"),
("VerifyRemoteCtrlSession", [], "Verify the remote controller session code to complete the connection.", ["CRRemoteCtrlConnected", "CRChatCmdError"], [], Nothing, "/verify remote ctrl " <> Param "sessionCode")
]
)
]
@@ -452,7 +458,6 @@ undocumentedCommands =
"APIVerifyToken",
"CheckChatRunning",
"ConfirmRemoteCtrl",
"ConnectRemoteCtrl",
"CustomChatCommand",
"DebugEvent",
"DebugLocks",
@@ -499,6 +504,5 @@ undocumentedCommands =
"SwitchRemoteHost",
"TestChatRelay",
"TestProtoServer",
"TestStorageEncryption",
"VerifyRemoteCtrlSession"
"TestStorageEncryption"
]
+7 -2
View File
@@ -152,6 +152,13 @@ chatEventsDocsData =
],
[]
),
( "Remote control events",
"Bots that act as remote control hosts receive these events during the remote control session lifecycle.",
[ ("CEvtRemoteCtrlSessionCode", "Remote controller session code ready for verification.\n\nUse [VerifyRemoteCtrlSession](./COMMANDS.md#verifyremotectrlsession) to complete the connection."),
("CEvtRemoteCtrlStopped", "Remote controller session stopped.")
],
[]
),
( "Error events",
"Bots may log these events for debugging. \
\There will be many error events - this does NOT indicate a malfunction - \
@@ -203,8 +210,6 @@ undocumentedEvents =
"CEvtRcvFileProgressXFTP",
"CEvtRcvStandaloneFileComplete",
"CEvtRemoteCtrlFound",
"CEvtRemoteCtrlSessionCode",
"CEvtRemoteCtrlStopped",
"CEvtRemoteHostConnected",
"CEvtRemoteHostSessionCode",
"CEvtRemoteHostStopped",
+5 -5
View File
@@ -88,11 +88,16 @@ chatResponsesDocsData =
("CRRcvFileAccepted", "File accepted to be received"),
("CRRcvFileAcceptedSndCancelled", "File accepted, but no longer sent"),
("CRRcvFileCancelled", "Cancelled receiving file"),
("CRRemoteCtrlConnected", "Remote controller session connected."),
("CRRemoteCtrlConnecting", "Remote controller is connecting."),
("CRSentConfirmation", "Confirmation sent to one-time invitation"),
("CRSentGroupInvitation", "Group invitation sent"),
("CRSentInvitation", "Invitation sent to contact address"),
("CRSentInvitationToContact", "Invitation sent to contact (when connecting via SimpleX name to a known contact address)."),
("CRServiceReplyAccepted", "Service reply accepted for delivery. `connectionId` correlates the reply delivery event."),
("CRSndFileCancelled", "Cancelled sending file"),
("CRStartedConnectionToContact", "Connection to contact started (when connecting via prepared contact)."),
("CRStartedConnectionToGroup", "Connection to channel started (when connecting via channel link)."),
("CRUserAcceptedGroupSent", "User accepted group invitation"),
("CRUserContactLink", "User contact address"),
("CRUserContactLinkCreated", "User contact address created"),
@@ -188,13 +193,10 @@ undocumentedResponses =
"CRQueueInfo",
"CRRcvStandaloneFileCreated",
"CRReactionMembers",
"CRRemoteCtrlConnected",
"CRRemoteCtrlConnecting",
"CRRemoteCtrlList",
"CRRemoteFileStored",
"CRRemoteHostList",
"CRRemoteHostStarted",
"CRSentInvitationToContact",
"CRServerOperatorConditions",
"CRServerTestResult",
"CRServiceResponse",
@@ -202,8 +204,6 @@ undocumentedResponses =
"CRSndStandaloneFileCreated",
"CRSQLResult",
"CRStandaloneFileInfo",
"CRStartedConnectionToContact",
"CRStartedConnectionToGroup",
"CRTagsUpdated",
"CRUsageConditions",
"CRUserPrivacy",
+13
View File
@@ -49,6 +49,8 @@ import Simplex.Messaging.Parsers (dropPrefix, fstToLower)
import Simplex.Messaging.Protocol (BlockingInfo (..), BlockingReason (..), CommandError (..), ErrorType (..), NameErrorType (..), NetworkError (..), ProxyError (..))
import Simplex.Messaging.Protocol.Types (ClientNotice (..))
import Simplex.Messaging.Transport
import Simplex.Chat.Remote.AppVersion (AppVersion, AppVersionRange)
import Simplex.Chat.Remote.Types (CtrlAppInfo (..))
import Simplex.RemoteControl.Types
import System.Console.ANSI.Types (Color (..))
@@ -211,6 +213,7 @@ chatTypesDocsData =
(sti @AgentCryptoError, STUnion, "", ["RATCHET_EARLIER", "RATCHET_SKIPPED"], "", ""), -- TODO add fields to types
(sti @AgentErrorType, STUnion, "", [], "", ""),
(sti @AgentServiceError, STUnion, "ASE", [], "", ""),
(STI "AppVersionRange" [RecordTypeInfo "AppVersionRange" [FieldInfo "minVersion" (TIType (ST TString [])), FieldInfo "maxVersion" (TIType (ST TString []))]], STRecord, "", [], "", "Remote controller app version range (min and max as version strings)."),
(sti @AutoAccept, STRecord, "", [], "", ""),
(sti @BadgeProof, STRecord, "", [], "", ""),
(sti @BlockingInfo, STRecord, "", [], "", ""),
@@ -243,6 +246,7 @@ chatTypesDocsData =
(sti @CIReactionCount, STRecord, "", [], "", ""),
(sti @CITimed, STRecord, "", [], "", ""),
(sti @ClientNotice, STRecord, "", [], "", ""),
(sti @CtrlAppInfo, STRecord, "", [], "", "Remote controller application info."),
(sti @Color, STEnum, "", [], "", ""),
(sti @CommandError, STUnion, "", [], "", ""),
(sti @CommandErrorType, STUnion, "", [], "", ""),
@@ -354,8 +358,12 @@ chatTypesDocsData =
(sti @RcvGroupEvent, STUnion, "RGE", [], "", ""),
(sti @RcvMsgError, STUnion, "RME", [], "", ""),
(sti @RelayCapabilities, STRecord, "", [], "", ""),
(sti @RelayConnectionResult, STRecord, "", [], "", ""),
(sti @RelayProfile, STRecord, "", [], "", ""),
(sti @RelayStatus, STEnum, "RS", [], "", ""),
(sti @RemoteCtrlInfo, STRecord, "", [], "", ""),
(sti @RemoteCtrlSessionState, STUnion, "RCS", [], "", ""),
(sti @RemoteCtrlStopReason, STUnion, "RCSR", [], "", ""),
(sti @ReportReason, STEnum' (dropPfxSfx "RR" ""), "", ["RRUnknown"], "", ""),
(sti @RoleGroupPreference, STRecord, "", [], "", ""),
(sti @SecurityCode, STRecord, "", [], "", ""),
@@ -471,6 +479,7 @@ deriving instance Generic CIMentionMember
deriving instance Generic CIReactionCount
deriving instance Generic CITimed
deriving instance Generic ClientNotice
deriving instance Generic CtrlAppInfo
deriving instance Generic Color
deriving instance Generic CommandError
deriving instance Generic CommandErrorType
@@ -589,8 +598,12 @@ deriving instance Generic RcvFileTransfer
deriving instance Generic RcvGroupEvent
deriving instance Generic RcvMsgError
deriving instance Generic RelayCapabilities
deriving instance Generic RelayConnectionResult
deriving instance Generic RelayProfile
deriving instance Generic RelayStatus
deriving instance Generic RemoteCtrlInfo
deriving instance Generic RemoteCtrlSessionState
deriving instance Generic RemoteCtrlStopReason
deriving instance Generic ReportReason
deriving instance Generic SecurityCode
deriving instance Generic SimplexDomain
+2
View File
@@ -200,6 +200,7 @@ toTypeInfo tr =
"AgentInvId",
"AgentRcvFileId",
"AgentSndFileId",
"AppVersion",
"BadgeMasterKey",
"B64UrlByteString",
"BBSProof",
@@ -219,6 +220,7 @@ toTypeInfo tr =
"ProofPresHeader",
"PublicKey",
"ProtocolServer",
"RCSignedInvitation",
"SbKey",
"SharedMsgId",
"Signature",
@@ -59,7 +59,7 @@ export interface APISetProfileAddress {
}
export namespace APISetProfileAddress {
export type Response = CR.UserProfileUpdated | CR.ChatCmdError
export type Response = CR.UserProfileUpdated | CR.UserProfileNoChange | CR.ChatCmdError
export function cmdString(self: APISetProfileAddress): string {
return '/_profile_address ' + self.userId + ' ' + (self.enable ? 'on' : 'off')
@@ -178,7 +178,7 @@ export namespace APIShareMyAddress {
export type Response = CR.ChatMsgContent
export function cmdString(self: APIShareMyAddress): string {
return '/_share address' + T.ChatRef.cmdString(self.toSendRef)
return '/_share address ' + T.ChatRef.cmdString(self.toSendRef)
}
}
@@ -582,7 +582,15 @@ export interface Connect {
}
export namespace Connect {
export type Response = CR.SentConfirmation | CR.ContactAlreadyExists | CR.SentInvitation | CR.ChatCmdError
export type Response =
| CR.SentConfirmation
| CR.ContactAlreadyExists
| CR.SentInvitation
| CR.ConnectionPlan
| CR.SentInvitationToContact
| CR.StartedConnectionToContact
| CR.StartedConnectionToGroup
| CR.ChatCmdError
export function cmdString(self: Connect): string {
return '/connect' + (self.connTarget_ ? ' ' + self.connTarget_ : '')
@@ -897,3 +905,34 @@ export namespace APIStopChat {
return '/_stop'
}
}
// Remote control commands
// Allows a bot to accept an incoming remote control session from a SimpleX Desktop client, giving the desktop live access to the bot's SimpleX instance.
// Connect to a remote controller using an OOB invitation link.
// Network usage: interactive.
export interface ConnectRemoteCtrl {
remoteInvitation: string
}
export namespace ConnectRemoteCtrl {
export type Response = CR.RemoteCtrlConnecting | CR.ChatCmdError
export function cmdString(self: ConnectRemoteCtrl): string {
return '/crc ' + self.remoteInvitation
}
}
// Verify the remote controller session code to complete the connection.
// Network usage: no.
export interface VerifyRemoteCtrlSession {
sessionCode: string
}
export namespace VerifyRemoteCtrlSession {
export type Response = CR.RemoteCtrlConnected | CR.ChatCmdError
export function cmdString(self: VerifyRemoteCtrlSession): string {
return '/verify remote ctrl ' + self.sessionCode
}
}
@@ -52,6 +52,8 @@ export type ChatEvent =
| CEvt.SubscriptionStatus
| CEvt.ServiceRequest
| CEvt.ServiceReplySent
| CEvt.RemoteCtrlSessionCode
| CEvt.RemoteCtrlStopped
| CEvt.MessageError
| CEvt.ChatError
| CEvt.ChatErrors
@@ -106,6 +108,8 @@ export namespace CEvt {
| "subscriptionStatus"
| "serviceRequest"
| "serviceReplySent"
| "remoteCtrlSessionCode"
| "remoteCtrlStopped"
| "messageError"
| "chatError"
| "chatErrors"
@@ -471,6 +475,18 @@ export namespace CEvt {
connectionId: string
}
export interface RemoteCtrlSessionCode extends Interface {
type: "remoteCtrlSessionCode"
remoteCtrl_?: T.RemoteCtrlInfo
sessionCode: string
}
export interface RemoteCtrlStopped extends Interface {
type: "remoteCtrlStopped"
rcsState: T.RemoteCtrlSessionState
rcStopReason: T.RemoteCtrlStopReason
}
export interface MessageError extends Interface {
type: "messageError"
user: T.User
@@ -47,11 +47,16 @@ export type ChatResponse =
| CR.RcvFileAccepted
| CR.RcvFileAcceptedSndCancelled
| CR.RcvFileCancelled
| CR.RemoteCtrlConnected
| CR.RemoteCtrlConnecting
| CR.SentConfirmation
| CR.SentGroupInvitation
| CR.SentInvitation
| CR.SentInvitationToContact
| CR.ServiceReplyAccepted
| CR.SndFileCancelled
| CR.StartedConnectionToContact
| CR.StartedConnectionToGroup
| CR.UserAcceptedGroupSent
| CR.UserContactLink
| CR.UserContactLinkCreated
@@ -108,11 +113,16 @@ export namespace CR {
| "rcvFileAccepted"
| "rcvFileAcceptedSndCancelled"
| "rcvFileCancelled"
| "remoteCtrlConnected"
| "remoteCtrlConnecting"
| "sentConfirmation"
| "sentGroupInvitation"
| "sentInvitation"
| "sentInvitationToContact"
| "serviceReplyAccepted"
| "sndFileCancelled"
| "startedConnectionToContact"
| "startedConnectionToGroup"
| "userAcceptedGroupSent"
| "userContactLink"
| "userContactLinkCreated"
@@ -407,6 +417,19 @@ export namespace CR {
rcvFileTransfer: T.RcvFileTransfer
}
export interface RemoteCtrlConnected extends Interface {
type: "remoteCtrlConnected"
remoteCtrl: T.RemoteCtrlInfo
compression: boolean
}
export interface RemoteCtrlConnecting extends Interface {
type: "remoteCtrlConnecting"
remoteCtrl_?: T.RemoteCtrlInfo
ctrlAppInfo: T.CtrlAppInfo
appVersion: string
}
export interface SentConfirmation extends Interface {
type: "sentConfirmation"
user: T.User
@@ -429,6 +452,13 @@ export namespace CR {
customUserProfile?: T.Profile
}
export interface SentInvitationToContact extends Interface {
type: "sentInvitationToContact"
user: T.User
contact: T.Contact
customUserProfile?: T.Profile
}
export interface ServiceReplyAccepted extends Interface {
type: "serviceReplyAccepted"
user: T.User
@@ -443,6 +473,21 @@ export namespace CR {
sndFileTransfers: T.SndFileTransfer[]
}
export interface StartedConnectionToContact extends Interface {
type: "startedConnectionToContact"
user: T.User
contact: T.Contact
customUserProfile?: T.Profile
}
export interface StartedConnectionToGroup extends Interface {
type: "startedConnectionToGroup"
user: T.User
groupInfo: T.GroupInfo
customUserProfile?: T.Profile
relayResults: T.RelayConnectionResult[]
}
export interface UserAcceptedGroupSent extends Interface {
type: "userAcceptedGroupSent"
user: T.User
@@ -223,6 +223,12 @@ export namespace AgentServiceError {
type: "badSignature"
}
}
// Remote controller app version range (min and max as version strings).
export interface AppVersionRange {
minVersion: string
maxVersion: string
}
export interface AutoAccept {
acceptIncognito: boolean
@@ -2210,6 +2216,13 @@ export interface CryptoFileArgs {
fileKey: string
fileNonce: string
}
// Remote controller application info.
export interface CtrlAppInfo {
appVersionRange: AppVersionRange
deviceName: string
compression: boolean
}
export interface DroppedMsg {
brokerTs: string // ISO-8601 timestamp
@@ -3950,6 +3963,11 @@ export interface RelayCapabilities {
webDomain?: string
}
export interface RelayConnectionResult {
relayMember: GroupMember
relayError?: ChatError
}
export interface RelayProfile {
displayName: string
fullName: string
@@ -3967,6 +3985,87 @@ export enum RelayStatus {
Rejected = "rejected",
}
export interface RemoteCtrlInfo {
remoteCtrlId: number // int64
ctrlDeviceName: string
sessionState?: RemoteCtrlSessionState
}
export type RemoteCtrlSessionState =
| RemoteCtrlSessionState.Starting
| RemoteCtrlSessionState.Searching
| RemoteCtrlSessionState.Connecting
| RemoteCtrlSessionState.PendingConfirmation
| RemoteCtrlSessionState.Connected
export namespace RemoteCtrlSessionState {
export type Tag =
| "starting"
| "searching"
| "connecting"
| "pendingConfirmation"
| "connected"
interface Interface {
type: Tag
}
export interface Starting extends Interface {
type: "starting"
}
export interface Searching extends Interface {
type: "searching"
}
export interface Connecting extends Interface {
type: "connecting"
}
export interface PendingConfirmation extends Interface {
type: "pendingConfirmation"
sessionCode: string
}
export interface Connected extends Interface {
type: "connected"
sessionCode: string
}
}
export type RemoteCtrlStopReason =
| RemoteCtrlStopReason.DiscoveryFailed
| RemoteCtrlStopReason.ConnectionFailed
| RemoteCtrlStopReason.SetupFailed
| RemoteCtrlStopReason.Disconnected
export namespace RemoteCtrlStopReason {
export type Tag = "discoveryFailed" | "connectionFailed" | "setupFailed" | "disconnected"
interface Interface {
type: Tag
}
export interface DiscoveryFailed extends Interface {
type: "discoveryFailed"
chatError: ChatError
}
export interface ConnectionFailed extends Interface {
type: "connectionFailed"
chatError: ChatError
}
export interface SetupFailed extends Interface {
type: "setupFailed"
chatError: ChatError
}
export interface Disconnected extends Interface {
type: "disconnected"
}
}
export enum ReportReason {
Spam = "spam",
Content = "content",
@@ -56,7 +56,7 @@ class APISetProfileAddress(TypedDict):
def APISetProfileAddress_cmd_string(self: APISetProfileAddress) -> str:
return '/_profile_address ' + str(self['userId']) + ' ' + ('on' if self['enable'] else 'off')
APISetProfileAddress_Response = CR.UserProfileUpdated | CR.ChatCmdError
APISetProfileAddress_Response = CR.UserProfileUpdated | CR.UserProfileNoChange | CR.ChatCmdError
# Set bot address settings.
@@ -156,7 +156,7 @@ class APIShareMyAddress(TypedDict):
def APIShareMyAddress_cmd_string(self: APIShareMyAddress) -> str:
return '/_share address' + T.ChatRef_cmd_string(self['toSendRef'])
return '/_share address ' + T.ChatRef_cmd_string(self['toSendRef'])
APIShareMyAddress_Response = CR.ChatMsgContent
@@ -513,7 +513,16 @@ class Connect(TypedDict):
def Connect_cmd_string(self: Connect) -> str:
return '/connect' + ((' ' + self.get('connTarget_')) if self.get('connTarget_') is not None else '')
Connect_Response = CR.SentConfirmation | CR.ContactAlreadyExists | CR.SentInvitation | CR.ChatCmdError
Connect_Response = (
CR.SentConfirmation
| CR.ContactAlreadyExists
| CR.SentInvitation
| CR.ConnectionPlan
| CR.SentInvitationToContact
| CR.StartedConnectionToContact
| CR.StartedConnectionToGroup
| CR.ChatCmdError
)
# Accept contact request.
@@ -787,3 +796,30 @@ def APIStopChat_cmd_string(self: APIStopChat) -> str:
APIStopChat_Response = CR.ChatStopped
# Remote control commands
# Allows a bot to accept an incoming remote control session from a SimpleX Desktop client, giving the desktop live access to the bot's SimpleX instance.
# Connect to a remote controller using an OOB invitation link.
# Network usage: interactive.
class ConnectRemoteCtrl(TypedDict):
remoteInvitation: str
def ConnectRemoteCtrl_cmd_string(self: ConnectRemoteCtrl) -> str:
return '/crc ' + self['remoteInvitation']
ConnectRemoteCtrl_Response = CR.RemoteCtrlConnecting | CR.ChatCmdError
# Verify the remote controller session code to complete the connection.
# Network usage: no.
class VerifyRemoteCtrlSession(TypedDict):
sessionCode: str
def VerifyRemoteCtrlSession_cmd_string(self: VerifyRemoteCtrlSession) -> str:
return '/verify remote ctrl ' + self['sessionCode']
VerifyRemoteCtrlSession_Response = CR.RemoteCtrlConnected | CR.ChatCmdError
@@ -314,6 +314,16 @@ class ServiceReplySent(TypedDict):
type: Literal["serviceReplySent"]
connectionId: str
class RemoteCtrlSessionCode(TypedDict):
type: Literal["remoteCtrlSessionCode"]
remoteCtrl_: NotRequired["T.RemoteCtrlInfo"]
sessionCode: str
class RemoteCtrlStopped(TypedDict):
type: Literal["remoteCtrlStopped"]
rcsState: "T.RemoteCtrlSessionState"
rcStopReason: "T.RemoteCtrlStopReason"
class MessageError(TypedDict):
type: Literal["messageError"]
user: "T.User"
@@ -377,12 +387,14 @@ ChatEvent = (
| SubscriptionStatus
| ServiceRequest
| ServiceReplySent
| RemoteCtrlSessionCode
| RemoteCtrlStopped
| MessageError
| ChatError
| ChatErrors
)
ChatEvent_Tag = Literal["contactConnected", "contactUpdated", "contactDeletedByContact", "receivedContactRequest", "newMemberContactReceivedInv", "contactSndReady", "newChatItems", "chatItemReaction", "chatItemsDeleted", "chatItemUpdated", "groupChatItemsDeleted", "chatItemsStatusesUpdated", "receivedGroupInvitation", "userJoinedGroup", "groupUpdated", "joinedGroupMember", "memberRole", "deletedMember", "leftMember", "deletedMemberUser", "groupDeleted", "connectedToGroupMember", "memberAcceptedByOther", "memberBlockedForAll", "groupMemberUpdated", "groupLinkDataUpdated", "groupRelayUpdated", "rcvFileDescrReady", "rcvFileComplete", "sndFileCompleteXFTP", "rcvFileStart", "rcvFileSndCancelled", "rcvFileAccepted", "rcvFileError", "rcvFileWarning", "sndFileError", "sndFileWarning", "acceptingContactRequest", "acceptingBusinessRequest", "contactConnecting", "businessLinkConnecting", "joinedGroupMemberConnecting", "groupLinkConnecting", "hostConnected", "hostDisconnected", "subscriptionStatus", "serviceRequest", "serviceReplySent", "messageError", "chatError", "chatErrors"]
ChatEvent_Tag = Literal["contactConnected", "contactUpdated", "contactDeletedByContact", "receivedContactRequest", "newMemberContactReceivedInv", "contactSndReady", "newChatItems", "chatItemReaction", "chatItemsDeleted", "chatItemUpdated", "groupChatItemsDeleted", "chatItemsStatusesUpdated", "receivedGroupInvitation", "userJoinedGroup", "groupUpdated", "joinedGroupMember", "memberRole", "deletedMember", "leftMember", "deletedMemberUser", "groupDeleted", "connectedToGroupMember", "memberAcceptedByOther", "memberBlockedForAll", "groupMemberUpdated", "groupLinkDataUpdated", "groupRelayUpdated", "rcvFileDescrReady", "rcvFileComplete", "sndFileCompleteXFTP", "rcvFileStart", "rcvFileSndCancelled", "rcvFileAccepted", "rcvFileError", "rcvFileWarning", "sndFileError", "sndFileWarning", "acceptingContactRequest", "acceptingBusinessRequest", "contactConnecting", "businessLinkConnecting", "joinedGroupMemberConnecting", "groupLinkConnecting", "hostConnected", "hostDisconnected", "subscriptionStatus", "serviceRequest", "serviceReplySent", "remoteCtrlSessionCode", "remoteCtrlStopped", "messageError", "chatError", "chatErrors"]
class OnEventDecorator(Protocol):
@@ -681,6 +693,18 @@ class OnEventDecorator(Protocol):
Callable[["ServiceReplySent"], Awaitable[None]],
]: ...
@overload
def __call__(self, event: Literal["remoteCtrlSessionCode"], /) -> Callable[
[Callable[["RemoteCtrlSessionCode"], Awaitable[None]]],
Callable[["RemoteCtrlSessionCode"], Awaitable[None]],
]: ...
@overload
def __call__(self, event: Literal["remoteCtrlStopped"], /) -> Callable[
[Callable[["RemoteCtrlStopped"], Awaitable[None]]],
Callable[["RemoteCtrlStopped"], Awaitable[None]],
]: ...
@overload
def __call__(self, event: Literal["messageError"], /) -> Callable[
[Callable[["MessageError"], Awaitable[None]]],
@@ -240,6 +240,17 @@ class RcvFileCancelled(TypedDict):
chatItem_: NotRequired["T.AChatItem"]
rcvFileTransfer: "T.RcvFileTransfer"
class RemoteCtrlConnected(TypedDict):
type: Literal["remoteCtrlConnected"]
remoteCtrl: "T.RemoteCtrlInfo"
compression: bool
class RemoteCtrlConnecting(TypedDict):
type: Literal["remoteCtrlConnecting"]
remoteCtrl_: NotRequired["T.RemoteCtrlInfo"]
ctrlAppInfo: "T.CtrlAppInfo"
appVersion: str
class SentConfirmation(TypedDict):
type: Literal["sentConfirmation"]
user: "T.User"
@@ -259,6 +270,12 @@ class SentInvitation(TypedDict):
connection: "T.PendingContactConnection"
customUserProfile: NotRequired["T.Profile"]
class SentInvitationToContact(TypedDict):
type: Literal["sentInvitationToContact"]
user: "T.User"
contact: "T.Contact"
customUserProfile: NotRequired["T.Profile"]
class ServiceReplyAccepted(TypedDict):
type: Literal["serviceReplyAccepted"]
user: "T.User"
@@ -271,6 +288,19 @@ class SndFileCancelled(TypedDict):
fileTransferMeta: "T.FileTransferMeta"
sndFileTransfers: list["T.SndFileTransfer"]
class StartedConnectionToContact(TypedDict):
type: Literal["startedConnectionToContact"]
user: "T.User"
contact: "T.Contact"
customUserProfile: NotRequired["T.Profile"]
class StartedConnectionToGroup(TypedDict):
type: Literal["startedConnectionToGroup"]
user: "T.User"
groupInfo: "T.GroupInfo"
customUserProfile: NotRequired["T.Profile"]
relayResults: list["T.RelayConnectionResult"]
class UserAcceptedGroupSent(TypedDict):
type: Literal["userAcceptedGroupSent"]
user: "T.User"
@@ -368,11 +398,16 @@ ChatResponse = (
| RcvFileAccepted
| RcvFileAcceptedSndCancelled
| RcvFileCancelled
| RemoteCtrlConnected
| RemoteCtrlConnecting
| SentConfirmation
| SentGroupInvitation
| SentInvitation
| SentInvitationToContact
| ServiceReplyAccepted
| SndFileCancelled
| StartedConnectionToContact
| StartedConnectionToGroup
| UserAcceptedGroupSent
| UserContactLink
| UserContactLinkCreated
@@ -385,4 +420,4 @@ ChatResponse = (
| ApiChats
)
ChatResponse_Tag = Literal["acceptingContactRequest", "activeUser", "chatItemNotChanged", "chatItemReaction", "chatItemUpdated", "chatItemsDeleted", "chatMsgContent", "chatRunning", "chatStarted", "chatStopped", "cmdOk", "chatCmdError", "connectionPlan", "contactAlreadyExists", "contactConnectionDeleted", "contactDeleted", "contactPrefsUpdated", "contactRequestRejected", "contactsList", "groupDeletedUser", "groupLink", "groupLinkCreated", "groupLinkDeleted", "groupCreated", "publicGroupCreated", "publicGroupCreationFailed", "groupRelays", "groupRelaysAdded", "groupRelaysAddFailed", "relayGroupAllowed", "groupMembers", "groupUpdated", "groupsList", "groupDomainVerified", "invitation", "leftMemberUser", "memberAccepted", "membersBlockedForAllUser", "membersRoleUser", "newChatItems", "rcvFileAccepted", "rcvFileAcceptedSndCancelled", "rcvFileCancelled", "sentConfirmation", "sentGroupInvitation", "sentInvitation", "serviceReplyAccepted", "sndFileCancelled", "userAcceptedGroupSent", "userContactLink", "userContactLinkCreated", "userContactLinkDeleted", "userContactLinkUpdated", "userDeletedMembers", "userProfileUpdated", "userProfileNoChange", "usersList", "apiChats"]
ChatResponse_Tag = Literal["acceptingContactRequest", "activeUser", "chatItemNotChanged", "chatItemReaction", "chatItemUpdated", "chatItemsDeleted", "chatMsgContent", "chatRunning", "chatStarted", "chatStopped", "cmdOk", "chatCmdError", "connectionPlan", "contactAlreadyExists", "contactConnectionDeleted", "contactDeleted", "contactPrefsUpdated", "contactRequestRejected", "contactsList", "groupDeletedUser", "groupLink", "groupLinkCreated", "groupLinkDeleted", "groupCreated", "publicGroupCreated", "publicGroupCreationFailed", "groupRelays", "groupRelaysAdded", "groupRelaysAddFailed", "relayGroupAllowed", "groupMembers", "groupUpdated", "groupsList", "groupDomainVerified", "invitation", "leftMemberUser", "memberAccepted", "membersBlockedForAllUser", "membersRoleUser", "newChatItems", "rcvFileAccepted", "rcvFileAcceptedSndCancelled", "rcvFileCancelled", "remoteCtrlConnected", "remoteCtrlConnecting", "sentConfirmation", "sentGroupInvitation", "sentInvitation", "sentInvitationToContact", "serviceReplyAccepted", "sndFileCancelled", "startedConnectionToContact", "startedConnectionToGroup", "userAcceptedGroupSent", "userContactLink", "userContactLinkCreated", "userContactLinkDeleted", "userContactLinkUpdated", "userDeletedMembers", "userProfileUpdated", "userProfileNoChange", "usersList", "apiChats"]
@@ -165,6 +165,12 @@ AgentServiceError = (
AgentServiceError_Tag = Literal["rejected", "timeout", "noPendingRequest", "notDRAddress", "badSignature"]
# Remote controller app version range (min and max as version strings).
class AppVersionRange(TypedDict):
minVersion: str
maxVersion: str
class AutoAccept(TypedDict):
acceptIncognito: bool
@@ -1560,6 +1566,13 @@ class CryptoFileArgs(TypedDict):
fileKey: str
fileNonce: str
# Remote controller application info.
class CtrlAppInfo(TypedDict):
appVersionRange: "AppVersionRange"
deviceName: str
compression: bool
class DroppedMsg(TypedDict):
brokerTs: str # ISO-8601 timestamp
attempts: int # int
@@ -2770,6 +2783,10 @@ RcvMsgError_Tag = Literal["dropped", "parseError"]
class RelayCapabilities(TypedDict):
webDomain: NotRequired[str]
class RelayConnectionResult(TypedDict):
relayMember: "GroupMember"
relayError: NotRequired["ChatError"]
class RelayProfile(TypedDict):
displayName: str
fullName: str
@@ -2778,6 +2795,62 @@ class RelayProfile(TypedDict):
RelayStatus = Literal["new", "invited", "accepted", "acknowledgedRoster", "active", "inactive", "rejected"]
class RemoteCtrlInfo(TypedDict):
remoteCtrlId: int # int64
ctrlDeviceName: str
sessionState: NotRequired["RemoteCtrlSessionState"]
class RemoteCtrlSessionState_starting(TypedDict):
type: Literal["starting"]
class RemoteCtrlSessionState_searching(TypedDict):
type: Literal["searching"]
class RemoteCtrlSessionState_connecting(TypedDict):
type: Literal["connecting"]
class RemoteCtrlSessionState_pendingConfirmation(TypedDict):
type: Literal["pendingConfirmation"]
sessionCode: str
class RemoteCtrlSessionState_connected(TypedDict):
type: Literal["connected"]
sessionCode: str
RemoteCtrlSessionState = (
RemoteCtrlSessionState_starting
| RemoteCtrlSessionState_searching
| RemoteCtrlSessionState_connecting
| RemoteCtrlSessionState_pendingConfirmation
| RemoteCtrlSessionState_connected
)
RemoteCtrlSessionState_Tag = Literal["starting", "searching", "connecting", "pendingConfirmation", "connected"]
class RemoteCtrlStopReason_discoveryFailed(TypedDict):
type: Literal["discoveryFailed"]
chatError: "ChatError"
class RemoteCtrlStopReason_connectionFailed(TypedDict):
type: Literal["connectionFailed"]
chatError: "ChatError"
class RemoteCtrlStopReason_setupFailed(TypedDict):
type: Literal["setupFailed"]
chatError: "ChatError"
class RemoteCtrlStopReason_disconnected(TypedDict):
type: Literal["disconnected"]
RemoteCtrlStopReason = (
RemoteCtrlStopReason_discoveryFailed
| RemoteCtrlStopReason_connectionFailed
| RemoteCtrlStopReason_setupFailed
| RemoteCtrlStopReason_disconnected
)
RemoteCtrlStopReason_Tag = Literal["discoveryFailed", "connectionFailed", "setupFailed", "disconnected"]
ReportReason = Literal["spam", "content", "community", "profile", "other"]
class RoleGroupPreference(TypedDict):
+2 -2
View File
@@ -655,10 +655,10 @@ data ChatCommand
| DeleteRemoteHost RemoteHostId -- Unregister remote host and remove its data
| StoreRemoteFile {remoteHostId :: RemoteHostId, storeEncrypted :: Maybe Bool, localPath :: FilePath}
| GetRemoteFile {remoteHostId :: RemoteHostId, file :: RemoteFile}
| ConnectRemoteCtrl RCSignedInvitation -- Connect new or existing controller via OOB data
| ConnectRemoteCtrl {remoteInvitation :: RCSignedInvitation} -- Connect new or existing controller via OOB data
| FindKnownRemoteCtrl -- Start listening for announcements from all existing controllers
| ConfirmRemoteCtrl RemoteCtrlId -- Confirm the connection with found controller
| VerifyRemoteCtrlSession Text -- Verify remote controller session
| VerifyRemoteCtrlSession {sessionCode :: Text} -- Verify remote controller session
| ListRemoteCtrls
| StopRemoteCtrl -- Stop listening for announcements or terminate an active session
| DeleteRemoteCtrl RemoteCtrlId -- Remove all local data associated with a remote controller session