mirror of
https://github.com/aljazceru/signal-cli-rest-api.git
synced 2025-12-20 16:14:29 +01:00
Merge branch 'groups'
This commit is contained in:
192
README.md
192
README.md
@@ -1,78 +1,114 @@
|
|||||||
# Dockerized Signal Messenger REST API
|
# Dockerized Signal Messenger REST API
|
||||||
|
|
||||||
This project creates a small dockerized REST API around [signal-cli](https://github.com/AsamK/signal-cli).
|
This project creates a small dockerized REST API around [signal-cli](https://github.com/AsamK/signal-cli).
|
||||||
|
|
||||||
|
|
||||||
At the moment, the following functionality is exposed via REST:
|
At the moment, the following functionality is exposed via REST:
|
||||||
|
|
||||||
* Register a number
|
* Register a number
|
||||||
* Verify the number using the code received via SMS
|
* Verify the number using the code received via SMS
|
||||||
* Send message (+ attachment) to multiple recipients
|
* Send message (+ attachment) to multiple recipients
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Sample `docker-compose.yml`file:
|
Sample `docker-compose.yml`file:
|
||||||
|
|
||||||
```
|
```
|
||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
signal-cli-rest-api:
|
signal-cli-rest-api:
|
||||||
image: bbernhard/signal-cli-rest-api:latest
|
image: bbernhard/signal-cli-rest-api:latest
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080" #map docker port 8080 to host port 8080.
|
- "8080:8080" #map docker port 8080 to host port 8080.
|
||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
volumes:
|
volumes:
|
||||||
- "./signal-cli-config:/home/.local/share/signal-cli" #map "signal-cli-config" folder on host system into docker container. the folder contains the password and cryptographic keys when a new number is registered
|
- "./signal-cli-config:/home/.local/share/signal-cli" #map "signal-cli-config" folder on host system into docker container. the folder contains the password and cryptographic keys when a new number is registered
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Sample REST API calls:
|
Sample REST API calls:
|
||||||
|
|
||||||
* Register a number (with SMS verification)
|
* Register a number (with SMS verification)
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/<number>'```
|
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/<number>'```
|
||||||
|
|
||||||
e.g:
|
e.g:
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/+431212131491291'```
|
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/+431212131491291'```
|
||||||
|
|
||||||
* Register a number (with voice verification)
|
* Register a number (with voice verification)
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" --data '{"use_voice": true}' 'http://127.0.0.1:8080/v1/register/<number>'```
|
```curl -X POST -H "Content-Type: application/json" --data '{"use_voice": true}' 'http://127.0.0.1:8080/v1/register/<number>'```
|
||||||
|
|
||||||
e.g:
|
e.g:
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" --data '{"use_voice": true}' 'http://127.0.0.1:8080/v1/register/+431212131491291'```
|
```curl -X POST -H "Content-Type: application/json" --data '{"use_voice": true}' 'http://127.0.0.1:8080/v1/register/+431212131491291'```
|
||||||
|
|
||||||
* Verify the number using the code received via SMS/voice
|
* Verify the number using the code received via SMS/voice
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/<number>/verify/<verification code>'```
|
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/<number>/verify/<verification code>'```
|
||||||
|
|
||||||
e.g:
|
e.g:
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/+431212131491291/verify/123-456'```
|
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/+431212131491291/verify/123-456'```
|
||||||
|
|
||||||
* Send message to multiple recipients
|
* Send message to multiple recipients
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" -d '{"message": "<message>", "number": "<number>", "recipients": ["<recipient1>", "<recipient2>"]}' 'http://127.0.0.1:8080/v1/send'```
|
```curl -X POST -H "Content-Type: application/json" -d '{"message": "<message>", "number": "<number>", "recipients": ["<recipient1>", "<recipient2>"]}' 'http://127.0.0.1:8080/v1/send'```
|
||||||
|
|
||||||
e.g:
|
e.g:
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" -d '{"message": "Hello World!", "number": "+431212131491291", "recipients": ["+4354546464654", "+4912812812121"]}' 'http://127.0.0.1:8080/v1/send'```
|
```curl -X POST -H "Content-Type: application/json" -d '{"message": "Hello World!", "number": "+431212131491291", "recipients": ["+4354546464654", "+4912812812121"]}' 'http://127.0.0.1:8080/v1/send'```
|
||||||
|
|
||||||
* Send a message (+ base64 encoded attachment) to multiple recipients
|
* Send a message (+ base64 encoded attachment) to multiple recipients
|
||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" -d '{"message": "<message>", "base64_attachment": "<base64 encoded attachment>", "number": "<number>", "recipients": ["<recipient1>", "<recipient2>"]}' 'http://127.0.0.1:8080/v1/send'```
|
```curl -X POST -H "Content-Type: application/json" -d '{"message": "<message>", "base64_attachment": "<base64 encoded attachment>", "number": "<number>", "recipients": ["<recipient1>", "<recipient2>"]}' 'http://127.0.0.1:8080/v1/send'```
|
||||||
|
|
||||||
* Receive messages
|
* Receive messages
|
||||||
|
|
||||||
Fetch all new messages in the inbox of the specified number.
|
Fetch all new messages in the inbox of the specified number.
|
||||||
|
|
||||||
```curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/receive/<number>'```
|
```curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/receive/<number>'```
|
||||||
|
|
||||||
e.g:
|
e.g:
|
||||||
|
|
||||||
```curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/receive/+431212131491291'```
|
```curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/receive/+431212131491291'```
|
||||||
|
|
||||||
In case you need more functionality, please **file a ticket** or **create a PR**
|
* Create a new group
|
||||||
|
|
||||||
|
Create a new group with the specified name and members.
|
||||||
|
|
||||||
|
```curl -X POST -H "Content-Type: application/json" -d '{"name": "<group name>", "members": ["<member1>", "<member2>"]}' 'http://127.0.0.1:8080/v1/groups/<number>'```
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
|
||||||
|
```curl -X POST -H "Content-Type: application/json" -d '{"name": "my group", "members": ["+4354546464654", "+4912812812121"]}' 'http://127.0.0.1:8080/v1/groups/+431212131491291'```
|
||||||
|
|
||||||
|
* List groups
|
||||||
|
|
||||||
|
```curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/groups/<number>'```
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
|
||||||
|
```curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/groups/+431212131491291'```
|
||||||
|
|
||||||
|
* Delete a group
|
||||||
|
|
||||||
|
Delete the group with the given group id. The group id can be obtained via the "List groups" REST call.
|
||||||
|
|
||||||
|
```curl -X DELETE -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/groups/<number>/<group id>'```
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
|
||||||
|
```curl -X DELETE -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/groups/+431212131491291/ckRzaEd4VmRzNnJaASAEsasa'```
|
||||||
|
|
||||||
|
* Send a message to a group
|
||||||
|
|
||||||
|
```curl -X POST -H "Content-Type: application/json" -d '{"message": "Hello World!", "number": "<number>", "recipients": ["<group id>"], "is_group": true}' 'http://127.0.0.1:8080/v1/send'```
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
|
||||||
|
```curl -X POST -H "Content-Type: application/json" -d '{"message": "Hello World!", "number": "+431212131491291", "recipients": ["ckRzaEd4VmRzNnJaASAEsasa"], "is_group": true}' 'http://127.0.0.1:8080/v1/send'```
|
||||||
|
|
||||||
|
In case you need more functionality, please **file a ticket** or **create a PR**
|
||||||
|
|||||||
@@ -46,5 +46,33 @@ e.g:
|
|||||||
|
|
||||||
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/+431212131491291/verify/123-456'```
|
```curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/register/+431212131491291/verify/123-456'```
|
||||||
|
|
||||||
|
|
||||||
|
## Sending messages to Signal Messenger groups
|
||||||
|
|
||||||
|
The `signal-cli-rest-api` docker container is also capable of sending messages to a Signal Messenger group.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
* Home Assistant Version >= 0.109
|
||||||
|
* signal-cli-rest-api build-nr >= 2
|
||||||
|
The build number can be checked with: `curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/about`
|
||||||
|
* your phone number needs to be properly registered (see the "Register phone number" section above on how to do that)
|
||||||
|
|
||||||
|
A new Signal Messenger group can be created with the following REST API request:
|
||||||
|
|
||||||
|
```curl -X POST -H "Content-Type: application/json" -d '{"name": "<name of the group>", "members": ["<member1>", "<member2>"]}' 'http://127.0.0.1:8080/v1/groups/<number>'```
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
|
||||||
|
This creates a new Signal Messenger group called `my group` with the members `+4354546464654` and `+4912812812121`.
|
||||||
|
|
||||||
|
```curl -X POST -H "Content-Type: application/json" -d '{"name": "my group", "members": ["+4354546464654", "+4912812812121"]}' 'http://127.0.0.1:8080/v1/groups/+431212131491291'```
|
||||||
|
|
||||||
|
Next, use the following endpoint to obtain the group id:
|
||||||
|
|
||||||
|
```curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8080/v1/groups/<number>'```
|
||||||
|
|
||||||
|
The group id then needs to be added to the Home Assistant `configuration.yaml` file (see [here](https://www.home-assistant.io/integrations/signal_messenger/) for details)
|
||||||
|
|
||||||
# Troubleshooting
|
# Troubleshooting
|
||||||
In case you've problems with the `signal-cli-rest-api` container, have a look [here](TROUBLESHOOTING.md)
|
In case you've problems with the `signal-cli-rest-api` container, have a look [here](TROUBLESHOOTING.md)
|
||||||
|
|||||||
29
publish.sh
29
publish.sh
@@ -1,10 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
while getopts v: option
|
while getopts v:t: option
|
||||||
do
|
do
|
||||||
case "${option}"
|
case "${option}"
|
||||||
in
|
in
|
||||||
v) VERSION=${OPTARG};;
|
v) VERSION=${OPTARG};;
|
||||||
|
t) TAG=${OPTARG};;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -14,8 +15,20 @@ then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z "$TAG" ]
|
||||||
|
then
|
||||||
|
echo "Please provide a valid tag with the -t flag. e.g: -t stable (supported tags: dev, stable)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$TAG" != "dev" && "$TAG" != "stable" ]]; then
|
||||||
|
echo "Please use either dev or stable as tag"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "This will upload a new signal-cli-rest-api to dockerhub"
|
echo "This will upload a new signal-cli-rest-api to dockerhub"
|
||||||
echo "Version: $VERSION"
|
echo "Version: $VERSION"
|
||||||
|
echo "Tag: $TAG"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
read -r -p "Are you sure? [y/N] " response
|
read -r -p "Are you sure? [y/N] " response
|
||||||
@@ -27,10 +40,18 @@ case "$response" in
|
|||||||
|
|
||||||
docker buildx create --name multibuilder
|
docker buildx create --name multibuilder
|
||||||
docker buildx use multibuilder
|
docker buildx use multibuilder
|
||||||
|
|
||||||
|
if [[ "$TAG" == "stable" ]]; then
|
||||||
|
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t bbernhard/signal-cli-rest-api:$VERSION . --push
|
||||||
|
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t bbernhard/signal-cli-rest-api:latest . --push
|
||||||
|
fi
|
||||||
|
|
||||||
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t bbernhard/signal-cli-rest-api:$VERSION . --push
|
if [[ "$TAG" == "dev" ]]; then
|
||||||
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t bbernhard/signal-cli-rest-api:latest . --push
|
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t bbernhard/signal-cli-rest-api:${VERSION}-dev . --push
|
||||||
;;
|
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t bbernhard/signal-cli-rest-api:latest-dev . --push
|
||||||
|
fi
|
||||||
|
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Aborting"
|
echo "Aborting"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
214
src/main.go
214
src/main.go
@@ -1,32 +1,61 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/satori/go.uuid"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/h2non/filetype"
|
|
||||||
"os/exec"
|
|
||||||
"time"
|
|
||||||
"errors"
|
|
||||||
"flag"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"os"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/h2non/filetype"
|
||||||
|
"github.com/satori/go.uuid"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GroupEntry struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Id string `json:"id"`
|
||||||
|
InternalId string `json:"internal_id"`
|
||||||
|
Members []string `json:"members"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
Blocked bool `json:"blocked"`
|
||||||
|
}
|
||||||
|
|
||||||
func cleanupTmpFiles(paths []string) {
|
func cleanupTmpFiles(paths []string) {
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
os.Remove(path)
|
os.Remove(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func send(c *gin.Context, attachmentTmpDir string, signalCliConfig string, number string, message string, recipients []string, base64Attachments []string) {
|
func send(c *gin.Context, attachmentTmpDir string, signalCliConfig string, number string, message string,
|
||||||
|
recipients []string, base64Attachments []string, isGroup bool) {
|
||||||
cmd := []string{"--config", signalCliConfig, "-u", number, "send", "-m", message}
|
cmd := []string{"--config", signalCliConfig, "-u", number, "send", "-m", message}
|
||||||
cmd = append(cmd, recipients...)
|
|
||||||
|
|
||||||
|
if len(recipients) == 0 {
|
||||||
|
c.JSON(400, gin.H{"error": "Please specify at least one recipient"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isGroup {
|
||||||
|
cmd = append(cmd, recipients...)
|
||||||
|
} else {
|
||||||
|
if len(recipients) > 1 {
|
||||||
|
c.JSON(400, gin.H{"error": "More than one recipient is currently not allowed"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
groupId, err := base64.StdEncoding.DecodeString(recipients[0])
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid group id"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = append(cmd, []string{"-g", string(groupId)}...)
|
||||||
|
}
|
||||||
|
|
||||||
attachmentTmpPaths := []string{}
|
attachmentTmpPaths := []string{}
|
||||||
for _, base64Attachment := range base64Attachments {
|
for _, base64Attachment := range base64Attachments {
|
||||||
@@ -35,7 +64,7 @@ func send(c *gin.Context, attachmentTmpDir string, signalCliConfig string, numbe
|
|||||||
c.JSON(400, gin.H{"error": err.Error()})
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dec, err := base64.StdEncoding.DecodeString(base64Attachment)
|
dec, err := base64.StdEncoding.DecodeString(base64Attachment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(400, gin.H{"error": err.Error()})
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
@@ -74,7 +103,7 @@ func send(c *gin.Context, attachmentTmpDir string, signalCliConfig string, numbe
|
|||||||
|
|
||||||
if len(attachmentTmpPaths) > 0 {
|
if len(attachmentTmpPaths) > 0 {
|
||||||
cmd = append(cmd, "-a")
|
cmd = append(cmd, "-a")
|
||||||
cmd = append(cmd , attachmentTmpPaths...)
|
cmd = append(cmd, attachmentTmpPaths...)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := runSignalCli(cmd)
|
_, err := runSignalCli(cmd)
|
||||||
@@ -86,6 +115,66 @@ func send(c *gin.Context, attachmentTmpDir string, signalCliConfig string, numbe
|
|||||||
c.JSON(201, nil)
|
c.JSON(201, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getGroups(number string, signalCliConfig string) ([]GroupEntry, error) {
|
||||||
|
groupEntries := []GroupEntry{}
|
||||||
|
|
||||||
|
out, err := runSignalCli([]string{"--config", signalCliConfig, "-u", number, "listGroups", "-d"})
|
||||||
|
if err != nil {
|
||||||
|
return groupEntries, err
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(out, "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
var groupEntry GroupEntry
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
idIdx := strings.Index(line, " Name: ")
|
||||||
|
idPair := line[:idIdx]
|
||||||
|
groupEntry.InternalId = strings.TrimPrefix(idPair, "Id: ")
|
||||||
|
groupEntry.Id = base64.StdEncoding.EncodeToString([]byte(groupEntry.InternalId))
|
||||||
|
lineWithoutId := strings.TrimLeft(line[idIdx:], " ")
|
||||||
|
|
||||||
|
nameIdx := strings.Index(lineWithoutId, " Active: ")
|
||||||
|
namePair := lineWithoutId[:nameIdx]
|
||||||
|
groupEntry.Name = strings.TrimRight(strings.TrimPrefix(namePair, "Name: "), " ")
|
||||||
|
lineWithoutName := strings.TrimLeft(lineWithoutId[nameIdx:], " ")
|
||||||
|
|
||||||
|
activeIdx := strings.Index(lineWithoutName, " Blocked: ")
|
||||||
|
activePair := lineWithoutName[:activeIdx]
|
||||||
|
active := strings.TrimPrefix(activePair, "Active: ")
|
||||||
|
if active == "true" {
|
||||||
|
groupEntry.Active = true
|
||||||
|
} else {
|
||||||
|
groupEntry.Active = false
|
||||||
|
}
|
||||||
|
lineWithoutActive := strings.TrimLeft(lineWithoutName[activeIdx:], " ")
|
||||||
|
|
||||||
|
blockedIdx := strings.Index(lineWithoutActive, " Members: ")
|
||||||
|
blockedPair := lineWithoutActive[:blockedIdx]
|
||||||
|
blocked := strings.TrimPrefix(blockedPair, "Blocked: ")
|
||||||
|
if blocked == "true" {
|
||||||
|
groupEntry.Blocked = true
|
||||||
|
} else {
|
||||||
|
groupEntry.Blocked = false
|
||||||
|
}
|
||||||
|
lineWithoutBlocked := strings.TrimLeft(lineWithoutActive[blockedIdx:], " ")
|
||||||
|
|
||||||
|
membersPair := lineWithoutBlocked
|
||||||
|
members := strings.TrimPrefix(membersPair, "Members: ")
|
||||||
|
trimmedMembers := strings.TrimRight(strings.TrimLeft(members, "["), "]")
|
||||||
|
trimmedMembersList := strings.Split(trimmedMembers, ",")
|
||||||
|
for _, member := range trimmedMembersList {
|
||||||
|
groupEntry.Members = append(groupEntry.Members, strings.Trim(member, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
groupEntries = append(groupEntries, groupEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupEntries, nil
|
||||||
|
}
|
||||||
|
|
||||||
func runSignalCli(args []string) (string, error) {
|
func runSignalCli(args []string) (string, error) {
|
||||||
cmd := exec.Command("signal-cli", args...)
|
cmd := exec.Command("signal-cli", args...)
|
||||||
var errBuffer bytes.Buffer
|
var errBuffer bytes.Buffer
|
||||||
@@ -128,16 +217,17 @@ func main() {
|
|||||||
router.GET("/v1/about", func(c *gin.Context) {
|
router.GET("/v1/about", func(c *gin.Context) {
|
||||||
type About struct {
|
type About struct {
|
||||||
SupportedApiVersions []string `json:"versions"`
|
SupportedApiVersions []string `json:"versions"`
|
||||||
|
BuildNr int `json:"build"`
|
||||||
}
|
}
|
||||||
|
|
||||||
about := About{SupportedApiVersions: []string{"v1", "v2"}}
|
about := About{SupportedApiVersions: []string{"v1", "v2"}, BuildNr: 2}
|
||||||
c.JSON(200, about)
|
c.JSON(200, about)
|
||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/v1/register/:number", func(c *gin.Context) {
|
router.POST("/v1/register/:number", func(c *gin.Context) {
|
||||||
number := c.Param("number")
|
number := c.Param("number")
|
||||||
|
|
||||||
type Request struct{
|
type Request struct {
|
||||||
UseVoice bool `json:"use_voice"`
|
UseVoice bool `json:"use_voice"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +279,6 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_, err := runSignalCli([]string{"--config", *signalCliConfig, "-u", number, "verify", token})
|
_, err := runSignalCli([]string{"--config", *signalCliConfig, "-u", number, "verify", token})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(400, gin.H{"error": err.Error()})
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
@@ -199,11 +288,12 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/v1/send", func(c *gin.Context) {
|
router.POST("/v1/send", func(c *gin.Context) {
|
||||||
type Request struct{
|
type Request struct {
|
||||||
Number string `json:"number"`
|
Number string `json:"number"`
|
||||||
Recipients []string `json:"recipients"`
|
Recipients []string `json:"recipients"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
Base64Attachment string `json:"base64_attachment"`
|
Base64Attachment string `json:"base64_attachment"`
|
||||||
|
IsGroup bool `json:"is_group"`
|
||||||
}
|
}
|
||||||
var req Request
|
var req Request
|
||||||
err := c.BindJSON(&req)
|
err := c.BindJSON(&req)
|
||||||
@@ -217,15 +307,16 @@ func main() {
|
|||||||
base64Attachments = append(base64Attachments, req.Base64Attachment)
|
base64Attachments = append(base64Attachments, req.Base64Attachment)
|
||||||
}
|
}
|
||||||
|
|
||||||
send(c, *signalCliConfig, *signalCliConfig, req.Number, req.Message, req.Recipients, base64Attachments)
|
send(c, *signalCliConfig, *signalCliConfig, req.Number, req.Message, req.Recipients, base64Attachments, req.IsGroup)
|
||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/v2/send", func(c *gin.Context) {
|
router.POST("/v2/send", func(c *gin.Context) {
|
||||||
type Request struct{
|
type Request struct {
|
||||||
Number string `json:"number"`
|
Number string `json:"number"`
|
||||||
Recipients []string `json:"recipients"`
|
Recipients []string `json:"recipients"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
Base64Attachments []string `json:"base64_attachments"`
|
Base64Attachments []string `json:"base64_attachments"`
|
||||||
|
IsGroup bool `json:"is_group"`
|
||||||
}
|
}
|
||||||
var req Request
|
var req Request
|
||||||
err := c.BindJSON(&req)
|
err := c.BindJSON(&req)
|
||||||
@@ -235,7 +326,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
send(c, *attachmentTmpDir, *signalCliConfig, req.Number, req.Message, req.Recipients, req.Base64Attachments)
|
send(c, *attachmentTmpDir, *signalCliConfig, req.Number, req.Message, req.Recipients, req.Base64Attachments, req.IsGroup)
|
||||||
})
|
})
|
||||||
|
|
||||||
router.GET("/v1/receive/:number", func(c *gin.Context) {
|
router.GET("/v1/receive/:number", func(c *gin.Context) {
|
||||||
@@ -247,10 +338,10 @@ func main() {
|
|||||||
c.JSON(400, err.Error())
|
c.JSON(400, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
out = strings.Trim(out, "\n")
|
out = strings.Trim(out, "\n")
|
||||||
lines := strings.Split(out, "\n")
|
lines := strings.Split(out, "\n")
|
||||||
|
|
||||||
jsonStr := "["
|
jsonStr := "["
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
jsonStr += line
|
jsonStr += line
|
||||||
@@ -263,5 +354,68 @@ func main() {
|
|||||||
c.String(200, jsonStr)
|
c.String(200, jsonStr)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.POST("/v1/groups/:number", func(c *gin.Context) {
|
||||||
|
number := c.Param("number")
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Members []string `json:"members"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var req Request
|
||||||
|
err := c.BindJSON(&req)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, "Couldn't process request - invalid request")
|
||||||
|
log.Error(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := []string{"--config", *signalCliConfig, "-u", number, "updateGroup", "-n", req.Name, "-m"}
|
||||||
|
cmd = append(cmd, req.Members...)
|
||||||
|
log.Info(cmd)
|
||||||
|
out, err := runSignalCli(cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info(out)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/v1/groups/:number", func(c *gin.Context) {
|
||||||
|
number := c.Param("number")
|
||||||
|
|
||||||
|
groups, err := getGroups(number, *signalCliConfig)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, groups)
|
||||||
|
})
|
||||||
|
|
||||||
|
router.DELETE("/v1/groups/:number/:groupid", func(c *gin.Context) {
|
||||||
|
base64EncodedGroupId := c.Param("groupid")
|
||||||
|
number := c.Param("number")
|
||||||
|
|
||||||
|
if base64EncodedGroupId == "" {
|
||||||
|
c.JSON(400, gin.H{"error": "Please specify a group id"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
groupId, err := base64.StdEncoding.DecodeString(base64EncodedGroupId)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid group id"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = runSignalCli([]string{"--config", *signalCliConfig, "-u", number, "quitGroup", "-g", string(groupId)})
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
router.Run()
|
router.Run()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user