signal-cli-rest-api is a wrapper around signal-cli and allows you to interact with it through http requests

Overview

signal-cli-rest-api

signal-cli-rest-api is a wrapper around signal-cli and allows you to interact with it through http requests.

Features

  • register/verify/unregister a number
  • send messages to multiple users/a group with one or multiple attachments
  • receive messages (with attachments)
  • block/unblock users and groups
  • link to existing device
  • list/create/update/leave groups
  • update profile (name/avatar)

To-Do

  • integrate dbus daemon for faster sending
  • authentication

Installation

pip

If you install signal-cli-rest-api through pip you need to manually install signal-cli on your system.

# by default the app will look for the signal config files in ~/.local/share/signal-cli
# you can change the directory by setting the SIGNAL_CONFIG_PATH env var to the desired path
# e.g. export SIGNAL_CONFIG_PATH=/opt/signal
pip install signal-cli-rest-api
uvicorn signal_cli_rest_api.app.main:app --host 0.0.0.0 --port 8000

Docker

export SIGNAL_DATA_DIR=~/signal/
docker run --name signal --restart unless-stopped -p 8000:8000 -v $SIGNAL_DATA_DIR:/root/.local/share/signal-cli sebastiannoelluebke/signal-cli-rest-api

docker-compose

git clone https://github.com/SebastianLuebke/signal-cli-rest-api.git
cd signal-cli-rest-api
# docker-compose build
docker-compose up -d

Security Notice

signal-cli-rest-api doesn't have any authentication for now. Everyone who knows the service address+port and the number is able to get your messages and send messages. So only use it a trusted environment and block external access.

Interactive Documentation

After installing signal-cli-rest-api start it and open the following page http://localhost:8000/docs

