Skip to content

Repository files navigation

Contributors Forks Stargazers Issues Apache-2.0 License


SMSGate CLI

A command-line interface for interacting with the SMSGate API
Explore the docs »

Report Bug · Request Feature

About The Project

There are two CLI tools in this repository:

  • smsgate -- Interact with the SMS Gateway for Android API to send SMS/MMS messages, manage webhooks, and retrieve logs.
  • smsgate-ca -- Issue TLS certificates for private deployments (webhook receivers and private servers on RFC 1918 addresses).

Built With

  • Go
  • Goreleaser

(back to top)

Getting Started

Prerequisites

  • Go 1.25+ (for building from source)
  • Docker (optional, for containerized execution)

Installation

Option 1: Download from GitHub Releases

  1. Go to the Releases page of this repository.
  2. Download the appropriate binary for your operating system and architecture.
  3. Extract the archive to a directory of your choice.
  4. Move the binary to a directory in your system's PATH.

Option 2: Install using Go

go install github.com/android-sms-gateway/cli/cmd/smsgate@latest

This will download, compile, and install the latest version of the CLI tool. Make sure your Go bin directory is in your system's PATH.

Option 3: Docker

docker run -it --rm --env-file .env ghcr.io/android-sms-gateway/cli \
  send --phone '+12025550123' 'Hello, Dr. Turk!'

(back to top)

Configuration

The CLI can be configured using environment variables or command-line flags. You can also use a .env file in the working directory to set these variables (loaded automatically via godotenv).

Available Options

Option Env Var Description Default value
--endpoint, -e ASG_ENDPOINT The endpoint URL https://api.sms-gate.app/3rdparty/v1
--username, -u ASG_USERNAME Your username required
--password, -p ASG_PASSWORD Your password required
--format, -f n/a Output format text

Output Formats

The CLI supports four output formats:

  1. text: Human-readable text output (default)
  2. json: Pretty printed JSON-formatted output
  3. raw: One-line JSON-formatted output
  4. table: Tab-aligned columnar output for lists and sub-tables

Please note that when the exit code is not 0, the error description is printed to stderr without any formatting.

(back to top)

Usage

smsgate [global options] command [command options] [arguments...]

Commands

The CLI offers three main groups of commands:

  • Messages: Commands for sending SMS, MMS, and data messages, and checking their status, including batch operations from CSV and Excel files.
  • Webhooks: Commands for managing webhooks, including registering, listing, and deleting them.
  • Logs: Commands for retrieving logs for a specific time range.

For a complete list of available commands, you can:

  • Run smsgate help or smsgate --help in your terminal.
  • Visit the official documentation at docs.sms-gate.app.

Exit codes

The CLI uses exit codes to indicate the outcome of operations:

  • 0: success
  • 1: invalid options or arguments
  • 2: server request error
  • 3: output formatting error
  • 4: internal error

Examples

For security reasons, it is recommended to pass credentials using environment variables or a .env file.

Credentials can also be passed via CLI options:

smsgate -u <username> -p <password> send --phones '+12025550123' 'Hello, Dr. Turk!'

Sending messages

The send command supports various options to customize message delivery:

# Send a simple text message
smsgate send --phones '+12025550123' 'Hello, Dr. Turk!'

# Send to multiple numbers
smsgate send --phones '+12025550123' --phones '+12025550124' 'Hello, doctors!'
# or
smsgate send --phones '+12025550123,+12025550124' 'Hello, doctors!'

# Send with explicit device selection
smsgate send --phones '+12025550123' --device-id device123 'Message'

# Send with SIM number selection (1-based)
smsgate send --phones '+12025550123' --sim-number 2 'Message'

# Send with priority (>=100 bypasses limits)
smsgate send --phones '+12025550123' --priority 100 'Urgent message'

# Send with time-to-live (TTL)
smsgate send --phones '+12025550123' --ttl 1h30m 'Expiring message'

# Send with expiration date (RFC3339 format)
smsgate send --phones '+12025550123' --valid-until '2026-12-31T23:59:59Z' 'Message'

# Disable delivery report
smsgate send --phones '+12025550123' --delivery-report=false 'Message'

# Skip phone number validation
smsgate send --phones '+12025550123' --skip-phone-validation 'Message'

# Filter by device activity (devices active within last 12 hours)
smsgate send --phones '+12025550123' --device-active-within 12 'Message'

# Send data message (base64 encoded)
echo -n 'hello world' | base64
smsgate send --phones '+12025550123' --data --data-port 12345 'aGVsbG8gd29ybGQ='

# Send MMS with subject and multiple attachments
smsgate send --mms --subject 'Project update' --phones '+12025550123' \
  --attachment /path/to/report.pdf \
  --attachment /path/to/chart.png \
  'Here are the latest documents'

# Send MMS with attachments only (no text)
smsgate send --mms --phones '+12025550123' \
  --attachment /path/to/photo.jpg

