Update protocol

This commit is contained in:
Finn 2021-01-26 14:25:56 -08:00
parent c11cd4a4e1
commit 1ff7366927
9 changed files with 783 additions and 970 deletions

View file

@ -2,7 +2,7 @@ signaldctl: signald/client-protocol
go build -o signaldctl ./cmd/signaldctl go build -o signaldctl ./cmd/signaldctl
protocol.json: protocol.json:
echo '{"type": "protocol", "version": "v1alpha1"}' | nc -q0 -U /var/run/signald/signald.sock | jq 'select(.type == "protocol").data' > protocol.json signald --dump-protocol > protocol.json
signald/client-protocol: protocol.json tools/generator/* signald/client-protocol: protocol.json tools/generator/*
go run ./tools/generator < protocol.json go run ./tools/generator < protocol.json

File diff suppressed because one or more lines are too long

View file

@ -25,6 +25,13 @@ type ConfigurationMessage struct {
UnidentifiedDeliveryIndicators *Optional `json:"unidentifiedDeliveryIndicators,omitempty"` UnidentifiedDeliveryIndicators *Optional `json:"unidentifiedDeliveryIndicators,omitempty"`
} }
type DeviceInfo struct {
Created int64 `json:"created,omitempty"`
ID int64 `json:"id,omitempty"`
LastSeen int64 `json:"lastSeen,omitempty"`
Name string `json:"name,omitempty"`
}
type HangupMessage struct { type HangupMessage struct {
DeviceId int32 `json:"deviceId,omitempty"` DeviceId int32 `json:"deviceId,omitempty"`
ID int64 `json:"id,omitempty"` ID int64 `json:"id,omitempty"`
@ -115,12 +122,6 @@ type JsonTypingMessage struct {
Timestamp int64 `json:"timestamp,omitempty"` Timestamp int64 `json:"timestamp,omitempty"`
} }
type Mention struct {
Length int32 `json:"length,omitempty"`
Start int32 `json:"start,omitempty"`
UUID string `json:"uuid,omitempty"`
}
type Name struct { type Name struct {
Display *Optional `json:"display,omitempty"` Display *Optional `json:"display,omitempty"`
Family *Optional `json:"family,omitempty"` Family *Optional `json:"family,omitempty"`

View file

@ -11,6 +11,193 @@ import (
"gitlab.com/signald/signald-go/signald" "gitlab.com/signald/signald-go/signald"
) )
// Submit: Accept a v2 group invitation. Note that you must have a profile name set to join groups.
func (r *AcceptInvitationRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) {
r.Version = "v1"
r.Type = "accept_invitation"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
// Submit: approve a request to join a group
func (r *ApproveMembershipRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) {
r.Version = "v1"
r.Type = "approve_membership"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
// Submit: Query the server for the latest state of a known group
func (r *GetGroupRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) {
r.Version = "v1"
r.Type = "get_group"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
// Submit: list all linked devices on a Signal account
func (r *GetLinkedDevicesRequest) Submit(conn *signald.Signald) (response LinkedDevices, err error) {
r.Version = "v1"
r.Type = "get_linked_devices"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
// Submit: Join a group using the a signal.group URL. Note that you must have a profile name set to join groups.
func (r *JoinGroupRequest) Submit(conn *signald.Signald) (response JsonGroupJoinInfo, err error) {
r.Version = "v1"
r.Type = "join_group"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
func (r *MarkReadRequest) Submit(conn *signald.Signald) error {
r.Version = "v1"
r.Type = "mark_read"
if r.ID == "" {
r.ID = generateID()
}
return conn.RawRequest(r)
}
func (r *ProtocolRequest) Submit(conn *signald.Signald) error {
r.Version = "v1"
r.Type = "protocol"
if r.ID == "" {
r.ID = generateID()
}
return conn.RawRequest(r)
}
// Submit: react to a previous message // Submit: react to a previous message
func (r *ReactRequest) Submit(conn *signald.Signald) (response SendResponse, err error) { func (r *ReactRequest) Submit(conn *signald.Signald) (response SendResponse, err error) {
r.Version = "v1" r.Version = "v1"
@ -44,6 +231,51 @@ func (r *ReactRequest) Submit(conn *signald.Signald) (response SendResponse, err
} }
// Submit: Remove a linked device from the Signal account. Only allowed when the local device id is 1
func (r *RemoveLinkedDeviceRequest) Submit(conn *signald.Signald) error {
r.Version = "v1"
r.Type = "remove_linked_device"
if r.ID == "" {
r.ID = generateID()
}
return conn.RawRequest(r)
}
// Submit: Resolve a partial JsonAddress with only a number or UUID to one with both. Anywhere that signald accepts a JsonAddress will except a partial, this is a convenience function for client authors, mostly because signald doesn't resolve all the partials it returns
func (r *ResolveAddressRequest) Submit(conn *signald.Signald) (response JsonAddress, err error) {
r.Version = "v1"
r.Type = "resolve_address"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
func (r *SendRequest) Submit(conn *signald.Signald) (response SendResponse, err error) { func (r *SendRequest) Submit(conn *signald.Signald) (response SendResponse, err error) {
r.Version = "v1" r.Version = "v1"
r.Type = "send" r.Type = "send"
@ -76,6 +308,50 @@ func (r *SendRequest) Submit(conn *signald.Signald) (response SendResponse, err
} }
func (r *SetProfile) Submit(conn *signald.Signald) error {
r.Version = "v1"
r.Type = "set_profile"
if r.ID == "" {
r.ID = generateID()
}
return conn.RawRequest(r)
}
// Submit: modify a group
func (r *UpdateGroupRequest) Submit(conn *signald.Signald) (response GroupInfo, err error) {
r.Version = "v1"
r.Type = "update_group"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
func (r *VersionRequest) Submit(conn *signald.Signald) (response JsonVersionMessage, err error) { func (r *VersionRequest) Submit(conn *signald.Signald) (response JsonVersionMessage, err error) {
r.Version = "v1" r.Version = "v1"
r.Type = "version" r.Type = "version"

View file

@ -12,6 +12,48 @@ type Request struct {
Type string `json:"type"` Type string `json:"type"`
} }
// AcceptInvitationRequest: Accept a v2 group invitation. Note that you must have a profile name set to join groups.
type AcceptInvitationRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
GroupID string `json:"groupID,omitempty"`
}
// ApproveMembershipRequest: approve a request to join a group
type ApproveMembershipRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
GroupID string `json:"groupID,omitempty"`
Members []*JsonAddress `json:"members,omitempty"` // list of requesting members to approve
}
// GetGroupRequest: Query the server for the latest state of a known group
type GetGroupRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
GroupID string `json:"groupID,omitempty"`
Revision int32 `json:"revision,omitempty"` // the latest known revision, default value (-1) forces fetch from server
}
// GetLinkedDevicesRequest: list all linked devices on a Signal account
type GetLinkedDevicesRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
}
// GroupInfo: A generic type that is used when the group version is not known
type GroupInfo struct {
V1 *JsonGroupInfo `json:"v1,omitempty"`
V2 *JsonGroupV2Info `json:"v2,omitempty"`
}
// JoinGroupRequest: Join a group using the a signal.group URL. Note that you must have a profile name set to join groups.
type JoinGroupRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
Uri string `json:"uri,omitempty"` // The signal.group URL
}
type JsonAddress struct { type JsonAddress struct {
Number string `json:"number,omitempty"` // An e164 phone number, starting with +. Currently the only available user-facing Signal identifier. Number string `json:"number,omitempty"` // An e164 phone number, starting with +. Currently the only available user-facing Signal identifier.
Relay string `json:"relay,omitempty"` Relay string `json:"relay,omitempty"`
@ -31,13 +73,14 @@ type JsonDataMessage struct {
ExpiresInSeconds int32 `json:"expiresInSeconds,omitempty"` // the expiry timer on the incoming message. Clients should delete records of the message within this number of seconds ExpiresInSeconds int32 `json:"expiresInSeconds,omitempty"` // the expiry timer on the incoming message. Clients should delete records of the message within this number of seconds
Group *JsonGroupInfo `json:"group,omitempty"` // if the incoming message was sent to a v1 group, information about that group will be here Group *JsonGroupInfo `json:"group,omitempty"` // if the incoming message was sent to a v1 group, information about that group will be here
GroupV2 *JsonGroupV2Info `json:"groupV2,omitempty"` // is the incoming message was sent to a v2 group, basic identifying information about that group will be here. For full information, use list_groups GroupV2 *JsonGroupV2Info `json:"groupV2,omitempty"` // is the incoming message was sent to a v2 group, basic identifying information about that group will be here. For full information, use list_groups
Mentions []*JsonMention `json:"mentions,omitempty"` // list of mentions in the message
Previews []*v0.JsonPreview `json:"previews,omitempty"` // if the incoming message has a link preview, information about that preview will be here Previews []*v0.JsonPreview `json:"previews,omitempty"` // if the incoming message has a link preview, information about that preview will be here
ProfileKeyUpdate bool `json:"profileKeyUpdate,omitempty"` ProfileKeyUpdate bool `json:"profileKeyUpdate,omitempty"`
Quote *JsonQuote `json:"quote,omitempty"` // if the incoming message is a quote or reply to another message, this will contain information about that message Quote *JsonQuote `json:"quote,omitempty"` // if the incoming message is a quote or reply to another message, this will contain information about that message
Reaction *JsonReaction `json:"reaction,omitempty"` // if the message adds or removes a reaction to another message, this will indicate what change is being made Reaction *JsonReaction `json:"reaction,omitempty"` // if the message adds or removes a reaction to another message, this will indicate what change is being made
RemoteDelete *v0.RemoteDelete `json:"remoteDelete,omitempty"` // if the inbound message is deleting a previously sent message, indicates which message should be deleted RemoteDelete *v0.RemoteDelete `json:"remoteDelete,omitempty"` // if the inbound message is deleting a previously sent message, indicates which message should be deleted
Sticker *v0.JsonSticker `json:"sticker,omitempty"` // if the incoming message is a sticker, information about the sicker will be here Sticker *v0.JsonSticker `json:"sticker,omitempty"` // if the incoming message is a sticker, information about the sicker will be here
Timestamp int64 `json:"timestamp,omitempty"` // the (unix) timestamp that the message was sent at, according to the sender's device. This is used to uniquely identify this message for things like reactions and quotes. Timestamp int64 `json:"timestamp,omitempty"` // the timestamp that the message was sent at, according to the sender's device. This is used to uniquely identify this message for things like reactions and quotes.
ViewOnce bool `json:"viewOnce,omitempty"` // indicates the message is a view once message. View once messages typically include no body and a single image attachment. Official Signal clients will prevent the user from saving the image, and once the user has viewed the image once they will destroy the image. ViewOnce bool `json:"viewOnce,omitempty"` // indicates the message is a view once message. View once messages typically include no body and a single image attachment. Official Signal clients will prevent the user from saving the image, and once the user has viewed the image once they will destroy the image.
} }
@ -49,22 +92,30 @@ type JsonGroupInfo struct {
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
} }
type JsonGroupJoinInfo struct {
AddFromInviteLink int32 `json:"addFromInviteLink,omitempty"`
GroupID string `json:"groupID,omitempty"`
MemberCount int32 `json:"memberCount,omitempty"`
PendingAdminApproval bool `json:"pendingAdminApproval,omitempty"`
Revision int32 `json:"revision,omitempty"`
Title string `json:"title,omitempty"`
}
type JsonGroupV2Info struct { type JsonGroupV2Info struct {
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
InviteLinkPassword string `json:"inviteLinkPassword,omitempty"` InviteLink string `json:"inviteLink,omitempty"`
MasterKey string `json:"masterKey,omitempty"` Members []*JsonAddress `json:"members,omitempty"`
Members []*JsonAddress `json:"members,omitempty"` PendingMembers []*JsonAddress `json:"pendingMembers,omitempty"`
PendingMembers []*JsonAddress `json:"pendingMembers,omitempty"` RequestingMembers []*JsonAddress `json:"requestingMembers,omitempty"`
RequestingMembers []*JsonAddress `json:"requestingMembers,omitempty"` Revision int32 `json:"revision,omitempty"`
Revision int32 `json:"revision,omitempty"` Timer int32 `json:"timer,omitempty"`
Timer int32 `json:"timer,omitempty"` Title string `json:"title,omitempty"`
Title string `json:"title,omitempty"`
} }
type JsonMention struct { type JsonMention struct {
Length int32 `json:"length,omitempty"` Length int32 `json:"length,omitempty"` // The length of the mention represented in the message. Seems to always be 1 but included here in case that changes.
Start int32 `json:"start,omitempty"` Start int32 `json:"start,omitempty"` // The number of characters in that the mention starts at. Note that due to a quirk of how signald encodes JSON, if this value is 0 (for example if the first character in the message is the mention) the field won't show up.
UUID string `json:"uuid,omitempty"` UUID string `json:"uuid,omitempty"` // The UUID of the account being mentioned
} }
type JsonMessageEnvelope struct { type JsonMessageEnvelope struct {
@ -96,11 +147,11 @@ type JsonMessageRequestResponseMessage struct {
// JsonQuote: A quote is a reply to a previous message. ID is the sent time of the message being replied to // JsonQuote: A quote is a reply to a previous message. ID is the sent time of the message being replied to
type JsonQuote struct { type JsonQuote struct {
Attachments []*v0.JsonQuotedAttachment `json:"attachments,omitempty"` Attachments []*v0.JsonQuotedAttachment `json:"attachments,omitempty"` // list of files attached to the quoted message
Author *JsonAddress `json:"author,omitempty"` Author *JsonAddress `json:"author,omitempty"` // the author of the message being quoted
ID int64 `json:"id,omitempty"` ID int64 `json:"id,omitempty"` // the client timestamp of the message being quoted
Mentions []*v0.Mention `json:"mentions,omitempty"` Mentions []*JsonMention `json:"mentions,omitempty"` // list of mentions in the quoted message
Text string `json:"text,omitempty"` Text string `json:"text,omitempty"` // the body of the message being quoted
} }
type JsonReaction struct { type JsonReaction struct {
@ -167,6 +218,21 @@ type JsonViewOnceOpenMessage struct {
Timestamp int64 `json:"timestamp,omitempty"` Timestamp int64 `json:"timestamp,omitempty"`
} }
type LinkedDevices struct {
Devices []*v0.DeviceInfo `json:"devices,omitempty"`
}
type MarkReadRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
Timestamps []int64 `json:"timestamps,omitempty"` // List of messages to mark as read
To *JsonAddress `json:"to,omitempty"` // The address that sent the message being marked as read
}
type ProtocolRequest struct {
Request
}
// ReactRequest: react to a previous message // ReactRequest: react to a previous message
type ReactRequest struct { type ReactRequest struct {
Request Request
@ -177,6 +243,20 @@ type ReactRequest struct {
Username string `json:"username,omitempty"` Username string `json:"username,omitempty"`
} }
// RemoveLinkedDeviceRequest: Remove a linked device from the Signal account. Only allowed when the local device id is 1
type RemoveLinkedDeviceRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
DeviceId int64 `json:"deviceId,omitempty"` // the ID of the device to unlink
}
// ResolveAddressRequest: Resolve a partial JsonAddress with only a number or UUID to one with both. Anywhere that signald accepts a JsonAddress will except a partial, this is a convenience function for client authors, mostly because signald doesn't resolve all the partials it returns
type ResolveAddressRequest struct {
Request
Account string `json:"account,omitempty"` // The signal account to use
Partial *JsonAddress `json:"partial,omitempty"` // The partial address, missing fields
}
type SendRequest struct { type SendRequest struct {
Request Request
Attachments []*v0.JsonAttachment `json:"attachments,omitempty"` Attachments []*v0.JsonAttachment `json:"attachments,omitempty"`
@ -194,6 +274,24 @@ type SendResponse struct {
Timestamp int64 `json:"timestamp,omitempty"` Timestamp int64 `json:"timestamp,omitempty"`
} }
type SetProfile struct {
Request
Account string `json:"account,omitempty"` // The phone number of the account to use
AvatarFile string `json:"avatarFile,omitempty"` // Path to new profile avatar file, if the avatar should be updated
Name string `json:"name,omitempty"` // New profile name. Set to empty string for no profile name
}
// UpdateGroupRequest: modify a group
type UpdateGroupRequest struct {
Request
Account string `json:"account,omitempty"` // The identifier of the account to interact with
AddMembers []*JsonAddress `json:"addMembers,omitempty"`
Avatar string `json:"avatar,omitempty"`
GroupID string `json:"groupID,omitempty"`
RemoveMembers []*JsonAddress `json:"removeMembers,omitempty"`
Title string `json:"title,omitempty"`
}
type VersionRequest struct { type VersionRequest struct {
Request Request
} }

View file

@ -3,11 +3,179 @@ package v1alpha1
// DO NOT EDIT: this file is automatically generated by ./tools/generator in this repo // DO NOT EDIT: this file is automatically generated by ./tools/generator in this repo
import ( import (
"encoding/json"
"fmt"
"log"
"math/rand" "math/rand"
"gitlab.com/signald/signald-go/signald" "gitlab.com/signald/signald-go/signald"
) )
// Submit: Accept a v2 group invitation. Note that you must have a profile name set to join groups.
func (r *AcceptInvitationRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) {
r.Version = "v1alpha1"
r.Type = "accept_invitation"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
// Submit: approve a request to join a group
func (r *ApproveMembershipRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) {
r.Version = "v1alpha1"
r.Type = "approve_membership"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
// Submit: Query the server for the latest state of a known group
func (r *GetGroupRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) {
r.Version = "v1alpha1"
r.Type = "get_group"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
// Submit: list all linked devices on a Signal account
func (r *GetLinkedDevicesRequest) Submit(conn *signald.Signald) (response LinkedDevices, err error) {
r.Version = "v1alpha1"
r.Type = "get_linked_devices"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
// Submit: Join a group using the a signal.group URL. Note that you must have a profile name set to join groups.
func (r *JoinGroupRequest) Submit(conn *signald.Signald) (response JsonGroupJoinInfo, err error) {
r.Version = "v1alpha1"
r.Type = "join_group"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
func (r *ProtocolRequest) Submit(conn *signald.Signald) error { func (r *ProtocolRequest) Submit(conn *signald.Signald) error {
r.Version = "v1alpha1" r.Version = "v1alpha1"
r.Type = "protocol" r.Type = "protocol"
@ -19,6 +187,51 @@ func (r *ProtocolRequest) Submit(conn *signald.Signald) error {
} }
// Submit: Remove a linked device from the Signal account. Only allowed when the local device id is 1
func (r *RemoveLinkedDeviceRequest) Submit(conn *signald.Signald) error {
r.Version = "v1alpha1"
r.Type = "remove_linked_device"
if r.ID == "" {
r.ID = generateID()
}
return conn.RawRequest(r)
}
// Submit: modify a group. only v2 groups for now
func (r *UpdateGroupRequest) Submit(conn *signald.Signald) (response JsonGroupV2Info, err error) {
r.Version = "v1alpha1"
r.Type = "update_group"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
const idsize = 10 const idsize = 10
var charset = []rune("abcdefghijklmnopqrstuvwxyz0123456789") var charset = []rune("abcdefghijklmnopqrstuvwxyz0123456789")

View file

@ -2,12 +2,94 @@ package v1alpha1
// DO NOT EDIT: this file is automatically generated by ./tools/generator in this repo // DO NOT EDIT: this file is automatically generated by ./tools/generator in this repo
import (
"gitlab.com/signald/signald-go/signald/client-protocol/v0"
"gitlab.com/signald/signald-go/signald/client-protocol/v1"
)
type Request struct { type Request struct {
ID string `json:"id"` ID string `json:"id"`
Version string `json:"version"` Version string `json:"version"`
Type string `json:"type"` Type string `json:"type"`
} }
// AcceptInvitationRequest: Accept a v2 group invitation. Note that you must have a profile name set to join groups.
type AcceptInvitationRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
GroupID string `json:"groupID,omitempty"`
}
// ApproveMembershipRequest: approve a request to join a group
type ApproveMembershipRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
GroupID string `json:"groupID,omitempty"`
Members []*v1.JsonAddress `json:"members,omitempty"` // list of requesting members to approve
}
// GetGroupRequest: Query the server for the latest state of a known group
type GetGroupRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
GroupID string `json:"groupID,omitempty"`
Revision int32 `json:"revision,omitempty"` // the latest known revision, default value (-1) forces fetch from server
}
// GetLinkedDevicesRequest: list all linked devices on a Signal account
type GetLinkedDevicesRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
}
// JoinGroupRequest: Join a group using the a signal.group URL. Note that you must have a profile name set to join groups.
type JoinGroupRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
Uri string `json:"uri,omitempty"` // The signal.group URL
}
type JsonGroupJoinInfo struct {
AddFromInviteLink int32 `json:"addFromInviteLink,omitempty"`
GroupID string `json:"groupID,omitempty"`
MemberCount int32 `json:"memberCount,omitempty"`
PendingAdminApproval bool `json:"pendingAdminApproval,omitempty"`
Revision int32 `json:"revision,omitempty"`
Title string `json:"title,omitempty"`
}
type JsonGroupV2Info struct {
ID string `json:"id,omitempty"`
InviteLink string `json:"inviteLink,omitempty"`
Members []*v1.JsonAddress `json:"members,omitempty"`
PendingMembers []*v1.JsonAddress `json:"pendingMembers,omitempty"`
RequestingMembers []*v1.JsonAddress `json:"requestingMembers,omitempty"`
Revision int32 `json:"revision,omitempty"`
Timer int32 `json:"timer,omitempty"`
Title string `json:"title,omitempty"`
}
type LinkedDevices struct {
Devices []*v0.DeviceInfo `json:"devices,omitempty"`
}
type ProtocolRequest struct { type ProtocolRequest struct {
Request Request
} }
// RemoveLinkedDeviceRequest: Remove a linked device from the Signal account. Only allowed when the local device id is 1
type RemoveLinkedDeviceRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
DeviceId int64 `json:"deviceId,omitempty"` // the ID of the device to unlink
}
// UpdateGroupRequest: modify a group. only v2 groups for now
type UpdateGroupRequest struct {
Request
Account string `json:"account,omitempty"` // The account to interact with
AddMembers []*v1.JsonAddress `json:"addMembers,omitempty"`
GroupID string `json:"groupID,omitempty"`
RemoveMembers []*v1.JsonAddress `json:"removeMembers,omitempty"`
Title string `json:"title,omitempty"`
}

View file

@ -0,0 +1,57 @@
package v1alpha2
// DO NOT EDIT: this file is automatically generated by ./tools/generator in this repo
import (
"encoding/json"
"fmt"
"log"
"math/rand"
"gitlab.com/signald/signald-go/signald"
)
// Submit: modify a group
func (r *UpdateGroupRequest) Submit(conn *signald.Signald) (response GroupInfo, err error) {
r.Version = "v1alpha2"
r.Type = "update_group"
if r.ID == "" {
r.ID = generateID()
}
err = conn.RawRequest(r)
if err != nil {
log.Println("signald-go: error submitting request to signald")
return response, err
}
responseChannel := conn.GetResponseListener(r.ID)
defer conn.CloseResponseListener(r.ID)
rawResponse := <-responseChannel
if rawResponse.Error != nil {
err = fmt.Errorf("signald error: %s", string(rawResponse.Error))
return
}
err = json.Unmarshal(rawResponse.Data, &response)
if err != nil {
rawResponseJson, _ := rawResponse.Data.MarshalJSON()
log.Println("signald-go: error unmarshalling response from signald of type", rawResponse.Type, string(rawResponseJson))
return response, err
}
return response, nil
}
const idsize = 10
var charset = []rune("abcdefghijklmnopqrstuvwxyz0123456789")
func generateID() string {
id := make([]rune, idsize)
for i := range id {
id[i] = charset[rand.Intn(len(charset))]
}
return string(id)
}

View file

@ -0,0 +1,30 @@
package v1alpha2
// DO NOT EDIT: this file is automatically generated by ./tools/generator in this repo
import (
"gitlab.com/signald/signald-go/signald/client-protocol/v1"
)
type Request struct {
ID string `json:"id"`
Version string `json:"version"`
Type string `json:"type"`
}
// GroupInfo: A generic type that is used when the group version is not known
type GroupInfo struct {
V1 *v1.JsonGroupInfo `json:"v1,omitempty"`
V2 *v1.JsonGroupV2Info `json:"v2,omitempty"`
}
// UpdateGroupRequest: modify a group
type UpdateGroupRequest struct {
Request
Account string `json:"account,omitempty"` // The identifier of the account to interact with
AddMembers []*v1.JsonAddress `json:"addMembers,omitempty"`
Avatar string `json:"avatar,omitempty"`
GroupID string `json:"groupID,omitempty"`
RemoveMembers []*v1.JsonAddress `json:"removeMembers,omitempty"`
Title string `json:"title,omitempty"`
}