Comments
  • Cannot install through pip method

    Cannot install through pip method

    I say: pip install signal-cli-rest-api, and got an error:

    Collecting signal-cli-rest-api
      Could not find a version that satisfies the requirement signal-cli-rest-api (from versions: )
    No matching distribution found for signal-cli-rest-api
    
    

    OS is Debian Buster, 64-bit.

    opened by MatejKovacic 7
  • Captcha request on /register/{number}/

    Captcha request on /register/{number}/

    When running registration like this (with a random number)

    curl -X 'POST' \
      'http://localhost:8000/register/%2B49080500' \
      -H 'accept: application/json' \
      -H 'Content-Type: application/json' \
      -d '{
      "voice_verification": true
    }'
    

    I am getting the following error:

    {
      "detail": "Starting signal-cli process failed: Captcha required for verification, use --captcha CAPTCHA\nTo get the token, go to https://signalcaptchas.org/registration/generate.html\nCheck the developer tools (F12) console for a failed redirect to signalcaptcha://\nEverything after signalcaptcha:// is the captcha token.\n"
    }
    

    Before I start poking around, maybe I am missing an obvious step? Is the captcha functionality already built into this wrapper?

    Btw, If this is an easy one, I would be happy to add documentation.

    opened by top-on 5
  • link device: newline character in QR code

    link device: newline character in QR code

    A newline character causes the QR code for device linking to be faulty. I am not providing a PR as I am unsure whether this can be safely escaped in run_signal_cli_command without affecting other functions, or if it should be done in link_device.

    bug 
    opened by kahrpatrick 5
  • Escape strings in shell command

    Escape strings in shell command

    This PR escapes all strings that are passed to the signal-cli shell command in order to prevent shell injections. It uses a function from the shlex libary that provides

    ... a shell-escaped version of the string s. The returned value is a string that can safely be used as one token in a shell command line, for cases where you cannot use a list. [https://docs.python.org/3/library/shlex.html#shlex.quote]

    I could not yet test all the commands for possible issues with the escaping.

    opened by kahrpatrick 2
  • 500 Internal Server Error during POST to /register

    500 Internal Server Error during POST to /register

    I'm using the workaround fix that is mentioned here

    and have updated the schema/register.py and endpoint/register.py files as per the changes a couple days ago (Fixed Captcha).

    I'm getting the following when trying to register a number: INFO: 192.168.0.117:56688 - "POST /register/xxx HTTP/1.1" 500 Internal Server Error (I replaced my phone # +1231231234 with xxx) and {"detail":"Starting signal-cli process failed: OpenJDK Server VM warning: You have loaded library /tmp/resource1973025829374288195.so which might have disabled stack guard. The VM will try to fix the stack guard now.\nIt's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.\nWARN App - WARNING: Support for new group V2 is disabled, because the required native library dependency is missing: libzkgroup\nMissing required native library dependency: libsignal-client\n"}

    signal-cli 
    opened by stygarfield 2
  • Cleanup

    Cleanup

    how about these small housekeeping commits? @SebastianLuebke, hope this goes into the right direction for you. feedback & change requests are welcome.

    opened by top-on 1
  • Error code 500

    Error code 500 "Internal Server Error"

    I got below error code 500 "Internal Server Error" Is there any guidance?

    INFO: 127.0.0.1:53539 - "POST /messages/00966546462471 HTTP/1.1" 500 Internal Server Error ERROR: Exception in ASGI application Traceback (most recent call last): File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\uvicorn-0.11.8-py3.7.egg\uvicorn\protocols\http\h11_impl.py", line 388, in run_asgi result = await app(self.scope, self.receive, self.send) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\uvicorn-0.11.8-py3.7.egg\uvicorn\middleware\proxy_headers.py", line 45, in __call__ return await self.app(scope, receive, send) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\fastapi-0.58.1-py3.7.egg\fastapi\applications.py", line 171, in __call__ await super().__call__(scope, receive, send) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\starlette-0.13.4-py3.7.egg\starlette\applications.py", line 102, in __call__ await self.middleware_stack(scope, receive, send) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\starlette-0.13.4-py3.7.egg\starlette\middleware\errors.py", line 181, in __call__ raise exc from None File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\starlette-0.13.4-py3.7.egg\starlette\middleware\errors.py", line 159, in __call__ await self.app(scope, receive, _send) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\starlette-0.13.4-py3.7.egg\starlette\exceptions.py", line 82, in __call__ raise exc from None File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\starlette-0.13.4-py3.7.egg\starlette\exceptions.py", line 71, in __call__ await self.app(scope, receive, sender) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\starlette-0.13.4-py3.7.egg\starlette\routing.py", line 550, in __call__ await route.handle(scope, receive, send) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\starlette-0.13.4-py3.7.egg\starlette\routing.py", line 227, in handle await self.app(scope, receive, send) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\starlette-0.13.4-py3.7.egg\starlette\routing.py", line 41, in app response = await func(request) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\fastapi-0.58.1-py3.7.egg\fastapi\routing.py", line 197, in app dependant=dependant, values=values, is_coroutine=is_coroutine File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\fastapi-0.58.1-py3.7.egg\fastapi\routing.py", line 147, in run_endpoint_function return await dependant.call(**values) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\signal_cli_rest_api-0.1.97-py3.7.egg\signal_cli_rest_api\app\api\api_v1\endpoints\messages.py", line 50, in send_message response = await run_signal_cli_command(cmd) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\site-packages\signal_cli_rest_api-0.1.97-py3.7.egg\signal_cli_rest_api\app\utils.py", line 73, in run_signal_cli_command process = await asyncio.subprocess.create_subprocess_shell(full_cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\asyncio\subprocess.py", line 202, in create_subprocess_shell stderr=stderr, **kwds) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 1510, in subprocess_shell protocol, cmd, True, stdin, stdout, stderr, bufsize, **kwargs) File "C:\Users\Admin\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 462, in _make_subprocess_transport raise NotImplementedError NotImplementedError

    opened by tamerplc 1
  • missing groupID for group messages

    missing groupID for group messages

    The send_message method of the messages endpoint does not append the groupID for group messages, resulting in an error when an API call with group: true is made. In fact, this field is also missing in the MessageOutgoing schema.

    This is the relevant section from the signal-cli man-page:

    -g GROUP, --group GROUP

    Specify the recipient group ID in base64 encoding.

    opened by kahrpatrick 1
  • [BugFix] Remove isReceipt from Envelope Validator

    [BugFix] Remove isReceipt from Envelope Validator

    On signal-cli 0.8.1, incomming message doesn't containt any isReceipt key in the JSON response, so when validating the schemas it resulting in following error:

     raise ValidationError(errors, field.type_)
    pydantic.error_wrappers.ValidationError: 1 validation error for MessageIncoming
    response -> 0 -> envelope -> isReceipt
      field required (type=value_error.missing)
    

    Here is the complete example of "new" JSON response in incomming message:

    {
    	"envelope": {
    		"source": "+6217081945001",
    		"sourceDevice": 1,
    		"timestamp": 1619484875616,
    		"dataMessage": {
    			"timestamp": 1619484875616,
    			"message": "Pray for Nanggala 402",
    			"expiresInSeconds": 0,
    			"viewOnce": false,
    			"mentions": [],
    			"attachments": [],
    			"contacts": []
    		}
    	}
    }
    

    Applied fix, we remove the isReceipt key from envelope schemas validator.

    opened by NarinLab 0
  • [BugFix] --json option has been deprecated

    [BugFix] --json option has been deprecated

    When received message, parameter error occured resulting in 500 Server Error.

      "detail": "Starting signal-cli process failed: WARN ReceiveCommand - \"--json\" option has been deprecated, please use the global \"--output=json\" instead.\n"
    }
    

    Patch apllied to messages.py, changing the --json parameter into new --output=json and ajusting the parameter position.

    opened by NarinLab 0
  • Update to V2 groups

    Update to V2 groups

    In version 0.7.0 signal-cli introduced support for V2 groups. This requires some native libraries that are compiled against glibc. This PR (again) changes the base image of the Dockerfile to make this work. In addition, the container now runs as unprivileged user.

    Changes in this PR:

    • update to latest signal-cli release
    • run as unprivileged user
    • install poetry via pip

    Breaking changes:

    • update mount path for persistent signal-cli volume to /srv/signal/.local/share/signal-cli
    opened by kahrpatrick 0
  • Bump fastapi from 0.58.1 to 0.65.2

    Bump fastapi from 0.58.1 to 0.65.2

    Bumps fastapi from 0.58.1 to 0.65.2.

    Release notes

    Sourced from fastapi's releases.

    0.65.2

    Security fixes

    This change fixes a CSRF security vulnerability when using cookies for authentication in path operations with JSON payloads sent by browsers.

    In versions lower than 0.65.2, FastAPI would try to read the request payload as JSON even if the content-type header sent was not set to application/json or a compatible JSON media type (e.g. application/geo+json).

    So, a request with a content type of text/plain containing JSON data would be accepted and the JSON data would be extracted.

    But requests with content type text/plain are exempt from CORS preflights, for being considered Simple requests. So, the browser would execute them right away including cookies, and the text content could be a JSON string that would be parsed and accepted by the FastAPI application.

    See CVE-2021-32677 for more details.

    Thanks to Dima Boger for the security report! 🙇🔒

    Internal

    0.65.1

    Security fixes

    0.65.0

    Breaking Changes - Upgrade

    • ⬆️ Upgrade Starlette to 0.14.2, including internal UJSONResponse migrated from Starlette. This includes several bug fixes and features from Starlette. PR #2335 by @​hanneskuettner.

    Translations

    Internal

    0.64.0

    Features

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Got 500 internal error

    Got 500 internal error

    Hello, everytime I try to get /message, I have an internal 500 error:

    500 Internal Server Error ERROR: Exception in ASGI application Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 390, in run_asgi result = await app(self.scope, self.receive, self.send) File "/usr/local/lib/python3.8/dist-packages/uvicorn/middleware/proxy_headers.py", line 45, in call return await self.app(scope, receive, send) File "/usr/local/lib/python3.8/dist-packages/fastapi/applications.py", line 171, in call await super().call(scope, receive, send) File "/usr/local/lib/python3.8/dist-packages/starlette/applications.py", line 102, in call await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.8/dist-packages/starlette/middleware/errors.py", line 181, in call raise exc from None File "/usr/local/lib/python3.8/dist-packages/starlette/middleware/errors.py", line 159, in call await self.app(scope, receive, _send) File "/usr/local/lib/python3.8/dist-packages/starlette/exceptions.py", line 82, in call raise exc from None File "/usr/local/lib/python3.8/dist-packages/starlette/exceptions.py", line 71, in call await self.app(scope, receive, sender) File "/usr/local/lib/python3.8/dist-packages/starlette/routing.py", line 550, in call await route.handle(scope, receive, send) File "/usr/local/lib/python3.8/dist-packages/starlette/routing.py", line 227, in handle await self.app(scope, receive, send) File "/usr/local/lib/python3.8/dist-packages/starlette/routing.py", line 41, in app response = await func(request) File "/usr/local/lib/python3.8/dist-packages/fastapi/routing.py", line 196, in app raw_response = await run_endpoint_function( File "/usr/local/lib/python3.8/dist-packages/fastapi/routing.py", line 149, in run_endpoint_function return await run_in_threadpool(dependant.call, **values) File "/usr/local/lib/python3.8/dist-packages/starlette/concurrency.py", line 34, in run_in_threadpool return await loop.run_in_executor(None, func, *args) File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/usr/local/lib/python3.8/dist-packages/signal_cli_rest_api/app/api/api_v1/endpoints/messages.py", line 24, in get_messages return [json.loads(m) for m in response.split("\n") if m != ""] AttributeError: 'coroutine' object has no attribute 'split' /usr/local/lib/python3.8/dist-packages/uvicorn/main.py:390: RuntimeWarning: coroutine 'run_signal_cli_command' was never awaited loop.run_until_complete(self.serve(sockets=sockets)) RuntimeWarning: Enable tracemalloc to get the object allocation traceback

    opened by PimpMySocial 2