# Send MMS to multiple recipients
smsgate send --mms --phones '+12025550123' --phones '+12025550124' \
  --subject 'Team update' --attachment /path/to/screenshot.png \
  'Please review'

Notes:

  • --data and --mms are mutually exclusive.
  • At least one of text or an attachment is required for MMS.
  • MIME type is detected from the file extension (falls back to application/octet-stream).

Send command options:

Option Description Default Value Example
--id A unique message ID. If not provided, one will be automatically generated. empty zXDYfTmTVf3iMd16zzdBj
--device-id, --device Optional device ID for explicit selection. If not provided, a random device will be selected. empty oi2i20J8xVP1ct5neqGZt
--phones, --phone, -p Specifies the recipient's phone number(s). This option can be used multiple times or accepts comma-separated values. Numbers must be in E.164 format. required +12025550123
--sim-number, --sim The one-based SIM card slot number. If not specified, the device's SIM rotation feature will be used. empty 2
--delivery-report Enables delivery report for the message. true true / false
--priority Sets the priority of the message. Messages with priority >= 100 bypass all limits and delays. Range: -128 to 127. 0 100
Data Message
--data Send data message instead of text (content must be base64 encoded). false true
--data-port Destination port for data message (1 to 65535). 53739 12345
MMS Message
--mms Send MMS message instead of text; text is optional when at least one attachment is provided. false true
--subject MMS subject line. Requires --mms. empty Photo update
--attachment Path to an attachment file. Repeatable; MIME type is detected from the file extension. Requires --mms. empty /path/to/image.jpg
Options
--ttl Time-to-live (TTL) for the message. Duration format (e.g., 1h30m). If not provided, the message will not expire.
Conflicts with --valid-until.
empty 1h30m
--valid-until The expiration date and time for the message. RFC3339 format (e.g., 2006-01-02T15:04:05Z07:00).
Conflicts with --ttl.
empty 2026-12-31T23:59:59Z
--skip-phone-validation Skip phone number validation. false true
--device-active-within Time window in hours for device activity filtering. 0 means no filtering. 0 12
--schedule-at Schedule delivery time (RFC3339 format). If not provided, the message is sent immediately.
Example: 2026-12-31T23:59:59Z.
immediate 2026-12-31T23:59:59Z

Batch message sending

The CLI supports sending messages in bulk from CSV and Excel files. The batch send command also supports the shared delivery/device options from send (such as --device-id, --sim-number, --priority, --ttl, --valid-until, --delivery-report, --skip-phone-validation, --device-active-within), allowing fine-grained control over each message in the batch.

Supported file formats:

  • CSV (Comma-Separated Values)
  • XLSX (Excel files)

Basic usage:

# Send messages from a CSV file
smsgate batch send contacts.csv --map phone=Phone,text=Message

# Send messages from an Excel file with specific sheet
smsgate batch send campaign.xlsx --sheet Sheet1 --map phone=Phone,text=Message

# Send with custom delimiter and no header
smsgate batch send data.csv --delimiter ';' --header=false --map phone=col_1,text=col_2

Batch-specific options:

Option Description Default Value Example
--sheet Sheet name (defaults to first sheet) empty Sheet1
--delimiter CSV delimiter character , ;
--header Treat first row as header true false
--map Column mapping (required) required phone=Phone,text=Message
--dry-run Validate and print normalized rows without sending false true
--validate-only Validate input only (no preview, no sending) false true
--concurrency Number of concurrent send workers CPU cores 5
--continue-on-error Continue sending after per-row failures false true

Inherited message options: The shared delivery/device options from the send command are also available (e.g., --device-id, --sim-number, --priority, --ttl, --valid-until, --delivery-report, --skip-phone-validation, --device-active-within). These apply to every message sent in the batch.

Column mapping:

The --map option defines how columns in your file map to message fields:

Field Required Description
phone ✅ Phone number column
text ✅ Message text column
id ❌ Message ID column (UUID generated when empty)
device_id ❌ Device identifier column
sim_number ❌ SIM number column (1-255)
priority ❌ Message priority column (-128 to 127)

Mapping examples:

# Basic mapping with headers
smsgate batch send --map phone=Phone,text=Message contacts.csv

# Excel file with specific sheet
smsgate batch send --sheet Sheet1 --map phone=Phone,text=Message campaign.xlsx

# No headers, column positions
smsgate batch send --header=false --map phone=col_1,text=col_2 data.csv

# Full mapping with optional fields
smsgate batch send --map phone=Phone,text=Message,device_id=Device,sim_number=SIM,priority=Priority contacts.csv

File format examples:

CSV with Headers:

Phone,Message,Device,Priority
+12025550123,"Hello Dr. Turk!",device1,1
+12025550124,"Hello Dr. Smith!",device1,2
+12025550125,"Hello Dr. Jones!",device2,1

