From 252389efbe7222185c9b2b23d5cfa2c11d2f6717 Mon Sep 17 00:00:00 2001 From: ildyria Date: Sun, 19 Apr 2026 11:26:49 +0200 Subject: [PATCH 01/40] Pin dependencies --- .github/workflows/ci.yml | 6 +++--- .github/workflows/release-dev-version.yml | 6 +++--- .github/workflows/release-productive-version.yml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index edf270b..ba197bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,9 +13,9 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Available platforms run: echo ${{ steps.buildx.outputs.platforms }} - name: Install Podman @@ -29,7 +29,7 @@ jobs: with: ref: ${{ github.ref }} - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/release-dev-version.yml b/.github/workflows/release-dev-version.yml index 3a46d0d..b2d59cd 100644 --- a/.github/workflows/release-dev-version.yml +++ b/.github/workflows/release-dev-version.yml @@ -13,9 +13,9 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Available platforms run: echo ${{ steps.buildx.outputs.platforms }} - name: Install Podman @@ -28,7 +28,7 @@ jobs: with: ref: ${{ github.ref }} - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/release-productive-version.yml b/.github/workflows/release-productive-version.yml index 750d9f4..dc0a491 100644 --- a/.github/workflows/release-productive-version.yml +++ b/.github/workflows/release-productive-version.yml @@ -13,9 +13,9 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Available platforms run: echo ${{ steps.buildx.outputs.platforms }} - name: Install Podman @@ -28,7 +28,7 @@ jobs: with: ref: ${{ github.ref }} - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} From e0af0091c94635f229417d5b45a2ac1817d5872e Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Sun, 19 Apr 2026 22:40:42 +0200 Subject: [PATCH 02/40] Add receive v1 json schemas to swagger This is done with a custom script to embed the schemas from signal-cli into the docs.go file --- Dockerfile | 7 +- src/docs/README.md | 8 + src/docs/add_v1_receive_schemas.go | 369 +++++++++++++++++++++++++++++ 3 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 src/docs/add_v1_receive_schemas.go diff --git a/Dockerfile b/Dockerfile index 8204dc3..6a352ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -87,7 +87,8 @@ RUN if [ "$(uname -m)" = "x86_64" ]; then \ && zip -qu libsignal-client.jar libsignal_jni.so \ && cd /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source \ && git apply /tmp/signal-cli-native.patch \ - && ./gradlew -q nativeCompile; \ + && ./gradlew -q nativeCompile \ + && ./gradlew jsonSchemas; \ elif [ "$(uname -m)" = "aarch64" ] ; then \ echo "Use native image from @morph027 (https://packaging.gitlab.io/signal-cli/) for arm64 - many thanks to @morph027" \ && curl -fsSL https://packaging.gitlab.io/signal-cli/gpg.key | gpg -o /usr/share/keyrings/signal-cli-native.pgp --dearmor \ @@ -152,6 +153,10 @@ RUN cd /tmp/signal-cli-rest-api-src/scripts && go build -o jsonrpc2-helper # build plugin_loader RUN cd /tmp/signal-cli-rest-api-src && go build -buildmode=plugin -o signal-cli-rest-api_plugin_loader.so plugin_loader.go +# Manually add the json schemas for the receive V1 endpoint +RUN cd /tmp/signal-cli-rest-api-src/src/docs \ + && go run update_receive_docs.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas + # Start a fresh container for release container # eclipse-temurin doesn't provide a OpenJDK 21 image for armv7 (see https://github.com/adoptium/containers/issues/502). Until this diff --git a/src/docs/README.md b/src/docs/README.md index 9810225..08f5f0b 100644 --- a/src/docs/README.md +++ b/src/docs/README.md @@ -21,6 +21,14 @@ Regenerate the files with your local source code changes. ```bash swag init --requiredByDefault ``` +1. Set the current working dir to `src/docs` + ```bash + cd docs + ``` +1. Run the script to add the receive V1 schemas + ```bash + go run add_v1_receive_schemas.go + ``` ## Run the web server diff --git a/src/docs/add_v1_receive_schemas.go b/src/docs/add_v1_receive_schemas.go new file mode 100644 index 0000000..ce5607a --- /dev/null +++ b/src/docs/add_v1_receive_schemas.go @@ -0,0 +1,369 @@ +//go:build ignore + +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "sort" + "strconv" + "strings" + + _ "github.com/bbernhard/signal-cli-rest-api/docs" +) + +const ( + docsPath = "docs.go" + openMarker = "const docTemplate = `" + closeMarker = "`\n\n// SwaggerInfo" + definitionsKey = `"definitions": {` + receivePrefix = "receive." + receivePathKey = `"/v1/receive/{number}":` + receiveWrapper = "data.Message" +) + +func main() { + if len(os.Args) != 2 { + fmt.Fprintf(os.Stderr, "usage: go run update_receive_docs.go \n") + os.Exit(1) + } + receiveDir := os.Args[1] + + if err := run(receiveDir); err != nil { + fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) + } +} + +func run(receiveDir string) error { + content, err := os.ReadFile(docsPath) + if err != nil { + return fmt.Errorf("read %s: %w", docsPath, err) + } + + template, err := extractDocTemplate(string(content)) + if err != nil { + return err + } + + definitions := make(map[string]interface{}) + + titleByFile, err := addReceiveSchemas(definitions, receiveDir) + if err != nil { + return err + } + + if err := updateReceiveSchemaRefs(definitions, titleByFile); err != nil { + return err + } + + addEnvelopeWrapperDefinition(definitions) + + newEntries, err := renderManagedDefinitions(definitions) + if err != nil { + return err + } + + updatedTemplate, err := appendDefinitionsEntries(template, newEntries) + if err != nil { + return err + } + + updatedTemplate, err = replaceReceiveResponseSchema(updatedTemplate) + if err != nil { + return err + } + + updated := strings.Replace(string(content), template, updatedTemplate, 1) + + if err := os.WriteFile(docsPath, []byte(updated), 0644); err != nil { + return fmt.Errorf("write %s: %w", docsPath, err) + } + + fmt.Printf("updated %s\n", docsPath) + return nil +} + +func extractDocTemplate(content string) (string, error) { + start := strings.Index(content, openMarker) + if start == -1 { + return "", fmt.Errorf("could not find docTemplate start in %s", docsPath) + } + + start += len(openMarker) + endOffset := strings.Index(content[start:], closeMarker) + if endOffset == -1 { + return "", fmt.Errorf("could not find docTemplate end in %s", docsPath) + } + + return content[start : start+endOffset], nil +} + +func definitionsBounds(template string) (int, int, error) { + definitionsIndex := strings.Index(template, definitionsKey) + if definitionsIndex == -1 { + return -1, -1, fmt.Errorf("could not find definitions block in docTemplate") + } + + braceIndex := definitionsIndex + strings.Index(definitionsKey, "{") + closingBraceIndex, err := findMatchingBrace(template, braceIndex) + if err != nil { + return -1, -1, err + } + + return braceIndex, closingBraceIndex, nil +} + +func appendDefinitionsEntries(template string, entries string) (string, error) { + braceIndex, closingBraceIndex, err := definitionsBounds(template) + if err != nil { + return "", err + } + + definitionsBlock := template[braceIndex : closingBraceIndex+1] + if strings.Contains(definitionsBlock, `"`+receiveWrapper+`"`) || strings.Contains(definitionsBlock, `"`+receivePrefix) { + return "", fmt.Errorf("definitions already contain receive entries; run swag init first") + } + + inner := strings.TrimSpace(template[braceIndex+1 : closingBraceIndex]) + + if inner == "" { + return template[:braceIndex+1] + "\n" + entries + "\n" + template[closingBraceIndex:], nil + } + + closingLine := "\n }" + insertIndex := strings.LastIndex(template[:closingBraceIndex+1], closingLine) + if insertIndex == -1 { + return "", fmt.Errorf("could not determine definitions closing line") + } + + return template[:insertIndex] + ",\n" + entries + template[insertIndex:], nil +} + +func addReceiveSchemas(definitions map[string]interface{}, receiveDir string) (map[string]string, error) { + entries, err := os.ReadDir(receiveDir) + if err != nil { + return nil, fmt.Errorf("read %s: %w", receiveDir, err) + } + + files := make([]string, 0) + for _, entry := range entries { + if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".schema.json") { + continue + } + files = append(files, entry.Name()) + } + sort.Strings(files) + titleByFile := make(map[string]string, len(files)) + + for _, name := range files { + fullPath := filepath.Join(receiveDir, name) + data, err := os.ReadFile(fullPath) + if err != nil { + return nil, fmt.Errorf("read schema file %s: %w", fullPath, err) + } + + var schemaObj map[string]interface{} + if err := json.Unmarshal(data, &schemaObj); err != nil { + return nil, fmt.Errorf("parse schema file %s: %w", fullPath, err) + } + + title, ok := schemaObj["title"].(string) + if !ok || strings.TrimSpace(title) == "" { + return nil, fmt.Errorf("schema file %s is missing title", fullPath) + } + + titleByFile[name] = title + definitions[receivePrefix+title] = removeSchemaKeysRecursive(schemaObj, "") + } + + return titleByFile, nil +} + +func removeSchemaKeysRecursive(value interface{}, parentKey string) interface{} { + switch typed := value.(type) { + case map[string]interface{}: + updated := make(map[string]interface{}, len(typed)) + for key, item := range typed { + if key == "$schema" || key == "$id" { + continue + } + if key == "title" && parentKey != "properties" { + continue + } + updated[key] = removeSchemaKeysRecursive(item, key) + } + return updated + case []interface{}: + updated := make([]interface{}, len(typed)) + for idx, item := range typed { + updated[idx] = removeSchemaKeysRecursive(item, parentKey) + } + return updated + default: + return value + } +} + +func updateReceiveSchemaRefs(definitions map[string]interface{}, titleByFile map[string]string) error { + for key, value := range definitions { + if !strings.HasPrefix(key, receivePrefix) { + continue + } + definitions[key] = rewriteSchemaRefs(value, titleByFile) + } + + return nil +} + +func rewriteSchemaRefs(value interface{}, titleByFile map[string]string) interface{} { + switch typed := value.(type) { + case map[string]interface{}: + updated := make(map[string]interface{}, len(typed)) + for k, v := range typed { + if k == "$ref" { + if refValue, ok := v.(string); ok { + if strings.HasSuffix(refValue, ".schema.json") { + base := filepath.Base(refValue) + if title, exists := titleByFile[base]; exists { + updated[k] = "#/definitions/" + receivePrefix + title + continue + } + } + } + } + + updated[k] = rewriteSchemaRefs(v, titleByFile) + } + return updated + case []interface{}: + updated := make([]interface{}, len(typed)) + for idx, item := range typed { + updated[idx] = rewriteSchemaRefs(item, titleByFile) + } + return updated + default: + return value + } +} + +func addEnvelopeWrapperDefinition(definitions map[string]interface{}) { + definitions[receiveWrapper] = map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "account": map[string]interface{}{"type": "string"}, + "envelope": map[string]interface{}{"$ref": "#/definitions/receive.MessageEnvelope"}, + }, + "required": []interface{}{"account", "envelope"}, + } +} + +func renderManagedDefinitions(definitions map[string]interface{}) (string, error) { + keys := make([]string, 0, len(definitions)) + for key := range definitions { + keys = append(keys, key) + } + sort.Strings(keys) + + parts := make([]string, 0, len(keys)) + for _, key := range keys { + raw, err := json.MarshalIndent(definitions[key], "", " ") + if err != nil { + return "", fmt.Errorf("marshal definition %s: %w", key, err) + } + + lines := strings.Split(string(raw), "\n") + for idx := range lines { + lines[idx] = " " + lines[idx] + } + + entry := " " + strconv.Quote(key) + ": " + strings.TrimPrefix(lines[0], " ") + if len(lines) > 1 { + entry += "\n" + strings.Join(lines[1:], "\n") + } + + parts = append(parts, entry) + } + + return strings.Join(parts, ",\n"), nil +} + +func replaceReceiveResponseSchema(template string) (string, error) { + pathIndex := strings.Index(template, receivePathKey) + if pathIndex == -1 { + return "", fmt.Errorf("could not find receive path block; run swag init first") + } + braceOffset := strings.Index(template[pathIndex+len(receivePathKey):], "{") + if braceOffset == -1 { + return "", fmt.Errorf("could not find opening brace for receive path block") + } + pathOpenBrace := pathIndex + len(receivePathKey) + braceOffset + pathCloseBrace, err := findMatchingBrace(template, pathOpenBrace) + if err != nil { + return "", err + } + + pathBlock := template[pathOpenBrace : pathCloseBrace+1] + + oldSchema := `"schema": { + "type": "array", + "items": { + "type": "string" + } + }` + + newSchema := `"schema": { + "$ref": "#/definitions/data.Message" + }` + + updatedPathBlock := strings.Replace(pathBlock, oldSchema, newSchema, 1) + if updatedPathBlock == pathBlock { + return "", fmt.Errorf("could not replace /v1/receive schema; ensure docs.go is freshly generated by swag") + } + + return template[:pathOpenBrace] + updatedPathBlock + template[pathCloseBrace+1:], nil +} + +func findMatchingBrace(input string, openBraceIndex int) (int, error) { + depth := 0 + inString := false + escaped := false + + for index := openBraceIndex; index < len(input); index++ { + char := input[index] + + if inString { + if escaped { + escaped = false + continue + } + if char == '\\' { + escaped = true + continue + } + if char == '"' { + inString = false + } + continue + } + + if char == '"' { + inString = true + continue + } + + switch char { + case '{': + depth++ + case '}': + depth-- + if depth == 0 { + return index, nil + } + } + } + + return -1, fmt.Errorf("could not find matching brace") +} From e712494d7f36f3afd49dba3fed0ab41c224e3bfd Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 20 Apr 2026 00:20:37 +0200 Subject: [PATCH 03/40] Only build docs on x86_64 --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6a352ff..16d8ed3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -154,8 +154,10 @@ RUN cd /tmp/signal-cli-rest-api-src/scripts && go build -o jsonrpc2-helper RUN cd /tmp/signal-cli-rest-api-src && go build -buildmode=plugin -o signal-cli-rest-api_plugin_loader.so plugin_loader.go # Manually add the json schemas for the receive V1 endpoint -RUN cd /tmp/signal-cli-rest-api-src/src/docs \ - && go run update_receive_docs.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas +RUN if [ "$(uname -m)" = "x86_64" ]; then \ + cd /tmp/signal-cli-rest-api-src/src/docs \ + && go run update_receive_docs.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ + fi; # Start a fresh container for release container From 0f2c12f28ee5af6ae1a8f40d26599357ee01fbc6 Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 20 Apr 2026 00:21:33 +0200 Subject: [PATCH 04/40] Use tabs --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 16d8ed3..e360006 100644 --- a/Dockerfile +++ b/Dockerfile @@ -155,8 +155,8 @@ RUN cd /tmp/signal-cli-rest-api-src && go build -buildmode=plugin -o signal-cli- # Manually add the json schemas for the receive V1 endpoint RUN if [ "$(uname -m)" = "x86_64" ]; then \ - cd /tmp/signal-cli-rest-api-src/src/docs \ - && go run update_receive_docs.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ + cd /tmp/signal-cli-rest-api-src/src/docs \ + && go run update_receive_docs.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ fi; # Start a fresh container for release container From 881e9203c1cec2f0cbdb25978b7242fe5cee8c9f Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Sat, 2 May 2026 22:54:44 +0200 Subject: [PATCH 05/40] switch back to apt-download for arm64 package --- Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index df8a7c9..c508169 100644 --- a/Dockerfile +++ b/Dockerfile @@ -97,11 +97,11 @@ RUN if [ "$(uname -m)" = "x86_64" ]; then \ && echo "deb [signed-by=/usr/share/keyrings/signal-cli-native.pgp] https://packaging.gitlab.io/signal-cli signalcli main" > /etc/apt/sources.list.d/morph027-signal-cli.list \ && mkdir -p /tmp/signal-cli-native \ && cd /tmp/signal-cli-native \ - && wget https://gitlab.com/packaging/signal-cli/-/jobs/14049119045/artifacts/download?file_type=archive -O /tmp/signal-cli-native/archive.zip \ - && unzip archive.zip \ - && mv signal-cli-native-arm64-trigger/*deb . \ - #&& apt-get update \ - #&& apt-get download signal-cli-native=${SIGNAL_CLI_NATIVE_PACKAGE_VERSION} \ + #&& wget https://gitlab.com/packaging/signal-cli/-/jobs/14049119045/artifacts/download?file_type=archive -O /tmp/signal-cli-native/archive.zip \ + #&& unzip archive.zip \ + #&& mv signal-cli-native-arm64-trigger/*deb . \ + && apt-get update \ + && apt-get download signal-cli-native=${SIGNAL_CLI_NATIVE_PACKAGE_VERSION} \ && ar x *.deb \ && tar xf data.tar.gz \ && mkdir -p /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile \ From 0a7c53a10a7672f90cc47fbe11cd41ad231585f4 Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 12:50:49 +0100 Subject: [PATCH 06/40] fix: docs paths in docker build --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ac09709..38fd2fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -143,6 +143,7 @@ COPY src/main.go /tmp/signal-cli-rest-api-src/ COPY src/go.mod /tmp/signal-cli-rest-api-src/ COPY src/go.sum /tmp/signal-cli-rest-api-src/ COPY src/plugin_loader.go /tmp/signal-cli-rest-api-src/ +COPY src/docs/add_v1_receive_schemas.go /tmp/signal-cli-rest-api-src/docs/add_v1_receive_schemas.go # build signal-cli-rest-api RUN ls -la /tmp/signal-cli-rest-api-src @@ -158,8 +159,8 @@ RUN cd /tmp/signal-cli-rest-api-src && go build -buildmode=plugin -o signal-cli- # Manually add the json schemas for the receive V1 endpoint RUN if [ "$(uname -m)" = "x86_64" ]; then \ - cd /tmp/signal-cli-rest-api-src/src/docs \ - && go run update_receive_docs.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ + cd /tmp/signal-cli-rest-api-src/docs \ + && go run add_v1_receive_schemas.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ fi; # Start a fresh container for release container From cb5e64a6d59f750b81a5f1c7b179c34d0b2e2e77 Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 13:00:45 +0100 Subject: [PATCH 07/40] Add the schemas before building the binary --- Dockerfile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 38fd2fe..8103d7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -148,6 +148,13 @@ COPY src/docs/add_v1_receive_schemas.go /tmp/signal-cli-rest-api-src/docs/add_v1 # build signal-cli-rest-api RUN ls -la /tmp/signal-cli-rest-api-src RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefault + +# Manually add the json schemas for the receive V1 endpoint +RUN if [ "$(uname -m)" = "x86_64" ]; then \ + cd /tmp/signal-cli-rest-api-src/docs \ + && go run add_v1_receive_schemas.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ + fi; + RUN cd /tmp/signal-cli-rest-api-src && go build -o signal-cli-rest-api main.go RUN cd /tmp/signal-cli-rest-api-src && go test ./client -v && go test ./utils -v @@ -157,12 +164,6 @@ RUN cd /tmp/signal-cli-rest-api-src/scripts && go build -o jsonrpc2-helper # build plugin_loader RUN cd /tmp/signal-cli-rest-api-src && go build -buildmode=plugin -o signal-cli-rest-api_plugin_loader.so plugin_loader.go -# Manually add the json schemas for the receive V1 endpoint -RUN if [ "$(uname -m)" = "x86_64" ]; then \ - cd /tmp/signal-cli-rest-api-src/docs \ - && go run add_v1_receive_schemas.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ - fi; - # Start a fresh container for release container # eclipse-temurin doesn't provide a OpenJDK 21 image for armv7 (see https://github.com/adoptium/containers/issues/502). Until this From 2ac55eec07166806e196285074a415d50091be28 Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 13:02:51 +0100 Subject: [PATCH 08/40] Split comments in docker build --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8103d7f..7b20209 100644 --- a/Dockerfile +++ b/Dockerfile @@ -145,16 +145,18 @@ COPY src/go.sum /tmp/signal-cli-rest-api-src/ COPY src/plugin_loader.go /tmp/signal-cli-rest-api-src/ COPY src/docs/add_v1_receive_schemas.go /tmp/signal-cli-rest-api-src/docs/add_v1_receive_schemas.go -# build signal-cli-rest-api RUN ls -la /tmp/signal-cli-rest-api-src + +# build the docs RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefault -# Manually add the json schemas for the receive V1 endpoint +# manually add the json schemas for the receive V1 endpoint to the docs RUN if [ "$(uname -m)" = "x86_64" ]; then \ cd /tmp/signal-cli-rest-api-src/docs \ && go run add_v1_receive_schemas.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ fi; +# build signal-cli-rest-api RUN cd /tmp/signal-cli-rest-api-src && go build -o signal-cli-rest-api main.go RUN cd /tmp/signal-cli-rest-api-src && go test ./client -v && go test ./utils -v From eda99213a7ff163867645a233ab857c3a2fcdfd5 Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 13:36:25 +0100 Subject: [PATCH 09/40] fix: remove swagger.json and swagger.yaml files --- Dockerfile | 2 +- src/docs/README.md | 4 +- src/docs/swagger.json | 3838 ----------------------------------------- src/docs/swagger.yaml | 2590 --------------------------- 4 files changed, 3 insertions(+), 6431 deletions(-) delete mode 100644 src/docs/swagger.json delete mode 100644 src/docs/swagger.yaml diff --git a/Dockerfile b/Dockerfile index 7b20209..b27f64f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -148,7 +148,7 @@ COPY src/docs/add_v1_receive_schemas.go /tmp/signal-cli-rest-api-src/docs/add_v1 RUN ls -la /tmp/signal-cli-rest-api-src # build the docs -RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefault +RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefault --outputTypes go # manually add the json schemas for the receive V1 endpoint to the docs RUN if [ "$(uname -m)" = "x86_64" ]; then \ diff --git a/src/docs/README.md b/src/docs/README.md index 08f5f0b..20d1b0d 100644 --- a/src/docs/README.md +++ b/src/docs/README.md @@ -15,11 +15,11 @@ Regenerate the files with your local source code changes. 1. Run swag to generate the docs * Option 1, via docker ```bash - docker run --rm -v $(pwd):/code ghcr.io/swaggo/swag:latest init --requiredByDefault + docker run --rm -v $(pwd):/code ghcr.io/swaggo/swag:latest init --requiredByDefault --outputTypes go ``` * Option 2, install swag and run the command line tool ```bash - swag init --requiredByDefault + swag init --requiredByDefault --outputTypes go ``` 1. Set the current working dir to `src/docs` ```bash diff --git a/src/docs/swagger.json b/src/docs/swagger.json deleted file mode 100644 index e8fbd6f..0000000 --- a/src/docs/swagger.json +++ /dev/null @@ -1,3838 +0,0 @@ -{ - "schemes": [ - "http" - ], - "swagger": "2.0", - "info": { - "description": "This is the Signal Cli REST API documentation.", - "title": "Signal Cli REST API", - "contact": {}, - "version": "1.0" - }, - "host": "localhost:8080", - "basePath": "/", - "paths": { - "/v1/about": { - "get": { - "description": "Returns the supported API versions and the internal build nr", - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Lists general information about the API", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.About" - } - } - } - } - }, - "/v1/accounts": { - "get": { - "description": "Lists all of the accounts linked or registered", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "List all accounts", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/pin": { - "post": { - "description": "Sets a new Signal Pin", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Set Pin", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SetPinRequest" - } - } - ], - "responses": { - "201": { - "description": "Created" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Removes a Signal Pin", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Remove Pin", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/rate-limit-challenge": { - "post": { - "description": "When running into rate limits, sometimes the limit can be lifted, by solving a CAPTCHA. To get the captcha token, go to https://signalcaptchas.org/challenge/generate.html For the staging environment, use: https://signalcaptchas.org/staging/registration/generate.html. The \"challenge_token\" is the token from the failed send attempt. The \"captcha\" is the captcha result, starting with signalcaptcha://", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Lift rate limit restrictions by solving a captcha.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RateLimitChallengeRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/settings": { - "put": { - "description": "Update the account attributes on the signal server.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Update the account settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateAccountSettingsRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/username": { - "post": { - "description": "Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Set a username.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SetUsernameRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/client.SetUsernameResponse" - } - }, - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Delete the username associated with this account.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Remove a username.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/attachments": { - "get": { - "description": "List all downloaded attachments", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "List all attachments.", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/attachments/{attachment}": { - "get": { - "description": "Serve the attachment with the given id", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "Serve Attachment.", - "parameters": [ - { - "type": "string", - "description": "Attachment ID", - "name": "attachment", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove the attachment with the given id from filesystem.", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "Remove attachment.", - "parameters": [ - { - "type": "string", - "description": "Attachment ID", - "name": "attachment", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/configuration": { - "get": { - "description": "List the REST API configuration.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "List the REST API configuration.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.Configuration" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Set the REST API configuration.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Set the REST API configuration.", - "parameters": [ - { - "description": "Configuration", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.Configuration" - } - } - ], - "responses": { - "204": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/configuration/{number}/settings": { - "get": { - "description": "List account specific settings.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "List account specific settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustModeResponse" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Set account specific settings.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Set account specific settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustModeRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}": { - "get": { - "description": "List all contacts for the given number.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "List Contacts", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Include all known recipients, not only contacts.", - "name": "all_recipients", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListContactsResponse" - } - } - } - } - }, - "put": { - "description": "Updates the info associated to a number on the contact list.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Updates the info associated to a number on the contact list. If the contact doesn’t exist yet, it will be added.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Contact", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateContactRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}/sync": { - "post": { - "description": "Send a synchronization message with the local contacts list to all linked devices. This command should only be used if this is the primary device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Send a synchronization message with the local contacts list to all linked devices.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}/{uuid}": { - "get": { - "description": "List a specific contact.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "List Contact", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Include all known recipients, not only contacts.", - "name": "all_recipients", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.ListContactsResponse" - } - } - } - } - }, - "/v1/contacts/{number}/{uuid}/avatar": { - "get": { - "description": "Returns the avatar of a contact.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Returns the avatar of a contact", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/devices/{number}": { - "get": { - "description": "List linked devices associated to this device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "List linked devices.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListDevicesResponse" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Links another device to this device. Only works, if this is the master device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Links another device to this device.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.AddDeviceRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/devices/{number}/local-data": { - "delete": { - "description": "Delete all local data for the specified account. Only use this after unregistering the account or after removing a linked device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Delete local account data", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Cleanup options", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.DeleteLocalAccountDataRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/devices/{number}/{deviceId}": { - "delete": { - "description": "Remove a linked device from the primary account.", - "tags": [ - "Devices" - ], - "summary": "Remove linked device", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Device ID from listDevices", - "name": "deviceId", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}": { - "get": { - "description": "List all Signal Groups.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "List all Signal Groups.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Expand the response to show more details (default: false)", - "name": "expand", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.GroupEntry" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Create a new Signal Group with the specified members.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Create a new Signal Group.", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.CreateGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.CreateGroupResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}": { - "get": { - "description": "List a specific Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "List a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Expand the response to show more details (default: false)", - "name": "expand", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.GroupEntry" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "put": { - "description": "Update the state of a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Update the state of a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - }, - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateGroupRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Delete the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Delete a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/admins": { - "post": { - "description": "Add one or more admins to an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Add one or more admins to an existing Signal Group.", - "parameters": [ - { - "description": "Admins", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupAdminsRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove one or more admins from an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Remove one or more admins from an existing Signal Group.", - "parameters": [ - { - "description": "Admins", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupAdminsRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/avatar": { - "get": { - "description": "Returns the avatar of a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Returns the avatar of a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/block": { - "post": { - "description": "Block the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Block a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/join": { - "post": { - "description": "Join the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Join a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/members": { - "post": { - "description": "Add one or more members to an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Add one or more members to an existing Signal Group.", - "parameters": [ - { - "description": "Members", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupMembersRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove one or more members from an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Remove one or more members from an existing Signal Group.", - "parameters": [ - { - "description": "Members", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupMembersRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/pin-message": { - "post": { - "description": "Pin a message in a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Pin a message in a Signal Group.", - "parameters": [ - { - "description": "Pin", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.PinMessageInGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Unpin a message in a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Unpin a message in a Signal Group.", - "parameters": [ - { - "description": "Unpin", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UnpinMessageInGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/quit": { - "post": { - "description": "Quit the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Quit a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/health": { - "get": { - "description": "Internally used by the docker container to perform the health check.", - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "API Health Check", - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/identities/{number}": { - "get": { - "description": "List all identities for the given number.", - "produces": [ - "application/json" - ], - "tags": [ - "Identities" - ], - "summary": "List Identities", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.IdentityEntry" - } - } - } - } - } - }, - "/v1/identities/{number}/trust/{numberToTrust}": { - "put": { - "description": "Trust an identity. When 'trust_all_known_keys' is set to' true', all known keys of this user are trusted. **This is only recommended for testing.**", - "produces": [ - "application/json" - ], - "tags": [ - "Identities" - ], - "summary": "Trust Identity", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustIdentityRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Number To Trust", - "name": "numberToTrust", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/polls/{number}": { - "post": { - "description": "Create a new poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Create a new poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.CreatePollRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.CreatePollResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Close a poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Close a poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ClosePollRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/polls/{number}/vote": { - "post": { - "description": "Answer a poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Answer a poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.VoteRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/profiles/{number}": { - "put": { - "description": "Set your name and optional an avatar.", - "produces": [ - "application/json" - ], - "tags": [ - "Profiles" - ], - "summary": "Update Profile.", - "parameters": [ - { - "description": "Profile Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateProfileRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/qrcodelink": { - "get": { - "description": "Link device and generate QR code", - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Link device and generate QR code.", - "parameters": [ - { - "type": "string", - "description": "Device Name", - "name": "device_name", - "in": "query", - "required": true - }, - { - "type": "integer", - "description": "QRCode Version (defaults to 10)", - "name": "qrcode_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/qrcodelink/raw": { - "get": { - "description": "Generate the deviceLinkUri string for linking without scanning a QR code.", - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Get raw device link URI", - "parameters": [ - { - "type": "string", - "description": "Device Name", - "name": "device_name", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.DeviceLinkUriResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/reactions/{number}": { - "post": { - "description": "React to a message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Reactions" - ], - "summary": "Send a reaction.", - "parameters": [ - { - "description": "Reaction", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendReactionRequest" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove a reaction", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Reactions" - ], - "summary": "Remove a reaction.", - "parameters": [ - { - "description": "Reaction", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RemoveReactionRequest" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/receipts/{number}": { - "post": { - "description": "Send a read or viewed receipt", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Receipts" - ], - "summary": "Send a receipt.", - "parameters": [ - { - "description": "Receipt", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.Receipt" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/receive/{number}": { - "get": { - "description": "Receives Signal Messages from the Signal Network. If you are running the docker container in normal/native mode, this is a GET endpoint. In json-rpc mode this is a websocket endpoint.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Receive Signal Messages.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Receive timeout in seconds (default: 1)", - "name": "timeout", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether the attachments of the received message should be ignored", - "name": "ignore_attachments", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether stories should be ignored when receiving messages", - "name": "ignore_stories", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether avatar downloads should be ignored when receiving messages", - "name": "ignore_avatars", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether sticker pack downloads should be ignored when receiving messages", - "name": "ignore_stickers", - "in": "query" - }, - { - "type": "string", - "description": "Specify the maximum number of messages to receive (default: unlimited)", - "name": "max_messages", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether read receipts should be sent when receiving messages", - "name": "send_read_receipts", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/register/{number}": { - "post": { - "description": "Register a phone number with the signal network.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Register a phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.RegisterNumberRequest" - } - } - ], - "responses": { - "201": { - "description": "Created" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/register/{number}/verify/{token}": { - "post": { - "description": "Verify a registered phone number with the signal network.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Verify a registered phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.VerifyNumberSettings" - } - }, - { - "type": "string", - "description": "Verification Code", - "name": "token", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/remote-delete/{number}": { - "delete": { - "description": "Delete a signal message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Delete a signal message.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RemoteDeleteRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.RemoteDeleteResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/search/{number}": { - "get": { - "description": "Check if one or more phone numbers are registered with the Signal Service.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Search" - ], - "summary": "Check if one or more phone numbers are registered with the Signal Service.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "description": "Numbers to check", - "name": "numbers", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/api.SearchResponse" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/send": { - "post": { - "description": "Send a signal message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Send a signal message.", - "deprecated": true, - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendMessageV1" - } - } - ], - "responses": { - "201": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/sticker-packs/{number}": { - "get": { - "description": "List Installed Sticker Packs.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Sticker Packs" - ], - "summary": "List Installed Sticker Packs.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListInstalledStickerPacksResponse" - } - } - }, - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the \"Add to Signal\" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX\u0026pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Sticker Packs" - ], - "summary": "Add Sticker Pack.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.AddStickerPackRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/typing-indicator/{number}": { - "put": { - "description": "Show Typing Indicator.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Show Typing Indicator.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TypingIndicatorRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Hide Typing Indicator.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Hide Typing Indicator.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TypingIndicatorRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/unregister/{number}": { - "post": { - "description": "Disables push support for this device. **WARNING:** If *delete_account* is set to *true*, the account will be deleted from the Signal Server. This cannot be undone without loss.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Unregister a phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.UnregisterNumberRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v2/send": { - "post": { - "description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\`monospace\\`. If you want to escape a formatting character, prefix it with two backslashes.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Send a signal message.", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendMessageV2" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.SendMessageResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.SendMessageError" - } - } - } - } - } - }, - "definitions": { - "api.AddDeviceRequest": { - "type": "object", - "required": [ - "uri" - ], - "properties": { - "uri": { - "type": "string" - } - } - }, - "api.AddStickerPackRequest": { - "type": "object", - "required": [ - "pack_id", - "pack_key" - ], - "properties": { - "pack_id": { - "type": "string", - "example": "9a32eda01a7a28574f2eb48668ae0dc4" - }, - "pack_key": { - "type": "string", - "example": "19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a" - } - } - }, - "api.ChangeGroupAdminsRequest": { - "type": "object", - "required": [ - "admins" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "api.ChangeGroupMembersRequest": { - "type": "object", - "required": [ - "members" - ], - "properties": { - "members": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "api.ClosePollRequest": { - "type": "object", - "required": [ - "poll_timestamp", - "recipient" - ], - "properties": { - "poll_timestamp": { - "type": "string", - "example": "1769271479" - }, - "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" - } - } - }, - "api.Configuration": { - "type": "object", - "required": [ - "logging" - ], - "properties": { - "logging": { - "$ref": "#/definitions/api.LoggingConfiguration" - } - } - }, - "api.CreateGroupRequest": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "expiration_time": { - "type": "integer" - }, - "group_link": { - "type": "string", - "enum": [ - "disabled", - "enabled", - "enabled-with-approval" - ] - }, - "members": { - "type": "array", - "items": { - "type": "string" - } - }, - "name": { - "type": "string" - }, - "permissions": { - "$ref": "#/definitions/data.GroupPermissions" - } - } - }, - "api.CreateGroupResponse": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - }, - "api.CreatePollRequest": { - "type": "object", - "required": [ - "answers", - "question", - "recipient" - ], - "properties": { - "allow_multiple_selections": { - "type": "boolean", - "example": true - }, - "answers": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "apple", - "banana", - "orange" - ] - }, - "question": { - "type": "string", - "example": "What's your favourite fruit?" - }, - "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" - } - } - }, - "api.CreatePollResponse": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "type": "string", - "example": "1769271479" - } - } - }, - "api.DeleteLocalAccountDataRequest": { - "type": "object", - "properties": { - "ignore_registered": { - "type": "boolean", - "example": false - } - } - }, - "api.DeviceLinkUriResponse": { - "type": "object", - "required": [ - "device_link_uri" - ], - "properties": { - "device_link_uri": { - "type": "string" - } - } - }, - "api.Error": { - "type": "object", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - } - } - }, - "api.LoggingConfiguration": { - "type": "object", - "required": [ - "Level" - ], - "properties": { - "Level": { - "type": "string" - } - } - }, - "api.PinMessageInGroupRequest": { - "type": "object", - "required": [ - "target_author", - "timestamp" - ], - "properties": { - "duration": { - "type": "integer" - }, - "target_author": { - "type": "string" - }, - "timestamp": { - "type": "integer" - } - } - }, - "api.RateLimitChallengeRequest": { - "type": "object", - "required": [ - "captcha", - "challenge_token" - ], - "properties": { - "captcha": { - "type": "string", - "example": "signalcaptcha://{captcha value}" - }, - "challenge_token": { - "type": "string", - "example": "\u003cchallenge token\u003e" - } - } - }, - "api.Receipt": { - "type": "object", - "required": [ - "receipt_type", - "recipient", - "timestamp" - ], - "properties": { - "receipt_type": { - "type": "string", - "enum": [ - "read", - "viewed" - ] - }, - "recipient": { - "type": "string" - }, - "timestamp": { - "type": "integer" - } - } - }, - "api.RegisterNumberRequest": { - "type": "object", - "properties": { - "captcha": { - "type": "string" - }, - "use_voice": { - "type": "boolean" - } - } - }, - "api.RemoteDeleteRequest": { - "type": "object", - "required": [ - "recipient", - "timestamp" - ], - "properties": { - "recipient": { - "type": "string" - }, - "timestamp": { - "type": "integer" - } - } - }, - "api.RemoteDeleteResponse": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "type": "string" - } - } - }, - "api.RemoveReactionRequest": { - "type": "object", - "required": [ - "recipient", - "target_author", - "timestamp" - ], - "properties": { - "reaction": { - "type": "string" - }, - "recipient": { - "type": "string" - }, - "target_author": { - "type": "string" - }, - "timestamp": { - "type": "integer" - } - } - }, - "api.SearchResponse": { - "type": "object", - "required": [ - "number", - "registered" - ], - "properties": { - "number": { - "type": "string" - }, - "registered": { - "type": "boolean" - } - } - }, - "api.SendMessageError": { - "type": "object", - "required": [ - "account", - "error" - ], - "properties": { - "account": { - "type": "string" - }, - "challenge_tokens": { - "type": "array", - "items": { - "type": "string" - } - }, - "error": { - "type": "string" - } - } - }, - "api.SendMessageResponse": { - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "type": "string" - } - } - }, - "api.SendMessageV1": { - "type": "object", - "required": [ - "message", - "number", - "recipients" - ], - "properties": { - "base64_attachment": { - "type": "string", - "example": "'\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;base64,\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64,\u003cBASE64 ENCODED DATA\u003e'" - }, - "is_group": { - "type": "boolean" - }, - "message": { - "type": "string" - }, - "number": { - "type": "string" - }, - "recipients": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "api.SendMessageV2": { - "type": "object", - "required": [ - "message", - "number", - "recipients" - ], - "properties": { - "base64_attachments": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "\u003cBASE64 ENCODED DATA\u003e", - "data:\u003cMIME-TYPE\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e", - "data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e" - ] - }, - "edit_timestamp": { - "type": "integer" - }, - "link_preview": { - "$ref": "#/definitions/data.LinkPreviewType" - }, - "mentions": { - "type": "array", - "items": { - "$ref": "#/definitions/data.MessageMention" - } - }, - "message": { - "type": "string" - }, - "notify_self": { - "type": "boolean" - }, - "number": { - "type": "string" - }, - "quote_author": { - "type": "string" - }, - "quote_mentions": { - "type": "array", - "items": { - "$ref": "#/definitions/data.MessageMention" - } - }, - "quote_message": { - "type": "string" - }, - "quote_timestamp": { - "type": "integer" - }, - "recipients": { - "type": "array", - "items": { - "type": "string" - } - }, - "sticker": { - "type": "string" - }, - "text_mode": { - "type": "string", - "enum": [ - "normal", - "styled" - ] - }, - "view_once": { - "type": "boolean" - } - } - }, - "api.SendReactionRequest": { - "type": "object", - "required": [ - "reaction", - "recipient", - "target_author", - "timestamp" - ], - "properties": { - "reaction": { - "type": "string" - }, - "recipient": { - "type": "string" - }, - "target_author": { - "type": "string" - }, - "timestamp": { - "type": "integer" - } - } - }, - "api.SetPinRequest": { - "type": "object", - "required": [ - "pin" - ], - "properties": { - "pin": { - "type": "string" - } - } - }, - "api.SetUsernameRequest": { - "type": "object", - "required": [ - "username" - ], - "properties": { - "username": { - "type": "string", - "example": "test" - } - } - }, - "api.TrustIdentityRequest": { - "type": "object", - "properties": { - "trust_all_known_keys": { - "type": "boolean", - "example": false - }, - "verified_safety_number": { - "type": "string" - } - } - }, - "api.TrustModeRequest": { - "type": "object", - "required": [ - "trust_mode" - ], - "properties": { - "trust_mode": { - "type": "string" - } - } - }, - "api.TrustModeResponse": { - "type": "object", - "required": [ - "trust_mode" - ], - "properties": { - "trust_mode": { - "type": "string" - } - } - }, - "api.TypingIndicatorRequest": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "recipient": { - "type": "string" - } - } - }, - "api.UnpinMessageInGroupRequest": { - "type": "object", - "required": [ - "target_author", - "timestamp" - ], - "properties": { - "target_author": { - "type": "string" - }, - "timestamp": { - "type": "integer" - } - } - }, - "api.UnregisterNumberRequest": { - "type": "object", - "properties": { - "delete_account": { - "type": "boolean", - "example": false - }, - "delete_local_data": { - "type": "boolean", - "example": false - } - } - }, - "api.UpdateAccountSettingsRequest": { - "type": "object", - "properties": { - "discoverable_by_number": { - "type": "boolean" - }, - "share_number": { - "type": "boolean" - } - } - }, - "api.UpdateContactRequest": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "expiration_in_seconds": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "recipient": { - "type": "string" - } - } - }, - "api.UpdateGroupRequest": { - "type": "object", - "properties": { - "base64_avatar": { - "type": "string" - }, - "description": { - "type": "string" - }, - "expiration_time": { - "type": "integer" - }, - "group_link": { - "type": "string", - "enum": [ - "disabled", - "enabled", - "enabled-with-approval" - ] - }, - "name": { - "type": "string" - }, - "permissions": { - "$ref": "#/definitions/data.GroupPermissions" - } - } - }, - "api.UpdateProfileRequest": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "about": { - "type": "string" - }, - "base64_avatar": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "api.VerifyNumberSettings": { - "type": "object", - "properties": { - "pin": { - "type": "string" - } - } - }, - "api.VoteRequest": { - "type": "object", - "required": [ - "poll_author", - "poll_timestamp", - "recipient", - "selected_answers" - ], - "properties": { - "poll_author": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cuuid\u003e" - }, - "poll_timestamp": { - "type": "string", - "example": "1769271479" - }, - "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" - }, - "selected_answers": { - "type": "array", - "items": { - "type": "integer" - }, - "example": [ - 1 - ] - } - } - }, - "client.About": { - "type": "object", - "required": [ - "build", - "capabilities", - "mode", - "version", - "versions" - ], - "properties": { - "build": { - "type": "integer" - }, - "capabilities": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "mode": { - "type": "string" - }, - "version": { - "type": "string" - }, - "versions": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "client.ContactProfile": { - "type": "object", - "required": [ - "about", - "given_name", - "has_avatar", - "last_updated_timestamp", - "lastname" - ], - "properties": { - "about": { - "type": "string" - }, - "given_name": { - "type": "string" - }, - "has_avatar": { - "type": "boolean" - }, - "last_updated_timestamp": { - "type": "integer" - }, - "lastname": { - "type": "string" - } - } - }, - "client.GroupEntry": { - "type": "object", - "required": [ - "admins", - "blocked", - "description", - "id", - "internal_id", - "invite_link", - "members", - "name", - "pending_invites", - "pending_requests", - "permissions" - ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - }, - "blocked": { - "type": "boolean" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string" - }, - "internal_id": { - "type": "string" - }, - "invite_link": { - "type": "string" - }, - "members": { - "type": "array", - "items": { - "type": "string" - } - }, - "name": { - "type": "string" - }, - "pending_invites": { - "type": "array", - "items": { - "type": "string" - } - }, - "pending_requests": { - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$ref": "#/definitions/data.GroupPermissions" - } - } - }, - "client.IdentityEntry": { - "type": "object", - "required": [ - "added", - "fingerprint", - "number", - "safety_number", - "status", - "uuid" - ], - "properties": { - "added": { - "type": "string" - }, - "fingerprint": { - "type": "string" - }, - "number": { - "type": "string" - }, - "safety_number": { - "type": "string" - }, - "status": { - "type": "string" - }, - "uuid": { - "type": "string" - } - } - }, - "client.ListContactsResponse": { - "type": "object", - "required": [ - "blocked", - "color", - "given_name", - "message_expiration", - "name", - "nickname", - "note", - "number", - "profile", - "profile_name", - "username", - "uuid" - ], - "properties": { - "blocked": { - "type": "boolean" - }, - "color": { - "type": "string" - }, - "given_name": { - "type": "string" - }, - "message_expiration": { - "type": "string" - }, - "name": { - "type": "string" - }, - "nickname": { - "$ref": "#/definitions/client.Nickname" - }, - "note": { - "type": "string" - }, - "number": { - "type": "string" - }, - "profile": { - "$ref": "#/definitions/client.ContactProfile" - }, - "profile_name": { - "type": "string" - }, - "username": { - "type": "string" - }, - "uuid": { - "type": "string" - } - } - }, - "client.ListDevicesResponse": { - "type": "object", - "required": [ - "creation_timestamp", - "id", - "last_seen_timestamp", - "name" - ], - "properties": { - "creation_timestamp": { - "type": "integer" - }, - "id": { - "type": "integer" - }, - "last_seen_timestamp": { - "type": "integer" - }, - "name": { - "type": "string" - } - } - }, - "client.ListInstalledStickerPacksResponse": { - "type": "object", - "required": [ - "author", - "installed", - "pack_id", - "title", - "url" - ], - "properties": { - "author": { - "type": "string" - }, - "installed": { - "type": "boolean" - }, - "pack_id": { - "type": "string" - }, - "title": { - "type": "string" - }, - "url": { - "type": "string" - } - } - }, - "client.Nickname": { - "type": "object", - "required": [ - "family_name", - "given_name", - "name" - ], - "properties": { - "family_name": { - "type": "string" - }, - "given_name": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "client.SetUsernameResponse": { - "type": "object", - "required": [ - "username", - "username_link" - ], - "properties": { - "username": { - "type": "string" - }, - "username_link": { - "type": "string" - } - } - }, - "data.GroupPermissions": { - "type": "object", - "required": [ - "add_members", - "edit_group", - "send_messages" - ], - "properties": { - "add_members": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "edit_group": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "send_messages": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - } - } - }, - "data.LinkPreviewType": { - "type": "object", - "required": [ - "base64_thumbnail", - "description", - "title", - "url" - ], - "properties": { - "base64_thumbnail": { - "type": "string" - }, - "description": { - "type": "string" - }, - "title": { - "type": "string" - }, - "url": { - "type": "string" - } - } - }, - "data.MessageMention": { - "type": "object", - "required": [ - "author", - "length", - "start" - ], - "properties": { - "author": { - "type": "string" - }, - "length": { - "type": "integer" - }, - "start": { - "type": "integer" - } - } - } - }, - "tags": [ - { - "description": "Some general endpoints.", - "name": "General" - }, - { - "description": "Register and link Devices.", - "name": "Devices" - }, - { - "description": "List registered and linked accounts", - "name": "Accounts" - }, - { - "description": "Create, List and Delete Signal Groups.", - "name": "Groups" - }, - { - "description": "Send and Receive Signal Messages.", - "name": "Messages" - }, - { - "description": "List and Delete Attachments.", - "name": "Attachments" - }, - { - "description": "Update Profile.", - "name": "Profiles" - }, - { - "description": "List and Trust Identities.", - "name": "Identities" - }, - { - "description": "React to messages.", - "name": "Reactions" - }, - { - "description": "Send receipts for messages.", - "name": "Receipts" - }, - { - "description": "Search the Signal Service.", - "name": "Search" - }, - { - "description": "List and Install Sticker Packs", - "name": "Sticker Packs" - } - ] -} \ No newline at end of file diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml deleted file mode 100644 index 0d10fc6..0000000 --- a/src/docs/swagger.yaml +++ /dev/null @@ -1,2590 +0,0 @@ -basePath: / -definitions: - api.AddDeviceRequest: - properties: - uri: - type: string - required: - - uri - type: object - api.AddStickerPackRequest: - properties: - pack_id: - example: 9a32eda01a7a28574f2eb48668ae0dc4 - type: string - pack_key: - example: 19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a - type: string - required: - - pack_id - - pack_key - type: object - api.ChangeGroupAdminsRequest: - properties: - admins: - items: - type: string - type: array - required: - - admins - type: object - api.ChangeGroupMembersRequest: - properties: - members: - items: - type: string - type: array - required: - - members - type: object - api.ClosePollRequest: - properties: - poll_timestamp: - example: "1769271479" - type: string - recipient: - example: OR OR - type: string - required: - - poll_timestamp - - recipient - type: object - api.Configuration: - properties: - logging: - $ref: '#/definitions/api.LoggingConfiguration' - required: - - logging - type: object - api.CreateGroupRequest: - properties: - description: - type: string - expiration_time: - type: integer - group_link: - enum: - - disabled - - enabled - - enabled-with-approval - type: string - members: - items: - type: string - type: array - name: - type: string - permissions: - $ref: '#/definitions/data.GroupPermissions' - type: object - api.CreateGroupResponse: - properties: - id: - type: string - required: - - id - type: object - api.CreatePollRequest: - properties: - allow_multiple_selections: - example: true - type: boolean - answers: - example: - - apple - - banana - - orange - items: - type: string - type: array - question: - example: What's your favourite fruit? - type: string - recipient: - example: OR OR - type: string - required: - - answers - - question - - recipient - type: object - api.CreatePollResponse: - properties: - timestamp: - example: "1769271479" - type: string - required: - - timestamp - type: object - api.DeleteLocalAccountDataRequest: - properties: - ignore_registered: - example: false - type: boolean - type: object - api.DeviceLinkUriResponse: - properties: - device_link_uri: - type: string - required: - - device_link_uri - type: object - api.Error: - properties: - error: - type: string - required: - - error - type: object - api.LoggingConfiguration: - properties: - Level: - type: string - required: - - Level - type: object - api.PinMessageInGroupRequest: - properties: - duration: - type: integer - target_author: - type: string - timestamp: - type: integer - required: - - target_author - - timestamp - type: object - api.RateLimitChallengeRequest: - properties: - captcha: - example: signalcaptcha://{captcha value} - type: string - challenge_token: - example: - type: string - required: - - captcha - - challenge_token - type: object - api.Receipt: - properties: - receipt_type: - enum: - - read - - viewed - type: string - recipient: - type: string - timestamp: - type: integer - required: - - receipt_type - - recipient - - timestamp - type: object - api.RegisterNumberRequest: - properties: - captcha: - type: string - use_voice: - type: boolean - type: object - api.RemoteDeleteRequest: - properties: - recipient: - type: string - timestamp: - type: integer - required: - - recipient - - timestamp - type: object - api.RemoteDeleteResponse: - properties: - timestamp: - type: string - required: - - timestamp - type: object - api.RemoveReactionRequest: - properties: - reaction: - type: string - recipient: - type: string - target_author: - type: string - timestamp: - type: integer - required: - - recipient - - target_author - - timestamp - type: object - api.SearchResponse: - properties: - number: - type: string - registered: - type: boolean - required: - - number - - registered - type: object - api.SendMessageError: - properties: - account: - type: string - challenge_tokens: - items: - type: string - type: array - error: - type: string - required: - - account - - error - type: object - api.SendMessageResponse: - properties: - timestamp: - type: string - required: - - timestamp - type: object - api.SendMessageV1: - properties: - base64_attachment: - example: ''''' OR ''data:;base64,'' OR ''data:;filename=;base64,''' - type: string - is_group: - type: boolean - message: - type: string - number: - type: string - recipients: - items: - type: string - type: array - required: - - message - - number - - recipients - type: object - api.SendMessageV2: - properties: - base64_attachments: - example: - - - - data:;base64 - - data:;filename=;base64 - items: - type: string - type: array - edit_timestamp: - type: integer - link_preview: - $ref: '#/definitions/data.LinkPreviewType' - mentions: - items: - $ref: '#/definitions/data.MessageMention' - type: array - message: - type: string - notify_self: - type: boolean - number: - type: string - quote_author: - type: string - quote_mentions: - items: - $ref: '#/definitions/data.MessageMention' - type: array - quote_message: - type: string - quote_timestamp: - type: integer - recipients: - items: - type: string - type: array - sticker: - type: string - text_mode: - enum: - - normal - - styled - type: string - view_once: - type: boolean - required: - - message - - number - - recipients - type: object - api.SendReactionRequest: - properties: - reaction: - type: string - recipient: - type: string - target_author: - type: string - timestamp: - type: integer - required: - - reaction - - recipient - - target_author - - timestamp - type: object - api.SetPinRequest: - properties: - pin: - type: string - required: - - pin - type: object - api.SetUsernameRequest: - properties: - username: - example: test - type: string - required: - - username - type: object - api.TrustIdentityRequest: - properties: - trust_all_known_keys: - example: false - type: boolean - verified_safety_number: - type: string - type: object - api.TrustModeRequest: - properties: - trust_mode: - type: string - required: - - trust_mode - type: object - api.TrustModeResponse: - properties: - trust_mode: - type: string - required: - - trust_mode - type: object - api.TypingIndicatorRequest: - properties: - recipient: - type: string - required: - - recipient - type: object - api.UnpinMessageInGroupRequest: - properties: - target_author: - type: string - timestamp: - type: integer - required: - - target_author - - timestamp - type: object - api.UnregisterNumberRequest: - properties: - delete_account: - example: false - type: boolean - delete_local_data: - example: false - type: boolean - type: object - api.UpdateAccountSettingsRequest: - properties: - discoverable_by_number: - type: boolean - share_number: - type: boolean - type: object - api.UpdateContactRequest: - properties: - expiration_in_seconds: - type: integer - name: - type: string - recipient: - type: string - required: - - recipient - type: object - api.UpdateGroupRequest: - properties: - base64_avatar: - type: string - description: - type: string - expiration_time: - type: integer - group_link: - enum: - - disabled - - enabled - - enabled-with-approval - type: string - name: - type: string - permissions: - $ref: '#/definitions/data.GroupPermissions' - type: object - api.UpdateProfileRequest: - properties: - about: - type: string - base64_avatar: - type: string - name: - type: string - required: - - name - type: object - api.VerifyNumberSettings: - properties: - pin: - type: string - type: object - api.VoteRequest: - properties: - poll_author: - example: OR - type: string - poll_timestamp: - example: "1769271479" - type: string - recipient: - example: OR OR - type: string - selected_answers: - example: - - 1 - items: - type: integer - type: array - required: - - poll_author - - poll_timestamp - - recipient - - selected_answers - type: object - client.About: - properties: - build: - type: integer - capabilities: - additionalProperties: - items: - type: string - type: array - type: object - mode: - type: string - version: - type: string - versions: - items: - type: string - type: array - required: - - build - - capabilities - - mode - - version - - versions - type: object - client.ContactProfile: - properties: - about: - type: string - given_name: - type: string - has_avatar: - type: boolean - last_updated_timestamp: - type: integer - lastname: - type: string - required: - - about - - given_name - - has_avatar - - last_updated_timestamp - - lastname - type: object - client.GroupEntry: - properties: - admins: - items: - type: string - type: array - blocked: - type: boolean - description: - type: string - id: - type: string - internal_id: - type: string - invite_link: - type: string - members: - items: - type: string - type: array - name: - type: string - pending_invites: - items: - type: string - type: array - pending_requests: - items: - type: string - type: array - permissions: - $ref: '#/definitions/data.GroupPermissions' - required: - - admins - - blocked - - description - - id - - internal_id - - invite_link - - members - - name - - pending_invites - - pending_requests - - permissions - type: object - client.IdentityEntry: - properties: - added: - type: string - fingerprint: - type: string - number: - type: string - safety_number: - type: string - status: - type: string - uuid: - type: string - required: - - added - - fingerprint - - number - - safety_number - - status - - uuid - type: object - client.ListContactsResponse: - properties: - blocked: - type: boolean - color: - type: string - given_name: - type: string - message_expiration: - type: string - name: - type: string - nickname: - $ref: '#/definitions/client.Nickname' - note: - type: string - number: - type: string - profile: - $ref: '#/definitions/client.ContactProfile' - profile_name: - type: string - username: - type: string - uuid: - type: string - required: - - blocked - - color - - given_name - - message_expiration - - name - - nickname - - note - - number - - profile - - profile_name - - username - - uuid - type: object - client.ListDevicesResponse: - properties: - creation_timestamp: - type: integer - id: - type: integer - last_seen_timestamp: - type: integer - name: - type: string - required: - - creation_timestamp - - id - - last_seen_timestamp - - name - type: object - client.ListInstalledStickerPacksResponse: - properties: - author: - type: string - installed: - type: boolean - pack_id: - type: string - title: - type: string - url: - type: string - required: - - author - - installed - - pack_id - - title - - url - type: object - client.Nickname: - properties: - family_name: - type: string - given_name: - type: string - name: - type: string - required: - - family_name - - given_name - - name - type: object - client.SetUsernameResponse: - properties: - username: - type: string - username_link: - type: string - required: - - username - - username_link - type: object - data.GroupPermissions: - properties: - add_members: - enum: - - only-admins - - every-member - type: string - edit_group: - enum: - - only-admins - - every-member - type: string - send_messages: - enum: - - only-admins - - every-member - type: string - required: - - add_members - - edit_group - - send_messages - type: object - data.LinkPreviewType: - properties: - base64_thumbnail: - type: string - description: - type: string - title: - type: string - url: - type: string - required: - - base64_thumbnail - - description - - title - - url - type: object - data.MessageMention: - properties: - author: - type: string - length: - type: integer - start: - type: integer - required: - - author - - length - - start - type: object -host: localhost:8080 -info: - contact: {} - description: This is the Signal Cli REST API documentation. - title: Signal Cli REST API - version: "1.0" -paths: - /v1/about: - get: - description: Returns the supported API versions and the internal build nr - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/client.About' - summary: Lists general information about the API - tags: - - General - /v1/accounts: - get: - description: Lists all of the accounts linked or registered - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - type: string - type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: List all accounts - tags: - - Accounts - /v1/accounts/{number}/pin: - delete: - description: Removes a Signal Pin - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Remove Pin - tags: - - Accounts - post: - description: Sets a new Signal Pin - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Request - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.SetPinRequest' - produces: - - application/json - responses: - "201": - description: Created - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Set Pin - tags: - - Accounts - /v1/accounts/{number}/rate-limit-challenge: - post: - consumes: - - application/json - description: 'When running into rate limits, sometimes the limit can be lifted, - by solving a CAPTCHA. To get the captcha token, go to https://signalcaptchas.org/challenge/generate.html - For the staging environment, use: https://signalcaptchas.org/staging/registration/generate.html. - The "challenge_token" is the token from the failed send attempt. The "captcha" - is the captcha result, starting with signalcaptcha://' - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Request - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.RateLimitChallengeRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Lift rate limit restrictions by solving a captcha. - tags: - - Accounts - /v1/accounts/{number}/settings: - put: - consumes: - - application/json - description: Update the account attributes on the signal server. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Request - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.UpdateAccountSettingsRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Update the account settings. - tags: - - Accounts - /v1/accounts/{number}/username: - delete: - consumes: - - application/json - description: Delete the username associated with this account. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Remove a username. - tags: - - Accounts - post: - consumes: - - application/json - description: Allows to set the username that should be used for this account. - This can either be just the nickname (e.g. test) or the complete username - with discriminator (e.g. test.123). Returns the new username with discriminator - and the username link. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Request - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.SetUsernameRequest' - produces: - - application/json - responses: - "201": - description: Created - schema: - $ref: '#/definitions/client.SetUsernameResponse' - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Set a username. - tags: - - Accounts - /v1/attachments: - get: - description: List all downloaded attachments - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - type: string - type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: List all attachments. - tags: - - Attachments - /v1/attachments/{attachment}: - delete: - description: Remove the attachment with the given id from filesystem. - parameters: - - description: Attachment ID - in: path - name: attachment - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Remove attachment. - tags: - - Attachments - get: - description: Serve the attachment with the given id - parameters: - - description: Attachment ID - in: path - name: attachment - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Serve Attachment. - tags: - - Attachments - /v1/configuration: - get: - consumes: - - application/json - description: List the REST API configuration. - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/api.Configuration' - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: List the REST API configuration. - tags: - - General - post: - consumes: - - application/json - description: Set the REST API configuration. - parameters: - - description: Configuration - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.Configuration' - produces: - - application/json - responses: - "204": - description: OK - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Set the REST API configuration. - tags: - - General - /v1/configuration/{number}/settings: - get: - consumes: - - application/json - description: List account specific settings. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Request - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.TrustModeResponse' - produces: - - application/json - responses: - "200": - description: OK - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: List account specific settings. - tags: - - General - post: - consumes: - - application/json - description: Set account specific settings. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Request - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.TrustModeRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Set account specific settings. - tags: - - General - /v1/contacts/{number}: - get: - description: List all contacts for the given number. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Include all known recipients, not only contacts. - in: query - name: all_recipients - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/client.ListContactsResponse' - type: array - summary: List Contacts - tags: - - Contacts - put: - consumes: - - application/json - description: Updates the info associated to a number on the contact list. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Contact - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.UpdateContactRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Updates the info associated to a number on the contact list. If the - contact doesn’t exist yet, it will be added. - tags: - - Contacts - /v1/contacts/{number}/{uuid}: - get: - description: List a specific contact. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Include all known recipients, not only contacts. - in: query - name: all_recipients - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/client.ListContactsResponse' - summary: List Contact - tags: - - Contacts - /v1/contacts/{number}/{uuid}/avatar: - get: - description: Returns the avatar of a contact. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "200": - description: Image - schema: - type: string - summary: Returns the avatar of a contact - tags: - - Contacts - /v1/contacts/{number}/sync: - post: - consumes: - - application/json - description: Send a synchronization message with the local contacts list to - all linked devices. This command should only be used if this is the primary - device. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Send a synchronization message with the local contacts list to all - linked devices. - tags: - - Contacts - /v1/devices/{number}: - get: - consumes: - - application/json - description: List linked devices associated to this device. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/client.ListDevicesResponse' - type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: List linked devices. - tags: - - Devices - post: - consumes: - - application/json - description: Links another device to this device. Only works, if this is the - master device. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Request - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.AddDeviceRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Links another device to this device. - tags: - - Devices - /v1/devices/{number}/{deviceId}: - delete: - description: Remove a linked device from the primary account. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Device ID from listDevices - in: path - name: deviceId - required: true - type: integer - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Remove linked device - tags: - - Devices - /v1/devices/{number}/local-data: - delete: - consumes: - - application/json - description: Delete all local data for the specified account. Only use this - after unregistering the account or after removing a linked device. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Cleanup options - in: body - name: data - schema: - $ref: '#/definitions/api.DeleteLocalAccountDataRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Delete local account data - tags: - - Devices - /v1/groups/{number}: - get: - consumes: - - application/json - description: List all Signal Groups. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: 'Expand the response to show more details (default: false)' - in: query - name: expand - type: boolean - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/client.GroupEntry' - type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: List all Signal Groups. - tags: - - Groups - post: - consumes: - - application/json - description: Create a new Signal Group with the specified members. - parameters: - - description: Input Data - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.CreateGroupRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "201": - description: Created - schema: - $ref: '#/definitions/api.CreateGroupResponse' - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Create a new Signal Group. - tags: - - Groups - /v1/groups/{number}/{groupid}: - delete: - consumes: - - application/json - description: Delete the specified Signal Group. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group Id - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Delete a Signal Group. - tags: - - Groups - get: - consumes: - - application/json - description: List a specific Signal Group. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - - description: 'Expand the response to show more details (default: false)' - in: query - name: expand - type: boolean - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/client.GroupEntry' - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: List a Signal Group. - tags: - - Groups - put: - consumes: - - application/json - description: Update the state of a Signal Group. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - - description: Input Data - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.UpdateGroupRequest' - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Update the state of a Signal Group. - tags: - - Groups - /v1/groups/{number}/{groupid}/admins: - delete: - consumes: - - application/json - description: Remove one or more admins from an existing Signal Group. - parameters: - - description: Admins - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.ChangeGroupAdminsRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Remove one or more admins from an existing Signal Group. - tags: - - Groups - post: - consumes: - - application/json - description: Add one or more admins to an existing Signal Group. - parameters: - - description: Admins - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.ChangeGroupAdminsRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Add one or more admins to an existing Signal Group. - tags: - - Groups - /v1/groups/{number}/{groupid}/avatar: - get: - consumes: - - application/json - description: Returns the avatar of a Signal Group. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "200": - description: Image - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Returns the avatar of a Signal Group. - tags: - - Groups - /v1/groups/{number}/{groupid}/block: - post: - consumes: - - application/json - description: Block the specified Signal Group. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Block a Signal Group. - tags: - - Groups - /v1/groups/{number}/{groupid}/join: - post: - consumes: - - application/json - description: Join the specified Signal Group. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Join a Signal Group. - tags: - - Groups - /v1/groups/{number}/{groupid}/members: - delete: - consumes: - - application/json - description: Remove one or more members from an existing Signal Group. - parameters: - - description: Members - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.ChangeGroupMembersRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Remove one or more members from an existing Signal Group. - tags: - - Groups - post: - consumes: - - application/json - description: Add one or more members to an existing Signal Group. - parameters: - - description: Members - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.ChangeGroupMembersRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Add one or more members to an existing Signal Group. - tags: - - Groups - /v1/groups/{number}/{groupid}/pin-message: - delete: - consumes: - - application/json - description: Unpin a message in a Signal Group. - parameters: - - description: Unpin - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.UnpinMessageInGroupRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group Id - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Unpin a message in a Signal Group. - tags: - - Groups - post: - consumes: - - application/json - description: Pin a message in a Signal Group. - parameters: - - description: Pin - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.PinMessageInGroupRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group Id - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Pin a message in a Signal Group. - tags: - - Groups - /v1/groups/{number}/{groupid}/quit: - post: - consumes: - - application/json - description: Quit the specified Signal Group. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Group ID - in: path - name: groupid - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Quit a Signal Group. - tags: - - Groups - /v1/health: - get: - description: Internally used by the docker container to perform the health check. - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - summary: API Health Check - tags: - - General - /v1/identities/{number}: - get: - description: List all identities for the given number. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/client.IdentityEntry' - type: array - summary: List Identities - tags: - - Identities - /v1/identities/{number}/trust/{numberToTrust}: - put: - description: Trust an identity. When 'trust_all_known_keys' is set to' true', - all known keys of this user are trusted. **This is only recommended for testing.** - parameters: - - description: Input Data - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.TrustIdentityRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Number To Trust - in: path - name: numberToTrust - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - summary: Trust Identity - tags: - - Identities - /v1/polls/{number}: - delete: - consumes: - - application/json - description: Close a poll - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Type - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.ClosePollRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Close a poll. - tags: - - Polls - post: - consumes: - - application/json - description: Create a new poll - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Type - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.CreatePollRequest' - produces: - - application/json - responses: - "201": - description: Created - schema: - $ref: '#/definitions/api.CreatePollResponse' - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Create a new poll. - tags: - - Polls - /v1/polls/{number}/vote: - post: - consumes: - - application/json - description: Answer a poll - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Type - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.VoteRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Answer a poll. - tags: - - Polls - /v1/profiles/{number}: - put: - description: Set your name and optional an avatar. - parameters: - - description: Profile Data - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.UpdateProfileRequest' - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Update Profile. - tags: - - Profiles - /v1/qrcodelink: - get: - description: Link device and generate QR code - parameters: - - description: Device Name - in: query - name: device_name - required: true - type: string - - description: QRCode Version (defaults to 10) - in: query - name: qrcode_version - type: integer - produces: - - application/json - responses: - "200": - description: Image - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Link device and generate QR code. - tags: - - Devices - /v1/qrcodelink/raw: - get: - description: Generate the deviceLinkUri string for linking without scanning - a QR code. - parameters: - - description: Device Name - in: query - name: device_name - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/api.DeviceLinkUriResponse' - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Get raw device link URI - tags: - - Devices - /v1/reactions/{number}: - delete: - consumes: - - application/json - description: Remove a reaction - parameters: - - description: Reaction - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.RemoveReactionRequest' - - description: Registered phone number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Remove a reaction. - tags: - - Reactions - post: - consumes: - - application/json - description: React to a message - parameters: - - description: Reaction - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.SendReactionRequest' - - description: Registered phone number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Send a reaction. - tags: - - Reactions - /v1/receipts/{number}: - post: - consumes: - - application/json - description: Send a read or viewed receipt - parameters: - - description: Receipt - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.Receipt' - - description: Registered phone number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Send a receipt. - tags: - - Receipts - /v1/receive/{number}: - get: - consumes: - - application/json - description: Receives Signal Messages from the Signal Network. If you are running - the docker container in normal/native mode, this is a GET endpoint. In json-rpc - mode this is a websocket endpoint. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: 'Receive timeout in seconds (default: 1)' - in: query - name: timeout - type: string - - description: Specify whether the attachments of the received message should - be ignored - in: query - name: ignore_attachments - type: string - - description: Specify whether stories should be ignored when receiving messages - in: query - name: ignore_stories - type: string - - description: Specify whether avatar downloads should be ignored when receiving - messages - in: query - name: ignore_avatars - type: string - - description: Specify whether sticker pack downloads should be ignored when - receiving messages - in: query - name: ignore_stickers - type: string - - description: 'Specify the maximum number of messages to receive (default: - unlimited)' - in: query - name: max_messages - type: string - - description: Specify whether read receipts should be sent when receiving messages - in: query - name: send_read_receipts - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - type: string - type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Receive Signal Messages. - tags: - - Messages - /v1/register/{number}: - post: - consumes: - - application/json - description: Register a phone number with the signal network. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Additional Settings - in: body - name: data - schema: - $ref: '#/definitions/api.RegisterNumberRequest' - produces: - - application/json - responses: - "201": - description: Created - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Register a phone number. - tags: - - Devices - /v1/register/{number}/verify/{token}: - post: - consumes: - - application/json - description: Verify a registered phone number with the signal network. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Additional Settings - in: body - name: data - schema: - $ref: '#/definitions/api.VerifyNumberSettings' - - description: Verification Code - in: path - name: token - required: true - type: string - produces: - - application/json - responses: - "201": - description: OK - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Verify a registered phone number. - tags: - - Devices - /v1/remote-delete/{number}: - delete: - consumes: - - application/json - description: Delete a signal message - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Type - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.RemoteDeleteRequest' - produces: - - application/json - responses: - "201": - description: Created - schema: - $ref: '#/definitions/api.RemoteDeleteResponse' - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Delete a signal message. - tags: - - Messages - /v1/search/{number}: - get: - consumes: - - application/json - description: Check if one or more phone numbers are registered with the Signal - Service. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - collectionFormat: multi - description: Numbers to check - in: query - items: - type: string - name: numbers - required: true - type: array - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/api.SearchResponse' - type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Check if one or more phone numbers are registered with the Signal Service. - tags: - - Search - /v1/send: - post: - consumes: - - application/json - deprecated: true - description: Send a signal message - parameters: - - description: Input Data - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.SendMessageV1' - produces: - - application/json - responses: - "201": - description: OK - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Send a signal message. - tags: - - Messages - /v1/sticker-packs/{number}: - get: - consumes: - - application/json - description: List Installed Sticker Packs. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/client.ListInstalledStickerPacksResponse' - type: array - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: List Installed Sticker Packs. - tags: - - Sticker Packs - post: - consumes: - - application/json - description: 'In order to add a sticker pack, browse to https://signalstickers.org/ - and select the sticker pack you want to add. Then, press the "Add to Signal" - button. If you look at the address bar in your browser you should see an URL - in this format: https://signal.art/addstickers/#pack_id=XXX&pack_key=YYY, - where XXX is the pack_id and YYY is the pack_key.' - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Request - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.AddStickerPackRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Add Sticker Pack. - tags: - - Sticker Packs - /v1/typing-indicator/{number}: - delete: - consumes: - - application/json - description: Hide Typing Indicator. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Type - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.TypingIndicatorRequest' - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Hide Typing Indicator. - tags: - - Messages - put: - consumes: - - application/json - description: Show Typing Indicator. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Type - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.TypingIndicatorRequest' - produces: - - application/json - responses: - "204": - description: No Content - schema: - type: string - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Show Typing Indicator. - tags: - - Messages - /v1/unregister/{number}: - post: - consumes: - - application/json - description: Disables push support for this device. **WARNING:** If *delete_account* - is set to *true*, the account will be deleted from the Signal Server. This - cannot be undone without loss. - parameters: - - description: Registered Phone Number - in: path - name: number - required: true - type: string - - description: Additional Settings - in: body - name: data - schema: - $ref: '#/definitions/api.UnregisterNumberRequest' - produces: - - application/json - responses: - "204": - description: No Content - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.Error' - summary: Unregister a phone number. - tags: - - Devices - /v2/send: - post: - consumes: - - application/json - description: 'Send a signal message. Set the text_mode to ''styled'' in case - you want to add formatting to your text message. Styling Options: \*italic - text\*, \*\*bold text\*\*, ~strikethrough text~, ||spoiler||, \`monospace\`. - If you want to escape a formatting character, prefix it with two backslashes.' - parameters: - - description: Input Data - in: body - name: data - required: true - schema: - $ref: '#/definitions/api.SendMessageV2' - produces: - - application/json - responses: - "201": - description: Created - schema: - $ref: '#/definitions/api.SendMessageResponse' - "400": - description: Bad Request - schema: - $ref: '#/definitions/api.SendMessageError' - summary: Send a signal message. - tags: - - Messages -schemes: -- http -swagger: "2.0" -tags: -- description: Some general endpoints. - name: General -- description: Register and link Devices. - name: Devices -- description: List registered and linked accounts - name: Accounts -- description: Create, List and Delete Signal Groups. - name: Groups -- description: Send and Receive Signal Messages. - name: Messages -- description: List and Delete Attachments. - name: Attachments -- description: Update Profile. - name: Profiles -- description: List and Trust Identities. - name: Identities -- description: React to messages. - name: Reactions -- description: Send receipts for messages. - name: Receipts -- description: Search the Signal Service. - name: Search -- description: List and Install Sticker Packs - name: Sticker Packs From 6fa06f961186bd77aacbb2044c6929472b532a3f Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 13:39:43 +0100 Subject: [PATCH 10/40] Add back swagger.json file --- src/docs/swagger.json | 5158 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5158 insertions(+) create mode 100644 src/docs/swagger.json diff --git a/src/docs/swagger.json b/src/docs/swagger.json new file mode 100644 index 0000000..5c75128 --- /dev/null +++ b/src/docs/swagger.json @@ -0,0 +1,5158 @@ +{ + "schemes": ["http","https"], + "swagger": "2.0", + "info": { + "description": "This is the Signal Cli REST API documentation.", + "title": "Signal Cli REST API", + "contact": {}, + "version": "0.99" + }, + "host": "192.168.0.166:8080", + "basePath": "/", + "paths": { + "/v1/about": { + "get": { + "description": "Returns the supported API versions and the internal build nr", + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Lists general information about the API", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.About" + } + } + } + } + }, + "/v1/accounts": { + "get": { + "description": "Lists all of the accounts linked or registered", + "produces": [ + "application/json" + ], + "tags": [ + "Accounts" + ], + "summary": "List all accounts", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/accounts/{number}/pin": { + "post": { + "description": "Sets a new Signal Pin", + "produces": [ + "application/json" + ], + "tags": [ + "Accounts" + ], + "summary": "Set Pin", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.SetPinRequest" + } + } + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Removes a Signal Pin", + "produces": [ + "application/json" + ], + "tags": [ + "Accounts" + ], + "summary": "Remove Pin", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/accounts/{number}/rate-limit-challenge": { + "post": { + "description": "When running into rate limits, sometimes the limit can be lifted, by solving a CAPTCHA. To get the captcha token, go to https://signalcaptchas.org/challenge/generate.html For the staging environment, use: https://signalcaptchas.org/staging/registration/generate.html. The \"challenge_token\" is the token from the failed send attempt. The \"captcha\" is the captcha result, starting with signalcaptcha://", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Accounts" + ], + "summary": "Lift rate limit restrictions by solving a captcha.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.RateLimitChallengeRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/accounts/{number}/settings": { + "put": { + "description": "Update the account attributes on the signal server.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Accounts" + ], + "summary": "Update the account settings.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateAccountSettingsRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/accounts/{number}/username": { + "post": { + "description": "Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Accounts" + ], + "summary": "Set a username.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.SetUsernameRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/client.SetUsernameResponse" + } + }, + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Delete the username associated with this account.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Accounts" + ], + "summary": "Remove a username.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/attachments": { + "get": { + "description": "List all downloaded attachments", + "produces": [ + "application/json" + ], + "tags": [ + "Attachments" + ], + "summary": "List all attachments.", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/attachments/{attachment}": { + "get": { + "description": "Serve the attachment with the given id", + "produces": [ + "application/json" + ], + "tags": [ + "Attachments" + ], + "summary": "Serve Attachment.", + "parameters": [ + { + "type": "string", + "description": "Attachment ID", + "name": "attachment", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Remove the attachment with the given id from filesystem.", + "produces": [ + "application/json" + ], + "tags": [ + "Attachments" + ], + "summary": "Remove attachment.", + "parameters": [ + { + "type": "string", + "description": "Attachment ID", + "name": "attachment", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/configuration": { + "get": { + "description": "List the REST API configuration.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "List the REST API configuration.", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.Configuration" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "Set the REST API configuration.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Set the REST API configuration.", + "parameters": [ + { + "description": "Configuration", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.Configuration" + } + } + ], + "responses": { + "204": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/configuration/{number}/settings": { + "get": { + "description": "List account specific settings.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "List account specific settings.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustModeResponse" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "Set account specific settings.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Set account specific settings.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustModeRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/contacts/{number}": { + "get": { + "description": "List all contacts for the given number.", + "produces": [ + "application/json" + ], + "tags": [ + "Contacts" + ], + "summary": "List Contacts", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/client.ListContactsResponse" + } + } + } + } + }, + "put": { + "description": "Updates the info associated to a number on the contact list.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Contacts" + ], + "summary": "Updates the info associated to a number on the contact list. If the contact doesn’t exist yet, it will be added.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Contact", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateContactRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/contacts/{number}/sync": { + "post": { + "description": "Send a synchronization message with the local contacts list to all linked devices. This command should only be used if this is the primary device.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Contacts" + ], + "summary": "Send a synchronization message with the local contacts list to all linked devices.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/contacts/{number}/{uuid}": { + "get": { + "description": "List a specific contact.", + "produces": [ + "application/json" + ], + "tags": [ + "Contacts" + ], + "summary": "List Contact", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.ListContactsResponse" + } + } + } + } + }, + "/v1/contacts/{number}/{uuid}/avatar": { + "get": { + "description": "Returns the avatar of a contact.", + "produces": [ + "application/json" + ], + "tags": [ + "Contacts" + ], + "summary": "Returns the avatar of a contact", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/devices/{number}": { + "get": { + "description": "List linked devices associated to this device.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Devices" + ], + "summary": "List linked devices.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/client.ListDevicesResponse" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "Links another device to this device. Only works, if this is the master device.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Devices" + ], + "summary": "Links another device to this device.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.AddDeviceRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/devices/{number}/local-data": { + "delete": { + "description": "Delete all local data for the specified account. Only use this after unregistering the account or after removing a linked device.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Devices" + ], + "summary": "Delete local account data", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Cleanup options", + "name": "data", + "in": "body", + "schema": { + "$ref": "#/definitions/api.DeleteLocalAccountDataRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/devices/{number}/{deviceId}": { + "delete": { + "description": "Remove a linked device from the primary account.", + "tags": [ + "Devices" + ], + "summary": "Remove linked device", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Device ID from listDevices", + "name": "deviceId", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}": { + "get": { + "description": "List all Signal Groups.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "List all Signal Groups.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Expand the response to show more details (default: false)", + "name": "expand", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/client.GroupEntry" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "Create a new Signal Group with the specified members.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Create a new Signal Group.", + "parameters": [ + { + "description": "Input Data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.CreateGroupRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.CreateGroupResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}/{groupid}": { + "get": { + "description": "List a specific Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "List a Signal Group.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Expand the response to show more details (default: false)", + "name": "expand", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.GroupEntry" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "put": { + "description": "Update the state of a Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Update the state of a Signal Group.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + }, + { + "description": "Input Data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateGroupRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Delete the specified Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Delete a Signal Group.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group Id", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}/{groupid}/admins": { + "post": { + "description": "Add one or more admins to an existing Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Add one or more admins to an existing Signal Group.", + "parameters": [ + { + "description": "Admins", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupAdminsRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Remove one or more admins from an existing Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Remove one or more admins from an existing Signal Group.", + "parameters": [ + { + "description": "Admins", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupAdminsRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}/{groupid}/avatar": { + "get": { + "description": "Returns the avatar of a Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Returns the avatar of a Signal Group.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}/{groupid}/block": { + "post": { + "description": "Block the specified Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Block a Signal Group.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}/{groupid}/join": { + "post": { + "description": "Join the specified Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Join a Signal Group.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}/{groupid}/members": { + "post": { + "description": "Add one or more members to an existing Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Add one or more members to an existing Signal Group.", + "parameters": [ + { + "description": "Members", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupMembersRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Remove one or more members from an existing Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Remove one or more members from an existing Signal Group.", + "parameters": [ + { + "description": "Members", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupMembersRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}/{groupid}/pin-message": { + "post": { + "description": "Pin a message in a Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Pin a message in a Signal Group.", + "parameters": [ + { + "description": "Pin", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.PinMessageInGroupRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group Id", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Unpin a message in a Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Unpin a message in a Signal Group.", + "parameters": [ + { + "description": "Unpin", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.UnpinMessageInGroupRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group Id", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/groups/{number}/{groupid}/quit": { + "post": { + "description": "Quit the specified Signal Group.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Groups" + ], + "summary": "Quit a Signal Group.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group ID", + "name": "groupid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/health": { + "get": { + "description": "Internally used by the docker container to perform the health check.", + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "API Health Check", + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/identities/{number}": { + "get": { + "description": "List all identities for the given number.", + "produces": [ + "application/json" + ], + "tags": [ + "Identities" + ], + "summary": "List Identities", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/client.IdentityEntry" + } + } + } + } + } + }, + "/v1/identities/{number}/trust/{numberToTrust}": { + "put": { + "description": "Trust an identity. When 'trust_all_known_keys' is set to' true', all known keys of this user are trusted. **This is only recommended for testing.**", + "produces": [ + "application/json" + ], + "tags": [ + "Identities" + ], + "summary": "Trust Identity", + "parameters": [ + { + "description": "Input Data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustIdentityRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Number To Trust", + "name": "numberToTrust", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + } + } + } + }, + "/v1/polls/{number}": { + "post": { + "description": "Create a new poll", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Polls" + ], + "summary": "Create a new poll.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Type", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.CreatePollRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.CreatePollResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Close a poll", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Polls" + ], + "summary": "Close a poll.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Type", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.ClosePollRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/polls/{number}/vote": { + "post": { + "description": "Answer a poll", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Polls" + ], + "summary": "Answer a poll.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Type", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.VoteRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/profiles/{number}": { + "put": { + "description": "Set your name and optional an avatar.", + "produces": [ + "application/json" + ], + "tags": [ + "Profiles" + ], + "summary": "Update Profile.", + "parameters": [ + { + "description": "Profile Data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateProfileRequest" + } + }, + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/qrcodelink": { + "get": { + "description": "Link device and generate QR code", + "produces": [ + "application/json" + ], + "tags": [ + "Devices" + ], + "summary": "Link device and generate QR code.", + "parameters": [ + { + "type": "string", + "description": "Device Name", + "name": "device_name", + "in": "query", + "required": true + }, + { + "type": "integer", + "description": "QRCode Version (defaults to 10)", + "name": "qrcode_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/qrcodelink/raw": { + "get": { + "description": "Generate the deviceLinkUri string for linking without scanning a QR code.", + "produces": [ + "application/json" + ], + "tags": [ + "Devices" + ], + "summary": "Get raw device link URI", + "parameters": [ + { + "type": "string", + "description": "Device Name", + "name": "device_name", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.DeviceLinkUriResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/reactions/{number}": { + "post": { + "description": "React to a message", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Reactions" + ], + "summary": "Send a reaction.", + "parameters": [ + { + "description": "Reaction", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendReactionRequest" + } + }, + { + "type": "string", + "description": "Registered phone number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Remove a reaction", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Reactions" + ], + "summary": "Remove a reaction.", + "parameters": [ + { + "description": "Reaction", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.RemoveReactionRequest" + } + }, + { + "type": "string", + "description": "Registered phone number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/receipts/{number}": { + "post": { + "description": "Send a read or viewed receipt", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Receipts" + ], + "summary": "Send a receipt.", + "parameters": [ + { + "description": "Receipt", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.Receipt" + } + }, + { + "type": "string", + "description": "Registered phone number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/receive/{number}": { + "get": { + "description": "Receives Signal Messages from the Signal Network. If you are running the docker container in normal/native mode, this is a GET endpoint. In json-rpc mode this is a websocket endpoint.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Messages" + ], + "summary": "Receive Signal Messages.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Receive timeout in seconds (default: 1)", + "name": "timeout", + "in": "query" + }, + { + "type": "string", + "description": "Specify whether the attachments of the received message should be ignored", + "name": "ignore_attachments", + "in": "query" + }, + { + "type": "string", + "description": "Specify whether stories should be ignored when receiving messages", + "name": "ignore_stories", + "in": "query" + }, + { + "type": "string", + "description": "Specify whether avatar downloads should be ignored when receiving messages", + "name": "ignore_avatars", + "in": "query" + }, + { + "type": "string", + "description": "Specify whether sticker pack downloads should be ignored when receiving messages", + "name": "ignore_stickers", + "in": "query" + }, + { + "type": "string", + "description": "Specify the maximum number of messages to receive (default: unlimited)", + "name": "max_messages", + "in": "query" + }, + { + "type": "string", + "description": "Specify whether read receipts should be sent when receiving messages", + "name": "send_read_receipts", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/data.Message" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/register/{number}": { + "post": { + "description": "Register a phone number with the signal network.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Devices" + ], + "summary": "Register a phone number.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Additional Settings", + "name": "data", + "in": "body", + "schema": { + "$ref": "#/definitions/api.RegisterNumberRequest" + } + } + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/register/{number}/verify/{token}": { + "post": { + "description": "Verify a registered phone number with the signal network.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Devices" + ], + "summary": "Verify a registered phone number.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Additional Settings", + "name": "data", + "in": "body", + "schema": { + "$ref": "#/definitions/api.VerifyNumberSettings" + } + }, + { + "type": "string", + "description": "Verification Code", + "name": "token", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/remote-delete/{number}": { + "delete": { + "description": "Delete a signal message", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Messages" + ], + "summary": "Delete a signal message.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Type", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.RemoteDeleteRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.RemoteDeleteResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/search/{number}": { + "get": { + "description": "Check if one or more phone numbers are registered with the Signal Service.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Search" + ], + "summary": "Check if one or more phone numbers are registered with the Signal Service.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Numbers to check", + "name": "numbers", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/api.SearchResponse" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/send": { + "post": { + "description": "Send a signal message", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Messages" + ], + "summary": "Send a signal message.", + "deprecated": true, + "parameters": [ + { + "description": "Input Data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendMessageV1" + } + } + ], + "responses": { + "201": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/sticker-packs/{number}": { + "get": { + "description": "List Installed Sticker Packs.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Sticker Packs" + ], + "summary": "List Installed Sticker Packs.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/client.ListInstalledStickerPacksResponse" + } + } + }, + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the \"Add to Signal\" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX\u0026pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Sticker Packs" + ], + "summary": "Add Sticker Pack.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.AddStickerPackRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/typing-indicator/{number}": { + "put": { + "description": "Show Typing Indicator.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Messages" + ], + "summary": "Show Typing Indicator.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Type", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.TypingIndicatorRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "delete": { + "description": "Hide Typing Indicator.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Messages" + ], + "summary": "Hide Typing Indicator.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Type", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.TypingIndicatorRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v1/unregister/{number}": { + "post": { + "description": "Disables push support for this device. **WARNING:** If *delete_account* is set to *true*, the account will be deleted from the Signal Server. This cannot be undone without loss.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Devices" + ], + "summary": "Unregister a phone number.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Additional Settings", + "name": "data", + "in": "body", + "schema": { + "$ref": "#/definitions/api.UnregisterNumberRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, + "/v2/send": { + "post": { + "description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\`monospace\\`. If you want to escape a formatting character, prefix it with two backslashes.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Messages" + ], + "summary": "Send a signal message.", + "parameters": [ + { + "description": "Input Data", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendMessageV2" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.SendMessageResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.SendMessageError" + } + } + } + } + } + }, + "definitions": { + "api.AddDeviceRequest": { + "type": "object", + "required": [ + "uri" + ], + "properties": { + "uri": { + "type": "string" + } + } + }, + "api.AddStickerPackRequest": { + "type": "object", + "required": [ + "pack_id", + "pack_key" + ], + "properties": { + "pack_id": { + "type": "string", + "example": "9a32eda01a7a28574f2eb48668ae0dc4" + }, + "pack_key": { + "type": "string", + "example": "19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a" + } + } + }, + "api.ChangeGroupAdminsRequest": { + "type": "object", + "required": [ + "admins" + ], + "properties": { + "admins": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "api.ChangeGroupMembersRequest": { + "type": "object", + "required": [ + "members" + ], + "properties": { + "members": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "api.ClosePollRequest": { + "type": "object", + "required": [ + "poll_timestamp", + "recipient" + ], + "properties": { + "poll_timestamp": { + "type": "string", + "example": "1769271479" + }, + "recipient": { + "type": "string", + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" + } + } + }, + "api.Configuration": { + "type": "object", + "required": [ + "logging" + ], + "properties": { + "logging": { + "$ref": "#/definitions/api.LoggingConfiguration" + } + } + }, + "api.CreateGroupRequest": { + "type": "object", + "required": [ + "description", + "expiration_time", + "group_link", + "members", + "name", + "permissions" + ], + "properties": { + "description": { + "type": "string" + }, + "expiration_time": { + "type": "integer" + }, + "group_link": { + "type": "string", + "enum": [ + "disabled", + "enabled", + "enabled-with-approval" + ] + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "permissions": { + "$ref": "#/definitions/data.GroupPermissions" + } + } + }, + "api.CreateGroupResponse": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string" + } + } + }, + "api.CreatePollRequest": { + "type": "object", + "required": [ + "allow_multiple_selections", + "answers", + "question", + "recipient" + ], + "properties": { + "allow_multiple_selections": { + "type": "boolean", + "example": true + }, + "answers": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "apple", + "banana", + "orange" + ] + }, + "question": { + "type": "string", + "example": "What's your favourite fruit?" + }, + "recipient": { + "type": "string", + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" + } + } + }, + "api.CreatePollResponse": { + "type": "object", + "required": [ + "timestamp" + ], + "properties": { + "timestamp": { + "type": "string", + "example": "1769271479" + } + } + }, + "api.DeleteLocalAccountDataRequest": { + "type": "object", + "required": [ + "ignore_registered" + ], + "properties": { + "ignore_registered": { + "type": "boolean", + "example": false + } + } + }, + "api.DeviceLinkUriResponse": { + "type": "object", + "required": [ + "device_link_uri" + ], + "properties": { + "device_link_uri": { + "type": "string" + } + } + }, + "api.Error": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + }, + "api.LoggingConfiguration": { + "type": "object", + "required": [ + "Level" + ], + "properties": { + "Level": { + "type": "string" + } + } + }, + "api.PinMessageInGroupRequest": { + "type": "object", + "required": [ + "duration", + "target_author", + "timestamp" + ], + "properties": { + "duration": { + "type": "integer" + }, + "target_author": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + } + }, + "api.RateLimitChallengeRequest": { + "type": "object", + "required": [ + "captcha", + "challenge_token" + ], + "properties": { + "captcha": { + "type": "string", + "example": "signalcaptcha://{captcha value}" + }, + "challenge_token": { + "type": "string", + "example": "\u003cchallenge token\u003e" + } + } + }, + "api.Receipt": { + "type": "object", + "required": [ + "receipt_type", + "recipient", + "timestamp" + ], + "properties": { + "receipt_type": { + "type": "string", + "enum": [ + "read", + "viewed" + ] + }, + "recipient": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + } + }, + "api.RegisterNumberRequest": { + "type": "object", + "required": [ + "captcha", + "use_voice" + ], + "properties": { + "captcha": { + "type": "string" + }, + "use_voice": { + "type": "boolean" + } + } + }, + "api.RemoteDeleteRequest": { + "type": "object", + "required": [ + "recipient", + "timestamp" + ], + "properties": { + "recipient": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + } + }, + "api.RemoteDeleteResponse": { + "type": "object", + "required": [ + "timestamp" + ], + "properties": { + "timestamp": { + "type": "string" + } + } + }, + "api.RemoveReactionRequest": { + "type": "object", + "required": [ + "reaction", + "recipient", + "target_author", + "timestamp" + ], + "properties": { + "reaction": { + "type": "string" + }, + "recipient": { + "type": "string" + }, + "target_author": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + } + }, + "api.SearchResponse": { + "type": "object", + "required": [ + "number", + "registered" + ], + "properties": { + "number": { + "type": "string" + }, + "registered": { + "type": "boolean" + } + } + }, + "api.SendMessageError": { + "type": "object", + "required": [ + "account", + "challenge_tokens", + "error" + ], + "properties": { + "account": { + "type": "string" + }, + "challenge_tokens": { + "type": "array", + "items": { + "type": "string" + } + }, + "error": { + "type": "string" + } + } + }, + "api.SendMessageResponse": { + "type": "object", + "required": [ + "timestamp" + ], + "properties": { + "timestamp": { + "type": "string" + } + } + }, + "api.SendMessageV1": { + "type": "object", + "required": [ + "base64_attachment", + "is_group", + "message", + "number", + "recipients" + ], + "properties": { + "base64_attachment": { + "type": "string", + "example": "'\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;base64,\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64,\u003cBASE64 ENCODED DATA\u003e'" + }, + "is_group": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "number": { + "type": "string" + }, + "recipients": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "api.SendMessageV2": { + "type": "object", + "required": [ + "base64_attachments", + "edit_timestamp", + "link_preview", + "mentions", + "message", + "notify_self", + "number", + "quote_author", + "quote_mentions", + "quote_message", + "quote_timestamp", + "recipients", + "sticker", + "text_mode", + "view_once" + ], + "properties": { + "base64_attachments": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "\u003cBASE64 ENCODED DATA\u003e", + "data:\u003cMIME-TYPE\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e", + "data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e" + ] + }, + "edit_timestamp": { + "type": "integer" + }, + "link_preview": { + "$ref": "#/definitions/data.LinkPreviewType" + }, + "mentions": { + "type": "array", + "items": { + "$ref": "#/definitions/data.MessageMention" + } + }, + "message": { + "type": "string" + }, + "notify_self": { + "type": "boolean" + }, + "number": { + "type": "string" + }, + "quote_author": { + "type": "string" + }, + "quote_mentions": { + "type": "array", + "items": { + "$ref": "#/definitions/data.MessageMention" + } + }, + "quote_message": { + "type": "string" + }, + "quote_timestamp": { + "type": "integer" + }, + "recipients": { + "type": "array", + "items": { + "type": "string" + } + }, + "sticker": { + "type": "string" + }, + "text_mode": { + "type": "string", + "enum": [ + "normal", + "styled" + ] + }, + "view_once": { + "type": "boolean" + } + } + }, + "api.SendReactionRequest": { + "type": "object", + "required": [ + "reaction", + "recipient", + "target_author", + "timestamp" + ], + "properties": { + "reaction": { + "type": "string" + }, + "recipient": { + "type": "string" + }, + "target_author": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + } + }, + "api.SetPinRequest": { + "type": "object", + "required": [ + "pin" + ], + "properties": { + "pin": { + "type": "string" + } + } + }, + "api.SetUsernameRequest": { + "type": "object", + "required": [ + "username" + ], + "properties": { + "username": { + "type": "string", + "example": "test" + } + } + }, + "api.TrustIdentityRequest": { + "type": "object", + "required": [ + "trust_all_known_keys", + "verified_safety_number" + ], + "properties": { + "trust_all_known_keys": { + "type": "boolean", + "example": false + }, + "verified_safety_number": { + "type": "string" + } + } + }, + "api.TrustModeRequest": { + "type": "object", + "required": [ + "trust_mode" + ], + "properties": { + "trust_mode": { + "type": "string" + } + } + }, + "api.TrustModeResponse": { + "type": "object", + "required": [ + "trust_mode" + ], + "properties": { + "trust_mode": { + "type": "string" + } + } + }, + "api.TypingIndicatorRequest": { + "type": "object", + "required": [ + "recipient" + ], + "properties": { + "recipient": { + "type": "string" + } + } + }, + "api.UnpinMessageInGroupRequest": { + "type": "object", + "required": [ + "target_author", + "timestamp" + ], + "properties": { + "target_author": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + } + }, + "api.UnregisterNumberRequest": { + "type": "object", + "required": [ + "delete_account", + "delete_local_data" + ], + "properties": { + "delete_account": { + "type": "boolean", + "example": false + }, + "delete_local_data": { + "type": "boolean", + "example": false + } + } + }, + "api.UpdateAccountSettingsRequest": { + "type": "object", + "required": [ + "discoverable_by_number", + "share_number" + ], + "properties": { + "discoverable_by_number": { + "type": "boolean" + }, + "share_number": { + "type": "boolean" + } + } + }, + "api.UpdateContactRequest": { + "type": "object", + "required": [ + "expiration_in_seconds", + "name", + "recipient" + ], + "properties": { + "expiration_in_seconds": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "recipient": { + "type": "string" + } + } + }, + "api.UpdateGroupRequest": { + "type": "object", + "required": [ + "base64_avatar", + "description", + "expiration_time", + "group_link", + "name", + "permissions" + ], + "properties": { + "base64_avatar": { + "type": "string" + }, + "description": { + "type": "string" + }, + "expiration_time": { + "type": "integer" + }, + "group_link": { + "type": "string", + "enum": [ + "disabled", + "enabled", + "enabled-with-approval" + ] + }, + "name": { + "type": "string" + }, + "permissions": { + "$ref": "#/definitions/data.GroupPermissions" + } + } + }, + "api.UpdateProfileRequest": { + "type": "object", + "required": [ + "about", + "base64_avatar", + "name" + ], + "properties": { + "about": { + "type": "string" + }, + "base64_avatar": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "api.VerifyNumberSettings": { + "type": "object", + "required": [ + "pin" + ], + "properties": { + "pin": { + "type": "string" + } + } + }, + "api.VoteRequest": { + "type": "object", + "required": [ + "poll_author", + "poll_timestamp", + "recipient", + "selected_answers" + ], + "properties": { + "poll_author": { + "type": "string", + "example": "\u003cphone number\u003e OR \u003cuuid\u003e" + }, + "poll_timestamp": { + "type": "string", + "example": "1769271479" + }, + "recipient": { + "type": "string", + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" + }, + "selected_answers": { + "type": "array", + "items": { + "type": "integer" + }, + "example": [ + 1 + ] + } + } + }, + "client.About": { + "type": "object", + "required": [ + "build", + "capabilities", + "mode", + "version", + "versions" + ], + "properties": { + "build": { + "type": "integer" + }, + "capabilities": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "mode": { + "type": "string" + }, + "version": { + "type": "string" + }, + "versions": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "client.ContactProfile": { + "type": "object", + "required": [ + "about", + "given_name", + "has_avatar", + "last_updated_timestamp", + "lastname" + ], + "properties": { + "about": { + "type": "string" + }, + "given_name": { + "type": "string" + }, + "has_avatar": { + "type": "boolean" + }, + "last_updated_timestamp": { + "type": "integer" + }, + "lastname": { + "type": "string" + } + } + }, + "client.GroupEntry": { + "type": "object", + "required": [ + "admins", + "blocked", + "description", + "id", + "internal_id", + "invite_link", + "members", + "name", + "pending_invites", + "pending_requests", + "permissions" + ], + "properties": { + "admins": { + "type": "array", + "items": { + "type": "string" + } + }, + "blocked": { + "type": "boolean" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "internal_id": { + "type": "string" + }, + "invite_link": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "pending_invites": { + "type": "array", + "items": { + "type": "string" + } + }, + "pending_requests": { + "type": "array", + "items": { + "type": "string" + } + }, + "permissions": { + "$ref": "#/definitions/data.GroupPermissions" + } + } + }, + "client.IdentityEntry": { + "type": "object", + "required": [ + "added", + "fingerprint", + "number", + "safety_number", + "status", + "uuid" + ], + "properties": { + "added": { + "type": "string" + }, + "fingerprint": { + "type": "string" + }, + "number": { + "type": "string" + }, + "safety_number": { + "type": "string" + }, + "status": { + "type": "string" + }, + "uuid": { + "type": "string" + } + } + }, + "client.ListContactsResponse": { + "type": "object", + "required": [ + "blocked", + "color", + "given_name", + "message_expiration", + "name", + "nickname", + "note", + "number", + "profile", + "profile_name", + "username", + "uuid" + ], + "properties": { + "blocked": { + "type": "boolean" + }, + "color": { + "type": "string" + }, + "given_name": { + "type": "string" + }, + "message_expiration": { + "type": "string" + }, + "name": { + "type": "string" + }, + "nickname": { + "$ref": "#/definitions/client.Nickname" + }, + "note": { + "type": "string" + }, + "number": { + "type": "string" + }, + "profile": { + "$ref": "#/definitions/client.ContactProfile" + }, + "profile_name": { + "type": "string" + }, + "username": { + "type": "string" + }, + "uuid": { + "type": "string" + } + } + }, + "client.ListDevicesResponse": { + "type": "object", + "required": [ + "creation_timestamp", + "id", + "last_seen_timestamp", + "name" + ], + "properties": { + "creation_timestamp": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "last_seen_timestamp": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "client.ListInstalledStickerPacksResponse": { + "type": "object", + "required": [ + "author", + "installed", + "pack_id", + "title", + "url" + ], + "properties": { + "author": { + "type": "string" + }, + "installed": { + "type": "boolean" + }, + "pack_id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "client.Nickname": { + "type": "object", + "required": [ + "family_name", + "given_name", + "name" + ], + "properties": { + "family_name": { + "type": "string" + }, + "given_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "client.SetUsernameResponse": { + "type": "object", + "required": [ + "username", + "username_link" + ], + "properties": { + "username": { + "type": "string" + }, + "username_link": { + "type": "string" + } + } + }, + "data.GroupPermissions": { + "type": "object", + "required": [ + "add_members", + "edit_group", + "send_messages" + ], + "properties": { + "add_members": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "edit_group": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "send_messages": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + } + } + }, + "data.LinkPreviewType": { + "type": "object", + "required": [ + "base64_thumbnail", + "description", + "title", + "url" + ], + "properties": { + "base64_thumbnail": { + "type": "string" + }, + "description": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "data.MessageMention": { + "type": "object", + "required": [ + "author", + "length", + "start" + ], + "properties": { + "author": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "start": { + "type": "integer" + } + } + }, + "data.Message": { + "properties": { + "account": { + "type": "string" + }, + "envelope": { + "$ref": "#/definitions/receive.MessageEnvelope" + } + }, + "required": [ + "account", + "envelope" + ], + "type": "object" + }, + "receive.AdminDelete": { + "properties": { + "targetAuthor": { + "type": "string" + }, + "targetAuthorNumber": { + "type": "string" + }, + "targetAuthorUuid": { + "type": "string" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp" + ], + "type": "object" + }, + "receive.Attachment": { + "properties": { + "caption": { + "type": "string" + }, + "contentType": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "uploadTimestamp": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "type": "object" + }, + "receive.AttachmentData": { + "properties": { + "data": { + "type": "string" + } + }, + "type": "object" + }, + "receive.CallMessage": { + "properties": { + "answerMessage": { + "properties": { + "id": { + "type": "integer" + }, + "opaque": { + "type": "string" + } + }, + "type": "object" + }, + "busyMessage": { + "properties": { + "id": { + "type": "integer" + } + }, + "type": "object" + }, + "hangupMessage": { + "properties": { + "deviceId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "type": { + "type": "string" + } + }, + "required": [ + "deviceId" + ], + "type": "object" + }, + "iceUpdateMessages": { + "items": { + "properties": { + "id": { + "type": "integer" + }, + "opaque": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "offerMessage": { + "properties": { + "id": { + "type": "integer" + }, + "opaque": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "receive.Contact": { + "properties": { + "color": { + "type": "string" + }, + "familyName": { + "type": "string" + }, + "givenName": { + "type": "string" + }, + "internal": { + "$ref": "#/definitions/receive.Internal" + }, + "isArchived": { + "type": "boolean" + }, + "isBlocked": { + "type": "boolean" + }, + "isHidden": { + "type": "boolean" + }, + "messageExpirationTime": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "nickFamilyName": { + "type": "string" + }, + "nickGivenName": { + "type": "string" + }, + "nickName": { + "type": "string" + }, + "note": { + "type": "string" + }, + "number": { + "type": "string" + }, + "profile": { + "$ref": "#/definitions/receive.Profile" + }, + "profileSharing": { + "type": "boolean" + }, + "unregistered": { + "type": "boolean" + }, + "username": { + "type": "string" + }, + "uuid": { + "type": "string" + } + }, + "required": [ + "isArchived", + "isBlocked", + "isHidden", + "messageExpirationTime", + "profileSharing", + "unregistered" + ], + "type": "object" + }, + "receive.ContactAddress": { + "properties": { + "city": { + "type": "string" + }, + "country": { + "type": "string" + }, + "label": { + "type": "string" + }, + "neighborhood": { + "type": "string" + }, + "pobox": { + "type": "string" + }, + "postcode": { + "type": "string" + }, + "region": { + "type": "string" + }, + "street": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "receive.ContactAvatar": { + "properties": { + "attachment": { + "$ref": "#/definitions/receive.Attachment" + }, + "isProfile": { + "type": "boolean" + } + }, + "required": [ + "isProfile" + ], + "type": "object" + }, + "receive.ContactEmail": { + "properties": { + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "receive.ContactName": { + "properties": { + "family": { + "type": "string" + }, + "given": { + "type": "string" + }, + "middle": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "suffix": { + "type": "string" + } + }, + "type": "object" + }, + "receive.ContactPhone": { + "properties": { + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "receive.DataMessage": { + "properties": { + "adminDelete": { + "$ref": "#/definitions/receive.AdminDelete" + }, + "attachments": { + "items": { + "$ref": "#/definitions/receive.Attachment" + }, + "type": "array" + }, + "contacts": { + "items": { + "$ref": "#/definitions/receive.SharedContact" + }, + "type": "array" + }, + "expiresInSeconds": { + "type": "integer" + }, + "groupInfo": { + "$ref": "#/definitions/receive.GroupInfo" + }, + "isExpirationUpdate": { + "type": "boolean" + }, + "mentions": { + "items": { + "$ref": "#/definitions/receive.Mention" + }, + "type": "array" + }, + "message": { + "type": "string" + }, + "payment": { + "$ref": "#/definitions/receive.Payment" + }, + "pinMessage": { + "$ref": "#/definitions/receive.PinMessage" + }, + "pollCreate": { + "$ref": "#/definitions/receive.PollCreate" + }, + "pollTerminate": { + "$ref": "#/definitions/receive.PollTerminate" + }, + "pollVote": { + "$ref": "#/definitions/receive.PollVote" + }, + "previews": { + "items": { + "$ref": "#/definitions/receive.Preview" + }, + "type": "array" + }, + "quote": { + "$ref": "#/definitions/receive.Quote" + }, + "reaction": { + "$ref": "#/definitions/receive.Reaction" + }, + "remoteDelete": { + "$ref": "#/definitions/receive.RemoteDelete" + }, + "sticker": { + "$ref": "#/definitions/receive.Sticker" + }, + "storyContext": { + "$ref": "#/definitions/receive.StoryContext" + }, + "textStyles": { + "items": { + "$ref": "#/definitions/receive.TextStyle" + }, + "type": "array" + }, + "timestamp": { + "type": "integer" + }, + "unpinMessage": { + "$ref": "#/definitions/receive.UnpinMessage" + }, + "viewOnce": { + "type": "boolean" + } + }, + "required": [ + "timestamp" + ], + "type": "object" + }, + "receive.EditMessage": { + "properties": { + "dataMessage": { + "$ref": "#/definitions/receive.DataMessage" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp" + ], + "type": "object" + }, + "receive.Error": { + "properties": { + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "receive.GroupInfo": { + "properties": { + "groupId": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "revision": { + "type": "integer" + }, + "type": { + "type": "string" + } + }, + "required": [ + "revision" + ], + "type": "object" + }, + "receive.Internal": { + "properties": { + "capabilities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "discoverableByPhonenumber": { + "type": "boolean" + }, + "sharesPhoneNumber": { + "type": "boolean" + }, + "unidentifiedAccessMode": { + "type": "string" + } + }, + "type": "object" + }, + "receive.Mention": { + "properties": { + "length": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "number": { + "type": "string" + }, + "start": { + "type": "integer" + }, + "uuid": { + "type": "string" + } + }, + "required": [ + "start", + "length" + ], + "type": "object" + }, + "receive.MessageEnvelope": { + "properties": { + "callMessage": { + "$ref": "#/definitions/receive.CallMessage" + }, + "dataMessage": { + "$ref": "#/definitions/receive.DataMessage" + }, + "editMessage": { + "$ref": "#/definitions/receive.EditMessage" + }, + "receiptMessage": { + "$ref": "#/definitions/receive.ReceiptMessage" + }, + "serverDeliveredTimestamp": { + "type": "integer" + }, + "serverReceivedTimestamp": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "sourceDevice": { + "type": "integer" + }, + "sourceName": { + "type": "string" + }, + "sourceNumber": { + "type": "string" + }, + "sourceUuid": { + "type": "string" + }, + "storyMessage": { + "$ref": "#/definitions/receive.StoryMessage" + }, + "syncMessage": { + "$ref": "#/definitions/receive.SyncMessage" + }, + "timestamp": { + "type": "integer" + }, + "typingMessage": { + "$ref": "#/definitions/receive.TypingMessage" + } + }, + "required": [ + "timestamp", + "serverReceivedTimestamp", + "serverDeliveredTimestamp" + ], + "type": "object" + }, + "receive.Payment": { + "properties": { + "note": { + "type": "string" + }, + "receipt": { + "type": "string" + } + }, + "required": [ + "receipt" + ], + "type": "object" + }, + "receive.PinMessage": { + "properties": { + "pinDurationSeconds": { + "type": "integer" + }, + "targetAuthor": { + "type": "string" + }, + "targetAuthorNumber": { + "type": "string" + }, + "targetAuthorUuid": { + "type": "string" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp", + "pinDurationSeconds" + ], + "type": "object" + }, + "receive.PollCreate": { + "properties": { + "allowMultiple": { + "type": "boolean" + }, + "options": { + "items": { + "type": "string" + }, + "type": "array" + }, + "question": { + "type": "string" + } + }, + "required": [ + "allowMultiple" + ], + "type": "object" + }, + "receive.PollTerminate": { + "properties": { + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp" + ], + "type": "object" + }, + "receive.PollVote": { + "properties": { + "author": { + "type": "string" + }, + "authorNumber": { + "type": "string" + }, + "authorUuid": { + "type": "string" + }, + "optionIndexes": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "targetSentTimestamp": { + "type": "integer" + }, + "voteCount": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp", + "voteCount" + ], + "type": "object" + }, + "receive.Preview": { + "properties": { + "description": { + "type": "string" + }, + "image": { + "$ref": "#/definitions/receive.Attachment" + }, + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "receive.Profile": { + "properties": { + "about": { + "type": "string" + }, + "aboutEmoji": { + "type": "string" + }, + "familyName": { + "type": "string" + }, + "givenName": { + "type": "string" + }, + "hasAvatar": { + "type": "boolean" + }, + "lastUpdateTimestamp": { + "type": "integer" + }, + "mobileCoinAddress": { + "type": "string" + } + }, + "required": [ + "lastUpdateTimestamp", + "hasAvatar" + ], + "type": "object" + }, + "receive.Quote": { + "properties": { + "attachments": { + "items": { + "$ref": "#/definitions/receive.QuotedAttachment" + }, + "type": "array" + }, + "author": { + "type": "string" + }, + "authorNumber": { + "type": "string" + }, + "authorUuid": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "mentions": { + "items": { + "$ref": "#/definitions/receive.Mention" + }, + "type": "array" + }, + "text": { + "type": "string" + }, + "textStyles": { + "items": { + "$ref": "#/definitions/receive.TextStyle" + }, + "type": "array" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "receive.QuotedAttachment": { + "properties": { + "contentType": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "thumbnail": { + "$ref": "#/definitions/receive.Attachment" + } + }, + "type": "object" + }, + "receive.Reaction": { + "properties": { + "emoji": { + "type": "string" + }, + "isRemove": { + "type": "boolean" + }, + "targetAuthor": { + "type": "string" + }, + "targetAuthorNumber": { + "type": "string" + }, + "targetAuthorUuid": { + "type": "string" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp", + "isRemove" + ], + "type": "object" + }, + "receive.ReceiptMessage": { + "properties": { + "isDelivery": { + "type": "boolean" + }, + "isRead": { + "type": "boolean" + }, + "isViewed": { + "type": "boolean" + }, + "timestamps": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "when": { + "type": "integer" + } + }, + "required": [ + "when", + "isDelivery", + "isRead", + "isViewed" + ], + "type": "object" + }, + "receive.RecipientAddress": { + "properties": { + "number": { + "type": "string" + }, + "username": { + "type": "string" + }, + "uuid": { + "type": "string" + } + }, + "type": "object" + }, + "receive.RemoteDelete": { + "properties": { + "timestamp": { + "type": "integer" + } + }, + "required": [ + "timestamp" + ], + "type": "object" + }, + "receive.SendMessageResult": { + "properties": { + "groupId": { + "type": "string" + }, + "recipientAddress": { + "$ref": "#/definitions/receive.RecipientAddress" + }, + "retryAfterSeconds": { + "type": "integer" + }, + "token": { + "type": "string" + }, + "type": { + "enum": [ + "SUCCESS", + "NETWORK_FAILURE", + "UNREGISTERED_FAILURE", + "IDENTITY_FAILURE", + "RATE_LIMIT_FAILURE", + "INVALID_PRE_KEY_FAILURE" + ], + "type": "string" + } + }, + "type": "object" + }, + "receive.SharedContact": { + "properties": { + "address": { + "items": { + "$ref": "#/definitions/receive.ContactAddress" + }, + "type": "array" + }, + "avatar": { + "$ref": "#/definitions/receive.ContactAvatar" + }, + "email": { + "items": { + "$ref": "#/definitions/receive.ContactEmail" + }, + "type": "array" + }, + "name": { + "$ref": "#/definitions/receive.ContactName" + }, + "organization": { + "type": "string" + }, + "phone": { + "items": { + "$ref": "#/definitions/receive.ContactPhone" + }, + "type": "array" + } + }, + "type": "object" + }, + "receive.Sticker": { + "properties": { + "packId": { + "type": "string" + }, + "stickerId": { + "type": "integer" + } + }, + "required": [ + "stickerId" + ], + "type": "object" + }, + "receive.StoryContext": { + "properties": { + "authorNumber": { + "type": "string" + }, + "authorUuid": { + "type": "string" + }, + "sentTimestamp": { + "type": "integer" + } + }, + "required": [ + "sentTimestamp" + ], + "type": "object" + }, + "receive.StoryMessage": { + "properties": { + "allowsReplies": { + "type": "boolean" + }, + "fileAttachment": { + "$ref": "#/definitions/receive.Attachment" + }, + "groupId": { + "type": "string" + }, + "textAttachment": { + "properties": { + "backgroundColor": { + "type": "string" + }, + "backgroundGradient": { + "properties": { + "angle": { + "type": "integer" + }, + "colors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "endColor": { + "type": "string" + }, + "positions": { + "items": { + "type": "number" + }, + "type": "array" + }, + "startColor": { + "type": "string" + } + }, + "type": "object" + }, + "preview": { + "$ref": "#/definitions/receive.Preview" + }, + "style": { + "type": "string" + }, + "text": { + "type": "string" + }, + "textBackgroundColor": { + "type": "string" + }, + "textForegroundColor": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "allowsReplies" + ], + "type": "object" + }, + "receive.SyncDataMessage": { + "properties": { + "adminDelete": { + "$ref": "#/definitions/receive.AdminDelete" + }, + "attachments": { + "items": { + "$ref": "#/definitions/receive.Attachment" + }, + "type": "array" + }, + "contacts": { + "items": { + "$ref": "#/definitions/receive.SharedContact" + }, + "type": "array" + }, + "destination": { + "type": "string" + }, + "destinationNumber": { + "type": "string" + }, + "destinationUuid": { + "type": "string" + }, + "editMessage": { + "$ref": "#/definitions/receive.EditMessage" + }, + "expiresInSeconds": { + "type": "integer" + }, + "groupInfo": { + "$ref": "#/definitions/receive.GroupInfo" + }, + "isExpirationUpdate": { + "type": "boolean" + }, + "mentions": { + "items": { + "$ref": "#/definitions/receive.Mention" + }, + "type": "array" + }, + "message": { + "type": "string" + }, + "payment": { + "$ref": "#/definitions/receive.Payment" + }, + "pinMessage": { + "$ref": "#/definitions/receive.PinMessage" + }, + "pollCreate": { + "$ref": "#/definitions/receive.PollCreate" + }, + "pollTerminate": { + "$ref": "#/definitions/receive.PollTerminate" + }, + "pollVote": { + "$ref": "#/definitions/receive.PollVote" + }, + "previews": { + "items": { + "$ref": "#/definitions/receive.Preview" + }, + "type": "array" + }, + "quote": { + "$ref": "#/definitions/receive.Quote" + }, + "reaction": { + "$ref": "#/definitions/receive.Reaction" + }, + "remoteDelete": { + "$ref": "#/definitions/receive.RemoteDelete" + }, + "sticker": { + "$ref": "#/definitions/receive.Sticker" + }, + "storyContext": { + "$ref": "#/definitions/receive.StoryContext" + }, + "textStyles": { + "items": { + "$ref": "#/definitions/receive.TextStyle" + }, + "type": "array" + }, + "timestamp": { + "type": "integer" + }, + "unpinMessage": { + "$ref": "#/definitions/receive.UnpinMessage" + }, + "viewOnce": { + "type": "boolean" + } + }, + "type": "object" + }, + "receive.SyncMessage": { + "properties": { + "blockedGroupIds": { + "items": { + "type": "string" + }, + "type": "array" + }, + "blockedNumbers": { + "items": { + "type": "string" + }, + "type": "array" + }, + "readMessages": { + "items": { + "$ref": "#/definitions/receive.SyncReadMessage" + }, + "type": "array" + }, + "sentMessage": { + "$ref": "#/definitions/receive.SyncDataMessage" + }, + "sentStoryMessage": { + "$ref": "#/definitions/receive.SyncStoryMessage" + }, + "type": { + "enum": [ + "CONTACTS_SYNC", + "GROUPS_SYNC", + "REQUEST_SYNC" + ], + "type": "string" + } + }, + "type": "object" + }, + "receive.SyncReadMessage": { + "properties": { + "sender": { + "type": "string" + }, + "senderNumber": { + "type": "string" + }, + "senderUuid": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + }, + "required": [ + "timestamp" + ], + "type": "object" + }, + "receive.SyncStoryMessage": { + "properties": { + "allowsReplies": { + "type": "boolean" + }, + "destinationNumber": { + "type": "string" + }, + "destinationUuid": { + "type": "string" + }, + "fileAttachment": { + "$ref": "#/definitions/receive.Attachment" + }, + "groupId": { + "type": "string" + }, + "textAttachment": { + "properties": { + "backgroundColor": { + "type": "string" + }, + "backgroundGradient": { + "properties": { + "angle": { + "type": "integer" + }, + "colors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "endColor": { + "type": "string" + }, + "positions": { + "items": { + "type": "number" + }, + "type": "array" + }, + "startColor": { + "type": "string" + } + }, + "type": "object" + }, + "preview": { + "$ref": "#/definitions/receive.Preview" + }, + "style": { + "type": "string" + }, + "text": { + "type": "string" + }, + "textBackgroundColor": { + "type": "string" + }, + "textForegroundColor": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "receive.TextStyle": { + "properties": { + "length": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "style": { + "type": "string" + } + }, + "required": [ + "start", + "length" + ], + "type": "object" + }, + "receive.TypingMessage": { + "properties": { + "action": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + }, + "required": [ + "timestamp" + ], + "type": "object" + }, + "receive.UnpinMessage": { + "properties": { + "targetAuthor": { + "type": "string" + }, + "targetAuthorNumber": { + "type": "string" + }, + "targetAuthorUuid": { + "type": "string" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp" + ], + "type": "object" + } + }, + "tags": [ + { + "description": "Some general endpoints.", + "name": "General" + }, + { + "description": "Register and link Devices.", + "name": "Devices" + }, + { + "description": "List registered and linked accounts", + "name": "Accounts" + }, + { + "description": "Create, List and Delete Signal Groups.", + "name": "Groups" + }, + { + "description": "Send and Receive Signal Messages.", + "name": "Messages" + }, + { + "description": "List and Delete Attachments.", + "name": "Attachments" + }, + { + "description": "Update Profile.", + "name": "Profiles" + }, + { + "description": "List and Trust Identities.", + "name": "Identities" + }, + { + "description": "React to messages.", + "name": "Reactions" + }, + { + "description": "Send receipts for messages.", + "name": "Receipts" + }, + { + "description": "Search the Signal Service.", + "name": "Search" + }, + { + "description": "List and Install Sticker Packs", + "name": "Sticker Packs" + } + ] +} \ No newline at end of file From 948a522ad8c189e3a2a53f22c3223082fb091f8e Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 13:44:20 +0100 Subject: [PATCH 11/40] Add back json generation --- Dockerfile | 2 +- src/docs/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index b27f64f..e9e2420 100644 --- a/Dockerfile +++ b/Dockerfile @@ -148,7 +148,7 @@ COPY src/docs/add_v1_receive_schemas.go /tmp/signal-cli-rest-api-src/docs/add_v1 RUN ls -la /tmp/signal-cli-rest-api-src # build the docs -RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefault --outputTypes go +RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefault --outputTypes "go,json" # manually add the json schemas for the receive V1 endpoint to the docs RUN if [ "$(uname -m)" = "x86_64" ]; then \ diff --git a/src/docs/README.md b/src/docs/README.md index 20d1b0d..92d8ba5 100644 --- a/src/docs/README.md +++ b/src/docs/README.md @@ -15,11 +15,11 @@ Regenerate the files with your local source code changes. 1. Run swag to generate the docs * Option 1, via docker ```bash - docker run --rm -v $(pwd):/code ghcr.io/swaggo/swag:latest init --requiredByDefault --outputTypes go + docker run --rm -v $(pwd):/code ghcr.io/swaggo/swag:latest init --requiredByDefault --outputTypes "go,json" ``` * Option 2, install swag and run the command line tool ```bash - swag init --requiredByDefault --outputTypes go + swag init --requiredByDefault --outputTypes "go,json" ``` 1. Set the current working dir to `src/docs` ```bash From 6ac432b509f3b9b9a65ba9e3fcb11d521d85d2f4 Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 14:09:12 +0100 Subject: [PATCH 12/40] Update script to also modify the json file Co-authored-by: Copilot --- src/docs/add_v1_receive_schemas.go | 82 ++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/src/docs/add_v1_receive_schemas.go b/src/docs/add_v1_receive_schemas.go index ce5607a..5d9729b 100644 --- a/src/docs/add_v1_receive_schemas.go +++ b/src/docs/add_v1_receive_schemas.go @@ -15,7 +15,8 @@ import ( ) const ( - docsPath = "docs.go" + goDocsPath = "docs.go" + jsonDocsPath = "swagger.json" openMarker = "const docTemplate = `" closeMarker = "`\n\n// SwaggerInfo" definitionsKey = `"definitions": {` @@ -38,16 +39,6 @@ func main() { } func run(receiveDir string) error { - content, err := os.ReadFile(docsPath) - if err != nil { - return fmt.Errorf("read %s: %w", docsPath, err) - } - - template, err := extractDocTemplate(string(content)) - if err != nil { - return err - } - definitions := make(map[string]interface{}) titleByFile, err := addReceiveSchemas(definitions, receiveDir) @@ -61,41 +52,90 @@ func run(receiveDir string) error { addEnvelopeWrapperDefinition(definitions) - newEntries, err := renderManagedDefinitions(definitions) + managedDefinitions, err := renderManagedDefinitions(definitions) if err != nil { return err } - updatedTemplate, err := appendDefinitionsEntries(template, newEntries) + if err := updateDocsGo(managedDefinitions); err != nil { + return err + } + + if err := updateSwaggerJSON(managedDefinitions); err != nil { + return err + } + + fmt.Printf("updated %s\n", goDocsPath) + fmt.Printf("updated %s\n", jsonDocsPath) + return nil +} + +func updateDocsGo(managedDefinitions string) error { + content, err := os.ReadFile(goDocsPath) + if err != nil { + return fmt.Errorf("read %s: %w", goDocsPath, err) + } + + template, err := extractDocTemplate(string(content)) if err != nil { return err } - updatedTemplate, err = replaceReceiveResponseSchema(updatedTemplate) + updatedTemplate, err := applyReceiveSchemaUpdates(template, managedDefinitions) if err != nil { return err } updated := strings.Replace(string(content), template, updatedTemplate, 1) - - if err := os.WriteFile(docsPath, []byte(updated), 0644); err != nil { - return fmt.Errorf("write %s: %w", docsPath, err) + if err := os.WriteFile(goDocsPath, []byte(updated), 0644); err != nil { + return fmt.Errorf("write %s: %w", goDocsPath, err) } - fmt.Printf("updated %s\n", docsPath) return nil } +func updateSwaggerJSON(managedDefinitions string) error { + content, err := os.ReadFile(jsonDocsPath) + if err != nil { + return fmt.Errorf("read %s: %w", jsonDocsPath, err) + } + + updated, err := applyReceiveSchemaUpdates(string(content), managedDefinitions) + if err != nil { + return err + } + + if err := os.WriteFile(jsonDocsPath, []byte(updated), 0644); err != nil { + return fmt.Errorf("write %s: %w", jsonDocsPath, err) + } + + return nil +} + +func applyReceiveSchemaUpdates(content string, managedDefinitions string) (string, error) { + updated, err := appendDefinitionsEntries(content, managedDefinitions) + if err != nil { + return "", err + } + + updated, err = replaceReceiveResponseSchema(updated) + if err != nil { + return "", err + } + + return updated, nil +} + func extractDocTemplate(content string) (string, error) { start := strings.Index(content, openMarker) if start == -1 { - return "", fmt.Errorf("could not find docTemplate start in %s", docsPath) + return "", fmt.Errorf("could not find docTemplate start in %s", goDocsPath) } start += len(openMarker) endOffset := strings.Index(content[start:], closeMarker) if endOffset == -1 { - return "", fmt.Errorf("could not find docTemplate end in %s", docsPath) + return "", fmt.Errorf("could not find docTemplate end in %s", goDocsPath) } return content[start : start+endOffset], nil @@ -320,7 +360,7 @@ func replaceReceiveResponseSchema(template string) (string, error) { updatedPathBlock := strings.Replace(pathBlock, oldSchema, newSchema, 1) if updatedPathBlock == pathBlock { - return "", fmt.Errorf("could not replace /v1/receive schema; ensure docs.go is freshly generated by swag") + return "", fmt.Errorf("could not replace /v1/receive schema; ensure generated docs are freshly generated by swag") } return template[:pathOpenBrace] + updatedPathBlock + template[pathCloseBrace+1:], nil From 1f222d72617516589f894b216b0f5065a8facaba Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 14:09:43 +0100 Subject: [PATCH 13/40] Add receive definitions to the docs files --- src/docs/docs.go | 1345 ++++++++++++++++++++++++++++++++++++++++- src/docs/swagger.json | 21 +- 2 files changed, 1358 insertions(+), 8 deletions(-) diff --git a/src/docs/docs.go b/src/docs/docs.go index d4e175d..36fb923 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -2190,10 +2190,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "array", - "items": { - "type": "string" - } + "$ref": "#/definitions/data.Message" } }, "400": { @@ -2790,6 +2787,14 @@ const docTemplate = `{ }, "api.CreateGroupRequest": { "type": "object", + "required": [ + "description", + "expiration_time", + "group_link", + "members", + "name", + "permissions" + ], "properties": { "description": { "type": "string" @@ -2833,6 +2838,7 @@ const docTemplate = `{ "api.CreatePollRequest": { "type": "object", "required": [ + "allow_multiple_selections", "answers", "question", "recipient" @@ -2877,6 +2883,9 @@ const docTemplate = `{ }, "api.DeleteLocalAccountDataRequest": { "type": "object", + "required": [ + "ignore_registered" + ], "properties": { "ignore_registered": { "type": "boolean", @@ -2920,6 +2929,7 @@ const docTemplate = `{ "api.PinMessageInGroupRequest": { "type": "object", "required": [ + "duration", "target_author", "timestamp" ], @@ -2977,6 +2987,10 @@ const docTemplate = `{ }, "api.RegisterNumberRequest": { "type": "object", + "required": [ + "captcha", + "use_voice" + ], "properties": { "captcha": { "type": "string" @@ -3015,6 +3029,7 @@ const docTemplate = `{ "api.RemoveReactionRequest": { "type": "object", "required": [ + "reaction", "recipient", "target_author", "timestamp" @@ -3053,6 +3068,7 @@ const docTemplate = `{ "type": "object", "required": [ "account", + "challenge_tokens", "error" ], "properties": { @@ -3084,6 +3100,8 @@ const docTemplate = `{ "api.SendMessageV1": { "type": "object", "required": [ + "base64_attachment", + "is_group", "message", "number", "recipients" @@ -3113,9 +3131,21 @@ const docTemplate = `{ "api.SendMessageV2": { "type": "object", "required": [ + "base64_attachments", + "edit_timestamp", + "link_preview", + "mentions", "message", + "notify_self", "number", - "recipients" + "quote_author", + "quote_mentions", + "quote_message", + "quote_timestamp", + "recipients", + "sticker", + "text_mode", + "view_once" ], "properties": { "base64_attachments": { @@ -3234,6 +3264,10 @@ const docTemplate = `{ }, "api.TrustIdentityRequest": { "type": "object", + "required": [ + "trust_all_known_keys", + "verified_safety_number" + ], "properties": { "trust_all_known_keys": { "type": "boolean", @@ -3294,6 +3328,10 @@ const docTemplate = `{ }, "api.UnregisterNumberRequest": { "type": "object", + "required": [ + "delete_account", + "delete_local_data" + ], "properties": { "delete_account": { "type": "boolean", @@ -3307,6 +3345,10 @@ const docTemplate = `{ }, "api.UpdateAccountSettingsRequest": { "type": "object", + "required": [ + "discoverable_by_number", + "share_number" + ], "properties": { "discoverable_by_number": { "type": "boolean" @@ -3319,6 +3361,8 @@ const docTemplate = `{ "api.UpdateContactRequest": { "type": "object", "required": [ + "expiration_in_seconds", + "name", "recipient" ], "properties": { @@ -3335,6 +3379,14 @@ const docTemplate = `{ }, "api.UpdateGroupRequest": { "type": "object", + "required": [ + "base64_avatar", + "description", + "expiration_time", + "group_link", + "name", + "permissions" + ], "properties": { "base64_avatar": { "type": "string" @@ -3364,6 +3416,8 @@ const docTemplate = `{ "api.UpdateProfileRequest": { "type": "object", "required": [ + "about", + "base64_avatar", "name" ], "properties": { @@ -3380,6 +3434,9 @@ const docTemplate = `{ }, "api.VerifyNumberSettings": { "type": "object", + "required": [ + "pin" + ], "properties": { "pin": { "type": "string" @@ -3786,6 +3843,1284 @@ const docTemplate = `{ "type": "integer" } } + }, + "data.Message": { + "properties": { + "account": { + "type": "string" + }, + "envelope": { + "$ref": "#/definitions/receive.MessageEnvelope" + } + }, + "required": [ + "account", + "envelope" + ], + "type": "object" + }, + "receive.AdminDelete": { + "properties": { + "targetAuthor": { + "type": "string" + }, + "targetAuthorNumber": { + "type": "string" + }, + "targetAuthorUuid": { + "type": "string" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp" + ], + "type": "object" + }, + "receive.Attachment": { + "properties": { + "caption": { + "type": "string" + }, + "contentType": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "uploadTimestamp": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "type": "object" + }, + "receive.AttachmentData": { + "properties": { + "data": { + "type": "string" + } + }, + "type": "object" + }, + "receive.CallMessage": { + "properties": { + "answerMessage": { + "properties": { + "id": { + "type": "integer" + }, + "opaque": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "busyMessage": { + "properties": { + "id": { + "type": "integer" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "hangupMessage": { + "properties": { + "deviceId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "deviceId" + ], + "type": "object" + }, + "iceUpdateMessages": { + "items": { + "properties": { + "id": { + "type": "integer" + }, + "opaque": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + }, + "offerMessage": { + "properties": { + "id": { + "type": "integer" + }, + "opaque": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + }, + "type": "object" + }, + "receive.Contact": { + "properties": { + "color": { + "type": "string" + }, + "familyName": { + "type": "string" + }, + "givenName": { + "type": "string" + }, + "internal": { + "$ref": "#/definitions/receive.Internal" + }, + "isArchived": { + "type": "boolean" + }, + "isBlocked": { + "type": "boolean" + }, + "isHidden": { + "type": "boolean" + }, + "messageExpirationTime": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "nickFamilyName": { + "type": "string" + }, + "nickGivenName": { + "type": "string" + }, + "nickName": { + "type": "string" + }, + "note": { + "type": "string" + }, + "number": { + "type": "string" + }, + "profile": { + "$ref": "#/definitions/receive.Profile" + }, + "profileSharing": { + "type": "boolean" + }, + "unregistered": { + "type": "boolean" + }, + "username": { + "type": "string" + }, + "uuid": { + "type": "string" + } + }, + "required": [ + "isArchived", + "isBlocked", + "isHidden", + "messageExpirationTime", + "profileSharing", + "unregistered" + ], + "type": "object" + }, + "receive.ContactAddress": { + "properties": { + "city": { + "type": "string" + }, + "country": { + "type": "string" + }, + "label": { + "type": "string" + }, + "neighborhood": { + "type": "string" + }, + "pobox": { + "type": "string" + }, + "postcode": { + "type": "string" + }, + "region": { + "type": "string" + }, + "street": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "receive.ContactAvatar": { + "properties": { + "attachment": { + "$ref": "#/definitions/receive.Attachment" + }, + "isProfile": { + "type": "boolean" + } + }, + "required": [ + "isProfile" + ], + "type": "object" + }, + "receive.ContactEmail": { + "properties": { + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "receive.ContactName": { + "properties": { + "family": { + "type": "string" + }, + "given": { + "type": "string" + }, + "middle": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "suffix": { + "type": "string" + } + }, + "type": "object" + }, + "receive.ContactPhone": { + "properties": { + "label": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "receive.DataMessage": { + "properties": { + "adminDelete": { + "$ref": "#/definitions/receive.AdminDelete" + }, + "attachments": { + "items": { + "$ref": "#/definitions/receive.Attachment" + }, + "type": "array" + }, + "contacts": { + "items": { + "$ref": "#/definitions/receive.SharedContact" + }, + "type": "array" + }, + "expiresInSeconds": { + "type": "integer" + }, + "groupInfo": { + "$ref": "#/definitions/receive.GroupInfo" + }, + "isExpirationUpdate": { + "type": "boolean" + }, + "mentions": { + "items": { + "$ref": "#/definitions/receive.Mention" + }, + "type": "array" + }, + "message": { + "type": "string" + }, + "payment": { + "$ref": "#/definitions/receive.Payment" + }, + "pinMessage": { + "$ref": "#/definitions/receive.PinMessage" + }, + "pollCreate": { + "$ref": "#/definitions/receive.PollCreate" + }, + "pollTerminate": { + "$ref": "#/definitions/receive.PollTerminate" + }, + "pollVote": { + "$ref": "#/definitions/receive.PollVote" + }, + "previews": { + "items": { + "$ref": "#/definitions/receive.Preview" + }, + "type": "array" + }, + "quote": { + "$ref": "#/definitions/receive.Quote" + }, + "reaction": { + "$ref": "#/definitions/receive.Reaction" + }, + "remoteDelete": { + "$ref": "#/definitions/receive.RemoteDelete" + }, + "sticker": { + "$ref": "#/definitions/receive.Sticker" + }, + "storyContext": { + "$ref": "#/definitions/receive.StoryContext" + }, + "textStyles": { + "items": { + "$ref": "#/definitions/receive.TextStyle" + }, + "type": "array" + }, + "timestamp": { + "type": "integer" + }, + "unpinMessage": { + "$ref": "#/definitions/receive.UnpinMessage" + }, + "viewOnce": { + "type": "boolean" + } + }, + "required": [ + "timestamp" + ], + "type": "object" + }, + "receive.EditMessage": { + "properties": { + "dataMessage": { + "$ref": "#/definitions/receive.DataMessage" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp" + ], + "type": "object" + }, + "receive.Error": { + "properties": { + "message": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "receive.GroupInfo": { + "properties": { + "groupId": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "revision": { + "type": "integer" + }, + "type": { + "type": "string" + } + }, + "required": [ + "revision" + ], + "type": "object" + }, + "receive.Internal": { + "properties": { + "capabilities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "discoverableByPhonenumber": { + "type": "boolean" + }, + "sharesPhoneNumber": { + "type": "boolean" + }, + "unidentifiedAccessMode": { + "type": "string" + } + }, + "type": "object" + }, + "receive.Mention": { + "properties": { + "length": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "number": { + "type": "string" + }, + "start": { + "type": "integer" + }, + "uuid": { + "type": "string" + } + }, + "required": [ + "start", + "length" + ], + "type": "object" + }, + "receive.MessageEnvelope": { + "properties": { + "callMessage": { + "$ref": "#/definitions/receive.CallMessage" + }, + "dataMessage": { + "$ref": "#/definitions/receive.DataMessage" + }, + "editMessage": { + "$ref": "#/definitions/receive.EditMessage" + }, + "receiptMessage": { + "$ref": "#/definitions/receive.ReceiptMessage" + }, + "serverDeliveredTimestamp": { + "type": "integer" + }, + "serverReceivedTimestamp": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "sourceDevice": { + "type": "integer" + }, + "sourceName": { + "type": "string" + }, + "sourceNumber": { + "type": "string" + }, + "sourceUuid": { + "type": "string" + }, + "storyMessage": { + "$ref": "#/definitions/receive.StoryMessage" + }, + "syncMessage": { + "$ref": "#/definitions/receive.SyncMessage" + }, + "timestamp": { + "type": "integer" + }, + "typingMessage": { + "$ref": "#/definitions/receive.TypingMessage" + } + }, + "required": [ + "timestamp", + "serverReceivedTimestamp", + "serverDeliveredTimestamp" + ], + "type": "object" + }, + "receive.Payment": { + "properties": { + "note": { + "type": "string" + }, + "receipt": { + "type": "string" + } + }, + "required": [ + "receipt" + ], + "type": "object" + }, + "receive.PinMessage": { + "properties": { + "pinDurationSeconds": { + "type": "integer" + }, + "targetAuthor": { + "type": "string" + }, + "targetAuthorNumber": { + "type": "string" + }, + "targetAuthorUuid": { + "type": "string" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp", + "pinDurationSeconds" + ], + "type": "object" + }, + "receive.PollCreate": { + "properties": { + "allowMultiple": { + "type": "boolean" + }, + "options": { + "items": { + "type": "string" + }, + "type": "array" + }, + "question": { + "type": "string" + } + }, + "required": [ + "allowMultiple" + ], + "type": "object" + }, + "receive.PollTerminate": { + "properties": { + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp" + ], + "type": "object" + }, + "receive.PollVote": { + "properties": { + "author": { + "type": "string" + }, + "authorNumber": { + "type": "string" + }, + "authorUuid": { + "type": "string" + }, + "optionIndexes": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "targetSentTimestamp": { + "type": "integer" + }, + "voteCount": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp", + "voteCount" + ], + "type": "object" + }, + "receive.Preview": { + "properties": { + "description": { + "type": "string" + }, + "image": { + "$ref": "#/definitions/receive.Attachment" + }, + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "receive.Profile": { + "properties": { + "about": { + "type": "string" + }, + "aboutEmoji": { + "type": "string" + }, + "familyName": { + "type": "string" + }, + "givenName": { + "type": "string" + }, + "hasAvatar": { + "type": "boolean" + }, + "lastUpdateTimestamp": { + "type": "integer" + }, + "mobileCoinAddress": { + "type": "string" + } + }, + "required": [ + "lastUpdateTimestamp", + "hasAvatar" + ], + "type": "object" + }, + "receive.Quote": { + "properties": { + "attachments": { + "items": { + "$ref": "#/definitions/receive.QuotedAttachment" + }, + "type": "array" + }, + "author": { + "type": "string" + }, + "authorNumber": { + "type": "string" + }, + "authorUuid": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "mentions": { + "items": { + "$ref": "#/definitions/receive.Mention" + }, + "type": "array" + }, + "text": { + "type": "string" + }, + "textStyles": { + "items": { + "$ref": "#/definitions/receive.TextStyle" + }, + "type": "array" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "receive.QuotedAttachment": { + "properties": { + "contentType": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "thumbnail": { + "$ref": "#/definitions/receive.Attachment" + } + }, + "type": "object" + }, + "receive.Reaction": { + "properties": { + "emoji": { + "type": "string" + }, + "isRemove": { + "type": "boolean" + }, + "targetAuthor": { + "type": "string" + }, + "targetAuthorNumber": { + "type": "string" + }, + "targetAuthorUuid": { + "type": "string" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp", + "isRemove" + ], + "type": "object" + }, + "receive.ReceiptMessage": { + "properties": { + "isDelivery": { + "type": "boolean" + }, + "isRead": { + "type": "boolean" + }, + "isViewed": { + "type": "boolean" + }, + "timestamps": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "when": { + "type": "integer" + } + }, + "required": [ + "when", + "isDelivery", + "isRead", + "isViewed" + ], + "type": "object" + }, + "receive.RecipientAddress": { + "properties": { + "number": { + "type": "string" + }, + "username": { + "type": "string" + }, + "uuid": { + "type": "string" + } + }, + "type": "object" + }, + "receive.RemoteDelete": { + "properties": { + "timestamp": { + "type": "integer" + } + }, + "required": [ + "timestamp" + ], + "type": "object" + }, + "receive.SendMessageResult": { + "properties": { + "groupId": { + "type": "string" + }, + "recipientAddress": { + "$ref": "#/definitions/receive.RecipientAddress" + }, + "retryAfterSeconds": { + "type": "integer" + }, + "token": { + "type": "string" + }, + "type": { + "enum": [ + "SUCCESS", + "NETWORK_FAILURE", + "UNREGISTERED_FAILURE", + "IDENTITY_FAILURE", + "RATE_LIMIT_FAILURE", + "INVALID_PRE_KEY_FAILURE" + ], + "type": "string" + } + }, + "type": "object" + }, + "receive.SharedContact": { + "properties": { + "address": { + "items": { + "$ref": "#/definitions/receive.ContactAddress" + }, + "type": "array" + }, + "avatar": { + "$ref": "#/definitions/receive.ContactAvatar" + }, + "email": { + "items": { + "$ref": "#/definitions/receive.ContactEmail" + }, + "type": "array" + }, + "name": { + "$ref": "#/definitions/receive.ContactName" + }, + "organization": { + "type": "string" + }, + "phone": { + "items": { + "$ref": "#/definitions/receive.ContactPhone" + }, + "type": "array" + } + }, + "type": "object" + }, + "receive.Sticker": { + "properties": { + "packId": { + "type": "string" + }, + "stickerId": { + "type": "integer" + } + }, + "required": [ + "stickerId" + ], + "type": "object" + }, + "receive.StoryContext": { + "properties": { + "authorNumber": { + "type": "string" + }, + "authorUuid": { + "type": "string" + }, + "sentTimestamp": { + "type": "integer" + } + }, + "required": [ + "sentTimestamp" + ], + "type": "object" + }, + "receive.StoryMessage": { + "properties": { + "allowsReplies": { + "type": "boolean" + }, + "fileAttachment": { + "$ref": "#/definitions/receive.Attachment" + }, + "groupId": { + "type": "string" + }, + "textAttachment": { + "properties": { + "backgroundColor": { + "type": "string" + }, + "backgroundGradient": { + "properties": { + "angle": { + "type": "integer" + }, + "colors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "endColor": { + "type": "string" + }, + "positions": { + "items": { + "type": "number" + }, + "type": "array" + }, + "startColor": { + "type": "string" + } + }, + "type": "object" + }, + "preview": { + "$ref": "#/definitions/receive.Preview" + }, + "style": { + "type": "string" + }, + "text": { + "type": "string" + }, + "textBackgroundColor": { + "type": "string" + }, + "textForegroundColor": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "allowsReplies" + ], + "type": "object" + }, + "receive.SyncDataMessage": { + "properties": { + "adminDelete": { + "$ref": "#/definitions/receive.AdminDelete" + }, + "attachments": { + "items": { + "$ref": "#/definitions/receive.Attachment" + }, + "type": "array" + }, + "contacts": { + "items": { + "$ref": "#/definitions/receive.SharedContact" + }, + "type": "array" + }, + "destination": { + "type": "string" + }, + "destinationNumber": { + "type": "string" + }, + "destinationUuid": { + "type": "string" + }, + "editMessage": { + "$ref": "#/definitions/receive.EditMessage" + }, + "expiresInSeconds": { + "type": "integer" + }, + "groupInfo": { + "$ref": "#/definitions/receive.GroupInfo" + }, + "isExpirationUpdate": { + "type": "boolean" + }, + "mentions": { + "items": { + "$ref": "#/definitions/receive.Mention" + }, + "type": "array" + }, + "message": { + "type": "string" + }, + "payment": { + "$ref": "#/definitions/receive.Payment" + }, + "pinMessage": { + "$ref": "#/definitions/receive.PinMessage" + }, + "pollCreate": { + "$ref": "#/definitions/receive.PollCreate" + }, + "pollTerminate": { + "$ref": "#/definitions/receive.PollTerminate" + }, + "pollVote": { + "$ref": "#/definitions/receive.PollVote" + }, + "previews": { + "items": { + "$ref": "#/definitions/receive.Preview" + }, + "type": "array" + }, + "quote": { + "$ref": "#/definitions/receive.Quote" + }, + "reaction": { + "$ref": "#/definitions/receive.Reaction" + }, + "remoteDelete": { + "$ref": "#/definitions/receive.RemoteDelete" + }, + "sticker": { + "$ref": "#/definitions/receive.Sticker" + }, + "storyContext": { + "$ref": "#/definitions/receive.StoryContext" + }, + "textStyles": { + "items": { + "$ref": "#/definitions/receive.TextStyle" + }, + "type": "array" + }, + "timestamp": { + "type": "integer" + }, + "unpinMessage": { + "$ref": "#/definitions/receive.UnpinMessage" + }, + "viewOnce": { + "type": "boolean" + } + }, + "type": "object" + }, + "receive.SyncMessage": { + "properties": { + "blockedGroupIds": { + "items": { + "type": "string" + }, + "type": "array" + }, + "blockedNumbers": { + "items": { + "type": "string" + }, + "type": "array" + }, + "readMessages": { + "items": { + "$ref": "#/definitions/receive.SyncReadMessage" + }, + "type": "array" + }, + "sentMessage": { + "$ref": "#/definitions/receive.SyncDataMessage" + }, + "sentStoryMessage": { + "$ref": "#/definitions/receive.SyncStoryMessage" + }, + "type": { + "enum": [ + "CONTACTS_SYNC", + "GROUPS_SYNC", + "REQUEST_SYNC" + ], + "type": "string" + } + }, + "type": "object" + }, + "receive.SyncReadMessage": { + "properties": { + "sender": { + "type": "string" + }, + "senderNumber": { + "type": "string" + }, + "senderUuid": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + }, + "required": [ + "timestamp" + ], + "type": "object" + }, + "receive.SyncStoryMessage": { + "properties": { + "allowsReplies": { + "type": "boolean" + }, + "destinationNumber": { + "type": "string" + }, + "destinationUuid": { + "type": "string" + }, + "fileAttachment": { + "$ref": "#/definitions/receive.Attachment" + }, + "groupId": { + "type": "string" + }, + "textAttachment": { + "properties": { + "backgroundColor": { + "type": "string" + }, + "backgroundGradient": { + "properties": { + "angle": { + "type": "integer" + }, + "colors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "endColor": { + "type": "string" + }, + "positions": { + "items": { + "type": "number" + }, + "type": "array" + }, + "startColor": { + "type": "string" + } + }, + "type": "object" + }, + "preview": { + "$ref": "#/definitions/receive.Preview" + }, + "style": { + "type": "string" + }, + "text": { + "type": "string" + }, + "textBackgroundColor": { + "type": "string" + }, + "textForegroundColor": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "receive.TextStyle": { + "properties": { + "length": { + "type": "integer" + }, + "start": { + "type": "integer" + }, + "style": { + "type": "string" + } + }, + "required": [ + "start", + "length" + ], + "type": "object" + }, + "receive.TypingMessage": { + "properties": { + "action": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "timestamp": { + "type": "integer" + } + }, + "required": [ + "timestamp" + ], + "type": "object" + }, + "receive.UnpinMessage": { + "properties": { + "targetAuthor": { + "type": "string" + }, + "targetAuthorNumber": { + "type": "string" + }, + "targetAuthorUuid": { + "type": "string" + }, + "targetSentTimestamp": { + "type": "integer" + } + }, + "required": [ + "targetSentTimestamp" + ], + "type": "object" } }, "tags": [ diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 5c75128..b5882d8 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -1,13 +1,15 @@ { - "schemes": ["http","https"], + "schemes": [ + "http" + ], "swagger": "2.0", "info": { "description": "This is the Signal Cli REST API documentation.", "title": "Signal Cli REST API", "contact": {}, - "version": "0.99" + "version": "1.0" }, - "host": "192.168.0.166:8080", + "host": "localhost:8080", "basePath": "/", "paths": { "/v1/about": { @@ -3922,6 +3924,9 @@ "type": "string" } }, + "required": [ + "id" + ], "type": "object" }, "busyMessage": { @@ -3930,6 +3935,9 @@ "type": "integer" } }, + "required": [ + "id" + ], "type": "object" }, "hangupMessage": { @@ -3945,6 +3953,7 @@ } }, "required": [ + "id", "deviceId" ], "type": "object" @@ -3959,6 +3968,9 @@ "type": "string" } }, + "required": [ + "id" + ], "type": "object" }, "type": "array" @@ -3975,6 +3987,9 @@ "type": "string" } }, + "required": [ + "id" + ], "type": "object" } }, From a168cf5547654b42cf96448992114c21086fb4d6 Mon Sep 17 00:00:00 2001 From: Era Dorta Date: Mon, 4 May 2026 14:59:48 +0100 Subject: [PATCH 14/40] Simplify the instructions in the readme --- src/docs/README.md | 61 ++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/src/docs/README.md b/src/docs/README.md index 92d8ba5..fddbd4a 100644 --- a/src/docs/README.md +++ b/src/docs/README.md @@ -4,52 +4,61 @@ These files are generated using the [swaggo/swag](https://github.com/swaggo/swag There are two steps, first generating the docs and then running the web server. -## Generating the docs +## With docker compose (recommended) -Regenerate the files with your local source code changes. +1. Build the docs + ```bash + docker compose build + ``` +2. Serve the docs + ```bash + docker compose up + ``` +3. Go to http://127.0.0.1:8080/swagger/index.html to view the docs + * If you get a Network error, replace the IP for the docker internal IP in the error, e.g: http://172.18.0.2:8080/swagger/index.html + +## Locally + +Install [go](https://go.dev/). + +### Generating the docs 1. Set the current working dir to `src` ```bash cd src ``` 1. Run swag to generate the docs - * Option 1, via docker + * Option 1, via go ```bash - docker run --rm -v $(pwd):/code ghcr.io/swaggo/swag:latest init --requiredByDefault --outputTypes "go,json" + go run github.com/swaggo/swag/cmd/swag@v1.16.6 init --requiredByDefault --outputTypes "go,json" ``` - * Option 2, install swag and run the command line tool + * Option 2, directly with swag ```bash swag init --requiredByDefault --outputTypes "go,json" ``` + * Option 3, swag via docker + ```bash + docker run --rm -v $(pwd):/code ghcr.io/swaggo/swag:latest init --requiredByDefault --outputTypes "go,json" + ``` 1. Set the current working dir to `src/docs` ```bash cd docs ``` -1. Run the script to add the receive V1 schemas +1. Run the script to add the receive V1 schemas from https://github.com/AsamK/signal-cli#json-schemas-for-the-json-rpc-mode ```bash - go run add_v1_receive_schemas.go + go run add_v1_receive_schemas.go ./path-to-signal-cli-json-schema-folder ``` -## Run the web server +### Run the web server Run the web server to visualize the generated docs. +1. Navigate to the `src` folder + ```bash + cd src + ``` 1. Run the main script - * Option 1, via docker, run the command at the root of the repository - ```bash - docker compose up - ``` - * Option 2, install go and run the command line tool - ```bash - cd src - ``` - ```bash - go run main.go - ``` - - -## Navigate to the docs - -The docs are served at: http://127.0.0.1:8080/swagger/index.html - -When serving with docker, if you get a Network error, replace the IP for the docker internal IP in the error, e.g: http://172.18.0.2:8080/swagger/index.html \ No newline at end of file + ```bash + go run main.go + ``` +1. Go to http://127.0.0.1:8080/swagger/index.html From 16c3214862eba3ff9223d8f0e5f9a06f6489a6f5 Mon Sep 17 00:00:00 2001 From: Gara Dorta Date: Wed, 6 May 2026 12:28:43 +0100 Subject: [PATCH 15/40] Add update docs ci --- .github/workflows/update-generated-docs.yml | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/update-generated-docs.yml diff --git a/.github/workflows/update-generated-docs.yml b/.github/workflows/update-generated-docs.yml new file mode 100644 index 0000000..8fa75f7 --- /dev/null +++ b/.github/workflows/update-generated-docs.yml @@ -0,0 +1,41 @@ +name: Update Generated Docs + +on: + push: + branches: + - master + +permissions: + contents: write + pull-requests: write + +jobs: + update-docs: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: src/go.mod + cache-dependency-path: src/go.sum + + - name: Regenerate docs + working-directory: src + run: go run github.com/swaggo/swag/cmd/swag@v1.16.6 init --requiredByDefault + + - name: Create pull request for regenerated docs + uses: peter-evans/create-pull-request@v8 + with: + branch: automation/update-generated-docs + delete-branch: true + commit-message: "chore: regenerate swagger docs" + title: "chore: regenerate swagger docs" + body: | + Update Swagger docs to match the latest changes in the main branch. + add-paths: | + src/docs/docs.go + src/docs/swagger.json + src/docs/swagger.yaml From 419b18331d192c126db5eaff0e299a001b2afb58 Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Fri, 8 May 2026 22:39:21 +0200 Subject: [PATCH 16/40] improved Dockerfile * do not build signal-cli-native in Dockerfile, but instead use pre-built binary from bbernhard/libsignal-client-builds --- Dockerfile | 68 ++++++++---------------------------------------------- 1 file changed, 9 insertions(+), 59 deletions(-) diff --git a/Dockerfile b/Dockerfile index c508169..9f13b46 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,7 @@ ARG SIGNAL_CLI_VERSION=0.14.3 ARG LIBSIGNAL_CLIENT_VERSION=0.92.1 -ARG SIGNAL_CLI_NATIVE_PACKAGE_VERSION=0.14.3+morph027+1 ARG SWAG_VERSION=1.16.4 -ARG GRAALVM_VERSION=25.0.2 ARG BUILD_VERSION_ARG=unset @@ -12,9 +10,7 @@ FROM golang:1.26-trixie AS buildcontainer ARG SIGNAL_CLI_VERSION ARG LIBSIGNAL_CLIENT_VERSION ARG SWAG_VERSION -ARG GRAALVM_VERSION ARG BUILD_VERSION_ARG -ARG SIGNAL_CLI_NATIVE_PACKAGE_VERSION RUN dpkg-reconfigure debconf --frontend=noninteractive \ && apt-get update \ @@ -23,8 +19,6 @@ RUN dpkg-reconfigure debconf --frontend=noninteractive \ file build-essential libz-dev zlib1g-dev binutils \ && rm -rf /var/lib/apt/lists/* -COPY ext/libraries/libsignal-client/signal-cli-native.patch /tmp/signal-cli-native.patch - #COPY ext/libraries/libsignal-client/v${LIBSIGNAL_CLIENT_VERSION} /tmp/libsignal-client-libraries RUN wget https://github.com/bbernhard/libsignal-client-builds/releases/download/v${LIBSIGNAL_CLIENT_VERSION}/libsignal-client-build-v${LIBSIGNAL_CLIENT_VERSION}.tar.gz -O /tmp/libsignal-client.tar.gz RUN cd /tmp && mkdir -p /tmp/libsignal-client-libraries && tar xf libsignal-client.tar.gz && mv x86-64 armv7 arm64 -t libsignal-client-libraries @@ -46,71 +40,27 @@ ENV JAVA_OPTS="-Djdk.lang.Process.launchMechanism=vfork" ENV LANG en_US.UTF-8 -#RUN cd /tmp/ \ -# && git clone https://github.com/swaggo/swag.git swag-${SWAG_VERSION} \ -# && cd swag-${SWAG_VERSION} \ -# && git checkout -q v${SWAG_VERSION} \ -# && make -s < /dev/null > /dev/null \ -# && cp /tmp/swag-${SWAG_VERSION}/swag /usr/bin/swag \ -# && rm -r /tmp/swag-${SWAG_VERSION} - - RUN go install github.com/swaggo/swag/cmd/swag@v${SWAG_VERSION} - RUN cd /tmp/ \ && wget -nv https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}.tar.gz -O /tmp/signal-cli.tar.gz \ && tar xf signal-cli.tar.gz -# build native image with graalvm - -RUN arch="$(uname -m)"; \ - case "$arch" in \ - aarch64) wget -nv https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${GRAALVM_VERSION}/graalvm-community-jdk-${GRAALVM_VERSION}_linux-aarch64_bin.tar.gz -O /tmp/gvm.tar.gz ;; \ - armv7l) echo "GRAALVM doesn't support 32bit" ;; \ - x86_64) wget -nv https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${GRAALVM_VERSION}/graalvm-community-jdk-${GRAALVM_VERSION}_linux-x64_bin.tar.gz -O /tmp/gvm.tar.gz ;; \ - *) echo "Invalid architecture" ;; \ - esac; - RUN if [ "$(uname -m)" = "x86_64" ]; then \ cd /tmp \ - && git clone https://github.com/AsamK/signal-cli.git signal-cli-${SIGNAL_CLI_VERSION}-source \ - && cd signal-cli-${SIGNAL_CLI_VERSION}-source \ - && git checkout -q v${SIGNAL_CLI_VERSION} \ - && cd /tmp && mkdir -p /tmp/graalvm && tar xf gvm.tar.gz -C /tmp/graalvm --strip-components=1 \ - && export GRAALVM_HOME=/tmp/graalvm \ - && export PATH=/tmp/graalvm/bin:$PATH \ - && cd /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source \ - && sed -i 's/Signal-Android\/5.22.3/Signal-Android\/5.51.7/g' src/main/java/org/asamk/signal/BaseConfig.java \ - && ./gradlew build \ - && ./gradlew installDist \ - && ls build/install/signal-cli/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar || (echo "\n\nsignal-client jar file with version ${LIBSIGNAL_CLIENT_VERSION} not found. Maybe the version needs to be bumped in the signal-cli-rest-api Dockerfile?\n\n" && echo "Available version: \n" && ls build/install/signal-cli/lib/libsignal-client-* && echo "\n\n" && exit 1) \ - && cd /tmp \ - && cp signal-cli-${SIGNAL_CLI_VERSION}-source/build/install/signal-cli/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar libsignal-client.jar \ - && zip -qu libsignal-client.jar libsignal_jni.so \ - && cd /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source \ - && git apply /tmp/signal-cli-native.patch \ - && ./gradlew -q nativeCompile; \ + && wget https://github.com/bbernhard/signal-cli-native-builds/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-native-v${SIGNAL_CLI_VERSION}.tar.gz \ + && tar xvf signal-cli-native-v${SIGNAL_CLI_VERSION}.tar.gz \ + && cp signal-cli-native-v${SIGNAL_CLI_VERSION}/x86-64/signal-cli-native /tmp/signal-cli-native; \ elif [ "$(uname -m)" = "aarch64" ] ; then \ - echo "Use native image from @morph027 (https://packaging.gitlab.io/signal-cli/) for arm64 - many thanks to @morph027" \ - && curl -fsSL https://packaging.gitlab.io/signal-cli/gpg.key | gpg -o /usr/share/keyrings/signal-cli-native.pgp --dearmor \ - && echo "deb [signed-by=/usr/share/keyrings/signal-cli-native.pgp] https://packaging.gitlab.io/signal-cli signalcli main" > /etc/apt/sources.list.d/morph027-signal-cli.list \ - && mkdir -p /tmp/signal-cli-native \ - && cd /tmp/signal-cli-native \ - #&& wget https://gitlab.com/packaging/signal-cli/-/jobs/14049119045/artifacts/download?file_type=archive -O /tmp/signal-cli-native/archive.zip \ - #&& unzip archive.zip \ - #&& mv signal-cli-native-arm64-trigger/*deb . \ - && apt-get update \ - && apt-get download signal-cli-native=${SIGNAL_CLI_NATIVE_PACKAGE_VERSION} \ - && ar x *.deb \ - && tar xf data.tar.gz \ - && mkdir -p /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile \ - && cp /tmp/signal-cli-native/usr/bin/signal-cli-native /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile/signal-cli; \ + cd /tmp \ + && wget https://github.com/bbernhard/signal-cli-native-builds/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-native-v${SIGNAL_CLI_VERSION}.tar.gz \ + && tar xvf signal-cli-native-v${SIGNAL_CLI_VERSION}.tar.gz \ + && cp signal-cli-native-v${SIGNAL_CLI_VERSION}/arm64/signal-cli-native /tmp/signal-cli-native; \ elif [ "$(uname -m)" = "armv7l" ] ; then \ echo "GRAALVM doesn't support 32bit" \ && echo "Creating temporary file, otherwise the below copy doesn't work for armv7" \ && mkdir -p /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile \ - && touch /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile/signal-cli; \ + && touch /tmp/signal-cli-native; \ else \ echo "Unknown architecture"; \ fi; @@ -180,7 +130,7 @@ RUN dpkg-reconfigure debconf --frontend=noninteractive \ COPY --from=buildcontainer /tmp/signal-cli-rest-api-src/signal-cli-rest-api /usr/bin/signal-cli-rest-api COPY --from=buildcontainer /opt/signal-cli-${SIGNAL_CLI_VERSION} /opt/signal-cli-${SIGNAL_CLI_VERSION} -COPY --from=buildcontainer /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile/signal-cli /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli-native +COPY --from=buildcontainer /tmp/signal-cli-native /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli-native COPY --from=buildcontainer /tmp/signal-cli-rest-api-src/scripts/jsonrpc2-helper /usr/bin/jsonrpc2-helper COPY --from=buildcontainer /tmp/signal-cli-rest-api-src/signal-cli-rest-api_plugin_loader.so /usr/bin/signal-cli-rest-api_plugin_loader.so COPY entrypoint.sh /entrypoint.sh From 2e8171d84c8edbd1620a8578eb7ebb57ab91791d Mon Sep 17 00:00:00 2001 From: Arne Huang <9079232+arnehuang@users.noreply.github.com> Date: Sat, 9 May 2026 09:56:36 -0700 Subject: [PATCH 17/40] Pin actions/checkout to a commit SHA Follow-up to #838: actions/checkout was the only third-party action left on a mutable ref (@master). Pin it to v6.0.2's commit SHA, matching the pattern used for docker/setup-qemu-action, docker/setup-buildx-action, and docker/login-action. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 2 +- .github/workflows/release-dev-version.yml | 2 +- .github/workflows/release-productive-version.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba197bc..de8aa19 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-24.04 needs: setup steps: - - uses: actions/checkout@master + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.ref }} - name: Login to Docker Hub diff --git a/.github/workflows/release-dev-version.yml b/.github/workflows/release-dev-version.yml index b2d59cd..82787cc 100644 --- a/.github/workflows/release-dev-version.yml +++ b/.github/workflows/release-dev-version.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-24.04 needs: setup steps: - - uses: actions/checkout@master + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.ref }} - name: Login to Docker Hub diff --git a/.github/workflows/release-productive-version.yml b/.github/workflows/release-productive-version.yml index dc0a491..800b751 100644 --- a/.github/workflows/release-productive-version.yml +++ b/.github/workflows/release-productive-version.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-24.04 needs: setup steps: - - uses: actions/checkout@master + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.ref }} - name: Login to Docker Hub From 69457e8f8138e7e1b1e9e8a6cc88af40f55cb41b Mon Sep 17 00:00:00 2001 From: Arne Huang <9079232+arnehuang@users.noreply.github.com> Date: Sat, 9 May 2026 10:00:28 -0700 Subject: [PATCH 18/40] Add empty permissions block at workflow level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caps GITHUB_TOKEN's blast radius. None of these workflows need any GitHub API write scope — they only push to Docker Hub — so the safest default is permissions: {}, matching the posture used by AsamK/signal-cli. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 2 ++ .github/workflows/release-dev-version.yml | 4 +++- .github/workflows/release-productive-version.yml | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba197bc..8d17df5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,8 @@ on: branches: - '**' #every branch +permissions: {} + jobs: setup: runs-on: ubuntu-24.04 diff --git a/.github/workflows/release-dev-version.yml b/.github/workflows/release-dev-version.yml index b2d59cd..8db6a49 100644 --- a/.github/workflows/release-dev-version.yml +++ b/.github/workflows/release-dev-version.yml @@ -4,9 +4,11 @@ on: workflow_dispatch: inputs: version: - description: 'Version' + description: 'Version' required: true +permissions: {} + jobs: setup: diff --git a/.github/workflows/release-productive-version.yml b/.github/workflows/release-productive-version.yml index dc0a491..bd6bf6f 100644 --- a/.github/workflows/release-productive-version.yml +++ b/.github/workflows/release-productive-version.yml @@ -4,9 +4,11 @@ on: workflow_dispatch: inputs: version: - description: 'Version' + description: 'Version' required: true +permissions: {} + jobs: setup: From 4bbadbf29ed11bec1c3f6577208f7b19f002bfd1 Mon Sep 17 00:00:00 2001 From: Gara Dorta Date: Sun, 10 May 2026 22:14:19 +0100 Subject: [PATCH 19/40] fix: download schemas from signal-cli releases --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index bc600c5..85532cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -102,7 +102,10 @@ RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefau # manually add the json schemas for the receive V1 endpoint to the docs RUN if [ "$(uname -m)" = "x86_64" ]; then \ cd /tmp/signal-cli-rest-api-src/docs \ - && go run add_v1_receive_schemas.go /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/generated/META-INF/schemas; \ + wget https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz \ + && mkdir signal-cli-schemas \ + && tar xf signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz -C signal-cli-schemas \ + && go run add_v1_receive_schemas.go signal-cli-schemas; \ fi; # build signal-cli-rest-api From e68cabf88f873ec70b93af27dcd945a417069ec4 Mon Sep 17 00:00:00 2001 From: Gara Dorta Date: Sun, 10 May 2026 22:18:07 +0100 Subject: [PATCH 20/40] fix: the docs regarless of architecture --- Dockerfile | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 85532cb..9969efb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -100,13 +100,11 @@ RUN ls -la /tmp/signal-cli-rest-api-src RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefault --outputTypes "go,json" # manually add the json schemas for the receive V1 endpoint to the docs -RUN if [ "$(uname -m)" = "x86_64" ]; then \ - cd /tmp/signal-cli-rest-api-src/docs \ - wget https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz \ - && mkdir signal-cli-schemas \ - && tar xf signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz -C signal-cli-schemas \ - && go run add_v1_receive_schemas.go signal-cli-schemas; \ - fi; +RUN cd /tmp/signal-cli-rest-api-src/docs \ + wget https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz \ + && mkdir signal-cli-schemas \ + && tar xf signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz -C signal-cli-schemas \ + && go run add_v1_receive_schemas.go signal-cli-schemas # build signal-cli-rest-api RUN cd /tmp/signal-cli-rest-api-src && go build -o signal-cli-rest-api main.go From 82f71512129b1d32603a6b5c695f5287e652b864 Mon Sep 17 00:00:00 2001 From: Gara Dorta Date: Sun, 10 May 2026 23:23:39 +0100 Subject: [PATCH 21/40] fix: download the schemas from signal-cli's fork --- Dockerfile | 2 +- src/docs/README.md | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9969efb..10bdf53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -101,7 +101,7 @@ RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefau # manually add the json schemas for the receive V1 endpoint to the docs RUN cd /tmp/signal-cli-rest-api-src/docs \ - wget https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz \ + && wget https://github.com/Gara-Dorta/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz \ && mkdir signal-cli-schemas \ && tar xf signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz -C signal-cli-schemas \ && go run add_v1_receive_schemas.go signal-cli-schemas diff --git a/src/docs/README.md b/src/docs/README.md index fddbd4a..5b162a4 100644 --- a/src/docs/README.md +++ b/src/docs/README.md @@ -44,10 +44,13 @@ Install [go](https://go.dev/). ```bash cd docs ``` -1. Run the script to add the receive V1 schemas from https://github.com/AsamK/signal-cli#json-schemas-for-the-json-rpc-mode - ```bash - go run add_v1_receive_schemas.go ./path-to-signal-cli-json-schema-folder - ``` +1. Add the signal-cli receive V1 schemas + * Download the `signal-cli-x.y.z-json-schemas.tar.gz` schema files from https://github.com/Gara-Dorta/signal-cli/releases + * Extract the files + * Run the script to add the schemas + ```bash + go run add_v1_receive_schemas.go ./path-to-signal-cli-json-schema-folder + ``` ### Run the web server From 7aa70683aaa4eeeec77d3d00552ab4ca57a4ad62 Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 18:29:20 +0200 Subject: [PATCH 22/40] Simplify the add_v1_receive_schemas.go my marshalling the whole document --- src/docs/add_v1_receive_schemas.go | 290 +++++++++++++---------------- 1 file changed, 125 insertions(+), 165 deletions(-) diff --git a/src/docs/add_v1_receive_schemas.go b/src/docs/add_v1_receive_schemas.go index 5d9729b..5679450 100644 --- a/src/docs/add_v1_receive_schemas.go +++ b/src/docs/add_v1_receive_schemas.go @@ -8,21 +8,21 @@ import ( "os" "path/filepath" "sort" - "strconv" "strings" _ "github.com/bbernhard/signal-cli-rest-api/docs" ) const ( - goDocsPath = "docs.go" - jsonDocsPath = "swagger.json" - openMarker = "const docTemplate = `" - closeMarker = "`\n\n// SwaggerInfo" - definitionsKey = `"definitions": {` - receivePrefix = "receive." - receivePathKey = `"/v1/receive/{number}":` - receiveWrapper = "data.Message" + goDocsPath = "docs.go" + jsonDocsPath = "swagger.json" + openMarker = "const docTemplate = `" + closeMarker = "`\n\n// SwaggerInfo" + schemesTemplateValue = "{{ marshal .Schemes }}" + schemesPlaceholderToken = "__SWAG_SCHEMES_PLACEHOLDER__" + receivePrefix = "receive." + receivePathKey = "/v1/receive/{number}" + receiveWrapper = "data.Message" ) func main() { @@ -52,16 +52,11 @@ func run(receiveDir string) error { addEnvelopeWrapperDefinition(definitions) - managedDefinitions, err := renderManagedDefinitions(definitions) - if err != nil { + if err := updateDocsGo(definitions); err != nil { return err } - if err := updateDocsGo(managedDefinitions); err != nil { - return err - } - - if err := updateSwaggerJSON(managedDefinitions); err != nil { + if err := updateSwaggerJSON(definitions); err != nil { return err } @@ -70,23 +65,41 @@ func run(receiveDir string) error { return nil } -func updateDocsGo(managedDefinitions string) error { +func updateDocsGo(receiveDefinitions map[string]interface{}) error { content, err := os.ReadFile(goDocsPath) if err != nil { return fmt.Errorf("read %s: %w", goDocsPath, err) } - template, err := extractDocTemplate(string(content)) + template, templateStart, templateEnd, err := extractDocTemplate(string(content)) if err != nil { return err } - updatedTemplate, err := applyReceiveSchemaUpdates(template, managedDefinitions) + document, err := unmarshalDocument(template, true) if err != nil { return err } - updated := strings.Replace(string(content), template, updatedTemplate, 1) + // Check for existing receive.* or data.Message definitions + if defs, ok := document["definitions"].(map[string]interface{}); ok { + for k := range defs { + if strings.HasPrefix(k, receivePrefix) || k == receiveWrapper { + return fmt.Errorf("definitions already contain receive entries; run swag init first") + } + } + } + + if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { + return err + } + + updatedTemplate, err := marshalDocument(document, true) + if err != nil { + return err + } + + updated := string(content[:templateStart]) + updatedTemplate + string(content[templateEnd:]) if err := os.WriteFile(goDocsPath, []byte(updated), 0644); err != nil { return fmt.Errorf("write %s: %w", goDocsPath, err) } @@ -94,13 +107,31 @@ func updateDocsGo(managedDefinitions string) error { return nil } -func updateSwaggerJSON(managedDefinitions string) error { +func updateSwaggerJSON(receiveDefinitions map[string]interface{}) error { content, err := os.ReadFile(jsonDocsPath) if err != nil { return fmt.Errorf("read %s: %w", jsonDocsPath, err) } - updated, err := applyReceiveSchemaUpdates(string(content), managedDefinitions) + document, err := unmarshalDocument(string(content), false) + if err != nil { + return err + } + + // Check for existing receive.* or data.Message definitions + if defs, ok := document["definitions"].(map[string]interface{}); ok { + for k := range defs { + if strings.HasPrefix(k, receivePrefix) || k == receiveWrapper { + return fmt.Errorf("definitions already contain receive entries; run swag init first") + } + } + } + + if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { + return err + } + + updated, err := marshalDocument(document, false) if err != nil { return err } @@ -112,74 +143,53 @@ func updateSwaggerJSON(managedDefinitions string) error { return nil } -func applyReceiveSchemaUpdates(content string, managedDefinitions string) (string, error) { - updated, err := appendDefinitionsEntries(content, managedDefinitions) - if err != nil { - return "", err - } - - updated, err = replaceReceiveResponseSchema(updated) - if err != nil { - return "", err - } - - return updated, nil -} - -func extractDocTemplate(content string) (string, error) { +func extractDocTemplate(content string) (string, int, int, error) { start := strings.Index(content, openMarker) if start == -1 { - return "", fmt.Errorf("could not find docTemplate start in %s", goDocsPath) + return "", -1, -1, fmt.Errorf("could not find docTemplate start in %s", goDocsPath) } start += len(openMarker) endOffset := strings.Index(content[start:], closeMarker) if endOffset == -1 { - return "", fmt.Errorf("could not find docTemplate end in %s", goDocsPath) + return "", -1, -1, fmt.Errorf("could not find docTemplate end in %s", goDocsPath) } - return content[start : start+endOffset], nil + end := start + endOffset + return content[start:end], start, end, nil } -func definitionsBounds(template string) (int, int, error) { - definitionsIndex := strings.Index(template, definitionsKey) - if definitionsIndex == -1 { - return -1, -1, fmt.Errorf("could not find definitions block in docTemplate") +func unmarshalDocument(content string, withSchemesTemplate bool) (map[string]interface{}, error) { + if withSchemesTemplate { + content = strings.ReplaceAll(content, "` + \"`\" + `", "`") } - braceIndex := definitionsIndex + strings.Index(definitionsKey, "{") - closingBraceIndex, err := findMatchingBrace(template, braceIndex) - if err != nil { - return -1, -1, err + if withSchemesTemplate { + content = strings.Replace(content, schemesTemplateValue, `"`+schemesPlaceholderToken+`"`, 1) } - return braceIndex, closingBraceIndex, nil + var document map[string]interface{} + if err := json.Unmarshal([]byte(content), &document); err != nil { + return nil, fmt.Errorf("parse document: %w", err) + } + + return document, nil } -func appendDefinitionsEntries(template string, entries string) (string, error) { - braceIndex, closingBraceIndex, err := definitionsBounds(template) +func marshalDocument(document map[string]interface{}, withSchemesTemplate bool) (string, error) { + raw, err := json.MarshalIndent(document, "", " ") if err != nil { - return "", err + return "", fmt.Errorf("marshal document: %w", err) } - definitionsBlock := template[braceIndex : closingBraceIndex+1] - if strings.Contains(definitionsBlock, `"`+receiveWrapper+`"`) || strings.Contains(definitionsBlock, `"`+receivePrefix) { - return "", fmt.Errorf("definitions already contain receive entries; run swag init first") + updated := string(raw) + if withSchemesTemplate { + // Single ` break the docs.go, replace with string concatenation + updated = strings.ReplaceAll(updated, "`", "` + \"`\" + `") + updated = strings.Replace(updated, `"`+schemesPlaceholderToken+`"`, schemesTemplateValue, 1) } - inner := strings.TrimSpace(template[braceIndex+1 : closingBraceIndex]) - - if inner == "" { - return template[:braceIndex+1] + "\n" + entries + "\n" + template[closingBraceIndex:], nil - } - - closingLine := "\n }" - insertIndex := strings.LastIndex(template[:closingBraceIndex+1], closingLine) - if insertIndex == -1 { - return "", fmt.Errorf("could not determine definitions closing line") - } - - return template[:insertIndex] + ",\n" + entries + template[insertIndex:], nil + return updated, nil } func addReceiveSchemas(definitions map[string]interface{}, receiveDir string) (map[string]string, error) { @@ -300,110 +310,60 @@ func addEnvelopeWrapperDefinition(definitions map[string]interface{}) { } } -func renderManagedDefinitions(definitions map[string]interface{}) (string, error) { - keys := make([]string, 0, len(definitions)) - for key := range definitions { - keys = append(keys, key) - } - sort.Strings(keys) - - parts := make([]string, 0, len(keys)) - for _, key := range keys { - raw, err := json.MarshalIndent(definitions[key], "", " ") - if err != nil { - return "", fmt.Errorf("marshal definition %s: %w", key, err) - } - - lines := strings.Split(string(raw), "\n") - for idx := range lines { - lines[idx] = " " + lines[idx] - } - - entry := " " + strconv.Quote(key) + ": " + strings.TrimPrefix(lines[0], " ") - if len(lines) > 1 { - entry += "\n" + strings.Join(lines[1:], "\n") - } - - parts = append(parts, entry) - } - - return strings.Join(parts, ",\n"), nil -} - -func replaceReceiveResponseSchema(template string) (string, error) { - pathIndex := strings.Index(template, receivePathKey) - if pathIndex == -1 { - return "", fmt.Errorf("could not find receive path block; run swag init first") - } - braceOffset := strings.Index(template[pathIndex+len(receivePathKey):], "{") - if braceOffset == -1 { - return "", fmt.Errorf("could not find opening brace for receive path block") - } - pathOpenBrace := pathIndex + len(receivePathKey) + braceOffset - pathCloseBrace, err := findMatchingBrace(template, pathOpenBrace) +func applyReceiveSchemaUpdates(document map[string]interface{}, receiveDefinitions map[string]interface{}) error { + definitions, err := getObject(document, "definitions") if err != nil { - return "", err + return err } - pathBlock := template[pathOpenBrace : pathCloseBrace+1] - - oldSchema := `"schema": { - "type": "array", - "items": { - "type": "string" - } - }` - - newSchema := `"schema": { - "$ref": "#/definitions/data.Message" - }` - - updatedPathBlock := strings.Replace(pathBlock, oldSchema, newSchema, 1) - if updatedPathBlock == pathBlock { - return "", fmt.Errorf("could not replace /v1/receive schema; ensure generated docs are freshly generated by swag") + for key := range definitions { + if strings.HasPrefix(key, receivePrefix) || key == receiveWrapper { + delete(definitions, key) + } } - return template[:pathOpenBrace] + updatedPathBlock + template[pathCloseBrace+1:], nil + for key, value := range receiveDefinitions { + definitions[key] = value + } + + paths, err := getObject(document, "paths") + if err != nil { + return err + } + receivePath, err := getObject(paths, receivePathKey) + if err != nil { + return err + } + receiveGet, err := getObject(receivePath, "get") + if err != nil { + return err + } + responses, err := getObject(receiveGet, "responses") + if err != nil { + return err + } + response200, err := getObject(responses, "200") + if err != nil { + return err + } + + response200["schema"] = map[string]interface{}{ + "$ref": "#/definitions/" + receiveWrapper, + } + + return nil } -func findMatchingBrace(input string, openBraceIndex int) (int, error) { - depth := 0 - inString := false - escaped := false - - for index := openBraceIndex; index < len(input); index++ { - char := input[index] - - if inString { - if escaped { - escaped = false - continue - } - if char == '\\' { - escaped = true - continue - } - if char == '"' { - inString = false - } - continue - } - - if char == '"' { - inString = true - continue - } - - switch char { - case '{': - depth++ - case '}': - depth-- - if depth == 0 { - return index, nil - } - } +func getObject(parent map[string]interface{}, key string) (map[string]interface{}, error) { + value, ok := parent[key] + if !ok { + return nil, fmt.Errorf("missing key %q", key) } - return -1, fmt.Errorf("could not find matching brace") + obj, ok := value.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("key %q is not an object", key) + } + + return obj, nil } From fa0f67fa6920428e760f50219d0a68155f776593 Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 18:34:50 +0200 Subject: [PATCH 23/40] Remove uneeded if statement --- src/docs/add_v1_receive_schemas.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/docs/add_v1_receive_schemas.go b/src/docs/add_v1_receive_schemas.go index 5679450..2d467b1 100644 --- a/src/docs/add_v1_receive_schemas.go +++ b/src/docs/add_v1_receive_schemas.go @@ -162,9 +162,6 @@ func extractDocTemplate(content string) (string, int, int, error) { func unmarshalDocument(content string, withSchemesTemplate bool) (map[string]interface{}, error) { if withSchemesTemplate { content = strings.ReplaceAll(content, "` + \"`\" + `", "`") - } - - if withSchemesTemplate { content = strings.Replace(content, schemesTemplateValue, `"`+schemesPlaceholderToken+`"`, 1) } From d0ec5b1b28ae572770f4b757b7b0e3c7c56df1c9 Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 18:51:22 +0200 Subject: [PATCH 24/40] Better variable naming --- src/docs/add_v1_receive_schemas.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/docs/add_v1_receive_schemas.go b/src/docs/add_v1_receive_schemas.go index 2d467b1..fc6d805 100644 --- a/src/docs/add_v1_receive_schemas.go +++ b/src/docs/add_v1_receive_schemas.go @@ -76,7 +76,7 @@ func updateDocsGo(receiveDefinitions map[string]interface{}) error { return err } - document, err := unmarshalDocument(template, true) + document, err := jsonUnmarshalSafe(template, true) if err != nil { return err } @@ -94,7 +94,7 @@ func updateDocsGo(receiveDefinitions map[string]interface{}) error { return err } - updatedTemplate, err := marshalDocument(document, true) + updatedTemplate, err := jsonMarshalIndentSafe(document, true) if err != nil { return err } @@ -113,7 +113,7 @@ func updateSwaggerJSON(receiveDefinitions map[string]interface{}) error { return fmt.Errorf("read %s: %w", jsonDocsPath, err) } - document, err := unmarshalDocument(string(content), false) + document, err := jsonUnmarshalSafe(string(content), false) if err != nil { return err } @@ -131,7 +131,7 @@ func updateSwaggerJSON(receiveDefinitions map[string]interface{}) error { return err } - updated, err := marshalDocument(document, false) + updated, err := jsonMarshalIndentSafe(document, false) if err != nil { return err } @@ -159,8 +159,8 @@ func extractDocTemplate(content string) (string, int, int, error) { return content[start:end], start, end, nil } -func unmarshalDocument(content string, withSchemesTemplate bool) (map[string]interface{}, error) { - if withSchemesTemplate { +func jsonUnmarshalSafe(content string, applyStringConcat bool) (map[string]interface{}, error) { + if applyStringConcat { content = strings.ReplaceAll(content, "` + \"`\" + `", "`") content = strings.Replace(content, schemesTemplateValue, `"`+schemesPlaceholderToken+`"`, 1) } @@ -173,15 +173,14 @@ func unmarshalDocument(content string, withSchemesTemplate bool) (map[string]int return document, nil } -func marshalDocument(document map[string]interface{}, withSchemesTemplate bool) (string, error) { +func jsonMarshalIndentSafe(document map[string]interface{}, backTicksAsStringConcat bool) (string, error) { raw, err := json.MarshalIndent(document, "", " ") if err != nil { return "", fmt.Errorf("marshal document: %w", err) } updated := string(raw) - if withSchemesTemplate { - // Single ` break the docs.go, replace with string concatenation + if backTicksAsStringConcat { updated = strings.ReplaceAll(updated, "`", "` + \"`\" + `") updated = strings.Replace(updated, `"`+schemesPlaceholderToken+`"`, schemesTemplateValue, 1) } From 9155e505af9641247132c9159f555b83bc00154a Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 18:52:32 +0200 Subject: [PATCH 25/40] Remove check for running swag init first --- src/docs/add_v1_receive_schemas.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/docs/add_v1_receive_schemas.go b/src/docs/add_v1_receive_schemas.go index fc6d805..2aeee4d 100644 --- a/src/docs/add_v1_receive_schemas.go +++ b/src/docs/add_v1_receive_schemas.go @@ -81,15 +81,6 @@ func updateDocsGo(receiveDefinitions map[string]interface{}) error { return err } - // Check for existing receive.* or data.Message definitions - if defs, ok := document["definitions"].(map[string]interface{}); ok { - for k := range defs { - if strings.HasPrefix(k, receivePrefix) || k == receiveWrapper { - return fmt.Errorf("definitions already contain receive entries; run swag init first") - } - } - } - if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { return err } @@ -118,15 +109,6 @@ func updateSwaggerJSON(receiveDefinitions map[string]interface{}) error { return err } - // Check for existing receive.* or data.Message definitions - if defs, ok := document["definitions"].(map[string]interface{}); ok { - for k := range defs { - if strings.HasPrefix(k, receivePrefix) || k == receiveWrapper { - return fmt.Errorf("definitions already contain receive entries; run swag init first") - } - } - } - if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { return err } From af48a4304b179235c443af7df5cb0eda2e479c20 Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 18:55:26 +0200 Subject: [PATCH 26/40] Regenerate docs --- src/docs/docs.go | 6355 ++++++++++++++++++++-------------------- src/docs/swagger.json | 6359 ++++++++++++++++++++--------------------- 2 files changed, 6284 insertions(+), 6430 deletions(-) diff --git a/src/docs/docs.go b/src/docs/docs.go index 36fb923..08b0e9e 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -4,2797 +4,93 @@ package docs import "github.com/swaggo/swag" const docTemplate = `{ - "schemes": {{ marshal .Schemes }}, - "swagger": "2.0", - "info": { - "description": "{{escape .Description}}", - "title": "{{.Title}}", - "contact": {}, - "version": "{{.Version}}" - }, - "host": "{{.Host}}", "basePath": "{{.BasePath}}", - "paths": { - "/v1/about": { - "get": { - "description": "Returns the supported API versions and the internal build nr", - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Lists general information about the API", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.About" - } - } - } - } - }, - "/v1/accounts": { - "get": { - "description": "Lists all of the accounts linked or registered", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "List all accounts", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/pin": { - "post": { - "description": "Sets a new Signal Pin", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Set Pin", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SetPinRequest" - } - } - ], - "responses": { - "201": { - "description": "Created" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Removes a Signal Pin", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Remove Pin", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/rate-limit-challenge": { - "post": { - "description": "When running into rate limits, sometimes the limit can be lifted, by solving a CAPTCHA. To get the captcha token, go to https://signalcaptchas.org/challenge/generate.html For the staging environment, use: https://signalcaptchas.org/staging/registration/generate.html. The \"challenge_token\" is the token from the failed send attempt. The \"captcha\" is the captcha result, starting with signalcaptcha://", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Lift rate limit restrictions by solving a captcha.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RateLimitChallengeRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/settings": { - "put": { - "description": "Update the account attributes on the signal server.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Update the account settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateAccountSettingsRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/username": { - "post": { - "description": "Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Set a username.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SetUsernameRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/client.SetUsernameResponse" - } - }, - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Delete the username associated with this account.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Remove a username.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/attachments": { - "get": { - "description": "List all downloaded attachments", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "List all attachments.", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/attachments/{attachment}": { - "get": { - "description": "Serve the attachment with the given id", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "Serve Attachment.", - "parameters": [ - { - "type": "string", - "description": "Attachment ID", - "name": "attachment", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove the attachment with the given id from filesystem.", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "Remove attachment.", - "parameters": [ - { - "type": "string", - "description": "Attachment ID", - "name": "attachment", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/configuration": { - "get": { - "description": "List the REST API configuration.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "List the REST API configuration.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.Configuration" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Set the REST API configuration.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Set the REST API configuration.", - "parameters": [ - { - "description": "Configuration", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.Configuration" - } - } - ], - "responses": { - "204": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/configuration/{number}/settings": { - "get": { - "description": "List account specific settings.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "List account specific settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustModeResponse" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Set account specific settings.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Set account specific settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustModeRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}": { - "get": { - "description": "List all contacts for the given number.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "List Contacts", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Include all known recipients, not only contacts.", - "name": "all_recipients", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListContactsResponse" - } - } - } - } - }, - "put": { - "description": "Updates the info associated to a number on the contact list.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Updates the info associated to a number on the contact list. If the contact doesn’t exist yet, it will be added.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Contact", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateContactRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}/sync": { - "post": { - "description": "Send a synchronization message with the local contacts list to all linked devices. This command should only be used if this is the primary device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Send a synchronization message with the local contacts list to all linked devices.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}/{uuid}": { - "get": { - "description": "List a specific contact.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "List Contact", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Include all known recipients, not only contacts.", - "name": "all_recipients", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.ListContactsResponse" - } - } - } - } - }, - "/v1/contacts/{number}/{uuid}/avatar": { - "get": { - "description": "Returns the avatar of a contact.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Returns the avatar of a contact", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/devices/{number}": { - "get": { - "description": "List linked devices associated to this device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "List linked devices.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListDevicesResponse" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Links another device to this device. Only works, if this is the master device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Links another device to this device.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.AddDeviceRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/devices/{number}/local-data": { - "delete": { - "description": "Delete all local data for the specified account. Only use this after unregistering the account or after removing a linked device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Delete local account data", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Cleanup options", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.DeleteLocalAccountDataRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/devices/{number}/{deviceId}": { - "delete": { - "description": "Remove a linked device from the primary account.", - "tags": [ - "Devices" - ], - "summary": "Remove linked device", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Device ID from listDevices", - "name": "deviceId", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}": { - "get": { - "description": "List all Signal Groups.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "List all Signal Groups.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Expand the response to show more details (default: false)", - "name": "expand", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.GroupEntry" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Create a new Signal Group with the specified members.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Create a new Signal Group.", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.CreateGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.CreateGroupResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}": { - "get": { - "description": "List a specific Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "List a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Expand the response to show more details (default: false)", - "name": "expand", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.GroupEntry" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "put": { - "description": "Update the state of a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Update the state of a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - }, - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateGroupRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Delete the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Delete a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/admins": { - "post": { - "description": "Add one or more admins to an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Add one or more admins to an existing Signal Group.", - "parameters": [ - { - "description": "Admins", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupAdminsRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove one or more admins from an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Remove one or more admins from an existing Signal Group.", - "parameters": [ - { - "description": "Admins", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupAdminsRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/avatar": { - "get": { - "description": "Returns the avatar of a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Returns the avatar of a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/block": { - "post": { - "description": "Block the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Block a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/join": { - "post": { - "description": "Join the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Join a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/members": { - "post": { - "description": "Add one or more members to an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Add one or more members to an existing Signal Group.", - "parameters": [ - { - "description": "Members", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupMembersRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove one or more members from an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Remove one or more members from an existing Signal Group.", - "parameters": [ - { - "description": "Members", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupMembersRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/pin-message": { - "post": { - "description": "Pin a message in a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Pin a message in a Signal Group.", - "parameters": [ - { - "description": "Pin", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.PinMessageInGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Unpin a message in a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Unpin a message in a Signal Group.", - "parameters": [ - { - "description": "Unpin", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UnpinMessageInGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/quit": { - "post": { - "description": "Quit the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Quit a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/health": { - "get": { - "description": "Internally used by the docker container to perform the health check.", - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "API Health Check", - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/identities/{number}": { - "get": { - "description": "List all identities for the given number.", - "produces": [ - "application/json" - ], - "tags": [ - "Identities" - ], - "summary": "List Identities", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.IdentityEntry" - } - } - } - } - } - }, - "/v1/identities/{number}/trust/{numberToTrust}": { - "put": { - "description": "Trust an identity. When 'trust_all_known_keys' is set to' true', all known keys of this user are trusted. **This is only recommended for testing.**", - "produces": [ - "application/json" - ], - "tags": [ - "Identities" - ], - "summary": "Trust Identity", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustIdentityRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Number To Trust", - "name": "numberToTrust", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/polls/{number}": { - "post": { - "description": "Create a new poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Create a new poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.CreatePollRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.CreatePollResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Close a poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Close a poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ClosePollRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/polls/{number}/vote": { - "post": { - "description": "Answer a poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Answer a poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.VoteRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/profiles/{number}": { - "put": { - "description": "Set your name and optional an avatar.", - "produces": [ - "application/json" - ], - "tags": [ - "Profiles" - ], - "summary": "Update Profile.", - "parameters": [ - { - "description": "Profile Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateProfileRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/qrcodelink": { - "get": { - "description": "Link device and generate QR code", - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Link device and generate QR code.", - "parameters": [ - { - "type": "string", - "description": "Device Name", - "name": "device_name", - "in": "query", - "required": true - }, - { - "type": "integer", - "description": "QRCode Version (defaults to 10)", - "name": "qrcode_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/qrcodelink/raw": { - "get": { - "description": "Generate the deviceLinkUri string for linking without scanning a QR code.", - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Get raw device link URI", - "parameters": [ - { - "type": "string", - "description": "Device Name", - "name": "device_name", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.DeviceLinkUriResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/reactions/{number}": { - "post": { - "description": "React to a message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Reactions" - ], - "summary": "Send a reaction.", - "parameters": [ - { - "description": "Reaction", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendReactionRequest" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove a reaction", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Reactions" - ], - "summary": "Remove a reaction.", - "parameters": [ - { - "description": "Reaction", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RemoveReactionRequest" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/receipts/{number}": { - "post": { - "description": "Send a read or viewed receipt", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Receipts" - ], - "summary": "Send a receipt.", - "parameters": [ - { - "description": "Receipt", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.Receipt" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/receive/{number}": { - "get": { - "description": "Receives Signal Messages from the Signal Network. If you are running the docker container in normal/native mode, this is a GET endpoint. In json-rpc mode this is a websocket endpoint.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Receive Signal Messages.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Receive timeout in seconds (default: 1)", - "name": "timeout", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether the attachments of the received message should be ignored", - "name": "ignore_attachments", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether stories should be ignored when receiving messages", - "name": "ignore_stories", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether avatar downloads should be ignored when receiving messages", - "name": "ignore_avatars", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether sticker pack downloads should be ignored when receiving messages", - "name": "ignore_stickers", - "in": "query" - }, - { - "type": "string", - "description": "Specify the maximum number of messages to receive (default: unlimited)", - "name": "max_messages", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether read receipts should be sent when receiving messages", - "name": "send_read_receipts", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/data.Message" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/register/{number}": { - "post": { - "description": "Register a phone number with the signal network.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Register a phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.RegisterNumberRequest" - } - } - ], - "responses": { - "201": { - "description": "Created" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/register/{number}/verify/{token}": { - "post": { - "description": "Verify a registered phone number with the signal network.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Verify a registered phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.VerifyNumberSettings" - } - }, - { - "type": "string", - "description": "Verification Code", - "name": "token", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/remote-delete/{number}": { - "delete": { - "description": "Delete a signal message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Delete a signal message.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RemoteDeleteRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.RemoteDeleteResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/search/{number}": { - "get": { - "description": "Check if one or more phone numbers are registered with the Signal Service.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Search" - ], - "summary": "Check if one or more phone numbers are registered with the Signal Service.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "description": "Numbers to check", - "name": "numbers", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/api.SearchResponse" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/send": { - "post": { - "description": "Send a signal message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Send a signal message.", - "deprecated": true, - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendMessageV1" - } - } - ], - "responses": { - "201": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/sticker-packs/{number}": { - "get": { - "description": "List Installed Sticker Packs.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Sticker Packs" - ], - "summary": "List Installed Sticker Packs.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListInstalledStickerPacksResponse" - } - } - }, - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the \"Add to Signal\" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX\u0026pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Sticker Packs" - ], - "summary": "Add Sticker Pack.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.AddStickerPackRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/typing-indicator/{number}": { - "put": { - "description": "Show Typing Indicator.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Show Typing Indicator.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TypingIndicatorRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Hide Typing Indicator.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Hide Typing Indicator.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TypingIndicatorRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/unregister/{number}": { - "post": { - "description": "Disables push support for this device. **WARNING:** If *delete_account* is set to *true*, the account will be deleted from the Signal Server. This cannot be undone without loss.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Unregister a phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.UnregisterNumberRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v2/send": { - "post": { - "description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\` + "`" + `monospace\\` + "`" + `. If you want to escape a formatting character, prefix it with two backslashes.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Send a signal message.", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendMessageV2" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.SendMessageResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.SendMessageError" - } - } - } - } - } - }, "definitions": { "api.AddDeviceRequest": { - "type": "object", - "required": [ - "uri" - ], "properties": { "uri": { "type": "string" } - } + }, + "required": [ + "uri" + ], + "type": "object" }, "api.AddStickerPackRequest": { - "type": "object", + "properties": { + "pack_id": { + "example": "9a32eda01a7a28574f2eb48668ae0dc4", + "type": "string" + }, + "pack_key": { + "example": "19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a", + "type": "string" + } + }, "required": [ "pack_id", "pack_key" ], - "properties": { - "pack_id": { - "type": "string", - "example": "9a32eda01a7a28574f2eb48668ae0dc4" - }, - "pack_key": { - "type": "string", - "example": "19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a" - } - } + "type": "object" }, "api.ChangeGroupAdminsRequest": { - "type": "object", + "properties": { + "admins": { + "items": { + "type": "string" + }, + "type": "array" + } + }, "required": [ "admins" ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - } - } + "type": "object" }, "api.ChangeGroupMembersRequest": { - "type": "object", + "properties": { + "members": { + "items": { + "type": "string" + }, + "type": "array" + } + }, "required": [ "members" ], - "properties": { - "members": { - "type": "array", - "items": { - "type": "string" - } - } - } + "type": "object" }, "api.ClosePollRequest": { - "type": "object", + "properties": { + "poll_timestamp": { + "example": "1769271479", + "type": "string" + }, + "recipient": { + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e", + "type": "string" + } + }, "required": [ "poll_timestamp", "recipient" ], - "properties": { - "poll_timestamp": { - "type": "string", - "example": "1769271479" - }, - "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" - } - } + "type": "object" }, "api.Configuration": { - "type": "object", - "required": [ - "logging" - ], "properties": { "logging": { "$ref": "#/definitions/api.LoggingConfiguration" } - } + }, + "required": [ + "logging" + ], + "type": "object" }, "api.CreateGroupRequest": { - "type": "object", - "required": [ - "description", - "expiration_time", - "group_link", - "members", - "name", - "permissions" - ], "properties": { "description": { "type": "string" @@ -2803,18 +99,18 @@ const docTemplate = `{ "type": "integer" }, "group_link": { - "type": "string", "enum": [ "disabled", "enabled", "enabled-with-approval" - ] + ], + "type": "string" }, "members": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "name": { "type": "string" @@ -2822,117 +118,108 @@ const docTemplate = `{ "permissions": { "$ref": "#/definitions/data.GroupPermissions" } - } + }, + "type": "object" }, "api.CreateGroupResponse": { - "type": "object", - "required": [ - "id" - ], "properties": { "id": { "type": "string" } - } + }, + "required": [ + "id" + ], + "type": "object" }, "api.CreatePollRequest": { - "type": "object", - "required": [ - "allow_multiple_selections", - "answers", - "question", - "recipient" - ], "properties": { "allow_multiple_selections": { - "type": "boolean", - "example": true + "example": true, + "type": "boolean" }, "answers": { - "type": "array", - "items": { - "type": "string" - }, "example": [ "apple", "banana", "orange" - ] + ], + "items": { + "type": "string" + }, + "type": "array" }, "question": { - "type": "string", - "example": "What's your favourite fruit?" + "example": "What's your favourite fruit?", + "type": "string" }, "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e", + "type": "string" } - } + }, + "required": [ + "answers", + "question", + "recipient" + ], + "type": "object" }, "api.CreatePollResponse": { - "type": "object", + "properties": { + "timestamp": { + "example": "1769271479", + "type": "string" + } + }, "required": [ "timestamp" ], - "properties": { - "timestamp": { - "type": "string", - "example": "1769271479" - } - } + "type": "object" }, "api.DeleteLocalAccountDataRequest": { - "type": "object", - "required": [ - "ignore_registered" - ], "properties": { "ignore_registered": { - "type": "boolean", - "example": false + "example": false, + "type": "boolean" } - } + }, + "type": "object" }, "api.DeviceLinkUriResponse": { - "type": "object", - "required": [ - "device_link_uri" - ], "properties": { "device_link_uri": { "type": "string" } - } + }, + "required": [ + "device_link_uri" + ], + "type": "object" }, "api.Error": { - "type": "object", - "required": [ - "error" - ], "properties": { "error": { "type": "string" } - } + }, + "required": [ + "error" + ], + "type": "object" }, "api.LoggingConfiguration": { - "type": "object", - "required": [ - "Level" - ], "properties": { "Level": { "type": "string" } - } + }, + "required": [ + "Level" + ], + "type": "object" }, "api.PinMessageInGroupRequest": { - "type": "object", - "required": [ - "duration", - "target_author", - "timestamp" - ], "properties": { "duration": { "type": "integer" @@ -2943,39 +230,38 @@ const docTemplate = `{ "timestamp": { "type": "integer" } - } + }, + "required": [ + "target_author", + "timestamp" + ], + "type": "object" }, "api.RateLimitChallengeRequest": { - "type": "object", + "properties": { + "captcha": { + "example": "signalcaptcha://{captcha value}", + "type": "string" + }, + "challenge_token": { + "example": "\u003cchallenge token\u003e", + "type": "string" + } + }, "required": [ "captcha", "challenge_token" ], - "properties": { - "captcha": { - "type": "string", - "example": "signalcaptcha://{captcha value}" - }, - "challenge_token": { - "type": "string", - "example": "\u003cchallenge token\u003e" - } - } + "type": "object" }, "api.Receipt": { - "type": "object", - "required": [ - "receipt_type", - "recipient", - "timestamp" - ], "properties": { "receipt_type": { - "type": "string", "enum": [ "read", "viewed" - ] + ], + "type": "string" }, "recipient": { "type": "string" @@ -2983,14 +269,15 @@ const docTemplate = `{ "timestamp": { "type": "integer" } - } + }, + "required": [ + "receipt_type", + "recipient", + "timestamp" + ], + "type": "object" }, "api.RegisterNumberRequest": { - "type": "object", - "required": [ - "captcha", - "use_voice" - ], "properties": { "captcha": { "type": "string" @@ -2998,14 +285,10 @@ const docTemplate = `{ "use_voice": { "type": "boolean" } - } + }, + "type": "object" }, "api.RemoteDeleteRequest": { - "type": "object", - "required": [ - "recipient", - "timestamp" - ], "properties": { "recipient": { "type": "string" @@ -3013,27 +296,25 @@ const docTemplate = `{ "timestamp": { "type": "integer" } - } - }, - "api.RemoteDeleteResponse": { - "type": "object", + }, "required": [ + "recipient", "timestamp" ], + "type": "object" + }, + "api.RemoteDeleteResponse": { "properties": { "timestamp": { "type": "string" } - } - }, - "api.RemoveReactionRequest": { - "type": "object", + }, "required": [ - "reaction", - "recipient", - "target_author", "timestamp" ], + "type": "object" + }, + "api.RemoveReactionRequest": { "properties": { "reaction": { "type": "string" @@ -3047,14 +328,15 @@ const docTemplate = `{ "timestamp": { "type": "integer" } - } + }, + "required": [ + "recipient", + "target_author", + "timestamp" + ], + "type": "object" }, "api.SearchResponse": { - "type": "object", - "required": [ - "number", - "registered" - ], "properties": { "number": { "type": "string" @@ -3062,54 +344,50 @@ const docTemplate = `{ "registered": { "type": "boolean" } - } + }, + "required": [ + "number", + "registered" + ], + "type": "object" }, "api.SendMessageError": { - "type": "object", - "required": [ - "account", - "challenge_tokens", - "error" - ], "properties": { "account": { "type": "string" }, "challenge_tokens": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "error": { "type": "string" } - } + }, + "required": [ + "account", + "error" + ], + "type": "object" }, "api.SendMessageResponse": { - "type": "object", - "required": [ - "timestamp" - ], "properties": { "timestamp": { "type": "string" } - } + }, + "required": [ + "timestamp" + ], + "type": "object" }, "api.SendMessageV1": { - "type": "object", - "required": [ - "base64_attachment", - "is_group", - "message", - "number", - "recipients" - ], "properties": { "base64_attachment": { - "type": "string", - "example": "'\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;base64,\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64,\u003cBASE64 ENCODED DATA\u003e'" + "example": "'\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;base64,\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64,\u003cBASE64 ENCODED DATA\u003e'", + "type": "string" }, "is_group": { "type": "boolean" @@ -3121,43 +399,31 @@ const docTemplate = `{ "type": "string" }, "recipients": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "api.SendMessageV2": { - "type": "object", - "required": [ - "base64_attachments", - "edit_timestamp", - "link_preview", - "mentions", - "message", - "notify_self", - "number", - "quote_author", - "quote_mentions", - "quote_message", - "quote_timestamp", - "recipients", - "sticker", - "text_mode", - "view_once" - ], - "properties": { - "base64_attachments": { - "type": "array", "items": { "type": "string" }, + "type": "array" + } + }, + "required": [ + "message", + "number", + "recipients" + ], + "type": "object" + }, + "api.SendMessageV2": { + "properties": { + "base64_attachments": { "example": [ "\u003cBASE64 ENCODED DATA\u003e", "data:\u003cMIME-TYPE\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e", "data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e" - ] + ], + "items": { + "type": "string" + }, + "type": "array" }, "edit_timestamp": { "type": "integer" @@ -3166,10 +432,10 @@ const docTemplate = `{ "$ref": "#/definitions/data.LinkPreviewType" }, "mentions": { - "type": "array", "items": { "$ref": "#/definitions/data.MessageMention" - } + }, + "type": "array" }, "message": { "type": "string" @@ -3184,10 +450,10 @@ const docTemplate = `{ "type": "string" }, "quote_mentions": { - "type": "array", "items": { "$ref": "#/definitions/data.MessageMention" - } + }, + "type": "array" }, "quote_message": { "type": "string" @@ -3196,34 +462,33 @@ const docTemplate = `{ "type": "integer" }, "recipients": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "sticker": { "type": "string" }, "text_mode": { - "type": "string", "enum": [ "normal", "styled" - ] + ], + "type": "string" }, "view_once": { "type": "boolean" } - } + }, + "required": [ + "message", + "number", + "recipients" + ], + "type": "object" }, "api.SendReactionRequest": { - "type": "object", - "required": [ - "reaction", - "recipient", - "target_author", - "timestamp" - ], "properties": { "reaction": { "type": "string" @@ -3237,86 +502,84 @@ const docTemplate = `{ "timestamp": { "type": "integer" } - } + }, + "required": [ + "reaction", + "recipient", + "target_author", + "timestamp" + ], + "type": "object" }, "api.SetPinRequest": { - "type": "object", - "required": [ - "pin" - ], "properties": { "pin": { "type": "string" } - } + }, + "required": [ + "pin" + ], + "type": "object" }, "api.SetUsernameRequest": { - "type": "object", + "properties": { + "username": { + "example": "test", + "type": "string" + } + }, "required": [ "username" ], - "properties": { - "username": { - "type": "string", - "example": "test" - } - } + "type": "object" }, "api.TrustIdentityRequest": { - "type": "object", - "required": [ - "trust_all_known_keys", - "verified_safety_number" - ], "properties": { "trust_all_known_keys": { - "type": "boolean", - "example": false + "example": false, + "type": "boolean" }, "verified_safety_number": { "type": "string" } - } + }, + "type": "object" }, "api.TrustModeRequest": { - "type": "object", - "required": [ - "trust_mode" - ], "properties": { "trust_mode": { "type": "string" } - } + }, + "required": [ + "trust_mode" + ], + "type": "object" }, "api.TrustModeResponse": { - "type": "object", - "required": [ - "trust_mode" - ], "properties": { "trust_mode": { "type": "string" } - } + }, + "required": [ + "trust_mode" + ], + "type": "object" }, "api.TypingIndicatorRequest": { - "type": "object", - "required": [ - "recipient" - ], "properties": { "recipient": { "type": "string" } - } + }, + "required": [ + "recipient" + ], + "type": "object" }, "api.UnpinMessageInGroupRequest": { - "type": "object", - "required": [ - "target_author", - "timestamp" - ], "properties": { "target_author": { "type": "string" @@ -3324,31 +587,27 @@ const docTemplate = `{ "timestamp": { "type": "integer" } - } + }, + "required": [ + "target_author", + "timestamp" + ], + "type": "object" }, "api.UnregisterNumberRequest": { - "type": "object", - "required": [ - "delete_account", - "delete_local_data" - ], "properties": { "delete_account": { - "type": "boolean", - "example": false + "example": false, + "type": "boolean" }, "delete_local_data": { - "type": "boolean", - "example": false + "example": false, + "type": "boolean" } - } + }, + "type": "object" }, "api.UpdateAccountSettingsRequest": { - "type": "object", - "required": [ - "discoverable_by_number", - "share_number" - ], "properties": { "discoverable_by_number": { "type": "boolean" @@ -3356,15 +615,10 @@ const docTemplate = `{ "share_number": { "type": "boolean" } - } + }, + "type": "object" }, "api.UpdateContactRequest": { - "type": "object", - "required": [ - "expiration_in_seconds", - "name", - "recipient" - ], "properties": { "expiration_in_seconds": { "type": "integer" @@ -3375,18 +629,13 @@ const docTemplate = `{ "recipient": { "type": "string" } - } + }, + "required": [ + "recipient" + ], + "type": "object" }, "api.UpdateGroupRequest": { - "type": "object", - "required": [ - "base64_avatar", - "description", - "expiration_time", - "group_link", - "name", - "permissions" - ], "properties": { "base64_avatar": { "type": "string" @@ -3398,12 +647,12 @@ const docTemplate = `{ "type": "integer" }, "group_link": { - "type": "string", "enum": [ "disabled", "enabled", "enabled-with-approval" - ] + ], + "type": "string" }, "name": { "type": "string" @@ -3411,15 +660,10 @@ const docTemplate = `{ "permissions": { "$ref": "#/definitions/data.GroupPermissions" } - } + }, + "type": "object" }, "api.UpdateProfileRequest": { - "type": "object", - "required": [ - "about", - "base64_avatar", - "name" - ], "properties": { "about": { "type": "string" @@ -3430,72 +674,65 @@ const docTemplate = `{ "name": { "type": "string" } - } + }, + "required": [ + "name" + ], + "type": "object" }, "api.VerifyNumberSettings": { - "type": "object", - "required": [ - "pin" - ], "properties": { "pin": { "type": "string" } - } + }, + "type": "object" }, "api.VoteRequest": { - "type": "object", + "properties": { + "poll_author": { + "example": "\u003cphone number\u003e OR \u003cuuid\u003e", + "type": "string" + }, + "poll_timestamp": { + "example": "1769271479", + "type": "string" + }, + "recipient": { + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e", + "type": "string" + }, + "selected_answers": { + "example": [ + 1 + ], + "items": { + "type": "integer" + }, + "type": "array" + } + }, "required": [ "poll_author", "poll_timestamp", "recipient", "selected_answers" ], - "properties": { - "poll_author": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cuuid\u003e" - }, - "poll_timestamp": { - "type": "string", - "example": "1769271479" - }, - "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" - }, - "selected_answers": { - "type": "array", - "items": { - "type": "integer" - }, - "example": [ - 1 - ] - } - } + "type": "object" }, "client.About": { - "type": "object", - "required": [ - "build", - "capabilities", - "mode", - "version", - "versions" - ], "properties": { "build": { "type": "integer" }, "capabilities": { - "type": "object", "additionalProperties": { - "type": "array", "items": { "type": "string" - } - } + }, + "type": "array" + }, + "type": "object" }, "mode": { "type": "string" @@ -3504,22 +741,22 @@ const docTemplate = `{ "type": "string" }, "versions": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" } - } + }, + "required": [ + "build", + "capabilities", + "mode", + "version", + "versions" + ], + "type": "object" }, "client.ContactProfile": { - "type": "object", - "required": [ - "about", - "given_name", - "has_avatar", - "last_updated_timestamp", - "lastname" - ], "properties": { "about": { "type": "string" @@ -3536,29 +773,23 @@ const docTemplate = `{ "lastname": { "type": "string" } - } + }, + "required": [ + "about", + "given_name", + "has_avatar", + "last_updated_timestamp", + "lastname" + ], + "type": "object" }, "client.GroupEntry": { - "type": "object", - "required": [ - "admins", - "blocked", - "description", - "id", - "internal_id", - "invite_link", - "members", - "name", - "pending_invites", - "pending_requests", - "permissions" - ], "properties": { "admins": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "blocked": { "type": "boolean" @@ -3576,41 +807,46 @@ const docTemplate = `{ "type": "string" }, "members": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "name": { "type": "string" }, "pending_invites": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "pending_requests": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "permissions": { "$ref": "#/definitions/data.GroupPermissions" } - } + }, + "required": [ + "admins", + "blocked", + "description", + "id", + "internal_id", + "invite_link", + "members", + "name", + "pending_invites", + "pending_requests", + "permissions" + ], + "type": "object" }, "client.IdentityEntry": { - "type": "object", - "required": [ - "added", - "fingerprint", - "number", - "safety_number", - "status", - "uuid" - ], "properties": { "added": { "type": "string" @@ -3630,24 +866,18 @@ const docTemplate = `{ "uuid": { "type": "string" } - } - }, - "client.ListContactsResponse": { - "type": "object", + }, "required": [ - "blocked", - "color", - "given_name", - "message_expiration", - "name", - "nickname", - "note", + "added", + "fingerprint", "number", - "profile", - "profile_name", - "username", + "safety_number", + "status", "uuid" ], + "type": "object" + }, + "client.ListContactsResponse": { "properties": { "blocked": { "type": "boolean" @@ -3685,16 +915,24 @@ const docTemplate = `{ "uuid": { "type": "string" } - } + }, + "required": [ + "blocked", + "color", + "given_name", + "message_expiration", + "name", + "nickname", + "note", + "number", + "profile", + "profile_name", + "username", + "uuid" + ], + "type": "object" }, "client.ListDevicesResponse": { - "type": "object", - "required": [ - "creation_timestamp", - "id", - "last_seen_timestamp", - "name" - ], "properties": { "creation_timestamp": { "type": "integer" @@ -3708,17 +946,16 @@ const docTemplate = `{ "name": { "type": "string" } - } + }, + "required": [ + "creation_timestamp", + "id", + "last_seen_timestamp", + "name" + ], + "type": "object" }, "client.ListInstalledStickerPacksResponse": { - "type": "object", - "required": [ - "author", - "installed", - "pack_id", - "title", - "url" - ], "properties": { "author": { "type": "string" @@ -3735,15 +972,17 @@ const docTemplate = `{ "url": { "type": "string" } - } + }, + "required": [ + "author", + "installed", + "pack_id", + "title", + "url" + ], + "type": "object" }, "client.Nickname": { - "type": "object", - "required": [ - "family_name", - "given_name", - "name" - ], "properties": { "family_name": { "type": "string" @@ -3754,14 +993,15 @@ const docTemplate = `{ "name": { "type": "string" } - } + }, + "required": [ + "family_name", + "given_name", + "name" + ], + "type": "object" }, "client.SetUsernameResponse": { - "type": "object", - "required": [ - "username", - "username_link" - ], "properties": { "username": { "type": "string" @@ -3769,47 +1009,45 @@ const docTemplate = `{ "username_link": { "type": "string" } - } + }, + "required": [ + "username", + "username_link" + ], + "type": "object" }, "data.GroupPermissions": { - "type": "object", + "properties": { + "add_members": { + "enum": [ + "only-admins", + "every-member" + ], + "type": "string" + }, + "edit_group": { + "enum": [ + "only-admins", + "every-member" + ], + "type": "string" + }, + "send_messages": { + "enum": [ + "only-admins", + "every-member" + ], + "type": "string" + } + }, "required": [ "add_members", "edit_group", "send_messages" ], - "properties": { - "add_members": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "edit_group": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "send_messages": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - } - } + "type": "object" }, "data.LinkPreviewType": { - "type": "object", - "required": [ - "base64_thumbnail", - "description", - "title", - "url" - ], "properties": { "base64_thumbnail": { "type": "string" @@ -3823,26 +1061,14 @@ const docTemplate = `{ "url": { "type": "string" } - } - }, - "data.MessageMention": { - "type": "object", + }, "required": [ - "author", - "length", - "start" + "base64_thumbnail", + "description", + "title", + "url" ], - "properties": { - "author": { - "type": "string" - }, - "length": { - "type": "integer" - }, - "start": { - "type": "integer" - } - } + "type": "object" }, "data.Message": { "properties": { @@ -3859,6 +1085,25 @@ const docTemplate = `{ ], "type": "object" }, + "data.MessageMention": { + "properties": { + "author": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "start": { + "type": "integer" + } + }, + "required": [ + "author", + "length", + "start" + ], + "type": "object" + }, "receive.AdminDelete": { "properties": { "targetAuthor": { @@ -3927,9 +1172,6 @@ const docTemplate = `{ "type": "string" } }, - "required": [ - "id" - ], "type": "object" }, "busyMessage": { @@ -3938,9 +1180,6 @@ const docTemplate = `{ "type": "integer" } }, - "required": [ - "id" - ], "type": "object" }, "hangupMessage": { @@ -3956,7 +1195,6 @@ const docTemplate = `{ } }, "required": [ - "id", "deviceId" ], "type": "object" @@ -3971,9 +1209,6 @@ const docTemplate = `{ "type": "string" } }, - "required": [ - "id" - ], "type": "object" }, "type": "array" @@ -3990,9 +1225,6 @@ const docTemplate = `{ "type": "string" } }, - "required": [ - "id" - ], "type": "object" } }, @@ -5123,6 +2355,2701 @@ const docTemplate = `{ "type": "object" } }, + "host": "{{.Host}}", + "info": { + "contact": {}, + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "version": "{{.Version}}" + }, + "paths": { + "/v1/about": { + "get": { + "description": "Returns the supported API versions and the internal build nr", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.About" + } + } + }, + "summary": "Lists general information about the API", + "tags": [ + "General" + ] + } + }, + "/v1/accounts": { + "get": { + "description": "Lists all of the accounts linked or registered", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List all accounts", + "tags": [ + "Accounts" + ] + } + }, + "/v1/accounts/{number}/pin": { + "delete": { + "description": "Removes a Signal Pin", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove Pin", + "tags": [ + "Accounts" + ] + }, + "post": { + "description": "Sets a new Signal Pin", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SetPinRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Set Pin", + "tags": [ + "Accounts" + ] + } + }, + "/v1/accounts/{number}/rate-limit-challenge": { + "post": { + "consumes": [ + "application/json" + ], + "description": "When running into rate limits, sometimes the limit can be lifted, by solving a CAPTCHA. To get the captcha token, go to https://signalcaptchas.org/challenge/generate.html For the staging environment, use: https://signalcaptchas.org/staging/registration/generate.html. The \"challenge_token\" is the token from the failed send attempt. The \"captcha\" is the captcha result, starting with signalcaptcha://", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.RateLimitChallengeRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Lift rate limit restrictions by solving a captcha.", + "tags": [ + "Accounts" + ] + } + }, + "/v1/accounts/{number}/settings": { + "put": { + "consumes": [ + "application/json" + ], + "description": "Update the account attributes on the signal server.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateAccountSettingsRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Update the account settings.", + "tags": [ + "Accounts" + ] + } + }, + "/v1/accounts/{number}/username": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Delete the username associated with this account.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove a username.", + "tags": [ + "Accounts" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SetUsernameRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/client.SetUsernameResponse" + } + }, + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Set a username.", + "tags": [ + "Accounts" + ] + } + }, + "/v1/attachments": { + "get": { + "description": "List all downloaded attachments", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List all attachments.", + "tags": [ + "Attachments" + ] + } + }, + "/v1/attachments/{attachment}": { + "delete": { + "description": "Remove the attachment with the given id from filesystem.", + "parameters": [ + { + "description": "Attachment ID", + "in": "path", + "name": "attachment", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove attachment.", + "tags": [ + "Attachments" + ] + }, + "get": { + "description": "Serve the attachment with the given id", + "parameters": [ + { + "description": "Attachment ID", + "in": "path", + "name": "attachment", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Serve Attachment.", + "tags": [ + "Attachments" + ] + } + }, + "/v1/configuration": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List the REST API configuration.", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.Configuration" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List the REST API configuration.", + "tags": [ + "General" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Set the REST API configuration.", + "parameters": [ + { + "description": "Configuration", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.Configuration" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Set the REST API configuration.", + "tags": [ + "General" + ] + } + }, + "/v1/configuration/{number}/settings": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List account specific settings.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustModeResponse" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List account specific settings.", + "tags": [ + "General" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Set account specific settings.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustModeRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Set account specific settings.", + "tags": [ + "General" + ] + } + }, + "/v1/contacts/{number}": { + "get": { + "description": "List all contacts for the given number.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Include all known recipients, not only contacts.", + "in": "query", + "name": "all_recipients", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.ListContactsResponse" + }, + "type": "array" + } + } + }, + "summary": "List Contacts", + "tags": [ + "Contacts" + ] + }, + "put": { + "consumes": [ + "application/json" + ], + "description": "Updates the info associated to a number on the contact list.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Contact", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateContactRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Updates the info associated to a number on the contact list. If the contact doesn’t exist yet, it will be added.", + "tags": [ + "Contacts" + ] + } + }, + "/v1/contacts/{number}/sync": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Send a synchronization message with the local contacts list to all linked devices. This command should only be used if this is the primary device.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Send a synchronization message with the local contacts list to all linked devices.", + "tags": [ + "Contacts" + ] + } + }, + "/v1/contacts/{number}/{uuid}": { + "get": { + "description": "List a specific contact.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Include all known recipients, not only contacts.", + "in": "query", + "name": "all_recipients", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.ListContactsResponse" + } + } + }, + "summary": "List Contact", + "tags": [ + "Contacts" + ] + } + }, + "/v1/contacts/{number}/{uuid}/avatar": { + "get": { + "description": "Returns the avatar of a contact.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + } + }, + "summary": "Returns the avatar of a contact", + "tags": [ + "Contacts" + ] + } + }, + "/v1/devices/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List linked devices associated to this device.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.ListDevicesResponse" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List linked devices.", + "tags": [ + "Devices" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Links another device to this device. Only works, if this is the master device.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.AddDeviceRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Links another device to this device.", + "tags": [ + "Devices" + ] + } + }, + "/v1/devices/{number}/local-data": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Delete all local data for the specified account. Only use this after unregistering the account or after removing a linked device.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Cleanup options", + "in": "body", + "name": "data", + "schema": { + "$ref": "#/definitions/api.DeleteLocalAccountDataRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Delete local account data", + "tags": [ + "Devices" + ] + } + }, + "/v1/devices/{number}/{deviceId}": { + "delete": { + "description": "Remove a linked device from the primary account.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Device ID from listDevices", + "in": "path", + "name": "deviceId", + "required": true, + "type": "integer" + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove linked device", + "tags": [ + "Devices" + ] + } + }, + "/v1/groups/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List all Signal Groups.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Expand the response to show more details (default: false)", + "in": "query", + "name": "expand", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.GroupEntry" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List all Signal Groups.", + "tags": [ + "Groups" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Create a new Signal Group with the specified members.", + "parameters": [ + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.CreateGroupRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.CreateGroupResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Create a new Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Delete the specified Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group Id", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Delete a Signal Group.", + "tags": [ + "Groups" + ] + }, + "get": { + "consumes": [ + "application/json" + ], + "description": "List a specific Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + }, + { + "description": "Expand the response to show more details (default: false)", + "in": "query", + "name": "expand", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.GroupEntry" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List a Signal Group.", + "tags": [ + "Groups" + ] + }, + "put": { + "consumes": [ + "application/json" + ], + "description": "Update the state of a Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + }, + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateGroupRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Update the state of a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/admins": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Remove one or more admins from an existing Signal Group.", + "parameters": [ + { + "description": "Admins", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupAdminsRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove one or more admins from an existing Signal Group.", + "tags": [ + "Groups" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Add one or more admins to an existing Signal Group.", + "parameters": [ + { + "description": "Admins", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupAdminsRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Add one or more admins to an existing Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/avatar": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Returns the avatar of a Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Returns the avatar of a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/block": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Block the specified Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Block a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/join": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Join the specified Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Join a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/members": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Remove one or more members from an existing Signal Group.", + "parameters": [ + { + "description": "Members", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupMembersRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove one or more members from an existing Signal Group.", + "tags": [ + "Groups" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Add one or more members to an existing Signal Group.", + "parameters": [ + { + "description": "Members", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupMembersRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Add one or more members to an existing Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/pin-message": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Unpin a message in a Signal Group.", + "parameters": [ + { + "description": "Unpin", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UnpinMessageInGroupRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group Id", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Unpin a message in a Signal Group.", + "tags": [ + "Groups" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Pin a message in a Signal Group.", + "parameters": [ + { + "description": "Pin", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.PinMessageInGroupRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group Id", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Pin a message in a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/quit": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Quit the specified Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Quit a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/health": { + "get": { + "description": "Internally used by the docker container to perform the health check.", + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + } + }, + "summary": "API Health Check", + "tags": [ + "General" + ] + } + }, + "/v1/identities/{number}": { + "get": { + "description": "List all identities for the given number.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.IdentityEntry" + }, + "type": "array" + } + } + }, + "summary": "List Identities", + "tags": [ + "Identities" + ] + } + }, + "/v1/identities/{number}/trust/{numberToTrust}": { + "put": { + "description": "Trust an identity. When 'trust_all_known_keys' is set to' true', all known keys of this user are trusted. **This is only recommended for testing.**", + "parameters": [ + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustIdentityRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Number To Trust", + "in": "path", + "name": "numberToTrust", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + } + }, + "summary": "Trust Identity", + "tags": [ + "Identities" + ] + } + }, + "/v1/polls/{number}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Close a poll", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ClosePollRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Close a poll.", + "tags": [ + "Polls" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Create a new poll", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.CreatePollRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.CreatePollResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Create a new poll.", + "tags": [ + "Polls" + ] + } + }, + "/v1/polls/{number}/vote": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Answer a poll", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.VoteRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Answer a poll.", + "tags": [ + "Polls" + ] + } + }, + "/v1/profiles/{number}": { + "put": { + "description": "Set your name and optional an avatar.", + "parameters": [ + { + "description": "Profile Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateProfileRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Update Profile.", + "tags": [ + "Profiles" + ] + } + }, + "/v1/qrcodelink": { + "get": { + "description": "Link device and generate QR code", + "parameters": [ + { + "description": "Device Name", + "in": "query", + "name": "device_name", + "required": true, + "type": "string" + }, + { + "description": "QRCode Version (defaults to 10)", + "in": "query", + "name": "qrcode_version", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Link device and generate QR code.", + "tags": [ + "Devices" + ] + } + }, + "/v1/qrcodelink/raw": { + "get": { + "description": "Generate the deviceLinkUri string for linking without scanning a QR code.", + "parameters": [ + { + "description": "Device Name", + "in": "query", + "name": "device_name", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.DeviceLinkUriResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Get raw device link URI", + "tags": [ + "Devices" + ] + } + }, + "/v1/reactions/{number}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Remove a reaction", + "parameters": [ + { + "description": "Reaction", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.RemoveReactionRequest" + } + }, + { + "description": "Registered phone number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove a reaction.", + "tags": [ + "Reactions" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "React to a message", + "parameters": [ + { + "description": "Reaction", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendReactionRequest" + } + }, + { + "description": "Registered phone number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Send a reaction.", + "tags": [ + "Reactions" + ] + } + }, + "/v1/receipts/{number}": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Send a read or viewed receipt", + "parameters": [ + { + "description": "Receipt", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.Receipt" + } + }, + { + "description": "Registered phone number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Send a receipt.", + "tags": [ + "Receipts" + ] + } + }, + "/v1/receive/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Receives Signal Messages from the Signal Network. If you are running the docker container in normal/native mode, this is a GET endpoint. In json-rpc mode this is a websocket endpoint.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Receive timeout in seconds (default: 1)", + "in": "query", + "name": "timeout", + "type": "string" + }, + { + "description": "Specify whether the attachments of the received message should be ignored", + "in": "query", + "name": "ignore_attachments", + "type": "string" + }, + { + "description": "Specify whether stories should be ignored when receiving messages", + "in": "query", + "name": "ignore_stories", + "type": "string" + }, + { + "description": "Specify whether avatar downloads should be ignored when receiving messages", + "in": "query", + "name": "ignore_avatars", + "type": "string" + }, + { + "description": "Specify whether sticker pack downloads should be ignored when receiving messages", + "in": "query", + "name": "ignore_stickers", + "type": "string" + }, + { + "description": "Specify the maximum number of messages to receive (default: unlimited)", + "in": "query", + "name": "max_messages", + "type": "string" + }, + { + "description": "Specify whether read receipts should be sent when receiving messages", + "in": "query", + "name": "send_read_receipts", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/data.Message" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Receive Signal Messages.", + "tags": [ + "Messages" + ] + } + }, + "/v1/register/{number}": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Register a phone number with the signal network.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Additional Settings", + "in": "body", + "name": "data", + "schema": { + "$ref": "#/definitions/api.RegisterNumberRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Register a phone number.", + "tags": [ + "Devices" + ] + } + }, + "/v1/register/{number}/verify/{token}": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Verify a registered phone number with the signal network.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Additional Settings", + "in": "body", + "name": "data", + "schema": { + "$ref": "#/definitions/api.VerifyNumberSettings" + } + }, + { + "description": "Verification Code", + "in": "path", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Verify a registered phone number.", + "tags": [ + "Devices" + ] + } + }, + "/v1/remote-delete/{number}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Delete a signal message", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.RemoteDeleteRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.RemoteDeleteResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Delete a signal message.", + "tags": [ + "Messages" + ] + } + }, + "/v1/search/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Check if one or more phone numbers are registered with the Signal Service.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "collectionFormat": "multi", + "description": "Numbers to check", + "in": "query", + "items": { + "type": "string" + }, + "name": "numbers", + "required": true, + "type": "array" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/api.SearchResponse" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Check if one or more phone numbers are registered with the Signal Service.", + "tags": [ + "Search" + ] + } + }, + "/v1/send": { + "post": { + "consumes": [ + "application/json" + ], + "deprecated": true, + "description": "Send a signal message", + "parameters": [ + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendMessageV1" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Send a signal message.", + "tags": [ + "Messages" + ] + } + }, + "/v1/sticker-packs/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List Installed Sticker Packs.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.ListInstalledStickerPacksResponse" + }, + "type": "array" + } + }, + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List Installed Sticker Packs.", + "tags": [ + "Sticker Packs" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the \"Add to Signal\" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX\u0026pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.AddStickerPackRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Add Sticker Pack.", + "tags": [ + "Sticker Packs" + ] + } + }, + "/v1/typing-indicator/{number}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Hide Typing Indicator.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TypingIndicatorRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Hide Typing Indicator.", + "tags": [ + "Messages" + ] + }, + "put": { + "consumes": [ + "application/json" + ], + "description": "Show Typing Indicator.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TypingIndicatorRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Show Typing Indicator.", + "tags": [ + "Messages" + ] + } + }, + "/v1/unregister/{number}": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Disables push support for this device. **WARNING:** If *delete_account* is set to *true*, the account will be deleted from the Signal Server. This cannot be undone without loss.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Additional Settings", + "in": "body", + "name": "data", + "schema": { + "$ref": "#/definitions/api.UnregisterNumberRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Unregister a phone number.", + "tags": [ + "Devices" + ] + } + }, + "/v2/send": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\` + "`" + `monospace\\` + "`" + `. If you want to escape a formatting character, prefix it with two backslashes.", + "parameters": [ + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendMessageV2" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.SendMessageResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.SendMessageError" + } + } + }, + "summary": "Send a signal message.", + "tags": [ + "Messages" + ] + } + } + }, + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", "tags": [ { "description": "Some general endpoints.", diff --git a/src/docs/swagger.json b/src/docs/swagger.json index b5882d8..fd913c7 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -1,2797 +1,91 @@ { - "schemes": [ - "http" - ], - "swagger": "2.0", - "info": { - "description": "This is the Signal Cli REST API documentation.", - "title": "Signal Cli REST API", - "contact": {}, - "version": "1.0" - }, - "host": "localhost:8080", "basePath": "/", - "paths": { - "/v1/about": { - "get": { - "description": "Returns the supported API versions and the internal build nr", - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Lists general information about the API", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.About" - } - } - } - } - }, - "/v1/accounts": { - "get": { - "description": "Lists all of the accounts linked or registered", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "List all accounts", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/pin": { - "post": { - "description": "Sets a new Signal Pin", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Set Pin", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SetPinRequest" - } - } - ], - "responses": { - "201": { - "description": "Created" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Removes a Signal Pin", - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Remove Pin", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/rate-limit-challenge": { - "post": { - "description": "When running into rate limits, sometimes the limit can be lifted, by solving a CAPTCHA. To get the captcha token, go to https://signalcaptchas.org/challenge/generate.html For the staging environment, use: https://signalcaptchas.org/staging/registration/generate.html. The \"challenge_token\" is the token from the failed send attempt. The \"captcha\" is the captcha result, starting with signalcaptcha://", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Lift rate limit restrictions by solving a captcha.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RateLimitChallengeRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/settings": { - "put": { - "description": "Update the account attributes on the signal server.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Update the account settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateAccountSettingsRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/accounts/{number}/username": { - "post": { - "description": "Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Set a username.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SetUsernameRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/client.SetUsernameResponse" - } - }, - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Delete the username associated with this account.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Accounts" - ], - "summary": "Remove a username.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/attachments": { - "get": { - "description": "List all downloaded attachments", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "List all attachments.", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/attachments/{attachment}": { - "get": { - "description": "Serve the attachment with the given id", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "Serve Attachment.", - "parameters": [ - { - "type": "string", - "description": "Attachment ID", - "name": "attachment", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove the attachment with the given id from filesystem.", - "produces": [ - "application/json" - ], - "tags": [ - "Attachments" - ], - "summary": "Remove attachment.", - "parameters": [ - { - "type": "string", - "description": "Attachment ID", - "name": "attachment", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/configuration": { - "get": { - "description": "List the REST API configuration.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "List the REST API configuration.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.Configuration" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Set the REST API configuration.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Set the REST API configuration.", - "parameters": [ - { - "description": "Configuration", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.Configuration" - } - } - ], - "responses": { - "204": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/configuration/{number}/settings": { - "get": { - "description": "List account specific settings.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "List account specific settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustModeResponse" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Set account specific settings.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Set account specific settings.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustModeRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}": { - "get": { - "description": "List all contacts for the given number.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "List Contacts", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Include all known recipients, not only contacts.", - "name": "all_recipients", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListContactsResponse" - } - } - } - } - }, - "put": { - "description": "Updates the info associated to a number on the contact list.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Updates the info associated to a number on the contact list. If the contact doesn’t exist yet, it will be added.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Contact", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateContactRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}/sync": { - "post": { - "description": "Send a synchronization message with the local contacts list to all linked devices. This command should only be used if this is the primary device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Send a synchronization message with the local contacts list to all linked devices.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/contacts/{number}/{uuid}": { - "get": { - "description": "List a specific contact.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "List Contact", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Include all known recipients, not only contacts.", - "name": "all_recipients", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.ListContactsResponse" - } - } - } - } - }, - "/v1/contacts/{number}/{uuid}/avatar": { - "get": { - "description": "Returns the avatar of a contact.", - "produces": [ - "application/json" - ], - "tags": [ - "Contacts" - ], - "summary": "Returns the avatar of a contact", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/devices/{number}": { - "get": { - "description": "List linked devices associated to this device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "List linked devices.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListDevicesResponse" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Links another device to this device. Only works, if this is the master device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Links another device to this device.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.AddDeviceRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/devices/{number}/local-data": { - "delete": { - "description": "Delete all local data for the specified account. Only use this after unregistering the account or after removing a linked device.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Delete local account data", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Cleanup options", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.DeleteLocalAccountDataRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/devices/{number}/{deviceId}": { - "delete": { - "description": "Remove a linked device from the primary account.", - "tags": [ - "Devices" - ], - "summary": "Remove linked device", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Device ID from listDevices", - "name": "deviceId", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}": { - "get": { - "description": "List all Signal Groups.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "List all Signal Groups.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Expand the response to show more details (default: false)", - "name": "expand", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.GroupEntry" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "Create a new Signal Group with the specified members.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Create a new Signal Group.", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.CreateGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.CreateGroupResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}": { - "get": { - "description": "List a specific Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "List a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Expand the response to show more details (default: false)", - "name": "expand", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/client.GroupEntry" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "put": { - "description": "Update the state of a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Update the state of a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - }, - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateGroupRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Delete the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Delete a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/admins": { - "post": { - "description": "Add one or more admins to an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Add one or more admins to an existing Signal Group.", - "parameters": [ - { - "description": "Admins", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupAdminsRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove one or more admins from an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Remove one or more admins from an existing Signal Group.", - "parameters": [ - { - "description": "Admins", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupAdminsRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/avatar": { - "get": { - "description": "Returns the avatar of a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Returns the avatar of a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/block": { - "post": { - "description": "Block the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Block a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/join": { - "post": { - "description": "Join the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Join a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/members": { - "post": { - "description": "Add one or more members to an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Add one or more members to an existing Signal Group.", - "parameters": [ - { - "description": "Members", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupMembersRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove one or more members from an existing Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Remove one or more members from an existing Signal Group.", - "parameters": [ - { - "description": "Members", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ChangeGroupMembersRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/pin-message": { - "post": { - "description": "Pin a message in a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Pin a message in a Signal Group.", - "parameters": [ - { - "description": "Pin", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.PinMessageInGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Unpin a message in a Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Unpin a message in a Signal Group.", - "parameters": [ - { - "description": "Unpin", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UnpinMessageInGroupRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group Id", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/groups/{number}/{groupid}/quit": { - "post": { - "description": "Quit the specified Signal Group.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Groups" - ], - "summary": "Quit a Signal Group.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group ID", - "name": "groupid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/health": { - "get": { - "description": "Internally used by the docker container to perform the health check.", - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "API Health Check", - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/identities/{number}": { - "get": { - "description": "List all identities for the given number.", - "produces": [ - "application/json" - ], - "tags": [ - "Identities" - ], - "summary": "List Identities", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.IdentityEntry" - } - } - } - } - } - }, - "/v1/identities/{number}/trust/{numberToTrust}": { - "put": { - "description": "Trust an identity. When 'trust_all_known_keys' is set to' true', all known keys of this user are trusted. **This is only recommended for testing.**", - "produces": [ - "application/json" - ], - "tags": [ - "Identities" - ], - "summary": "Trust Identity", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TrustIdentityRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Number To Trust", - "name": "numberToTrust", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - } - } - } - }, - "/v1/polls/{number}": { - "post": { - "description": "Create a new poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Create a new poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.CreatePollRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.CreatePollResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Close a poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Close a poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.ClosePollRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/polls/{number}/vote": { - "post": { - "description": "Answer a poll", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Polls" - ], - "summary": "Answer a poll.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.VoteRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/profiles/{number}": { - "put": { - "description": "Set your name and optional an avatar.", - "produces": [ - "application/json" - ], - "tags": [ - "Profiles" - ], - "summary": "Update Profile.", - "parameters": [ - { - "description": "Profile Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.UpdateProfileRequest" - } - }, - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/qrcodelink": { - "get": { - "description": "Link device and generate QR code", - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Link device and generate QR code.", - "parameters": [ - { - "type": "string", - "description": "Device Name", - "name": "device_name", - "in": "query", - "required": true - }, - { - "type": "integer", - "description": "QRCode Version (defaults to 10)", - "name": "qrcode_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Image", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/qrcodelink/raw": { - "get": { - "description": "Generate the deviceLinkUri string for linking without scanning a QR code.", - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Get raw device link URI", - "parameters": [ - { - "type": "string", - "description": "Device Name", - "name": "device_name", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/api.DeviceLinkUriResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/reactions/{number}": { - "post": { - "description": "React to a message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Reactions" - ], - "summary": "Send a reaction.", - "parameters": [ - { - "description": "Reaction", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendReactionRequest" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Remove a reaction", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Reactions" - ], - "summary": "Remove a reaction.", - "parameters": [ - { - "description": "Reaction", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RemoveReactionRequest" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/receipts/{number}": { - "post": { - "description": "Send a read or viewed receipt", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Receipts" - ], - "summary": "Send a receipt.", - "parameters": [ - { - "description": "Receipt", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.Receipt" - } - }, - { - "type": "string", - "description": "Registered phone number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/receive/{number}": { - "get": { - "description": "Receives Signal Messages from the Signal Network. If you are running the docker container in normal/native mode, this is a GET endpoint. In json-rpc mode this is a websocket endpoint.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Receive Signal Messages.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Receive timeout in seconds (default: 1)", - "name": "timeout", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether the attachments of the received message should be ignored", - "name": "ignore_attachments", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether stories should be ignored when receiving messages", - "name": "ignore_stories", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether avatar downloads should be ignored when receiving messages", - "name": "ignore_avatars", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether sticker pack downloads should be ignored when receiving messages", - "name": "ignore_stickers", - "in": "query" - }, - { - "type": "string", - "description": "Specify the maximum number of messages to receive (default: unlimited)", - "name": "max_messages", - "in": "query" - }, - { - "type": "string", - "description": "Specify whether read receipts should be sent when receiving messages", - "name": "send_read_receipts", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/data.Message" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/register/{number}": { - "post": { - "description": "Register a phone number with the signal network.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Register a phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.RegisterNumberRequest" - } - } - ], - "responses": { - "201": { - "description": "Created" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/register/{number}/verify/{token}": { - "post": { - "description": "Verify a registered phone number with the signal network.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Verify a registered phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.VerifyNumberSettings" - } - }, - { - "type": "string", - "description": "Verification Code", - "name": "token", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/remote-delete/{number}": { - "delete": { - "description": "Delete a signal message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Delete a signal message.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.RemoteDeleteRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.RemoteDeleteResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/search/{number}": { - "get": { - "description": "Check if one or more phone numbers are registered with the Signal Service.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Search" - ], - "summary": "Check if one or more phone numbers are registered with the Signal Service.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "description": "Numbers to check", - "name": "numbers", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/api.SearchResponse" - } - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/send": { - "post": { - "description": "Send a signal message", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Send a signal message.", - "deprecated": true, - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendMessageV1" - } - } - ], - "responses": { - "201": { - "description": "OK", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/sticker-packs/{number}": { - "get": { - "description": "List Installed Sticker Packs.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Sticker Packs" - ], - "summary": "List Installed Sticker Packs.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/client.ListInstalledStickerPacksResponse" - } - } - }, - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "post": { - "description": "In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the \"Add to Signal\" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX\u0026pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Sticker Packs" - ], - "summary": "Add Sticker Pack.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Request", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.AddStickerPackRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/typing-indicator/{number}": { - "put": { - "description": "Show Typing Indicator.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Show Typing Indicator.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TypingIndicatorRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - }, - "delete": { - "description": "Hide Typing Indicator.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Hide Typing Indicator.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Type", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.TypingIndicatorRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content", - "schema": { - "type": "string" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v1/unregister/{number}": { - "post": { - "description": "Disables push support for this device. **WARNING:** If *delete_account* is set to *true*, the account will be deleted from the Signal Server. This cannot be undone without loss.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Devices" - ], - "summary": "Unregister a phone number.", - "parameters": [ - { - "type": "string", - "description": "Registered Phone Number", - "name": "number", - "in": "path", - "required": true - }, - { - "description": "Additional Settings", - "name": "data", - "in": "body", - "schema": { - "$ref": "#/definitions/api.UnregisterNumberRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.Error" - } - } - } - } - }, - "/v2/send": { - "post": { - "description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\`monospace\\`. If you want to escape a formatting character, prefix it with two backslashes.", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Messages" - ], - "summary": "Send a signal message.", - "parameters": [ - { - "description": "Input Data", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/api.SendMessageV2" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/api.SendMessageResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/api.SendMessageError" - } - } - } - } - } - }, "definitions": { "api.AddDeviceRequest": { - "type": "object", - "required": [ - "uri" - ], "properties": { "uri": { "type": "string" } - } + }, + "required": [ + "uri" + ], + "type": "object" }, "api.AddStickerPackRequest": { - "type": "object", + "properties": { + "pack_id": { + "example": "9a32eda01a7a28574f2eb48668ae0dc4", + "type": "string" + }, + "pack_key": { + "example": "19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a", + "type": "string" + } + }, "required": [ "pack_id", "pack_key" ], - "properties": { - "pack_id": { - "type": "string", - "example": "9a32eda01a7a28574f2eb48668ae0dc4" - }, - "pack_key": { - "type": "string", - "example": "19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a" - } - } + "type": "object" }, "api.ChangeGroupAdminsRequest": { - "type": "object", + "properties": { + "admins": { + "items": { + "type": "string" + }, + "type": "array" + } + }, "required": [ "admins" ], - "properties": { - "admins": { - "type": "array", - "items": { - "type": "string" - } - } - } + "type": "object" }, "api.ChangeGroupMembersRequest": { - "type": "object", + "properties": { + "members": { + "items": { + "type": "string" + }, + "type": "array" + } + }, "required": [ "members" ], - "properties": { - "members": { - "type": "array", - "items": { - "type": "string" - } - } - } + "type": "object" }, "api.ClosePollRequest": { - "type": "object", + "properties": { + "poll_timestamp": { + "example": "1769271479", + "type": "string" + }, + "recipient": { + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e", + "type": "string" + } + }, "required": [ "poll_timestamp", "recipient" ], - "properties": { - "poll_timestamp": { - "type": "string", - "example": "1769271479" - }, - "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" - } - } + "type": "object" }, "api.Configuration": { - "type": "object", - "required": [ - "logging" - ], "properties": { "logging": { "$ref": "#/definitions/api.LoggingConfiguration" } - } + }, + "required": [ + "logging" + ], + "type": "object" }, "api.CreateGroupRequest": { - "type": "object", - "required": [ - "description", - "expiration_time", - "group_link", - "members", - "name", - "permissions" - ], "properties": { "description": { "type": "string" @@ -2800,18 +94,18 @@ "type": "integer" }, "group_link": { - "type": "string", "enum": [ "disabled", "enabled", "enabled-with-approval" - ] + ], + "type": "string" }, "members": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "name": { "type": "string" @@ -2819,117 +113,108 @@ "permissions": { "$ref": "#/definitions/data.GroupPermissions" } - } + }, + "type": "object" }, "api.CreateGroupResponse": { - "type": "object", - "required": [ - "id" - ], "properties": { "id": { "type": "string" } - } + }, + "required": [ + "id" + ], + "type": "object" }, "api.CreatePollRequest": { - "type": "object", - "required": [ - "allow_multiple_selections", - "answers", - "question", - "recipient" - ], "properties": { "allow_multiple_selections": { - "type": "boolean", - "example": true + "example": true, + "type": "boolean" }, "answers": { - "type": "array", - "items": { - "type": "string" - }, "example": [ "apple", "banana", "orange" - ] + ], + "items": { + "type": "string" + }, + "type": "array" }, "question": { - "type": "string", - "example": "What's your favourite fruit?" + "example": "What's your favourite fruit?", + "type": "string" }, "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e", + "type": "string" } - } + }, + "required": [ + "answers", + "question", + "recipient" + ], + "type": "object" }, "api.CreatePollResponse": { - "type": "object", + "properties": { + "timestamp": { + "example": "1769271479", + "type": "string" + } + }, "required": [ "timestamp" ], - "properties": { - "timestamp": { - "type": "string", - "example": "1769271479" - } - } + "type": "object" }, "api.DeleteLocalAccountDataRequest": { - "type": "object", - "required": [ - "ignore_registered" - ], "properties": { "ignore_registered": { - "type": "boolean", - "example": false + "example": false, + "type": "boolean" } - } + }, + "type": "object" }, "api.DeviceLinkUriResponse": { - "type": "object", - "required": [ - "device_link_uri" - ], "properties": { "device_link_uri": { "type": "string" } - } + }, + "required": [ + "device_link_uri" + ], + "type": "object" }, "api.Error": { - "type": "object", - "required": [ - "error" - ], "properties": { "error": { "type": "string" } - } + }, + "required": [ + "error" + ], + "type": "object" }, "api.LoggingConfiguration": { - "type": "object", - "required": [ - "Level" - ], "properties": { "Level": { "type": "string" } - } + }, + "required": [ + "Level" + ], + "type": "object" }, "api.PinMessageInGroupRequest": { - "type": "object", - "required": [ - "duration", - "target_author", - "timestamp" - ], "properties": { "duration": { "type": "integer" @@ -2940,39 +225,38 @@ "timestamp": { "type": "integer" } - } + }, + "required": [ + "target_author", + "timestamp" + ], + "type": "object" }, "api.RateLimitChallengeRequest": { - "type": "object", + "properties": { + "captcha": { + "example": "signalcaptcha://{captcha value}", + "type": "string" + }, + "challenge_token": { + "example": "\u003cchallenge token\u003e", + "type": "string" + } + }, "required": [ "captcha", "challenge_token" ], - "properties": { - "captcha": { - "type": "string", - "example": "signalcaptcha://{captcha value}" - }, - "challenge_token": { - "type": "string", - "example": "\u003cchallenge token\u003e" - } - } + "type": "object" }, "api.Receipt": { - "type": "object", - "required": [ - "receipt_type", - "recipient", - "timestamp" - ], "properties": { "receipt_type": { - "type": "string", "enum": [ "read", "viewed" - ] + ], + "type": "string" }, "recipient": { "type": "string" @@ -2980,14 +264,15 @@ "timestamp": { "type": "integer" } - } + }, + "required": [ + "receipt_type", + "recipient", + "timestamp" + ], + "type": "object" }, "api.RegisterNumberRequest": { - "type": "object", - "required": [ - "captcha", - "use_voice" - ], "properties": { "captcha": { "type": "string" @@ -2995,14 +280,10 @@ "use_voice": { "type": "boolean" } - } + }, + "type": "object" }, "api.RemoteDeleteRequest": { - "type": "object", - "required": [ - "recipient", - "timestamp" - ], "properties": { "recipient": { "type": "string" @@ -3010,27 +291,25 @@ "timestamp": { "type": "integer" } - } - }, - "api.RemoteDeleteResponse": { - "type": "object", + }, "required": [ + "recipient", "timestamp" ], + "type": "object" + }, + "api.RemoteDeleteResponse": { "properties": { "timestamp": { "type": "string" } - } - }, - "api.RemoveReactionRequest": { - "type": "object", + }, "required": [ - "reaction", - "recipient", - "target_author", "timestamp" ], + "type": "object" + }, + "api.RemoveReactionRequest": { "properties": { "reaction": { "type": "string" @@ -3044,14 +323,15 @@ "timestamp": { "type": "integer" } - } + }, + "required": [ + "recipient", + "target_author", + "timestamp" + ], + "type": "object" }, "api.SearchResponse": { - "type": "object", - "required": [ - "number", - "registered" - ], "properties": { "number": { "type": "string" @@ -3059,54 +339,50 @@ "registered": { "type": "boolean" } - } + }, + "required": [ + "number", + "registered" + ], + "type": "object" }, "api.SendMessageError": { - "type": "object", - "required": [ - "account", - "challenge_tokens", - "error" - ], "properties": { "account": { "type": "string" }, "challenge_tokens": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "error": { "type": "string" } - } + }, + "required": [ + "account", + "error" + ], + "type": "object" }, "api.SendMessageResponse": { - "type": "object", - "required": [ - "timestamp" - ], "properties": { "timestamp": { "type": "string" } - } + }, + "required": [ + "timestamp" + ], + "type": "object" }, "api.SendMessageV1": { - "type": "object", - "required": [ - "base64_attachment", - "is_group", - "message", - "number", - "recipients" - ], "properties": { "base64_attachment": { - "type": "string", - "example": "'\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;base64,\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64,\u003cBASE64 ENCODED DATA\u003e'" + "example": "'\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;base64,\u003cBASE64 ENCODED DATA\u003e' OR 'data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64,\u003cBASE64 ENCODED DATA\u003e'", + "type": "string" }, "is_group": { "type": "boolean" @@ -3118,43 +394,31 @@ "type": "string" }, "recipients": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "api.SendMessageV2": { - "type": "object", - "required": [ - "base64_attachments", - "edit_timestamp", - "link_preview", - "mentions", - "message", - "notify_self", - "number", - "quote_author", - "quote_mentions", - "quote_message", - "quote_timestamp", - "recipients", - "sticker", - "text_mode", - "view_once" - ], - "properties": { - "base64_attachments": { - "type": "array", "items": { "type": "string" }, + "type": "array" + } + }, + "required": [ + "message", + "number", + "recipients" + ], + "type": "object" + }, + "api.SendMessageV2": { + "properties": { + "base64_attachments": { "example": [ "\u003cBASE64 ENCODED DATA\u003e", "data:\u003cMIME-TYPE\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e", "data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e" - ] + ], + "items": { + "type": "string" + }, + "type": "array" }, "edit_timestamp": { "type": "integer" @@ -3163,10 +427,10 @@ "$ref": "#/definitions/data.LinkPreviewType" }, "mentions": { - "type": "array", "items": { "$ref": "#/definitions/data.MessageMention" - } + }, + "type": "array" }, "message": { "type": "string" @@ -3181,10 +445,10 @@ "type": "string" }, "quote_mentions": { - "type": "array", "items": { "$ref": "#/definitions/data.MessageMention" - } + }, + "type": "array" }, "quote_message": { "type": "string" @@ -3193,34 +457,33 @@ "type": "integer" }, "recipients": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "sticker": { "type": "string" }, "text_mode": { - "type": "string", "enum": [ "normal", "styled" - ] + ], + "type": "string" }, "view_once": { "type": "boolean" } - } + }, + "required": [ + "message", + "number", + "recipients" + ], + "type": "object" }, "api.SendReactionRequest": { - "type": "object", - "required": [ - "reaction", - "recipient", - "target_author", - "timestamp" - ], "properties": { "reaction": { "type": "string" @@ -3234,86 +497,84 @@ "timestamp": { "type": "integer" } - } + }, + "required": [ + "reaction", + "recipient", + "target_author", + "timestamp" + ], + "type": "object" }, "api.SetPinRequest": { - "type": "object", - "required": [ - "pin" - ], "properties": { "pin": { "type": "string" } - } + }, + "required": [ + "pin" + ], + "type": "object" }, "api.SetUsernameRequest": { - "type": "object", + "properties": { + "username": { + "example": "test", + "type": "string" + } + }, "required": [ "username" ], - "properties": { - "username": { - "type": "string", - "example": "test" - } - } + "type": "object" }, "api.TrustIdentityRequest": { - "type": "object", - "required": [ - "trust_all_known_keys", - "verified_safety_number" - ], "properties": { "trust_all_known_keys": { - "type": "boolean", - "example": false + "example": false, + "type": "boolean" }, "verified_safety_number": { "type": "string" } - } + }, + "type": "object" }, "api.TrustModeRequest": { - "type": "object", - "required": [ - "trust_mode" - ], "properties": { "trust_mode": { "type": "string" } - } + }, + "required": [ + "trust_mode" + ], + "type": "object" }, "api.TrustModeResponse": { - "type": "object", - "required": [ - "trust_mode" - ], "properties": { "trust_mode": { "type": "string" } - } + }, + "required": [ + "trust_mode" + ], + "type": "object" }, "api.TypingIndicatorRequest": { - "type": "object", - "required": [ - "recipient" - ], "properties": { "recipient": { "type": "string" } - } + }, + "required": [ + "recipient" + ], + "type": "object" }, "api.UnpinMessageInGroupRequest": { - "type": "object", - "required": [ - "target_author", - "timestamp" - ], "properties": { "target_author": { "type": "string" @@ -3321,31 +582,27 @@ "timestamp": { "type": "integer" } - } + }, + "required": [ + "target_author", + "timestamp" + ], + "type": "object" }, "api.UnregisterNumberRequest": { - "type": "object", - "required": [ - "delete_account", - "delete_local_data" - ], "properties": { "delete_account": { - "type": "boolean", - "example": false + "example": false, + "type": "boolean" }, "delete_local_data": { - "type": "boolean", - "example": false + "example": false, + "type": "boolean" } - } + }, + "type": "object" }, "api.UpdateAccountSettingsRequest": { - "type": "object", - "required": [ - "discoverable_by_number", - "share_number" - ], "properties": { "discoverable_by_number": { "type": "boolean" @@ -3353,15 +610,10 @@ "share_number": { "type": "boolean" } - } + }, + "type": "object" }, "api.UpdateContactRequest": { - "type": "object", - "required": [ - "expiration_in_seconds", - "name", - "recipient" - ], "properties": { "expiration_in_seconds": { "type": "integer" @@ -3372,18 +624,13 @@ "recipient": { "type": "string" } - } + }, + "required": [ + "recipient" + ], + "type": "object" }, "api.UpdateGroupRequest": { - "type": "object", - "required": [ - "base64_avatar", - "description", - "expiration_time", - "group_link", - "name", - "permissions" - ], "properties": { "base64_avatar": { "type": "string" @@ -3395,12 +642,12 @@ "type": "integer" }, "group_link": { - "type": "string", "enum": [ "disabled", "enabled", "enabled-with-approval" - ] + ], + "type": "string" }, "name": { "type": "string" @@ -3408,15 +655,10 @@ "permissions": { "$ref": "#/definitions/data.GroupPermissions" } - } + }, + "type": "object" }, "api.UpdateProfileRequest": { - "type": "object", - "required": [ - "about", - "base64_avatar", - "name" - ], "properties": { "about": { "type": "string" @@ -3427,72 +669,65 @@ "name": { "type": "string" } - } + }, + "required": [ + "name" + ], + "type": "object" }, "api.VerifyNumberSettings": { - "type": "object", - "required": [ - "pin" - ], "properties": { "pin": { "type": "string" } - } + }, + "type": "object" }, "api.VoteRequest": { - "type": "object", + "properties": { + "poll_author": { + "example": "\u003cphone number\u003e OR \u003cuuid\u003e", + "type": "string" + }, + "poll_timestamp": { + "example": "1769271479", + "type": "string" + }, + "recipient": { + "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e", + "type": "string" + }, + "selected_answers": { + "example": [ + 1 + ], + "items": { + "type": "integer" + }, + "type": "array" + } + }, "required": [ "poll_author", "poll_timestamp", "recipient", "selected_answers" ], - "properties": { - "poll_author": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cuuid\u003e" - }, - "poll_timestamp": { - "type": "string", - "example": "1769271479" - }, - "recipient": { - "type": "string", - "example": "\u003cphone number\u003e OR \u003cusername\u003e OR \u003cgroup id\u003e" - }, - "selected_answers": { - "type": "array", - "items": { - "type": "integer" - }, - "example": [ - 1 - ] - } - } + "type": "object" }, "client.About": { - "type": "object", - "required": [ - "build", - "capabilities", - "mode", - "version", - "versions" - ], "properties": { "build": { "type": "integer" }, "capabilities": { - "type": "object", "additionalProperties": { - "type": "array", "items": { "type": "string" - } - } + }, + "type": "array" + }, + "type": "object" }, "mode": { "type": "string" @@ -3501,22 +736,22 @@ "type": "string" }, "versions": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" } - } + }, + "required": [ + "build", + "capabilities", + "mode", + "version", + "versions" + ], + "type": "object" }, "client.ContactProfile": { - "type": "object", - "required": [ - "about", - "given_name", - "has_avatar", - "last_updated_timestamp", - "lastname" - ], "properties": { "about": { "type": "string" @@ -3533,29 +768,23 @@ "lastname": { "type": "string" } - } + }, + "required": [ + "about", + "given_name", + "has_avatar", + "last_updated_timestamp", + "lastname" + ], + "type": "object" }, "client.GroupEntry": { - "type": "object", - "required": [ - "admins", - "blocked", - "description", - "id", - "internal_id", - "invite_link", - "members", - "name", - "pending_invites", - "pending_requests", - "permissions" - ], "properties": { "admins": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "blocked": { "type": "boolean" @@ -3573,41 +802,46 @@ "type": "string" }, "members": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "name": { "type": "string" }, "pending_invites": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "pending_requests": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "permissions": { "$ref": "#/definitions/data.GroupPermissions" } - } + }, + "required": [ + "admins", + "blocked", + "description", + "id", + "internal_id", + "invite_link", + "members", + "name", + "pending_invites", + "pending_requests", + "permissions" + ], + "type": "object" }, "client.IdentityEntry": { - "type": "object", - "required": [ - "added", - "fingerprint", - "number", - "safety_number", - "status", - "uuid" - ], "properties": { "added": { "type": "string" @@ -3627,24 +861,18 @@ "uuid": { "type": "string" } - } - }, - "client.ListContactsResponse": { - "type": "object", + }, "required": [ - "blocked", - "color", - "given_name", - "message_expiration", - "name", - "nickname", - "note", + "added", + "fingerprint", "number", - "profile", - "profile_name", - "username", + "safety_number", + "status", "uuid" ], + "type": "object" + }, + "client.ListContactsResponse": { "properties": { "blocked": { "type": "boolean" @@ -3682,16 +910,24 @@ "uuid": { "type": "string" } - } + }, + "required": [ + "blocked", + "color", + "given_name", + "message_expiration", + "name", + "nickname", + "note", + "number", + "profile", + "profile_name", + "username", + "uuid" + ], + "type": "object" }, "client.ListDevicesResponse": { - "type": "object", - "required": [ - "creation_timestamp", - "id", - "last_seen_timestamp", - "name" - ], "properties": { "creation_timestamp": { "type": "integer" @@ -3705,17 +941,16 @@ "name": { "type": "string" } - } + }, + "required": [ + "creation_timestamp", + "id", + "last_seen_timestamp", + "name" + ], + "type": "object" }, "client.ListInstalledStickerPacksResponse": { - "type": "object", - "required": [ - "author", - "installed", - "pack_id", - "title", - "url" - ], "properties": { "author": { "type": "string" @@ -3732,15 +967,17 @@ "url": { "type": "string" } - } + }, + "required": [ + "author", + "installed", + "pack_id", + "title", + "url" + ], + "type": "object" }, "client.Nickname": { - "type": "object", - "required": [ - "family_name", - "given_name", - "name" - ], "properties": { "family_name": { "type": "string" @@ -3751,14 +988,15 @@ "name": { "type": "string" } - } + }, + "required": [ + "family_name", + "given_name", + "name" + ], + "type": "object" }, "client.SetUsernameResponse": { - "type": "object", - "required": [ - "username", - "username_link" - ], "properties": { "username": { "type": "string" @@ -3766,47 +1004,45 @@ "username_link": { "type": "string" } - } + }, + "required": [ + "username", + "username_link" + ], + "type": "object" }, "data.GroupPermissions": { - "type": "object", + "properties": { + "add_members": { + "enum": [ + "only-admins", + "every-member" + ], + "type": "string" + }, + "edit_group": { + "enum": [ + "only-admins", + "every-member" + ], + "type": "string" + }, + "send_messages": { + "enum": [ + "only-admins", + "every-member" + ], + "type": "string" + } + }, "required": [ "add_members", "edit_group", "send_messages" ], - "properties": { - "add_members": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "edit_group": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "send_messages": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - } - } + "type": "object" }, "data.LinkPreviewType": { - "type": "object", - "required": [ - "base64_thumbnail", - "description", - "title", - "url" - ], "properties": { "base64_thumbnail": { "type": "string" @@ -3820,26 +1056,14 @@ "url": { "type": "string" } - } - }, - "data.MessageMention": { - "type": "object", + }, "required": [ - "author", - "length", - "start" + "base64_thumbnail", + "description", + "title", + "url" ], - "properties": { - "author": { - "type": "string" - }, - "length": { - "type": "integer" - }, - "start": { - "type": "integer" - } - } + "type": "object" }, "data.Message": { "properties": { @@ -3856,6 +1080,25 @@ ], "type": "object" }, + "data.MessageMention": { + "properties": { + "author": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "start": { + "type": "integer" + } + }, + "required": [ + "author", + "length", + "start" + ], + "type": "object" + }, "receive.AdminDelete": { "properties": { "targetAuthor": { @@ -3924,9 +1167,6 @@ "type": "string" } }, - "required": [ - "id" - ], "type": "object" }, "busyMessage": { @@ -3935,9 +1175,6 @@ "type": "integer" } }, - "required": [ - "id" - ], "type": "object" }, "hangupMessage": { @@ -3953,7 +1190,6 @@ } }, "required": [ - "id", "deviceId" ], "type": "object" @@ -3968,9 +1204,6 @@ "type": "string" } }, - "required": [ - "id" - ], "type": "object" }, "type": "array" @@ -3987,9 +1220,6 @@ "type": "string" } }, - "required": [ - "id" - ], "type": "object" } }, @@ -5120,6 +2350,2703 @@ "type": "object" } }, + "host": "localhost:8080", + "info": { + "contact": {}, + "description": "This is the Signal Cli REST API documentation.", + "title": "Signal Cli REST API", + "version": "1.0" + }, + "paths": { + "/v1/about": { + "get": { + "description": "Returns the supported API versions and the internal build nr", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.About" + } + } + }, + "summary": "Lists general information about the API", + "tags": [ + "General" + ] + } + }, + "/v1/accounts": { + "get": { + "description": "Lists all of the accounts linked or registered", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List all accounts", + "tags": [ + "Accounts" + ] + } + }, + "/v1/accounts/{number}/pin": { + "delete": { + "description": "Removes a Signal Pin", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove Pin", + "tags": [ + "Accounts" + ] + }, + "post": { + "description": "Sets a new Signal Pin", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SetPinRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Set Pin", + "tags": [ + "Accounts" + ] + } + }, + "/v1/accounts/{number}/rate-limit-challenge": { + "post": { + "consumes": [ + "application/json" + ], + "description": "When running into rate limits, sometimes the limit can be lifted, by solving a CAPTCHA. To get the captcha token, go to https://signalcaptchas.org/challenge/generate.html For the staging environment, use: https://signalcaptchas.org/staging/registration/generate.html. The \"challenge_token\" is the token from the failed send attempt. The \"captcha\" is the captcha result, starting with signalcaptcha://", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.RateLimitChallengeRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Lift rate limit restrictions by solving a captcha.", + "tags": [ + "Accounts" + ] + } + }, + "/v1/accounts/{number}/settings": { + "put": { + "consumes": [ + "application/json" + ], + "description": "Update the account attributes on the signal server.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateAccountSettingsRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Update the account settings.", + "tags": [ + "Accounts" + ] + } + }, + "/v1/accounts/{number}/username": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Delete the username associated with this account.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove a username.", + "tags": [ + "Accounts" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Allows to set the username that should be used for this account. This can either be just the nickname (e.g. test) or the complete username with discriminator (e.g. test.123). Returns the new username with discriminator and the username link.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SetUsernameRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/client.SetUsernameResponse" + } + }, + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Set a username.", + "tags": [ + "Accounts" + ] + } + }, + "/v1/attachments": { + "get": { + "description": "List all downloaded attachments", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List all attachments.", + "tags": [ + "Attachments" + ] + } + }, + "/v1/attachments/{attachment}": { + "delete": { + "description": "Remove the attachment with the given id from filesystem.", + "parameters": [ + { + "description": "Attachment ID", + "in": "path", + "name": "attachment", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove attachment.", + "tags": [ + "Attachments" + ] + }, + "get": { + "description": "Serve the attachment with the given id", + "parameters": [ + { + "description": "Attachment ID", + "in": "path", + "name": "attachment", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Serve Attachment.", + "tags": [ + "Attachments" + ] + } + }, + "/v1/configuration": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List the REST API configuration.", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.Configuration" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List the REST API configuration.", + "tags": [ + "General" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Set the REST API configuration.", + "parameters": [ + { + "description": "Configuration", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.Configuration" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Set the REST API configuration.", + "tags": [ + "General" + ] + } + }, + "/v1/configuration/{number}/settings": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List account specific settings.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustModeResponse" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List account specific settings.", + "tags": [ + "General" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Set account specific settings.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustModeRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Set account specific settings.", + "tags": [ + "General" + ] + } + }, + "/v1/contacts/{number}": { + "get": { + "description": "List all contacts for the given number.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Include all known recipients, not only contacts.", + "in": "query", + "name": "all_recipients", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.ListContactsResponse" + }, + "type": "array" + } + } + }, + "summary": "List Contacts", + "tags": [ + "Contacts" + ] + }, + "put": { + "consumes": [ + "application/json" + ], + "description": "Updates the info associated to a number on the contact list.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Contact", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateContactRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Updates the info associated to a number on the contact list. If the contact doesn’t exist yet, it will be added.", + "tags": [ + "Contacts" + ] + } + }, + "/v1/contacts/{number}/sync": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Send a synchronization message with the local contacts list to all linked devices. This command should only be used if this is the primary device.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Send a synchronization message with the local contacts list to all linked devices.", + "tags": [ + "Contacts" + ] + } + }, + "/v1/contacts/{number}/{uuid}": { + "get": { + "description": "List a specific contact.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Include all known recipients, not only contacts.", + "in": "query", + "name": "all_recipients", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.ListContactsResponse" + } + } + }, + "summary": "List Contact", + "tags": [ + "Contacts" + ] + } + }, + "/v1/contacts/{number}/{uuid}/avatar": { + "get": { + "description": "Returns the avatar of a contact.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + } + }, + "summary": "Returns the avatar of a contact", + "tags": [ + "Contacts" + ] + } + }, + "/v1/devices/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List linked devices associated to this device.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.ListDevicesResponse" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List linked devices.", + "tags": [ + "Devices" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Links another device to this device. Only works, if this is the master device.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.AddDeviceRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Links another device to this device.", + "tags": [ + "Devices" + ] + } + }, + "/v1/devices/{number}/local-data": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Delete all local data for the specified account. Only use this after unregistering the account or after removing a linked device.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Cleanup options", + "in": "body", + "name": "data", + "schema": { + "$ref": "#/definitions/api.DeleteLocalAccountDataRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Delete local account data", + "tags": [ + "Devices" + ] + } + }, + "/v1/devices/{number}/{deviceId}": { + "delete": { + "description": "Remove a linked device from the primary account.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Device ID from listDevices", + "in": "path", + "name": "deviceId", + "required": true, + "type": "integer" + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove linked device", + "tags": [ + "Devices" + ] + } + }, + "/v1/groups/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List all Signal Groups.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Expand the response to show more details (default: false)", + "in": "query", + "name": "expand", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.GroupEntry" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List all Signal Groups.", + "tags": [ + "Groups" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Create a new Signal Group with the specified members.", + "parameters": [ + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.CreateGroupRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.CreateGroupResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Create a new Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Delete the specified Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group Id", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Delete a Signal Group.", + "tags": [ + "Groups" + ] + }, + "get": { + "consumes": [ + "application/json" + ], + "description": "List a specific Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + }, + { + "description": "Expand the response to show more details (default: false)", + "in": "query", + "name": "expand", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/client.GroupEntry" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List a Signal Group.", + "tags": [ + "Groups" + ] + }, + "put": { + "consumes": [ + "application/json" + ], + "description": "Update the state of a Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + }, + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateGroupRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Update the state of a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/admins": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Remove one or more admins from an existing Signal Group.", + "parameters": [ + { + "description": "Admins", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupAdminsRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove one or more admins from an existing Signal Group.", + "tags": [ + "Groups" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Add one or more admins to an existing Signal Group.", + "parameters": [ + { + "description": "Admins", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupAdminsRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Add one or more admins to an existing Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/avatar": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Returns the avatar of a Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Returns the avatar of a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/block": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Block the specified Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Block a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/join": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Join the specified Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Join a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/members": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Remove one or more members from an existing Signal Group.", + "parameters": [ + { + "description": "Members", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupMembersRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove one or more members from an existing Signal Group.", + "tags": [ + "Groups" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Add one or more members to an existing Signal Group.", + "parameters": [ + { + "description": "Members", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ChangeGroupMembersRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Add one or more members to an existing Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/pin-message": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Unpin a message in a Signal Group.", + "parameters": [ + { + "description": "Unpin", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UnpinMessageInGroupRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group Id", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Unpin a message in a Signal Group.", + "tags": [ + "Groups" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Pin a message in a Signal Group.", + "parameters": [ + { + "description": "Pin", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.PinMessageInGroupRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group Id", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Pin a message in a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/groups/{number}/{groupid}/quit": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Quit the specified Signal Group.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Group ID", + "in": "path", + "name": "groupid", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Quit a Signal Group.", + "tags": [ + "Groups" + ] + } + }, + "/v1/health": { + "get": { + "description": "Internally used by the docker container to perform the health check.", + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + } + }, + "summary": "API Health Check", + "tags": [ + "General" + ] + } + }, + "/v1/identities/{number}": { + "get": { + "description": "List all identities for the given number.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.IdentityEntry" + }, + "type": "array" + } + } + }, + "summary": "List Identities", + "tags": [ + "Identities" + ] + } + }, + "/v1/identities/{number}/trust/{numberToTrust}": { + "put": { + "description": "Trust an identity. When 'trust_all_known_keys' is set to' true', all known keys of this user are trusted. **This is only recommended for testing.**", + "parameters": [ + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TrustIdentityRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Number To Trust", + "in": "path", + "name": "numberToTrust", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + } + }, + "summary": "Trust Identity", + "tags": [ + "Identities" + ] + } + }, + "/v1/polls/{number}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Close a poll", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.ClosePollRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Close a poll.", + "tags": [ + "Polls" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "Create a new poll", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.CreatePollRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.CreatePollResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Create a new poll.", + "tags": [ + "Polls" + ] + } + }, + "/v1/polls/{number}/vote": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Answer a poll", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.VoteRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Answer a poll.", + "tags": [ + "Polls" + ] + } + }, + "/v1/profiles/{number}": { + "put": { + "description": "Set your name and optional an avatar.", + "parameters": [ + { + "description": "Profile Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.UpdateProfileRequest" + } + }, + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Update Profile.", + "tags": [ + "Profiles" + ] + } + }, + "/v1/qrcodelink": { + "get": { + "description": "Link device and generate QR code", + "parameters": [ + { + "description": "Device Name", + "in": "query", + "name": "device_name", + "required": true, + "type": "string" + }, + { + "description": "QRCode Version (defaults to 10)", + "in": "query", + "name": "qrcode_version", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Image", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Link device and generate QR code.", + "tags": [ + "Devices" + ] + } + }, + "/v1/qrcodelink/raw": { + "get": { + "description": "Generate the deviceLinkUri string for linking without scanning a QR code.", + "parameters": [ + { + "description": "Device Name", + "in": "query", + "name": "device_name", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.DeviceLinkUriResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Get raw device link URI", + "tags": [ + "Devices" + ] + } + }, + "/v1/reactions/{number}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Remove a reaction", + "parameters": [ + { + "description": "Reaction", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.RemoveReactionRequest" + } + }, + { + "description": "Registered phone number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Remove a reaction.", + "tags": [ + "Reactions" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "React to a message", + "parameters": [ + { + "description": "Reaction", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendReactionRequest" + } + }, + { + "description": "Registered phone number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Send a reaction.", + "tags": [ + "Reactions" + ] + } + }, + "/v1/receipts/{number}": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Send a read or viewed receipt", + "parameters": [ + { + "description": "Receipt", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.Receipt" + } + }, + { + "description": "Registered phone number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Send a receipt.", + "tags": [ + "Receipts" + ] + } + }, + "/v1/receive/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Receives Signal Messages from the Signal Network. If you are running the docker container in normal/native mode, this is a GET endpoint. In json-rpc mode this is a websocket endpoint.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Receive timeout in seconds (default: 1)", + "in": "query", + "name": "timeout", + "type": "string" + }, + { + "description": "Specify whether the attachments of the received message should be ignored", + "in": "query", + "name": "ignore_attachments", + "type": "string" + }, + { + "description": "Specify whether stories should be ignored when receiving messages", + "in": "query", + "name": "ignore_stories", + "type": "string" + }, + { + "description": "Specify whether avatar downloads should be ignored when receiving messages", + "in": "query", + "name": "ignore_avatars", + "type": "string" + }, + { + "description": "Specify whether sticker pack downloads should be ignored when receiving messages", + "in": "query", + "name": "ignore_stickers", + "type": "string" + }, + { + "description": "Specify the maximum number of messages to receive (default: unlimited)", + "in": "query", + "name": "max_messages", + "type": "string" + }, + { + "description": "Specify whether read receipts should be sent when receiving messages", + "in": "query", + "name": "send_read_receipts", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/data.Message" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Receive Signal Messages.", + "tags": [ + "Messages" + ] + } + }, + "/v1/register/{number}": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Register a phone number with the signal network.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Additional Settings", + "in": "body", + "name": "data", + "schema": { + "$ref": "#/definitions/api.RegisterNumberRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Register a phone number.", + "tags": [ + "Devices" + ] + } + }, + "/v1/register/{number}/verify/{token}": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Verify a registered phone number with the signal network.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Additional Settings", + "in": "body", + "name": "data", + "schema": { + "$ref": "#/definitions/api.VerifyNumberSettings" + } + }, + { + "description": "Verification Code", + "in": "path", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Verify a registered phone number.", + "tags": [ + "Devices" + ] + } + }, + "/v1/remote-delete/{number}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Delete a signal message", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.RemoteDeleteRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.RemoteDeleteResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Delete a signal message.", + "tags": [ + "Messages" + ] + } + }, + "/v1/search/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "Check if one or more phone numbers are registered with the Signal Service.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "collectionFormat": "multi", + "description": "Numbers to check", + "in": "query", + "items": { + "type": "string" + }, + "name": "numbers", + "required": true, + "type": "array" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/api.SearchResponse" + }, + "type": "array" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Check if one or more phone numbers are registered with the Signal Service.", + "tags": [ + "Search" + ] + } + }, + "/v1/send": { + "post": { + "consumes": [ + "application/json" + ], + "deprecated": true, + "description": "Send a signal message", + "parameters": [ + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendMessageV1" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Send a signal message.", + "tags": [ + "Messages" + ] + } + }, + "/v1/sticker-packs/{number}": { + "get": { + "consumes": [ + "application/json" + ], + "description": "List Installed Sticker Packs.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "items": { + "$ref": "#/definitions/client.ListInstalledStickerPacksResponse" + }, + "type": "array" + } + }, + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "List Installed Sticker Packs.", + "tags": [ + "Sticker Packs" + ] + }, + "post": { + "consumes": [ + "application/json" + ], + "description": "In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the \"Add to Signal\" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX\u0026pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Request", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.AddStickerPackRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Add Sticker Pack.", + "tags": [ + "Sticker Packs" + ] + } + }, + "/v1/typing-indicator/{number}": { + "delete": { + "consumes": [ + "application/json" + ], + "description": "Hide Typing Indicator.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TypingIndicatorRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Hide Typing Indicator.", + "tags": [ + "Messages" + ] + }, + "put": { + "consumes": [ + "application/json" + ], + "description": "Show Typing Indicator.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Type", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.TypingIndicatorRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Show Typing Indicator.", + "tags": [ + "Messages" + ] + } + }, + "/v1/unregister/{number}": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Disables push support for this device. **WARNING:** If *delete_account* is set to *true*, the account will be deleted from the Signal Server. This cannot be undone without loss.", + "parameters": [ + { + "description": "Registered Phone Number", + "in": "path", + "name": "number", + "required": true, + "type": "string" + }, + { + "description": "Additional Settings", + "in": "body", + "name": "data", + "schema": { + "$ref": "#/definitions/api.UnregisterNumberRequest" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + }, + "summary": "Unregister a phone number.", + "tags": [ + "Devices" + ] + } + }, + "/v2/send": { + "post": { + "consumes": [ + "application/json" + ], + "description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\`monospace\\`. If you want to escape a formatting character, prefix it with two backslashes.", + "parameters": [ + { + "description": "Input Data", + "in": "body", + "name": "data", + "required": true, + "schema": { + "$ref": "#/definitions/api.SendMessageV2" + } + } + ], + "produces": [ + "application/json" + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.SendMessageResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.SendMessageError" + } + } + }, + "summary": "Send a signal message.", + "tags": [ + "Messages" + ] + } + } + }, + "schemes": [ + "http" + ], + "swagger": "2.0", "tags": [ { "description": "Some general endpoints.", From a7c91737b8193674173f806687a517818e035dca Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 19:28:57 +0200 Subject: [PATCH 27/40] Refactor --- src/docs/add_v1_receive_schemas.go | 56 +++++++++++------------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/src/docs/add_v1_receive_schemas.go b/src/docs/add_v1_receive_schemas.go index 2aeee4d..8d5fbda 100644 --- a/src/docs/add_v1_receive_schemas.go +++ b/src/docs/add_v1_receive_schemas.go @@ -76,19 +76,21 @@ func updateDocsGo(receiveDefinitions map[string]interface{}) error { return err } - document, err := jsonUnmarshalSafe(template, true) - if err != nil { - return err + var document map[string]interface{} + if err := json.Unmarshal([]byte(toValidJson(template)), &document); err != nil { + return fmt.Errorf("parse document: %w", err) } if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { return err } - updatedTemplate, err := jsonMarshalIndentSafe(document, true) + raw, err := json.MarshalIndent(document, "", " ") if err != nil { - return err + return fmt.Errorf("marshal document: %w", err) } + updatedTemplate := string(raw) + updatedTemplate = encodeForGoRawString(updatedTemplate) updated := string(content[:templateStart]) + updatedTemplate + string(content[templateEnd:]) if err := os.WriteFile(goDocsPath, []byte(updated), 0644); err != nil { @@ -104,19 +106,20 @@ func updateSwaggerJSON(receiveDefinitions map[string]interface{}) error { return fmt.Errorf("read %s: %w", jsonDocsPath, err) } - document, err := jsonUnmarshalSafe(string(content), false) - if err != nil { - return err + var document map[string]interface{} + if err := json.Unmarshal(content, &document); err != nil { + return fmt.Errorf("parse document: %w", err) } if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { return err } - updated, err := jsonMarshalIndentSafe(document, false) + raw, err := json.MarshalIndent(document, "", " ") if err != nil { - return err + return fmt.Errorf("marshal document: %w", err) } + updated := string(raw) if err := os.WriteFile(jsonDocsPath, []byte(updated), 0644); err != nil { return fmt.Errorf("write %s: %w", jsonDocsPath, err) @@ -141,33 +144,16 @@ func extractDocTemplate(content string) (string, int, int, error) { return content[start:end], start, end, nil } -func jsonUnmarshalSafe(content string, applyStringConcat bool) (map[string]interface{}, error) { - if applyStringConcat { - content = strings.ReplaceAll(content, "` + \"`\" + `", "`") - content = strings.Replace(content, schemesTemplateValue, `"`+schemesPlaceholderToken+`"`, 1) - } - - var document map[string]interface{} - if err := json.Unmarshal([]byte(content), &document); err != nil { - return nil, fmt.Errorf("parse document: %w", err) - } - - return document, nil +func toValidJson(content string) string { + content = strings.ReplaceAll(content, "` + \"`\" + `", "`") + content = strings.Replace(content, schemesTemplateValue, `"`+schemesPlaceholderToken+`"`, 1) + return content } -func jsonMarshalIndentSafe(document map[string]interface{}, backTicksAsStringConcat bool) (string, error) { - raw, err := json.MarshalIndent(document, "", " ") - if err != nil { - return "", fmt.Errorf("marshal document: %w", err) - } - - updated := string(raw) - if backTicksAsStringConcat { - updated = strings.ReplaceAll(updated, "`", "` + \"`\" + `") - updated = strings.Replace(updated, `"`+schemesPlaceholderToken+`"`, schemesTemplateValue, 1) - } - - return updated, nil +func encodeForGoRawString(content string) string { + content = strings.ReplaceAll(content, "`", "` + \"`\" + `") + content = strings.Replace(content, `"`+schemesPlaceholderToken+`"`, schemesTemplateValue, 1) + return content } func addReceiveSchemas(definitions map[string]interface{}, receiveDir string) (map[string]string, error) { From 91bdd60c7a40c3b50ed0acf5fc3c5a8042aa3ee5 Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 19:31:52 +0200 Subject: [PATCH 28/40] Additional refactor --- src/docs/add_v1_receive_schemas.go | 54 +++++++++++++----------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/src/docs/add_v1_receive_schemas.go b/src/docs/add_v1_receive_schemas.go index 8d5fbda..a24fc32 100644 --- a/src/docs/add_v1_receive_schemas.go +++ b/src/docs/add_v1_receive_schemas.go @@ -46,9 +46,7 @@ func run(receiveDir string) error { return err } - if err := updateReceiveSchemaRefs(definitions, titleByFile); err != nil { - return err - } + updateReceiveSchemaRefs(definitions, titleByFile) addEnvelopeWrapperDefinition(definitions) @@ -76,20 +74,10 @@ func updateDocsGo(receiveDefinitions map[string]interface{}) error { return err } - var document map[string]interface{} - if err := json.Unmarshal([]byte(toValidJson(template)), &document); err != nil { - return fmt.Errorf("parse document: %w", err) - } - - if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { + updatedTemplate, err := updateJSONDocument(toValidJson(template), receiveDefinitions) + if err != nil { return err } - - raw, err := json.MarshalIndent(document, "", " ") - if err != nil { - return fmt.Errorf("marshal document: %w", err) - } - updatedTemplate := string(raw) updatedTemplate = encodeForGoRawString(updatedTemplate) updated := string(content[:templateStart]) + updatedTemplate + string(content[templateEnd:]) @@ -106,21 +94,11 @@ func updateSwaggerJSON(receiveDefinitions map[string]interface{}) error { return fmt.Errorf("read %s: %w", jsonDocsPath, err) } - var document map[string]interface{} - if err := json.Unmarshal(content, &document); err != nil { - return fmt.Errorf("parse document: %w", err) - } - - if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { + updated, err := updateJSONDocument(string(content), receiveDefinitions) + if err != nil { return err } - raw, err := json.MarshalIndent(document, "", " ") - if err != nil { - return fmt.Errorf("marshal document: %w", err) - } - updated := string(raw) - if err := os.WriteFile(jsonDocsPath, []byte(updated), 0644); err != nil { return fmt.Errorf("write %s: %w", jsonDocsPath, err) } @@ -156,6 +134,24 @@ func encodeForGoRawString(content string) string { return content } +func updateJSONDocument(content string, receiveDefinitions map[string]interface{}) (string, error) { + var document map[string]interface{} + if err := json.Unmarshal([]byte(content), &document); err != nil { + return "", fmt.Errorf("parse document: %w", err) + } + + if err := applyReceiveSchemaUpdates(document, receiveDefinitions); err != nil { + return "", err + } + + raw, err := json.MarshalIndent(document, "", " ") + if err != nil { + return "", fmt.Errorf("marshal document: %w", err) + } + + return string(raw), nil +} + func addReceiveSchemas(definitions map[string]interface{}, receiveDir string) (map[string]string, error) { entries, err := os.ReadDir(receiveDir) if err != nil { @@ -221,15 +217,13 @@ func removeSchemaKeysRecursive(value interface{}, parentKey string) interface{} } } -func updateReceiveSchemaRefs(definitions map[string]interface{}, titleByFile map[string]string) error { +func updateReceiveSchemaRefs(definitions map[string]interface{}, titleByFile map[string]string) { for key, value := range definitions { if !strings.HasPrefix(key, receivePrefix) { continue } definitions[key] = rewriteSchemaRefs(value, titleByFile) } - - return nil } func rewriteSchemaRefs(value interface{}, titleByFile map[string]string) interface{} { From 44ac16d49cae38f7a086ced29e1f3f851161c38c Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 19:47:51 +0200 Subject: [PATCH 29/40] check docs before a release --- .github/workflows/check-docs.yml | 28 +++++++++++++ .github/workflows/release-dev-version.yml | 4 ++ .../workflows/release-productive-version.yml | 4 ++ .github/workflows/update-generated-docs.yml | 41 ------------------- 4 files changed, 36 insertions(+), 41 deletions(-) create mode 100644 .github/workflows/check-docs.yml delete mode 100644 .github/workflows/update-generated-docs.yml diff --git a/.github/workflows/check-docs.yml b/.github/workflows/check-docs.yml new file mode 100644 index 0000000..0d372af --- /dev/null +++ b/.github/workflows/check-docs.yml @@ -0,0 +1,28 @@ +name: Check Generated Docs + +on: + workflow_call: + +permissions: + contents: read + +jobs: + check-docs: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up Go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.0.0 + with: + go-version-file: src/go.mod + cache-dependency-path: src/go.sum + + - name: Regenerate docs + working-directory: src + run: go run github.com/swaggo/swag/cmd/swag@v1.16.6 init --requiredByDefault + + - name: Fail if docs are out of date + run: | + git diff --exit-code -- src/docs/docs.go src/docs/swagger.json src/docs/swagger.yaml diff --git a/.github/workflows/release-dev-version.yml b/.github/workflows/release-dev-version.yml index 683825e..a1bceac 100644 --- a/.github/workflows/release-dev-version.yml +++ b/.github/workflows/release-dev-version.yml @@ -11,8 +11,12 @@ permissions: {} jobs: + check-docs: + uses: ./.github/workflows/check-docs.yml + setup: runs-on: ubuntu-24.04 + needs: check-docs steps: - name: Set up QEMU uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 diff --git a/.github/workflows/release-productive-version.yml b/.github/workflows/release-productive-version.yml index c0b5f9a..a38e4a7 100644 --- a/.github/workflows/release-productive-version.yml +++ b/.github/workflows/release-productive-version.yml @@ -11,8 +11,12 @@ permissions: {} jobs: + check-docs: + uses: ./.github/workflows/check-docs.yml + setup: runs-on: ubuntu-24.04 + needs: check-docs steps: - name: Set up QEMU uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 diff --git a/.github/workflows/update-generated-docs.yml b/.github/workflows/update-generated-docs.yml deleted file mode 100644 index 8fa75f7..0000000 --- a/.github/workflows/update-generated-docs.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Update Generated Docs - -on: - push: - branches: - - master - -permissions: - contents: write - pull-requests: write - -jobs: - update-docs: - runs-on: ubuntu-24.04 - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version-file: src/go.mod - cache-dependency-path: src/go.sum - - - name: Regenerate docs - working-directory: src - run: go run github.com/swaggo/swag/cmd/swag@v1.16.6 init --requiredByDefault - - - name: Create pull request for regenerated docs - uses: peter-evans/create-pull-request@v8 - with: - branch: automation/update-generated-docs - delete-branch: true - commit-message: "chore: regenerate swagger docs" - title: "chore: regenerate swagger docs" - body: | - Update Swagger docs to match the latest changes in the main branch. - add-paths: | - src/docs/docs.go - src/docs/swagger.json - src/docs/swagger.yaml From 0aaab36e5f6759c7a28ba4b2470efac4a8e6778d Mon Sep 17 00:00:00 2001 From: Gara Dorta <1507774+Gara-Dorta@users.noreply.github.com> Date: Fri, 15 May 2026 19:50:35 +0200 Subject: [PATCH 30/40] Enable read of repo --- .github/workflows/release-dev-version.yml | 4 ++-- .github/workflows/release-productive-version.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-dev-version.yml b/.github/workflows/release-dev-version.yml index a1bceac..8581b3d 100644 --- a/.github/workflows/release-dev-version.yml +++ b/.github/workflows/release-dev-version.yml @@ -7,8 +7,8 @@ on: description: 'Version' required: true -permissions: {} - +permissions: + contents: read jobs: check-docs: diff --git a/.github/workflows/release-productive-version.yml b/.github/workflows/release-productive-version.yml index a38e4a7..357818c 100644 --- a/.github/workflows/release-productive-version.yml +++ b/.github/workflows/release-productive-version.yml @@ -7,8 +7,8 @@ on: description: 'Version' required: true -permissions: {} - +permissions: + contents: read jobs: check-docs: From 6e7941b1c1d91b4bbf9471fc3fa6b8b061657761 Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Sat, 23 May 2026 13:18:37 +0200 Subject: [PATCH 31/40] improved plugin mechanism + added sqlite3 plugin --- plugins/README.md | 55 ++++---- plugins/example.def | 1 + plugins/example.lua | 42 +++--- plugins/migrate-v1-plugin-to-v2.md | 29 +++++ plugins/persistence/README.md | 35 +++++ plugins/persistence/persist-message.def | 3 + plugins/persistence/persist-message.lua | 37 ++++++ plugins/persistence/query-message.def | 3 + plugins/persistence/query-message.lua | 35 +++++ src/go.mod | 7 +- src/main.go | 12 ++ src/plugin_loader.go | 163 +++++++++++++++++++++--- src/utils/plugin_config.go | 5 +- src/utils/plugin_handler.go | 1 + 14 files changed, 365 insertions(+), 63 deletions(-) create mode 100644 plugins/migrate-v1-plugin-to-v2.md create mode 100644 plugins/persistence/README.md create mode 100644 plugins/persistence/persist-message.def create mode 100644 plugins/persistence/persist-message.lua create mode 100644 plugins/persistence/query-message.def create mode 100644 plugins/persistence/query-message.lua diff --git a/plugins/README.md b/plugins/README.md index 6d7d7a2..17e76f3 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -40,45 +40,56 @@ The definition file (with the file suffix `.def`) contains some metadata which i ``` endpoint: my-custom-send-endpoint/:number method: POST +version: 2 ``` -The `endpoint` specifies the URI of the newly created endpoint. All custom endpoints are registered under the `/v1/plugins` endpoint. So, our `my-custom-send-endpoint` will be available at `/v1/plugins/my-custom-endpoint`. If you want to use variables inside the endpoint, prefix them with a `:`. +The `endpoint` specifies the URI of the newly created endpoint. All custom endpoints are registered under the `/v1/plugins` endpoint. So, our `my-custom-send-endpoint` will be available at `/v1/plugins/my-custom-endpoint`. If you want to use variables inside the endpoint, prefix them with a `:`. + +If you write a new plugin, it is recommended to use the `version: 2` of the plugin mechanism. (`version: 1` is deprecated!) The `method` parameter specifies the HTTP method that is used for the endpoint registration. # The script file -The script file (with the file suffix `.lua`) contains the implementation of the endpoint. +The script file (with the file suffix `.lua`) contains the implementation of the endpoint. Each plugin must implement a `exec` function and can optionally implement a `init` function. The `exec` function gets called whenever the plugin is called. The `init` function only gets called once during the startup and can be used to perform initialization tasks. Example: ``` -local http = require("http") -local json = require("json") +-- +function exec() + local http = require("http") + local json = require("json") -local url = "http://127.0.0.1:8080/v2/send" + local url = "http://127.0.0.1:8080/v2/send" -local customEndpointPayload = json.decode(pluginInputData.payload) + local customEndpointPayload = json.decode(pluginInputData.payload) -local sendEndpointPayload = { - recipients = {customEndpointPayload.recipient}, - message = customEndpointPayload.message, - number = pluginInputData.Params.number -} + local sendEndpointPayload = { + recipients = {customEndpointPayload.recipient}, + message = customEndpointPayload.message, + number = pluginInputData.Params.number + } -local encodedSendEndpointPayload = json.encode(sendEndpointPayload) + local encodedSendEndpointPayload = json.encode(sendEndpointPayload) -response, error_message = http.request("POST", url, { - timeout="30s", - headers={ - Accept="*/*", - ["Content-Type"]="application/json" - }, - body=encodedSendEndpointPayload -}) + response, error_message = http.request("POST", url, { + timeout="30s", + headers={ + Accept="*/*", + ["Content-Type"]="application/json" + }, + body=encodedSendEndpointPayload + }) -pluginOutputData:SetPayload(response["body"]) -pluginOutputData:SetHttpStatusCode(response.status_code) + pluginOutputData:SetPayload(response["body"]) + pluginOutputData:SetHttpStatusCode(response.status_code) +end + +-- optional init function +function init() + +end ``` What the lua script does, is parse the JSON payload from the custom request, extract the `recipient` and the `message` from the payload and the `number` from the URL parameter and call the `/v2/send` endpoint with those parameters. The HTTP status code and the body that is returned by the HTTP request is then returned to the caller (this is done via the `pluginOutputData:SetPayload` and `pluginOutputData:SetHttpStatusCode` functions. diff --git a/plugins/example.def b/plugins/example.def index f4b6dfe..0ce1784 100644 --- a/plugins/example.def +++ b/plugins/example.def @@ -1,2 +1,3 @@ endpoint: my-custom-send-endpoint/:number method: POST +version: 2 diff --git a/plugins/example.lua b/plugins/example.lua index 8a66f11..019a15f 100644 --- a/plugins/example.lua +++ b/plugins/example.lua @@ -1,27 +1,27 @@ local http = require("http") local json = require("json") -local url = "http://127.0.0.1:8080/v2/send" +function exec() + local url = "http://127.0.0.1:8080/v2/send" + local customEndpointPayload = json.decode(pluginInputData.payload) + local sendEndpointPayload = { + recipients = {customEndpointPayload.recipient}, + message = customEndpointPayload.message, + number = pluginInputData.Params.number + } -local customEndpointPayload = json.decode(pluginInputData.payload) + local encodedSendEndpointPayload = json.encode(sendEndpointPayload) + print(encodedSendEndpointPayload) -local sendEndpointPayload = { - recipients = {customEndpointPayload.recipient}, - message = customEndpointPayload.message, - number = pluginInputData.Params.number -} + response, error_message = http.request("POST", url, { + timeout="30s", + headers={ + Accept="*/*", + ["Content-Type"]="application/json" + }, + body=encodedSendEndpointPayload + }) -local encodedSendEndpointPayload = json.encode(sendEndpointPayload) -print(encodedSendEndpointPayload) - -response, error_message = http.request("POST", url, { - timeout="30s", - headers={ - Accept="*/*", - ["Content-Type"]="application/json" - }, - body=encodedSendEndpointPayload -}) - -pluginOutputData:SetPayload(response["body"]) -pluginOutputData:SetHttpStatusCode(response.status_code) + pluginOutputData:SetPayload(response["body"]) + pluginOutputData:SetHttpStatusCode(response.status_code) +end diff --git a/plugins/migrate-v1-plugin-to-v2.md b/plugins/migrate-v1-plugin-to-v2.md new file mode 100644 index 0000000..4512608 --- /dev/null +++ b/plugins/migrate-v1-plugin-to-v2.md @@ -0,0 +1,29 @@ +Migrating a plugin from version `1` to version `2` is really easy. + +* Change your plugin definition (`*.def`) file + and set the version to `2` +e.g: + +``` +endpoint: my-custom-send-endpoint/:number +method: POST +version: 2 +``` + +* Change your plugin script + and implement the `exec` (and optionally the `init`) functions. + +e.g: + +``` +function exec() + -- your plugin code goes here +end + +function init() + -- if your script needs some additional setup (e.g a sqlite database, a config file, etc) + -- the initialization can be done here. +end +``` + + diff --git a/plugins/persistence/README.md b/plugins/persistence/README.md new file mode 100644 index 0000000..5f9e3ff --- /dev/null +++ b/plugins/persistence/README.md @@ -0,0 +1,35 @@ +# Persistence Plugin + +Plugin which writes every received message to a sqlite3 database. + +## Howto enable this plugin + +* Download the `persist-message.def`, `persist-message.lua`, `query-message.def` and `query-message.lua` files and put them in a `plugins` folder on your filesystem +* Create a `persistence` folder on your host system. In this folder the docker container then creates the sqlite3 database. +* Adapt your `docker-compose.yml` to enable the plugin and map the required resources into the docker container + +``` +services: + signal-cli-rest-api: + image: bbernhard/signal-cli-rest-api:latest + environment: + - MODE=json-rpc #supported modes: json-rpc, native, normal (choose the mode you want; the plugin works with all modes) + - ENABLE_PLUGINS=true # enable plugins + - "./plugins:/plugins" #map "plugins" folder from the host system into the docker container + - "./persistence;/persistence" #map "persistence" folder from the host system into the docker container + - RECEIVE_WEBHOOK_URL=http://127.0.0.1:8080/v1/plugins/persistence/persist-message #register an internal webhook endpoint +``` +* Restart your docker container + +Every message that is received is then written to the `messages.db` inside the `persistence` folder. + +The stored messages can then be received via the REST API with: + +`curl -X GET 'http://127.0.0.1:8080/v1/plugins/persistence/query-message'` + +## Debugging and Troubleshooting + +* Make sure that the docker container has write permissions to the `persistence` folder +* On the host system, check if the `messages.db` gets created in the `persistence` folder +* Check the logs. Do you see any error? + diff --git a/plugins/persistence/persist-message.def b/plugins/persistence/persist-message.def new file mode 100644 index 0000000..047e374 --- /dev/null +++ b/plugins/persistence/persist-message.def @@ -0,0 +1,3 @@ +endpoint: persistence/persist-message +method: POST +version: 2 diff --git a/plugins/persistence/persist-message.lua b/plugins/persistence/persist-message.lua new file mode 100644 index 0000000..34f1c3d --- /dev/null +++ b/plugins/persistence/persist-message.lua @@ -0,0 +1,37 @@ +local http = require("http") +local json = require("json") +local sqlite = require("sqlite3").new(); + +function exec() + ok, err = sqlite:open("/persistence/messages.db", { cache = "shared", mode = "rw" }); + if ok then + local data = json.decode(pluginInputData.payload); + if data.params and data.params.envelope and data.params.envelope.dataMessage then + local strippedPayload = json.encode(data.params.envelope) + res, err = sqlite:exec("insert into messages(data) values(?)", strippedPayload) + if err == nil then + pluginOutputData:SetHttpStatusCode(200) + else + pluginOutputData:SetHttpStatusCode(400) + pluginOutputData:SetPayload("Couldn't persist data to sqlite db") + end + else + pluginOutputData:SetHttpStatusCode(200) + end + else + pluginOutputData:SetHttpStatusCode(400) + pluginOutputData:SetPayload("Couldn't persist data to sqlite db") + end +end + +function init() + ok, err = sqlite:open("/persistence/messages.db", { cache = "shared", mode = "rwc" }); + if ok then + res, err = sqlite:exec("create table if not exists messages (id INTEGER PRIMARY KEY, data json, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP)"); + if err ~= nil then + print(err) + return nil, err + end + end + return nil, nil +end diff --git a/plugins/persistence/query-message.def b/plugins/persistence/query-message.def new file mode 100644 index 0000000..00bbec5 --- /dev/null +++ b/plugins/persistence/query-message.def @@ -0,0 +1,3 @@ +endpoint: persistence/query-message +method: GET +version: 2 diff --git a/plugins/persistence/query-message.lua b/plugins/persistence/query-message.lua new file mode 100644 index 0000000..40e2542 --- /dev/null +++ b/plugins/persistence/query-message.lua @@ -0,0 +1,35 @@ +local http = require("http") +local json = require("json") +local sqlite = require("sqlite3").new(); + +function exec() + ok, err = sqlite:open("/persistence/messages.db", { cache = "shared", mode = "rw" }); + if ok then + res, err = sqlite:query("select data, timestamp from messages") + if err == nil then + for _, row in ipairs(res) do + row.data = json.decode(row.data) + end + pluginOutputData:SetPayload(json.encode(res)) + pluginOutputData:SetHttpStatusCode(200) + else + pluginOutputData:SetHttpStatusCode(400) + pluginOutputData:SetPayload("Couldn't query data from sqlite db") + end + else + pluginOutputData:SetHttpStatusCode(400) + pluginOutputData:SetPayload("Couldn't query data from sqlite db") + end +end + +function init() + ok, err = sqlite:open("/persistence/messages.db", { cache = "shared", mode = "rwc" }); + if ok then + res, err = sqlite:exec("create table if not exists messages (id INTEGER PRIMARY KEY, data json, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP)"); + if err ~= nil then + print(err) + return nil, err + end + end + return nil, nil +end diff --git a/src/go.mod b/src/go.mod index a348eed..9f5a509 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,6 +3,7 @@ module github.com/bbernhard/signal-cli-rest-api go 1.24.0 require ( + github.com/bbernhard/gluasql v0.2.0 github.com/cjoudrey/gluahttp v0.0.0-20201111170219-25003d9adfa9 github.com/cyphar/filepath-securejoin v0.2.4 github.com/gabriel-vasile/mimetype v1.4.8 @@ -17,13 +18,14 @@ require ( github.com/swaggo/gin-swagger v1.6.0 github.com/swaggo/swag v1.16.4 github.com/tidwall/sjson v1.2.5 - github.com/yuin/gopher-lua v1.1.1 + github.com/yuin/gopher-lua v1.1.2 gopkg.in/yaml.v2 v2.4.0 layeh.com/gopher-json v0.0.0-20201124131017-552bb3c4c3bf layeh.com/gopher-luar v1.0.11 ) require ( + filippo.io/edwards25519 v1.2.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/bytedance/sonic v1.12.8 // indirect github.com/bytedance/sonic/loader v0.2.3 // indirect @@ -36,13 +38,16 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.24.0 // indirect + github.com/go-sql-driver/mysql v1.10.0 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/junhsieh/goexamples v0.0.0-20210908032526-acdd3160140b // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-sqlite3 v1.14.44 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect diff --git a/src/main.go b/src/main.go index 2450496..ede0cc1 100644 --- a/src/main.go +++ b/src/main.go @@ -349,6 +349,18 @@ func main() { } for _, pluginConfig := range pluginConfigs.Configs { + if pluginConfig.Version > 1 { + err = pluginHandler.InitPlugin(pluginConfig) + if err != nil { + log.Error("Couldn't initialize plugin ", pluginConfig.Endpoint) + continue + } + } else { + log.Info("Plugin ", pluginConfig.Endpoint, " still uses plugin version 1. Consider migrating to version 2! (see https://github.com/bbernhard/signal-cli-rest-api/plugins/migrate-v1-plugin-to-v2.md)") + } + + log.Info("Registering plugin ", pluginConfig.Endpoint) + if pluginConfig.Method == "GET" { plugins.GET(pluginConfig.Endpoint, pluginHandler.ExecutePlugin(pluginConfig)) } else if pluginConfig.Method == "POST" { diff --git a/src/plugin_loader.go b/src/plugin_loader.go index fa11447..a4e1f40 100644 --- a/src/plugin_loader.go +++ b/src/plugin_loader.go @@ -1,27 +1,30 @@ package main import ( - "github.com/yuin/gopher-lua" - "github.com/cjoudrey/gluahttp" - "layeh.com/gopher-luar" - luajson "layeh.com/gopher-json" - "github.com/gin-gonic/gin" + "errors" "io" - log "github.com/sirupsen/logrus" - "github.com/bbernhard/signal-cli-rest-api/utils" - "github.com/bbernhard/signal-cli-rest-api/api" - "strings" "net/http" + "strings" + + gluasql "github.com/bbernhard/gluasql" + "github.com/bbernhard/signal-cli-rest-api/api" + "github.com/bbernhard/signal-cli-rest-api/utils" + "github.com/cjoudrey/gluahttp" + "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" + lua "github.com/yuin/gopher-lua" + luajson "layeh.com/gopher-json" + luar "layeh.com/gopher-luar" ) type PluginInputData struct { - Params map[string]string + Params map[string]string QueryParams map[string]string - Payload string + Payload string } type PluginOutputData struct { - payload string + payload string httpStatusCode int } @@ -41,7 +44,7 @@ func (p *PluginOutputData) HttpStatusCode() int { return p.httpStatusCode } -func execPlugin(c *gin.Context, pluginConfig utils.PluginConfig) { +func execPluginV1(c *gin.Context, pluginConfig utils.PluginConfig) { jsonData, err := io.ReadAll(c.Request.Body) if err != nil { c.JSON(400, api.Error{Msg: "Couldn't process request - invalid input data"}) @@ -50,13 +53,13 @@ func execPlugin(c *gin.Context, pluginConfig utils.PluginConfig) { } pluginInputData := &PluginInputData{ - Params: make(map[string]string), + Params: make(map[string]string), QueryParams: make(map[string]string), - Payload: string(jsonData), + Payload: string(jsonData), } pluginOutputData := &PluginOutputData{ - payload: "", + payload: "", httpStatusCode: 200, } @@ -78,8 +81,10 @@ func execPlugin(c *gin.Context, pluginConfig utils.PluginConfig) { l.SetGlobal("pluginOutputData", luar.New(l, pluginOutputData)) l.PreloadModule("http", gluahttp.NewHttpModule(&http.Client{}).Loader) luajson.Preload(l) + gluasql.Preload(l) defer l.Close() if err := l.DoFile(pluginConfig.ScriptPath); err != nil { + log.Error("Error executing lua script: ", err) c.JSON(400, api.Error{Msg: err.Error()}) return } @@ -87,16 +92,138 @@ func execPlugin(c *gin.Context, pluginConfig utils.PluginConfig) { c.JSON(pluginOutputData.HttpStatusCode(), pluginOutputData.Payload()) } +func execPluginV2(c *gin.Context, pluginConfig utils.PluginConfig) { + jsonData, err := io.ReadAll(c.Request.Body) + if err != nil { + c.JSON(400, api.Error{Msg: "Couldn't process request - invalid input data"}) + log.Error(err.Error()) + return + } + + pluginInputData := &PluginInputData{ + Params: make(map[string]string), + QueryParams: make(map[string]string), + Payload: string(jsonData), + } + + pluginOutputData := &PluginOutputData{ + payload: "", + httpStatusCode: 200, + } + + parts := strings.Split(pluginConfig.Endpoint, "/") + for _, part := range parts { + if strings.HasPrefix(part, ":") { + paramName := strings.TrimPrefix(part, ":") + pluginInputData.Params[paramName] = c.Param(paramName) + } + } + + queryParams := c.Request.URL.Query() + for key, values := range queryParams { + pluginInputData.QueryParams[key] = values[0] + } + + l := lua.NewState() + l.SetGlobal("pluginInputData", luar.New(l, pluginInputData)) + l.SetGlobal("pluginOutputData", luar.New(l, pluginOutputData)) + l.PreloadModule("http", gluahttp.NewHttpModule(&http.Client{}).Loader) + luajson.Preload(l) + gluasql.Preload(l) + defer l.Close() + if err := l.DoFile(pluginConfig.ScriptPath); err != nil { + log.Error("Error executing lua script: ", err) + c.JSON(400, api.Error{Msg: err.Error()}) + return + } + + // Get global "exec" + lv := l.GetGlobal("exec") + + // Check if it exists and is a function + if fn, ok := lv.(*lua.LFunction); ok { + err := l.CallByParam(lua.P{ + Fn: fn, + NRet: 1, // exec function returns one value + Protect: true, + }) + + if err != nil { + log.Error("Couldn't execute plugin: ", err.Error()) + c.JSON(400, "Couldn't execute plugin: "+err.Error()) + return + } + + ret := l.Get(-1) + l.Pop(1) + + if ret != lua.LNil { + log.Error("Couldn't execute plugin") + c.JSON(400, "Couldn't execute plugin") + } + c.Data( + pluginOutputData.HttpStatusCode(), + "application/json", + []byte(pluginOutputData.Payload()), + ) + } else { + log.Error("Couldn't execute plugin. No exec function implemented!") + c.JSON(400, "Couldn't execute plugin. No exec function implemented!") + } +} + type plugHandler struct { } func (p plugHandler) ExecutePlugin(pluginConfig utils.PluginConfig) gin.HandlerFunc { fn := func(c *gin.Context) { - execPlugin(c, pluginConfig) + if pluginConfig.Version == 1 { + execPluginV1(c, pluginConfig) + } else { + execPluginV2(c, pluginConfig) + } } return gin.HandlerFunc(fn) } -//exported +func (p plugHandler) InitPlugin(pluginConfig utils.PluginConfig) error { + l := lua.NewState() + l.PreloadModule("http", gluahttp.NewHttpModule(&http.Client{}).Loader) + luajson.Preload(l) + gluasql.Preload(l) + defer l.Close() + err := l.DoFile(pluginConfig.ScriptPath) + if err != nil { + log.Error("Error executing lua script: ", err) + } + + // Get global "init" + lv := l.GetGlobal("init") + + // Check if it exists and is a function + if fn, ok := lv.(*lua.LFunction); ok { + err := l.CallByParam(lua.P{ + Fn: fn, + NRet: 2, // init function returns two values + Protect: true, + }) + + if err != nil { + return err + } + + _ = l.Get(-2) + errVal := l.Get(-1) + l.Pop(2) + + if errVal != lua.LNil { + return errors.New("Couldn't initialize lua script: " + errVal.String()) + } + } + + return nil +} + +// exported var PluginHandler plugHandler diff --git a/src/utils/plugin_config.go b/src/utils/plugin_config.go index 5349216..e752b95 100644 --- a/src/utils/plugin_config.go +++ b/src/utils/plugin_config.go @@ -1,16 +1,18 @@ package utils import ( - "gopkg.in/yaml.v2" "io/ioutil" "os" "path/filepath" "strings" + + "gopkg.in/yaml.v2" ) type PluginConfig struct { Endpoint string `yaml:"endpoint"` Method string `yaml:"method"` + Version int `yaml:"version,omitempty"` ScriptPath string } @@ -40,6 +42,7 @@ func (c *PluginConfigs) Load(baseDirectory string) error { } var pluginConfig PluginConfig + pluginConfig.Version = 1 err = yaml.Unmarshal(data, &pluginConfig) if err != nil { return err diff --git a/src/utils/plugin_handler.go b/src/utils/plugin_handler.go index d2931b6..b432efd 100644 --- a/src/utils/plugin_handler.go +++ b/src/utils/plugin_handler.go @@ -6,4 +6,5 @@ import ( type PluginHandler interface { ExecutePlugin(pluginConfig PluginConfig) gin.HandlerFunc + InitPlugin(pluginConfig PluginConfig) error } From c8c461627f91fab1eaa6cd456e42c6be22086694 Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Sun, 24 May 2026 21:25:57 +0200 Subject: [PATCH 32/40] updated signal-cli to v0.14.4.1 --- Dockerfile | 4 ++-- src/{ => plugins}/plugin_loader.go | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename src/{ => plugins}/plugin_loader.go (100%) diff --git a/Dockerfile b/Dockerfile index 10bdf53..b1a1c52 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -ARG SIGNAL_CLI_VERSION=0.14.3 -ARG LIBSIGNAL_CLIENT_VERSION=0.92.1 +ARG SIGNAL_CLI_VERSION=0.14.4.1 +ARG LIBSIGNAL_CLIENT_VERSION=0.94.1 ARG SWAG_VERSION=1.16.4 diff --git a/src/plugin_loader.go b/src/plugins/plugin_loader.go similarity index 100% rename from src/plugin_loader.go rename to src/plugins/plugin_loader.go From 9a2e93a6fa7b5f03e3f7c3e442211e563514e7ed Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Sun, 24 May 2026 21:27:07 +0200 Subject: [PATCH 33/40] build json-schemas directly from the signal-cli source --- Dockerfile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index b1a1c52..41b3f81 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ RUN dpkg-reconfigure debconf --frontend=noninteractive \ && apt-get update \ && apt-get -y install --no-install-recommends \ wget git locales zip unzip \ - file build-essential libz-dev zlib1g-dev binutils \ + file build-essential libz-dev zlib1g-dev binutils openjdk-25-jdk \ && rm -rf /var/lib/apt/lists/* #COPY ext/libraries/libsignal-client/v${LIBSIGNAL_CLIENT_VERSION} /tmp/libsignal-client-libraries @@ -40,6 +40,11 @@ ENV JAVA_OPTS="-Djdk.lang.Process.launchMechanism=vfork" ENV LANG en_US.UTF-8 +RUN cd /tmp \ + && git clone https://github.com/AsamK/signal-cli.git --branch v${SIGNAL_CLI_VERSION} --single-branch signal-cli-source \ + && cd signal-cli-source \ + && ./gradlew jsonSchemas + RUN go install github.com/swaggo/swag/cmd/swag@v${SWAG_VERSION} RUN cd /tmp/ \ @@ -101,9 +106,7 @@ RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefau # manually add the json schemas for the receive V1 endpoint to the docs RUN cd /tmp/signal-cli-rest-api-src/docs \ - && wget https://github.com/Gara-Dorta/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz \ - && mkdir signal-cli-schemas \ - && tar xf signal-cli-${SIGNAL_CLI_VERSION}-json-schemas.tar.gz -C signal-cli-schemas \ + && cp -r /tmp/signal-cli-source/build/generated/META-INF/schemas signal-cli-schemas \ && go run add_v1_receive_schemas.go signal-cli-schemas # build signal-cli-rest-api From 99157a035fb46c27d31c3f8773bd30e511f23f9f Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Sun, 24 May 2026 23:44:21 +0200 Subject: [PATCH 34/40] renamed file --- src/{plugins => }/plugin_loader.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{plugins => }/plugin_loader.go (100%) diff --git a/src/plugins/plugin_loader.go b/src/plugin_loader.go similarity index 100% rename from src/plugins/plugin_loader.go rename to src/plugin_loader.go From 6b89035dd5322c451d122851111ac7baac0aad96 Mon Sep 17 00:00:00 2001 From: SAY-5 Date: Sun, 24 May 2026 16:21:46 -0700 Subject: [PATCH 35/40] fix: prevent slice out of range when attachment data starts with base64, Signed-off-by: SAY-5 --- src/client/attachment.go | 3 +++ src/client/attachment_test.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/client/attachment.go b/src/client/attachment.go index a51d902..5688506 100644 --- a/src/client/attachment.go +++ b/src/client/attachment.go @@ -44,6 +44,9 @@ func (attachmentEntry *AttachmentEntry) extractMetaData(attachmentData string) { } attachmentEntry.Base64 = attachmentData[base64FlagIndex+len("base64,"):] + if base64FlagIndex == 0 { + return + } metaDataKeys := map[string]string{ "data:": "MimeInfo", "filename=": "FileName", diff --git a/src/client/attachment_test.go b/src/client/attachment_test.go index 8e4e711..1482ad2 100644 --- a/src/client/attachment_test.go +++ b/src/client/attachment_test.go @@ -45,6 +45,9 @@ func Test_Attachment_ExtractMetadata_ShouldPrepareDataFor_toDataForSignal(t *tes { "-base64 +data +filename", "data:someData;filename=file.name;INVALIDMTIzNDU=", false, "data:someData;filename=file.name;INVALIDMTIzNDU=", false, "", "", "data:someData;filename=file.name;INVALIDMTIzNDU=", }, + { + "base64 prefix at start +data", "base64,data:someData", false, "data:someData", false, "", "", "data:someData", + }, } attachmentTmp := flag.String("attachment-tmp-dir", string(os.PathSeparator)+"tmp"+string(os.PathSeparator), "Attachment tmp directory") From 7d8f62a4bb19572f5bc2203aeeebc242c4b3c35d Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Mon, 25 May 2026 17:33:51 +0200 Subject: [PATCH 36/40] updated go.sum --- src/go.sum | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/go.sum b/src/go.sum index 5bb1df4..4e60dac 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,10 +1,16 @@ +filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= +filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/bbernhard/gluasql v0.2.0 h1:2UanAHDSbNQeWTr+utubePjItTOSVRE157zuC5rIl3g= +github.com/bbernhard/gluasql v0.2.0/go.mod h1:swUFFVYyknwnRX8bfeHaKtNLc1/oeWftlzvlBx8pW5Y= github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs= github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0= github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -18,6 +24,10 @@ github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dolthub/go-mysql-server v0.14.1-0.20230203234751-35092f80aa59 h1:puVbTWGX6h0pdi6J8n6dilweYk7jU8LElfw8yBxLHEk= +github.com/dolthub/go-mysql-server v0.14.1-0.20230203234751-35092f80aa59/go.mod h1:aVtgxAf6Bfs0hCj+KzIH7Y1aAxg7/7FlslouCh94VVQ= +github.com/dolthub/vitess v0.0.0-20230201234433-864c7d109df8 h1:h1DBe5+9JIArCVsBV14fA+RHDXWY8ynUheDL5ZVPOTg= +github.com/dolthub/vitess v0.0.0-20230201234433-864c7d109df8/go.mod h1:oVFIBdqMFEkt4Xz2fzFJBNtzKhDEjwdCF0dzde39iKs= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= @@ -26,6 +36,8 @@ github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= @@ -42,21 +54,35 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg= github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= +github.com/go-sql-driver/mysql v1.10.0 h1:Q+1LV8DkHJvSYAdR83XzuhDaTykuDx0l6fkXxoWCWfw= +github.com/go-sql-driver/mysql v1.10.0/go.mod h1:M+cqaI7+xxXGG9swrdeUIoPG3Y3KCkF0pZej+SK+nWk= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/gocraft/dbr/v2 v2.7.2 h1:ccUxMuz6RdZvD7VPhMRRMSS/ECF3gytPhPtcavjktHk= +github.com/gocraft/dbr/v2 v2.7.2/go.mod h1:5bCqyIXO5fYn3jEp/L06QF4K1siFdhxChMjdNu6YJrg= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/flatbuffers v2.0.6+incompatible h1:XHFReMv7nFFusa+CEokzWbzaYocKXI6C7hdU5Kgh9Lw= +github.com/google/flatbuffers v2.0.6+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/junhsieh/goexamples v0.0.0-20210908032526-acdd3160140b h1:9HQYGbaDnuRLMuM//SZVkZJ43ANmMStSAQAx4aQX3II= +github.com/junhsieh/goexamples v0.0.0-20210908032526-acdd3160140b/go.mod h1:JNqB8Da6SnlJvmZusESDfgqUkJXO6+/a1by1etsVJ2M= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= @@ -67,23 +93,35 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lestrrat-go/strftime v1.0.4 h1:T1Rb9EPkAhgxKqbcMIPguPq8glqXTA1koF8n9BHElA8= +github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.44 h1:3VSe+xafpbzsLbdr2AWlAZk9yRHiBhTBakioXaCKTF8= +github.com/mattn/go-sqlite3 v1.14.44/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ= +github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= +github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ= github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= @@ -122,8 +160,12 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= -github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= -github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +github.com/yuin/gopher-lua v1.1.2 h1:yF/FjE3hD65tBbt0VXLE13HWS9h34fdzJmrWRXwobGA= +github.com/yuin/gopher-lua v1.1.2/go.mod h1:7aRmXIWl37SqRf0koeyylBEzJ+aPt8A+mmkQ4f1ntR8= +go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= +go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= +go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4= golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -154,6 +196,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU= +golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -169,11 +213,17 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 h1:pl8qT5D+48655f14yDURpIZwSPvMWuuekfAP+gxtjvk= +google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/src-d/go-errors.v1 v1.0.0 h1:cooGdZnCjYbeS1zb1s6pVAAimTdKceRrpn7aKOnNIfc= +gopkg.in/src-d/go-errors.v1 v1.0.0/go.mod h1:q1cBlomlw2FnDBDNGlnh6X0jPihy+QxZfMMNxPCbdYg= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From d1a3956c8c2d994bf72ea7d8c39611c769fcf57c Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Mon, 25 May 2026 21:52:06 +0200 Subject: [PATCH 37/40] download gradle manually --- Dockerfile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 41b3f81..e9e71f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,9 +41,13 @@ ENV JAVA_OPTS="-Djdk.lang.Process.launchMechanism=vfork" ENV LANG en_US.UTF-8 RUN cd /tmp \ - && git clone https://github.com/AsamK/signal-cli.git --branch v${SIGNAL_CLI_VERSION} --single-branch signal-cli-source \ + && wget https://services.gradle.org/distributions/gradle-9.5.1-bin.zip \ + && unzip -d /opt/gradle gradle-9.5.1-bin.zip + +ENV PATH=$PATH:/opt/gradle/gradle-9.5.1/bin +RUN git clone https://github.com/AsamK/signal-cli.git --branch v${SIGNAL_CLI_VERSION} --single-branch signal-cli-source \ && cd signal-cli-source \ - && ./gradlew jsonSchemas + && /opt/gradle/gradle-9.5.1/bin/gradle jsonSchemas RUN go install github.com/swaggo/swag/cmd/swag@v${SWAG_VERSION} From 52d902cda42679416672135022ea0577f3952f2e Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Tue, 26 May 2026 22:11:26 +0200 Subject: [PATCH 38/40] temporary fix to get the build working again --- Dockerfile | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index e9e71f5..3366b78 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,14 +40,14 @@ ENV JAVA_OPTS="-Djdk.lang.Process.launchMechanism=vfork" ENV LANG en_US.UTF-8 -RUN cd /tmp \ - && wget https://services.gradle.org/distributions/gradle-9.5.1-bin.zip \ - && unzip -d /opt/gradle gradle-9.5.1-bin.zip - -ENV PATH=$PATH:/opt/gradle/gradle-9.5.1/bin -RUN git clone https://github.com/AsamK/signal-cli.git --branch v${SIGNAL_CLI_VERSION} --single-branch signal-cli-source \ +# building the jsonSchemas for armv7l unfortunately doesn't work, so as a temporary fix, do not build the json schema +# for armv7. should be removed as soon as https://github.com/AsamK/signal-cli/pull/2040 is merged +RUN if [ "$(uname -m)" != "armv7l" ]; then \ + cd /tmp \ + && git clone https://github.com/AsamK/signal-cli.git --branch v${SIGNAL_CLI_VERSION} --single-branch signal-cli-source \ && cd signal-cli-source \ - && /opt/gradle/gradle-9.5.1/bin/gradle jsonSchemas + && ./gradlew jsonSchemas; \ +fi; RUN go install github.com/swaggo/swag/cmd/swag@v${SWAG_VERSION} @@ -108,10 +108,15 @@ RUN ls -la /tmp/signal-cli-rest-api-src # build the docs RUN cd /tmp/signal-cli-rest-api-src && ${GOPATH}/bin/swag init --requiredByDefault --outputTypes "go,json" + # manually add the json schemas for the receive V1 endpoint to the docs -RUN cd /tmp/signal-cli-rest-api-src/docs \ +# (building the jsonSchemas for armv7l unfortunately doesn't work, so as a temporary fix, do not build the json schema +# for armv7. should be removed as soon as https://github.com/AsamK/signal-cli/pull/2040 is merged) +RUN if [ "$(uname -m)" != "armv7l" ]; then \ + cd /tmp/signal-cli-rest-api-src/docs \ && cp -r /tmp/signal-cli-source/build/generated/META-INF/schemas signal-cli-schemas \ - && go run add_v1_receive_schemas.go signal-cli-schemas + && go run add_v1_receive_schemas.go signal-cli-schemas; \ + fi; # build signal-cli-rest-api RUN cd /tmp/signal-cli-rest-api-src && go build -o signal-cli-rest-api main.go From 595e53d397425611fa3036110d4bec5b90072815 Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Wed, 27 May 2026 22:23:20 +0200 Subject: [PATCH 39/40] updated gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8da7d43..3380c9f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ signal-cli-config src/main src/signal-cli-rest-api .idea/ +./persistence From e6810926ca47d9e6aabfabcf0c8ef84304a38977 Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Thu, 28 May 2026 23:57:26 +0200 Subject: [PATCH 40/40] fixed bug in Dockerfile * make signal-cli-native binary executable --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3366b78..ab4058e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -59,12 +59,14 @@ RUN if [ "$(uname -m)" = "x86_64" ]; then \ cd /tmp \ && wget https://github.com/bbernhard/signal-cli-native-builds/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-native-v${SIGNAL_CLI_VERSION}.tar.gz \ && tar xvf signal-cli-native-v${SIGNAL_CLI_VERSION}.tar.gz \ - && cp signal-cli-native-v${SIGNAL_CLI_VERSION}/x86-64/signal-cli-native /tmp/signal-cli-native; \ + && cp signal-cli-native-v${SIGNAL_CLI_VERSION}/x86-64/signal-cli-native /tmp/signal-cli-native \ + && chmod +x /tmp/signal-cli-native; \ elif [ "$(uname -m)" = "aarch64" ] ; then \ cd /tmp \ && wget https://github.com/bbernhard/signal-cli-native-builds/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-native-v${SIGNAL_CLI_VERSION}.tar.gz \ && tar xvf signal-cli-native-v${SIGNAL_CLI_VERSION}.tar.gz \ - && cp signal-cli-native-v${SIGNAL_CLI_VERSION}/arm64/signal-cli-native /tmp/signal-cli-native; \ + && cp signal-cli-native-v${SIGNAL_CLI_VERSION}/arm64/signal-cli-native /tmp/signal-cli-native \ + && chmod +x /tmp/signal-cli-native; \ elif [ "$(uname -m)" = "armv7l" ] ; then \ echo "GRAALVM doesn't support 32bit" \ && echo "Creating temporary file, otherwise the below copy doesn't work for armv7" \