Owner
Sebastian Noel Lübke
Sebastian Noel Lübke
Backend, modern REST API for obtaining match and odds data crawled from multiple sites. Using FastAPI, MongoDB as database, Motor as async MongoDB client, Scrapy as crawler and Docker.

Introduction Apiestas is a project composed of a backend powered by the awesome framework FastAPI and a crawler powered by Scrapy. This project has fo

Fran Lozano 54 Dec 13, 2022
REST API with FastAPI and SQLite3.

REST API with FastAPI and SQLite3

Luis Quiñones Requelme 2 Mar 14, 2022
Publish Xarray Datasets via a REST API.

Xpublish Publish Xarray Datasets via a REST API. Serverside: Publish a Xarray Dataset through a rest API ds.rest.serve(host="0.0.0.0", port=9000) Clie

xarray-contrib 106 Jan 6, 2023
All of the ad-hoc things you're doing to manage incidents today, done for you, and much more!

About What's Dispatch? Put simply, Dispatch is: All of the ad-hoc things you’re doing to manage incidents today, done for you, and a bunch of other th

Netflix, Inc. 3.7k Jan 5, 2023
ReST based network device broker

The Open API Platform for Network Devices netpalm makes it easy to push and pull state from your apps to your network by providing multiple southbound

null 368 Dec 31, 2022
[rewrite 중] 코로나바이러스감염증-19(COVID-19)의 국내/국외 발생 동향 조회 API | Coronavirus Infectious Disease-19 (COVID-19) outbreak trend inquiry API