CSV without Headers:

+12025550123,"Hello Dr. Turk!",device1,1
+12025550124,"Hello Dr. Smith!",device1,2
+12025550125,"Hello Dr. Jones!",device2,1

Excel Files:

  • Supports multiple sheets (use --sheet to specify)
  • First row treated as headers by default
  • Column mapping works the same as CSV

Workflow modes:

  1. Validation Only - Validates file format and column mapping, checks required fields, exits without sending:

    smsgate batch send --map phone=Phone,text=Message --validate-only contacts.csv
  2. Dry Run - Validates and processes all rows, shows what would be sent without actually sending:

    smsgate batch send --map phone=Phone,text=Message --dry-run contacts.csv
  3. Full Send - Sends all messages with real-time progress:

    smsgate batch send --map phone=Phone,text=Message --concurrency=5 contacts.csv

Output and error handling:

  • Summary: Batch send summary: total=100 enqueued=95 failed=3 skipped=2
  • Real-time progress: Shows each message's UUID and state during sending
  • Error handling: By default stops on first error; use --continue-on-error to send all rows even if some fail

Best practices:

  1. Always use --dry-run or --validate-only first to test your configuration
  2. Ensure phone numbers are in E.164 format
  3. Start with lower concurrency values and increase as needed
  4. Use --continue-on-error for non-critical bulk sends
  5. Combine with inherited message options (e.g., --device-id, --priority) for advanced scenarios

Getting message status

# Get the status of a sent message
smsgate status zXDYfTmTVf3iMd16zzdBj

Managing webhooks

# Register a webhook for SMS received events
smsgate webhooks register -e sms:received https://example.com/webhook

# Register a device-specific webhook
smsgate webhooks register -e sms:sent --device-id device123 https://example.com/webhook

# List all registered webhooks
smsgate webhooks list

# Delete a webhook by ID
smsgate webhooks delete <webhook-id>

Supported webhook events: sms:received, sms:sent, sms:failed, device:connected, device:disconnected

Getting logs

The logs command retrieves logs for a specific time range. Dates should be in RFC3339 format (e.g., 2024-01-15T10:30:00Z).

# Get logs for the last 24 hours (default)
smsgate logs

# Get logs for a specific time range
smsgate logs --from '2024-01-15T00:00:00Z' --to '2024-01-15T23:59:59Z'

# Get logs with custom time range and output format
smsgate --format json logs --from '2024-01-15T10:00:00+07:00' --to '2024-01-15T18:00:00+07:00'

Output formats

Text

ID: zXDYfTmTVf3iMd16zzdBj
State: Pending
IsHashed: false
IsEncrypted: false
Recipients:
        +12025550123    Pending
        +12025550124    Pending

JSON

{
  "id": "zXDYfTmTVf3iMd16zzdBj",
  "state": "Pending",
  "isHashed": false,
  "isEncrypted": false,
  "recipients": [
    {
      "phoneNumber": "+12025550123",
      "state": "Pending"
    },
    {
      "phoneNumber": "+12025550124",
      "state": "Pending"
    }
  ],
  "states": {}
}

Raw

{"id":"zXDYfTmTVf3iMd16zzdBj","state":"Pending","isHashed":false,"isEncrypted":false,"recipients":[{"phoneNumber":"+12025550123","state":"Pending"},{"phoneNumber":"+12025550124","state":"Pending"}],"states":{}}

Table

ID                                    EVENT          URL                              DEVICE ID
123e4567-e89b-12d3-a456-426614174000  sms:received   https://example.com/webhook      dev-abc
def45678-e89b-12d3-a456-426614174000  sms:sent       https://example.com/other        

(back to top)

Certificate Authority (smsgate-ca)

The smsgate-ca tool issues TLS certificates for private deployments. It generates ECDSA P-256 certificates signed by the SMS Gateway CA.

smsgate-ca [global flags] <command> [command flags] [arguments]

Global Flags

Flag Aliases Env Var Default Description
--timeout -t ASG_CA_TIMEOUT 30s Request timeout

Commands

webhooks

Issue a TLS certificate for a webhook receiver running on a private IP address.

smsgate-ca webhooks <ip-address> --out server.crt --keyout server.key

private

Issue a TLS certificate for a private server running on a private IP address.

smsgate-ca private <ip-address> --out server.crt --keyout server.key

Command Flags

Flag Default Description
--out server.crt Certificate output file
--keyout server.key Private key output file

Note: The IP address must be a private/RFC 1918 address (e.g., 10.x.x.x, 172.16.x.x, 192.168.x.x).

(back to top)

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

License

Distributed under the Apache-2.0 license. See LICENSE for more information.

(back to top)

Legal Notice

Android is a trademark of Google LLC.

(back to top)

Releases

Packages

Used by

Contributors

Languages