USB Modems

Connect USB GSM modems to your server for SMS sending without an Android phone.

Overview

The Vendel modem agent is a lightweight Go binary that connects USB GSM modems to your Vendel instance. It receives message assignments in real-time via Server-Sent Events (SSE), sends SMS using AT commands, and reports delivery status back to the server.

Prerequisites

  • A USB GSM modem with a SIM card inserted (any AT-compatible modem)
  • Serial port access — add your user to the dialout group:
    sudo usermod -aG dialout $USER
    Log out and back in for the group change to take effect.
  • Go 1.21+ (only needed if building from source)
  • An Vendel instance running and accessible from the agent host

Step 1: Create a modem device

In the Vendel dashboard, go to Devices and click Add Device. Select USB Modem as the device type, enter a name and the SIM card's phone number. Save the API key shown after creation — you'll need it to configure the agent.

Step 2: Get the agent

Option 1: Download pre-built binary

Download the latest release for your platform:

Extract and install:

# Linux / macOS
tar -xzf vendel-modem-agent_*.tar.gz
sudo mv vendel-modem-agent /usr/local/bin/

# Windows — extract the .zip and add vendel-modem-agent.exe to your PATH

Option 2: Build from source

Requires Go 1.21+:

git clone https://github.com/JimScope/vendel.git
cd vendel/modem-agent
go build -o vendel-modem-agent .

Step 3: Configure

The agent uses two environment variables:

  • VENDEL_URL — Your Vendel server URL (default: http://localhost:8090)
  • MODEMS — Comma-separated list of modem definitions in the format api_key:command_port[:notify_port]

The notify_port is optional and defaults to the command port for single-port modems. Dual-port modems (like the Huawei E173) use separate ports for commands and unsolicited notifications.

# Single modem
MODEMS=dk_abc123:/dev/ttyUSB0:/dev/ttyUSB1

# Multiple modems
MODEMS=dk_abc123:/dev/ttyUSB0:/dev/ttyUSB1,dk_xyz789:/dev/ttyUSB2:/dev/ttyUSB3

Step 4: Run

VENDEL_URL=https://app.vendel.cc MODEMS=dk_abc123:/dev/ttyUSB0:/dev/ttyUSB1 ./vendel-modem-agent

Or use a .env file (copy from .env.example):

cp .env.example .env
# Edit .env with your values
./vendel-modem-agent

Docker deployment

If you're already running Vendel with Docker Compose, you can run the modem agent as an opt-in service instead of building from source. Add these variables to your .env file:

# Modem agent (required when using --profile modem)
MODEMS=dk_abc123:/dev/ttyUSB0:/dev/ttyUSB1

# Host serial device to map into the container (default: /dev/ttyUSB0)
MODEM_DEVICE_0=/dev/ttyUSB0

Then start with the modem profile:

docker compose --profile modem up -d

The modem-agent container will wait for the Vendel app to be healthy before starting, and connects to the backend via Docker internal DNS (http://app:8090). The host serial device is mapped into the container automatically.

View modem agent logs:

docker compose --profile modem logs -f modem-agent

Systemd service

If you're not using Docker, you can run the agent as a systemd service for production use so it starts automatically on boot:

# /etc/systemd/system/vendel-modem-agent.service
[Unit]
Description=Vendel Modem Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=vendel
Group=dialout
Environment=VENDEL_URL=https://app.vendel.cc
Environment=MODEMS=dk_abc123:/dev/ttyUSB0:/dev/ttyUSB1
ExecStart=/usr/local/bin/vendel-modem-agent
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now vendel-modem-agent

Multi-modem setup

The agent supports multiple modems simultaneously. Each modem runs independently in its own goroutine with its own SSE connection and serial port. List all modems in the MODEMS variable separated by commas:

MODEMS=dk_key1:/dev/ttyUSB0:/dev/ttyUSB1,dk_key2:/dev/ttyUSB2:/dev/ttyUSB3

Each modem must have its own device registered in the dashboard with its own API key. Messages are distributed among all available devices (including Android phones) via round-robin.

Incoming SMS

The agent automatically monitors for incoming SMS on all connected modems. Received messages are reported to Vendel and trigger your configured webhooks with the sms_received event.

Supported modems

Any AT-compatible USB GSM modem should work. Tested models include:

  • Huawei E173 / E1752 / E3531
  • ZTE MF180 / MF190
  • Alcatel MW40
  • SIMCom SIM800 / SIM900 modules
  • Quectel M95 / UC20 / EC25

If your modem is not listed but supports standard AT commands for SMS (AT+CMGS, AT+CMGR), it should work. Open an issue on GitHub if you encounter compatibility problems.