COVID-19API 코로나 바이러스 감염증-19(COVID-19, SARS-CoV-2)의 국내/외 발생 동향 조회 API Corona Virus Infectious Disease-19 (COVID-19, SARS-CoV-2) outbreak trend inquiry

Euiseo Cha 28 Oct 29, 2022
API & Webapp to answer questions about COVID-19. Using NLP (Question Answering) and trusted data sources.

This open source project serves two purposes. Collection and evaluation of a Question Answering dataset to improve existing QA/search methods - COVID-

deepset 329 Nov 10, 2022
Deploy an inference API on AWS (EC2) using FastAPI Docker and Github Actions

Deploy an inference API on AWS (EC2) using FastAPI Docker and Github Actions To learn more about this project: medium blog post The goal of this proje

Ahmed BESBES 60 Dec 17, 2022
api versioning for fastapi web applications

fastapi-versioning api versioning for fastapi web applications Installation pip install fastapi-versioning Examples from fastapi import FastAPI from f

Dean Way 472 Jan 2, 2023
This is a FastAPI application that provides a RESTful API for the Podcasts from different podcast's RSS feeds

The Podcaster API This is a FastAPI application that provides a RESTful API for the Podcasts from different podcast's RSS feeds. The API response is i

Sagar Giri 2 Nov 7, 2021
A Nepali Dictionary API made using FastAPI.

Nepali Dictionary API A Nepali dictionary api created using Fast API and inspired from https://github.com/nirooj56/Nepdict. You can say this is just t

Nishant Sapkota 4 Mar 18, 2022
Twitter API with fastAPI

Twitter API with fastAPI Content Forms Cookies and headers management Files edition Status codes HTTPExceptions Docstrings or documentation Deprecate

Juan Agustin Di Pasquo 1 Dec 21, 2021
First API using FastApi

First API using FastApi Made this Simple Api to store and Retrive Student Data of My College Ncc-Bim To View All the endpoits Visit /docs To Run Local

Sameer Joshi 2 Jun 21, 2022
Mnist API server w/ FastAPI

Mnist API server w/ FastAPI

Jinwoo Park (Curt) 8 Feb 8, 2022
Minimal example utilizing fastapi and celery with RabbitMQ for task queue, Redis for celery backend and flower for monitoring the celery tasks.

FastAPI with Celery Minimal example utilizing FastAPI and Celery with RabbitMQ for task queue, Redis for Celery backend and flower for monitoring the

Grega Vrbančič 371 Jan 1, 2023
Social Distancing Detector using deep learning and capable to run on edge AI devices such as NVIDIA Jetson, Google Coral, and more.

Smart Social Distancing Smart Social Distancing Introduction Getting Started Prerequisites Usage Processor Optional Parameters Configuring AWS credent

Neuralet 129 Dec 12, 2022
Example app using FastAPI and JWT

FastAPI-Auth Example app using FastAPI and JWT virtualenv -p python3 venv source venv/bin/activate pip3 install -r requirements.txt mv config.yaml.exa

Sander 28 Oct 25, 2022
Web Inventory tool, takes screenshots of webpages using Pyppeteer (headless Chrome/Chromium) and provides some extra bells & whistles to make life easier.

WitnessMe WitnessMe is primarily a Web Inventory tool inspired by Eyewitness, its also written to be extensible allowing you to create custom function

byt3bl33d3r 648 Jan 5, 2023
Backend Skeleton using FastAPI and Sqlalchemy ORM

Backend API Skeleton Based on @tiangolo's full stack postgres template, with some things added, some things removed, and some things changed. This is

David Montague 18 Oct 31, 2022