SignalBot-JS
A minimal, clean JavaScript/TypeScript Signal bot framework for building automated Signal messaging applications.

Features
- 🚀 Simple Setup - Get a Signal bot running in 5 minutes
- 🏗️ Command Pattern - Easy to add new bot features
- 📎 Attachment Support - Handle images, documents, and files
- 🔒 Production Ready - TypeScript, error handling, logging
- 🔌 Extensible - Built for any Signal automation use case
- 🐳 Docker Based - Uses proven signal-cli-rest-api
Quick Start (NPM)
Prerequisites
Before starting, you'll need:
- Node.js 18+ and npm installed
- Docker Desktop - Download from docker.com
- Signal app on your phone with a registered number
- Basic command line knowledge
Option 1: Copy an Example (Recommended)
npm install signalbot-js dotenv
cp node_modules/signalbot-js/examples/basic-bot.js my-bot.js
echo 'SIGNAL_PHONE="+1234567890"' > .env
echo '{"type": "module", "dependencies": {"signalbot-js": "*", "dotenv": "*"}}' > package.json
node my-bot.js
Option 2: Start from Scratch
npm install signalbot-js dotenv
Create bot.js:
import { SignalBot, Command } from 'signalbot-js';
import { config } from 'dotenv';
config();
class PingCommand extends Command {
get name() { return 'ping'; }
async handle(ctx) {
if (ctx.startsWith('ping')) {
await ctx.send('pong 🏓');
return true;
}
return false;
}
}
const bot = new SignalBot({
signal_service: 'localhost:8080',
phone_number: process.env.SIGNAL_PHONE,
poll_interval: 3000,
debug: true
});
bot.register(new PingCommand());
await bot.start();
Create .env:
SIGNAL_PHONE="+1234567890"
Make sure your package.json has:
{
"type": "module"
}
Signal Setup (Required)
Your bot uses signal-cli-rest-api to communicate with Signal servers:
1. Start Signal API Container
docker run -d \
--name signal-api \
-p 8080:8080 \
-v $(pwd)/bot-config:/home/.local/share/signal-cli \
-e 'MODE=native' \
bbernhard/signal-cli-rest-api:latest
2. Link Your Signal Account
curl -X GET 'http://localhost:8080/v1/qrcodelink?device_name=MyBot' --output qr.png
open qr.png
3. Test Setup
node bot.js
Need detailed setup help? See our complete guide
Development Setup
1. Prerequisites
- Docker Desktop installed and running
- Node.js 18+ and pnpm
- A Signal-registered phone number
2. Installation
git clone https://github.com/PaulAndreRada/signal-bot.js.git
cd signal-bot.js
pnpm install
pnpm build
3. Configuration
cp .env.example .env
4. Start Signal API
docker run -d \
--name signal-api \
-p 8080:8080 \
-v $(pwd)/bot-config:/home/.local/share/signal-cli \
-e 'MODE=native' \
bbernhard/signal-cli-rest-api:latest
5. Link Your Signal Account
curl -X GET 'http://localhost:8080/v1/qrcodelink?device_name=SignalBot' --output qr.png
open qr.png
6. Run Example Bot
node examples/basic-bot.js
Send "ping" to your Signal number and get "pong 🏓" back!
Examples
Basic Bot
import { SignalBot, Command } from 'signalbot-js';
import { config } from 'dotenv';
config();
class PingCommand extends Command {
get name() { return 'ping'; }
get description() { return 'Responds to ping with pong'; }
async handle(ctx) {
if (ctx.startsWith('ping')) {
console.log(`Ping received from ${ctx.sender}`);
await ctx.send('pong 🏓');
return true;
}
return false;
}
}
class EchoCommand extends Command {
get name() { return 'echo'; }
get description() { return 'Echo back your message'; }
async handle(ctx) {
if (ctx.startsWith('echo')) {
const [, ...words] = ctx.args();
await ctx.send(`You said: ${words.join(' ')}`);
return true;
}
return false;
}
}
class HelpCommand extends Command {
get name() { return 'help'; }
get description() { return 'Show available commands'; }
async handle(ctx) {
if (ctx.startsWith('help')) {
const commands = bot.registeredCommands;
const helpText = [
'🤖 Available Commands:',
...commands.map(cmd => `• ${cmd.name} - ${cmd.description}`)
].join('\n');
await ctx.send(helpText);
return true;
}
return false;
}
}
const bot = new SignalBot({
signal_service: 'localhost:8080',
phone_number: process.env.SIGNAL_PHONE,
poll_interval: 3000,
debug: true
});
bot.register(new PingCommand());
bot.register(new EchoCommand());
bot.register(new HelpCommand());
console.log('🤖 Starting Signal bot...');
try {
await bot.start();
console.log('✅ Bot is running! Send "ping", "echo hello", or "help"');
} catch (error) {
console.error('❌ Failed to start bot:', error.message);
}