mirror of
https://github.com/aljazceru/signal-cli-rest-api.git
synced 2025-12-19 15:44:28 +01:00
switched implementation to multi-account mode
* instead of starting signal-cli in json-rpc mode with the '-u', we start signal-cli without the '-u' parameter (also known as multi-account mode). This makes it possible to register a number in json-rpc mode.
This commit is contained in:
@@ -384,7 +384,7 @@ func (a *Api) SendV2(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Api) handleSignalReceive(ws *websocket.Conn, number string, stop chan struct{}) {
|
func (a *Api) handleSignalReceive(ws *websocket.Conn, number string, stop chan struct{}) {
|
||||||
receiveChannel, err := a.signalClient.GetReceiveChannel(number)
|
receiveChannel, err := a.signalClient.GetReceiveChannel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Couldn't get receive channel: ", err.Error())
|
log.Error("Couldn't get receive channel: ", err.Error())
|
||||||
return
|
return
|
||||||
@@ -404,12 +404,24 @@ func (a *Api) handleSignalReceive(ws *websocket.Conn, number string, stop chan s
|
|||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if data != "" {
|
if data != "" {
|
||||||
err = ws.WriteMessage(websocket.TextMessage, []byte(data))
|
type Response struct {
|
||||||
|
Account string `json:"account"`
|
||||||
|
}
|
||||||
|
var response Response
|
||||||
|
err = json.Unmarshal([]byte(data), &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
|
log.Error("Couldn't parse message ", data, ":", err.Error())
|
||||||
log.Error("Couldn't write message: " + err.Error())
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.Account == number {
|
||||||
|
err = ws.WriteMessage(websocket.TextMessage, []byte(data)) //TODO split up data in different channels
|
||||||
|
if err != nil {
|
||||||
|
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
|
||||||
|
log.Error("Couldn't write message: " + err.Error())
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ func (s *SignalClient) send(number string, message string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.signalCliMode == JsonRpc {
|
if s.signalCliMode == JsonRpc {
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -431,7 +431,7 @@ func (s *SignalClient) send(number string, message string,
|
|||||||
request.TextStyles = signalCliTextFormatStrings
|
request.TextStyles = signalCliTextFormatStrings
|
||||||
}
|
}
|
||||||
|
|
||||||
rawData, err := jsonRpc2Client.getRaw("send", request)
|
rawData, err := jsonRpc2Client.getRaw("send", &number, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cleanupAttachmentEntries(attachmentEntries)
|
cleanupAttachmentEntries(attachmentEntries)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -526,20 +526,41 @@ func (s *SignalClient) About() About {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignalClient) RegisterNumber(number string, useVoice bool, captcha string) error {
|
func (s *SignalClient) RegisterNumber(number string, useVoice bool, captcha string) error {
|
||||||
|
var err error
|
||||||
if s.signalCliMode == JsonRpc {
|
if s.signalCliMode == JsonRpc {
|
||||||
return errors.New(endpointNotSupportedInJsonRpcMode)
|
type Request struct {
|
||||||
}
|
UseVoice bool `json:"voice,omitempty"`
|
||||||
command := []string{"--config", s.signalCliConfig, "-a", number, "register"}
|
Captcha string `json:"captcha,omitempty"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
}
|
||||||
|
request := Request{Account: number}
|
||||||
|
|
||||||
if useVoice {
|
if useVoice {
|
||||||
command = append(command, "--voice")
|
request.UseVoice = useVoice
|
||||||
}
|
}
|
||||||
|
|
||||||
if captcha != "" {
|
if captcha != "" {
|
||||||
command = append(command, []string{"--captcha", captcha}...)
|
request.Captcha = captcha
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := s.cliClient.Execute(true, command, "")
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = jsonRpc2Client.getRaw("register", nil, request)
|
||||||
|
} else {
|
||||||
|
command := []string{"--config", s.signalCliConfig, "-a", number, "register"}
|
||||||
|
|
||||||
|
if useVoice {
|
||||||
|
command = append(command, "--voice")
|
||||||
|
}
|
||||||
|
|
||||||
|
if captcha != "" {
|
||||||
|
command = append(command, []string{"--captcha", captcha}...)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = s.cliClient.Execute(true, command, "")
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,8 +609,8 @@ func (s *SignalClient) SendV1(number string, message string, recipients []string
|
|||||||
return timestamp, err
|
return timestamp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignalClient) getJsonRpc2Client(number string) (*JsonRpc2Client, error) {
|
func (s *SignalClient) getJsonRpc2Client() (*JsonRpc2Client, error) {
|
||||||
if val, ok := s.jsonRpc2Clients[number]; ok {
|
if val, ok := s.jsonRpc2Clients[utils.MULTI_ACCOUNT_NUMBER]; ok {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("Number not registered with JSON-RPC")
|
return nil, errors.New("Number not registered with JSON-RPC")
|
||||||
@@ -692,8 +713,8 @@ func (s *SignalClient) Receive(number string, timeout int64, ignoreAttachments b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignalClient) GetReceiveChannel(number string) (chan JsonRpc2ReceivedMessage, error) {
|
func (s *SignalClient) GetReceiveChannel() (chan JsonRpc2ReceivedMessage, error) {
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -729,11 +750,11 @@ func (s *SignalClient) CreateGroup(number string, name string, members []string,
|
|||||||
request.AddMembersPermissions = addMembersPermission.String()
|
request.AddMembersPermissions = addMembersPermission.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
rawData, err := jsonRpc2Client.getRaw("updateGroup", request)
|
rawData, err := jsonRpc2Client.getRaw("updateGroup", &number, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -817,11 +838,11 @@ func (s *SignalClient) updateGroupMembers(number string, groupId string, members
|
|||||||
request.RemoveMembers = append(request.RemoveMembers, members...)
|
request.RemoveMembers = append(request.RemoveMembers, members...)
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("updateGroup", request)
|
_, err = jsonRpc2Client.getRaw("updateGroup", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateGroup", "-g", internalGroupId}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateGroup", "-g", internalGroupId}
|
||||||
|
|
||||||
@@ -880,11 +901,11 @@ func (s *SignalClient) updateGroupAdmins(number string, groupId string, admins [
|
|||||||
request.RemoveAdmins = append(request.RemoveAdmins, admins...)
|
request.RemoveAdmins = append(request.RemoveAdmins, admins...)
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("updateGroup", request)
|
_, err = jsonRpc2Client.getRaw("updateGroup", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateGroup", "-g", internalGroupId}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateGroup", "-g", internalGroupId}
|
||||||
|
|
||||||
@@ -916,11 +937,11 @@ func (s *SignalClient) GetGroups(number string) ([]GroupEntry, error) {
|
|||||||
var rawData string
|
var rawData string
|
||||||
|
|
||||||
if s.signalCliMode == JsonRpc {
|
if s.signalCliMode == JsonRpc {
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return groupEntries, err
|
return groupEntries, err
|
||||||
}
|
}
|
||||||
rawData, err = jsonRpc2Client.getRaw("listGroups", nil)
|
rawData, err = jsonRpc2Client.getRaw("listGroups", &number, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return groupEntries, err
|
return groupEntries, err
|
||||||
}
|
}
|
||||||
@@ -999,11 +1020,11 @@ func (s *SignalClient) DeleteGroup(number string, groupId string) error {
|
|||||||
}
|
}
|
||||||
request := Request{GroupId: groupId}
|
request := Request{GroupId: groupId}
|
||||||
|
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("quitGroup", request)
|
_, err = jsonRpc2Client.getRaw("quitGroup", &number, request)
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
ret, err := s.cliClient.Execute(true, []string{"--config", s.signalCliConfig, "-a", number, "quitGroup", "-g", string(groupId)}, "")
|
ret, err := s.cliClient.Execute(true, []string{"--config", s.signalCliConfig, "-a", number, "quitGroup", "-g", string(groupId)}, "")
|
||||||
@@ -1139,11 +1160,11 @@ func (s *SignalClient) UpdateProfile(number string, profileName string, base64Av
|
|||||||
request.Avatar = avatarTmpPath
|
request.Avatar = avatarTmpPath
|
||||||
request.RemoveAvatar = false
|
request.RemoveAvatar = false
|
||||||
}
|
}
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("updateProfile", request)
|
_, err = jsonRpc2Client.getRaw("updateProfile", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateProfile", "--given-name", profileName}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateProfile", "--given-name", profileName}
|
||||||
if base64Avatar == "" {
|
if base64Avatar == "" {
|
||||||
@@ -1162,11 +1183,11 @@ func (s *SignalClient) UpdateProfile(number string, profileName string, base64Av
|
|||||||
func (s *SignalClient) ListIdentities(number string) (*[]IdentityEntry, error) {
|
func (s *SignalClient) ListIdentities(number string) (*[]IdentityEntry, error) {
|
||||||
identityEntries := []IdentityEntry{}
|
identityEntries := []IdentityEntry{}
|
||||||
if s.signalCliMode == JsonRpc {
|
if s.signalCliMode == JsonRpc {
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rawData, err := jsonRpc2Client.getRaw("listIdentities", nil)
|
rawData, err := jsonRpc2Client.getRaw("listIdentities", &number, nil)
|
||||||
signalCliIdentityEntries := []SignalCliIdentityEntry{}
|
signalCliIdentityEntries := []SignalCliIdentityEntry{}
|
||||||
err = json.Unmarshal([]byte(rawData), &signalCliIdentityEntries)
|
err = json.Unmarshal([]byte(rawData), &signalCliIdentityEntries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1224,11 +1245,11 @@ func (s *SignalClient) TrustIdentity(number string, numberToTrust string, verifi
|
|||||||
request.TrustAllKnownKeys = *trustAllKnownKeys
|
request.TrustAllKnownKeys = *trustAllKnownKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("trust", request)
|
_, err = jsonRpc2Client.getRaw("trust", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "trust", numberToTrust}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "trust", numberToTrust}
|
||||||
|
|
||||||
@@ -1252,11 +1273,11 @@ func (s *SignalClient) BlockGroup(number string, groupId string) error {
|
|||||||
GroupId string `json:"groupId"`
|
GroupId string `json:"groupId"`
|
||||||
}
|
}
|
||||||
request := Request{GroupId: groupId}
|
request := Request{GroupId: groupId}
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("block", request)
|
_, err = jsonRpc2Client.getRaw("block", &number, request)
|
||||||
} else {
|
} else {
|
||||||
_, err = s.cliClient.Execute(true, []string{"--config", s.signalCliConfig, "-a", number, "block", "-g", groupId}, "")
|
_, err = s.cliClient.Execute(true, []string{"--config", s.signalCliConfig, "-a", number, "block", "-g", groupId}, "")
|
||||||
}
|
}
|
||||||
@@ -1270,11 +1291,11 @@ func (s *SignalClient) JoinGroup(number string, groupId string) error {
|
|||||||
GroupId string `json:"groupId"`
|
GroupId string `json:"groupId"`
|
||||||
}
|
}
|
||||||
request := Request{GroupId: groupId}
|
request := Request{GroupId: groupId}
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("updateGroup", request)
|
_, err = jsonRpc2Client.getRaw("updateGroup", &number, request)
|
||||||
} else {
|
} else {
|
||||||
_, err = s.cliClient.Execute(true, []string{"--config", s.signalCliConfig, "-a", number, "updateGroup", "-g", groupId}, "")
|
_, err = s.cliClient.Execute(true, []string{"--config", s.signalCliConfig, "-a", number, "updateGroup", "-g", groupId}, "")
|
||||||
}
|
}
|
||||||
@@ -1288,11 +1309,11 @@ func (s *SignalClient) QuitGroup(number string, groupId string) error {
|
|||||||
GroupId string `json:"groupId"`
|
GroupId string `json:"groupId"`
|
||||||
}
|
}
|
||||||
request := Request{GroupId: groupId}
|
request := Request{GroupId: groupId}
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("quitGroup", request)
|
_, err = jsonRpc2Client.getRaw("quitGroup", &number, request)
|
||||||
} else {
|
} else {
|
||||||
_, err = s.cliClient.Execute(true, []string{"--config", s.signalCliConfig, "-a", number, "quitGroup", "-g", groupId}, "")
|
_, err = s.cliClient.Execute(true, []string{"--config", s.signalCliConfig, "-a", number, "quitGroup", "-g", groupId}, "")
|
||||||
}
|
}
|
||||||
@@ -1352,11 +1373,11 @@ func (s *SignalClient) UpdateGroup(number string, groupId string, base64Avatar *
|
|||||||
request.Description = groupDescription
|
request.Description = groupDescription
|
||||||
|
|
||||||
|
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("updateGroup", request)
|
_, err = jsonRpc2Client.getRaw("updateGroup", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateGroup", "-g", groupId}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateGroup", "-g", groupId}
|
||||||
if base64Avatar != nil {
|
if base64Avatar != nil {
|
||||||
@@ -1413,11 +1434,11 @@ func (s *SignalClient) SendReaction(number string, recipient string, emoji strin
|
|||||||
if remove {
|
if remove {
|
||||||
request.Remove = remove
|
request.Remove = remove
|
||||||
}
|
}
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("sendReaction", request)
|
_, err = jsonRpc2Client.getRaw("sendReaction", &number, request)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1463,11 +1484,11 @@ func (s *SignalClient) SendStartTyping(number string, recipient string) error {
|
|||||||
request.GroupId = recp
|
request.GroupId = recp
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("sendTyping", request)
|
_, err = jsonRpc2Client.getRaw("sendTyping", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "sendTyping"}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "sendTyping"}
|
||||||
if !isGroup {
|
if !isGroup {
|
||||||
@@ -1506,11 +1527,11 @@ func (s *SignalClient) SendStopTyping(number string, recipient string) error {
|
|||||||
request.GroupId = recp
|
request.GroupId = recp
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("sendTyping", request)
|
_, err = jsonRpc2Client.getRaw("sendTyping", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "sendTyping", "--stop"}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "sendTyping", "--stop"}
|
||||||
if !isGroup {
|
if !isGroup {
|
||||||
@@ -1540,7 +1561,7 @@ func (s *SignalClient) SearchForNumbers(number string, numbers []string) ([]Sear
|
|||||||
return searchResultEntries, errors.New("No JsonRpc2Client registered!")
|
return searchResultEntries, errors.New("No JsonRpc2Client registered!")
|
||||||
}
|
}
|
||||||
for _, jsonRpc2Client := range jsonRpc2Clients {
|
for _, jsonRpc2Client := range jsonRpc2Clients {
|
||||||
rawData, err = jsonRpc2Client.getRaw("getUserStatus", request)
|
rawData, err = jsonRpc2Client.getRaw("getUserStatus", &number, request)
|
||||||
if err == nil { //getUserStatus doesn't need an account to work, so try all the registered acounts and stop until we succeed
|
if err == nil { //getUserStatus doesn't need an account to work, so try all the registered acounts and stop until we succeed
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -1585,11 +1606,11 @@ func (s *SignalClient) SearchForNumbers(number string, numbers []string) ([]Sear
|
|||||||
func (s* SignalClient) SendContacts(number string) error {
|
func (s* SignalClient) SendContacts(number string) error {
|
||||||
var err error
|
var err error
|
||||||
if s.signalCliMode == JsonRpc {
|
if s.signalCliMode == JsonRpc {
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("sendContacts", nil)
|
_, err = jsonRpc2Client.getRaw("sendContacts", &number, nil)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "sendContacts"}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "sendContacts"}
|
||||||
_, err = s.cliClient.Execute(true, cmd, "")
|
_, err = s.cliClient.Execute(true, cmd, "")
|
||||||
@@ -1612,11 +1633,11 @@ func (s *SignalClient) UpdateContact(number string, recipient string, name *stri
|
|||||||
if expirationInSeconds != nil {
|
if expirationInSeconds != nil {
|
||||||
request.Expiration = *expirationInSeconds
|
request.Expiration = *expirationInSeconds
|
||||||
}
|
}
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("updateContact", request)
|
_, err = jsonRpc2Client.getRaw("updateContact", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateContact", recipient}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "updateContact", recipient}
|
||||||
if name != nil {
|
if name != nil {
|
||||||
@@ -1637,11 +1658,11 @@ func (s *SignalClient) AddDevice(number string, uri string) error {
|
|||||||
Uri string `json:"uri"`
|
Uri string `json:"uri"`
|
||||||
}
|
}
|
||||||
request := Request{Uri: uri}
|
request := Request{Uri: uri}
|
||||||
jsonRpc2Client, err := s.getJsonRpc2Client(number)
|
jsonRpc2Client, err := s.getJsonRpc2Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = jsonRpc2Client.getRaw("addDevice", request)
|
_, err = jsonRpc2Client.getRaw("addDevice", &number, request)
|
||||||
} else {
|
} else {
|
||||||
cmd := []string{"--config", s.signalCliConfig, "-a", number, "addDevice", "--uri", uri}
|
cmd := []string{"--config", s.signalCliConfig, "-a", number, "addDevice", "--uri", uri}
|
||||||
_, err = s.cliClient.Execute(true, cmd, "")
|
_, err = s.cliClient.Execute(true, cmd, "")
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func (r *JsonRpc2Client) Dial(address string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *JsonRpc2Client) getRaw(command string, args interface{}) (string, error) {
|
func (r *JsonRpc2Client) getRaw(command string, account *string, args interface{}) (string, error) {
|
||||||
type Request struct {
|
type Request struct {
|
||||||
JsonRpc string `json:"jsonrpc"`
|
JsonRpc string `json:"jsonrpc"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
@@ -99,6 +99,13 @@ func (r *JsonRpc2Client) getRaw(command string, args interface{}) (string, error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if account != nil {
|
||||||
|
fullCommandBytes, err = sjson.SetBytes(fullCommandBytes, "params.account", account)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log.Debug("full command: ", string(fullCommandBytes))
|
log.Debug("full command: ", string(fullCommandBytes))
|
||||||
|
|
||||||
_, err = r.conn.Write([]byte(string(fullCommandBytes) + "\n"))
|
_, err = r.conn.Write([]byte(string(fullCommandBytes) + "\n"))
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/bbernhard/signal-cli-rest-api/utils"
|
"github.com/bbernhard/signal-cli-rest-api/utils"
|
||||||
"github.com/gabriel-vasile/mimetype"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,7 +14,7 @@ const supervisorctlConfigTemplate = `
|
|||||||
[program:%s]
|
[program:%s]
|
||||||
environment=JAVA_HOME=/opt/java/openjdk
|
environment=JAVA_HOME=/opt/java/openjdk
|
||||||
process_name=%s
|
process_name=%s
|
||||||
command=bash -c "nc -l -p %d <%s | signal-cli --output=json -u %s --config %s jsonRpc >%s"
|
command=bash -c "nc -l -p %d <%s | signal-cli --output=json --config %s jsonRpc >%s"
|
||||||
autostart=true
|
autostart=true
|
||||||
autorestart=true
|
autorestart=true
|
||||||
startretries=10
|
startretries=10
|
||||||
@@ -32,37 +28,6 @@ stdout_logfile_backups=10
|
|||||||
numprocs=1
|
numprocs=1
|
||||||
`
|
`
|
||||||
|
|
||||||
func isSignalCliLinkedNumberConfigFile(filename string) (bool, error) {
|
|
||||||
fileExtension := filepath.Ext(filename)
|
|
||||||
if fileExtension != "" {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
mimetype, err := mimetype.DetectFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if mimetype.String() == "application/json" {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUsernameFromLinkedNumberConfigFile(filename string) (string, error) {
|
|
||||||
type LinkedNumberConfigFile struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
}
|
|
||||||
bytes, err := ioutil.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
var linkedNumberConfigFile LinkedNumberConfigFile
|
|
||||||
err = json.Unmarshal(bytes, &linkedNumberConfigFile)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return linkedNumberConfigFile.Username, nil
|
|
||||||
}
|
|
||||||
func main() {
|
func main() {
|
||||||
signalCliConfigDir := "/home/.local/share/signal-cli/"
|
signalCliConfigDir := "/home/.local/share/signal-cli/"
|
||||||
signalCliConfigDirEnv := utils.GetEnv("SIGNAL_CLI_CONFIG_DIR", "")
|
signalCliConfigDirEnv := utils.GetEnv("SIGNAL_CLI_CONFIG_DIR", "")
|
||||||
@@ -73,81 +38,47 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signalCliConfigDataDir := signalCliConfigDir + "data"
|
|
||||||
|
|
||||||
jsonRpc2ClientConfig := utils.NewJsonRpc2ClientConfig()
|
jsonRpc2ClientConfig := utils.NewJsonRpc2ClientConfig()
|
||||||
|
|
||||||
var tcpBasePort int64 = 6000
|
var tcpPort int64 = 6001
|
||||||
fifoBasePathName := "/tmp/sigsocket"
|
fifoPathname := "/tmp/sigsocket1"
|
||||||
var ctr int64 = 0
|
|
||||||
|
|
||||||
items, err := ioutil.ReadDir(signalCliConfigDataDir)
|
jsonRpc2ClientConfig.AddEntry(utils.MULTI_ACCOUNT_NUMBER, utils.JsonRpc2ClientConfigEntry{TcpPort: tcpPort, FifoPathname: fifoPathname})
|
||||||
|
|
||||||
|
os.Remove(fifoPathname) //remove any existing named pipe
|
||||||
|
|
||||||
|
_, err := exec.Command("mkfifo", fifoPathname).Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Couldn't read contents of ", signalCliConfigDataDir, ". Is your phone number properly registered? Please be aware that registering a phone number only works in normal/native mode and is currently not supported in json-rpc mode!")
|
log.Fatal("Couldn't create fifo with name ", fifoPathname, ": ", err.Error())
|
||||||
}
|
}
|
||||||
for _, item := range items {
|
|
||||||
if item.IsDir() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
filename := filepath.Base(item.Name())
|
|
||||||
isSignalCliLinkedNumberConfigFile, err := isSignalCliLinkedNumberConfigFile(signalCliConfigDataDir + "/" + filename)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Couldn't determine whether file ", filename, " is a signal-cli config file: ", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(filename, "+") || isSignalCliLinkedNumberConfigFile {
|
uid := utils.GetEnv("SIGNAL_CLI_UID", "1000")
|
||||||
var number string = ""
|
gid := utils.GetEnv("SIGNAL_CLI_GID", "1000")
|
||||||
if utils.IsPhoneNumber(filename) {
|
_, err = exec.Command("chown", uid+":"+gid, fifoPathname).Output()
|
||||||
number = filename
|
if err != nil {
|
||||||
} else if isSignalCliLinkedNumberConfigFile {
|
log.Fatal("Couldn't change permissions of fifo with name ", fifoPathname, ": ", err.Error())
|
||||||
number, err = getUsernameFromLinkedNumberConfigFile(signalCliConfigDataDir + "/" + filename)
|
}
|
||||||
if err != nil {
|
|
||||||
log.Debug("Skipping ", filename, " as it is not a valid signal-cli config file: ", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Error("Skipping ", filename, " as it is not a valid phone number!")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fifoPathname := fifoBasePathName + strconv.FormatInt(ctr, 10)
|
supervisorctlProgramName := "signal-cli-json-rpc-1"
|
||||||
tcpPort := tcpBasePort + ctr
|
supervisorctlLogFolder := "/var/log/" + supervisorctlProgramName
|
||||||
jsonRpc2ClientConfig.AddEntry(number, utils.JsonRpc2ClientConfigEntry{TcpPort: tcpPort, FifoPathname: fifoPathname})
|
_, err = exec.Command("mkdir", "-p", supervisorctlLogFolder).Output()
|
||||||
ctr += 1
|
if err != nil {
|
||||||
|
log.Fatal("Couldn't create log folder ", supervisorctlLogFolder, ": ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
os.Remove(fifoPathname) //remove any existing named pipe
|
log.Info("Updated jsonrpc2.yml")
|
||||||
|
|
||||||
_, err = exec.Command("mkfifo", fifoPathname).Output()
|
//write supervisorctl config
|
||||||
if err != nil {
|
supervisorctlConfigFilename := "/etc/supervisor/conf.d/" + "signal-cli-json-rpc-1.conf"
|
||||||
log.Fatal("Couldn't create fifo with name ", fifoPathname, ": ", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
uid := utils.GetEnv("SIGNAL_CLI_UID", "1000")
|
|
||||||
gid := utils.GetEnv("SIGNAL_CLI_GID", "1000")
|
|
||||||
_, err = exec.Command("chown", uid+":"+gid, fifoPathname).Output()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Couldn't change permissions of fifo with name ", fifoPathname, ": ", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
supervisorctlProgramName := "signal-cli-json-rpc-" + strconv.FormatInt(ctr, 10)
|
supervisorctlConfig := fmt.Sprintf(supervisorctlConfigTemplate, supervisorctlProgramName, supervisorctlProgramName,
|
||||||
supervisorctlLogFolder := "/var/log/" + supervisorctlProgramName
|
tcpPort, fifoPathname, signalCliConfigDir, fifoPathname, supervisorctlProgramName, supervisorctlProgramName)
|
||||||
_, err = exec.Command("mkdir", "-p", supervisorctlLogFolder).Output()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Couldn't create log folder ", supervisorctlLogFolder, ": ", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Found number ", number, " and added it to jsonrpc2.yml")
|
err = ioutil.WriteFile(supervisorctlConfigFilename, []byte(supervisorctlConfig), 0644)
|
||||||
|
if err != nil {
|
||||||
//write supervisorctl config
|
log.Fatal("Couldn't write ", supervisorctlConfigFilename, ": ", err.Error())
|
||||||
supervisorctlConfigFilename := "/etc/supervisor/conf.d/" + "signal-cli-json-rpc-" + strconv.FormatInt(ctr, 10) + ".conf"
|
|
||||||
supervisorctlConfig := fmt.Sprintf(supervisorctlConfigTemplate, supervisorctlProgramName, supervisorctlProgramName,
|
|
||||||
tcpPort, fifoPathname, number, signalCliConfigDir, fifoPathname, supervisorctlProgramName, supervisorctlProgramName)
|
|
||||||
err = ioutil.WriteFile(supervisorctlConfigFilename, []byte(supervisorctlConfig), 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Couldn't write ", supervisorctlConfigFilename, ": ", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write jsonrpc.yml config file
|
// write jsonrpc.yml config file
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const MULTI_ACCOUNT_NUMBER string = "<multi-account>"
|
||||||
|
|
||||||
type JsonRpc2ClientConfigEntry struct {
|
type JsonRpc2ClientConfigEntry struct {
|
||||||
TcpPort int64 `yaml:"tcp_port"`
|
TcpPort int64 `yaml:"tcp_port"`
|
||||||
FifoPathname string `yaml:"fifo_pathname"`
|
FifoPathname string `yaml:"fifo_pathname"`
|
||||||
|
|||||||
Reference in New Issue
Block a user