Skip to content

About

Publish to email, social and messaging platforms over SMS. RelaySMS Publisher receives end-to-end encrypted payloads by SMS, SMTP or HTTP, decrypts them and posts through platform adapters (Gmail, X, Telegram and more) using the user's stored OAuth2 or phone-based tokens.

Topics

Resources

Contributing

Stars

15 stars

Watchers

1 watching

Forks

Latest commit

 

History

758 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RelaySMS Publisher

Publishes to online platforms (Gmail, X, Telegram and more) from content sent by SMS, so people can post without an internet connection.

Contents

How it works

  1. A user links an account (Gmail, X, ...) through the gRPC API, which stores its token encrypted.
  2. Offline, the user's app encrypts the content and sends it by SMS to a gateway client: a phone number that relays SMS to this server.
  3. The payload arrives over REST, the Twilio webhook or SMTP and is queued.
  4. A Celery worker decrypts it and publishes it through the platform's adapter.

Requirements

  • Ubuntu 24.04 or Debian 13
  • Python 3.12 or newer
  • A database: SQLite (the default), MySQL 8.0.28 or newer, MariaDB, or PostgreSQL 12 or newer

The installer sets up everything else, including the system packages and Rust.

Install on a server

  1. Run the installer. It installs to /opt/relaysms/relaysms-publisher, generates the encryption keys and starts the services under systemd:

    curl -fsSL https://raw.githubusercontent.com/smswithoutborders/RelaySMS-Publisher/main/install.sh | sudo bash

    With no flags it asks about each option. To choose up front, pass flags after bash -s --:

    curl -fsSL https://raw.githubusercontent.com/smswithoutborders/RelaySMS-Publisher/main/install.sh | \
      sudo bash -s -- --site-name publisher.example.com --setup-db postgres
    Flag Does
    --site-name DOMAIN Puts nginx with a Let's Encrypt certificate in front; --skip-nginx skips it
    --setup-db mysql|postgres Installs the database server and writes its details to .env (details)
    --setup-broker rabbitmq Uses RabbitMQ instead of SQLite as the Celery broker, for heavier load (details)
    --setup-observability Adds SigNoz and Uptime Kuma (details)
    --install-dir PATH, --instance-name NAME Installs elsewhere, or a second copy on the same host (details)

    install.sh --help lists every flag.

  2. Go to the install directory and check the configuration:

    cd /opt/relaysms/relaysms-publisher
    sudo ./manage.sh check
  3. Create an administrator credential for the REST API:

    ./publisher.sh creds create --username ops --administrator

    [!IMPORTANT] The password is printed once. Store it before closing the terminal.

  4. Add the platform adapters you want to offer, then follow each adapter's README to configure it:

    ./publisher.sh platforms add https://github.com/smswithoutborders/gmail-oauth2-adapter
  5. Register the gateway clients that relay SMS to this server:

    ./publisher.sh gateway-clients create --msisdn +237123456789 --protocols https
  6. Check that the services are up:

    sudo ./manage.sh status
    curl http://127.0.0.1:16000/health

INSTALL.md covers installing by hand and every setting.

Manage the services

From the install directory:

Command Does
sudo ./manage.sh status Show each service's state
sudo ./manage.sh logs Follow the service logs
sudo ./manage.sh start, stop, restart Control every service together
sudo ./manage.sh enable, disable Start the services on boot, or stop doing so
sudo ./manage.sh update Pull the latest code, rebuild and restart; add --migrate when the release has migrations
sudo ./manage.sh migrate Apply database migrations
sudo ./manage.sh check Report every missing or invalid setting
sudo ./manage.sh nginx [DOMAIN] Re-render the nginx site and reattach or obtain its certificate
sudo ./manage.sh uninstall Remove the services and the install directory

See Service Management for log filters and what update and nginx do.

Run with Docker

  1. Clone the repository with its submodule:

    git clone --recurse-submodules https://github.com/smswithoutborders/RelaySMS-Publisher.git
    cd RelaySMS-Publisher
  2. Create .env with fresh encryption keys:

    cp template.env .env
    for key in DATABASE_ENCRYPTION_KEY DATABASE_FIELD_ENCRYPTION_KEY DATA_ENCRYPTION_KEY; do
      sed -i "s/^$key=$/$key=$(openssl rand -hex 32)/" .env
    done
  3. Build and start:

    docker compose up -d --build

The container applies pending migrations, then starts every service. It listens on PORT (16000) and GRPC_PORT (6000) from .env, and keeps its data in ./data.

Caution

Back up .env with ./data: its encryption keys are the only way to read the data.

Development

CONTRIBUTING.md walks through setting up, running the services locally, testing and making common changes. In short:

git clone --recurse-submodules https://github.com/smswithoutborders/RelaySMS-Publisher.git
cd RelaySMS-Publisher
python3 -m venv venv && source venv/bin/activate
pip install -r requirements-dev.txt
pre-commit install --install-hooks
make build

Then follow Run locally. To fill a local database with sample data:

python -m publisher seed stats --count 5000 --days 90   # publication stats
python -m publisher seed creds --count 5                # credentials; prints their passwords
python -m publisher seed platforms                      # adapter rows, without their files
python -m publisher seed gateway-clients --count 10     # gateway clients, some disabled

Configuration

Settings live in .env. template.env lists every setting with its default and what it does, and python -m publisher config check (or sudo ./manage.sh check on a server) reports any that are missing or invalid.

Settings Documented in
Server, database, encryption, Celery, adapters INSTALL.md
REST API login and sessions (AUTH_*) REST API
SMTP transport (SMTP_*) SMTP Transport
Twilio SMS transport (TWILIO_*) The comments in template.env
Tracing, metrics and logs (OTEL_*) Observability
Offline publishing (OFFLINE_PUBLISH_*) Below

Offline Publishing

Offline payloads are tagged with the protocol they arrived on: https for REST /publications, smtp for the SMTP transport and sms for the Twilio webhook.

OFFLINE_PUBLISH_ALLOWED_PROTOCOLS=smtp   # comma-separated; empty allows every protocol
OFFLINE_PUBLISH_SHARED_SECRET=           # 64-char hex; empty disables the check

Offline payloads from a protocol not in OFFLINE_PUBLISH_ALLOWED_PROTOCOLS are discarded. When OFFLINE_PUBLISH_SHARED_SECRET is set, offline payloads over https must carry it in the request's tag field.

Warning

https is unauthenticated, so anyone can send to it. The SMTP and Twilio listeners authenticate the sender (DKIM and an allowlist for smtp, Twilio's signature for sms), which is why template.env allows only smtp.

Platform adapters

Each platform is served by an adapter installed from its own repository. GET /v1/platforms lists the enabled ones.

docs/platforms.md covers adding, updating, disabling and removing adapters. Each adapter's README covers its own settings.

Gateway clients

Gateway clients are the phone numbers that relay SMS to this server. GET /v1/gateway-clients lists the enabled ones, and docs/gateway-clients.md covers managing them.

Credentials

Credentials log in to the REST API, each with its own scopes. One holding every scope is an administrator. They can also be managed over the REST API.

./publisher.sh creds scopes                                        # list scopes
./publisher.sh creds create --username ops --administrator         # prints the password once
./publisher.sh creds create --username analyst --scope stats:publications:read
./publisher.sh creds set-scopes --username analyst --scope stats:publications:read --scope stats:publications:reasons
./publisher.sh creds list
./publisher.sh creds reset-password --username analyst
./publisher.sh creds disable --username analyst
./publisher.sh creds enable --username analyst
./publisher.sh creds revoke-sessions --username analyst
./publisher.sh creds delete --username analyst

Documentation

License

Licensed under the GNU General Public License v3. See LICENSE.

About

Publish to email, social and messaging platforms over SMS. RelaySMS Publisher receives end-to-end encrypted payloads by SMS, SMTP or HTTP, decrypts them and posts through platform adapters (Gmail, X, Telegram and more) using the user's stored OAuth2 or phone-based tokens.

Topics

Resources

Contributing

Stars

15 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages