A simple Signal messenger bot written in Go. This bot can respond to commands in both direct messages and group chats.
- β Responds to commands in direct messages and group chats
- β Easy to extend with custom commands
- β Uses signal-cli for Signal protocol communication
- β Docker support for easy deployment
- β Environment-based configuration
- β Polls & Voting - Create polls for group decisions with real-time results
- β Group Statistics - Track message counts, active members, and top contributors
- β Announcements - Pin important messages that everyone can reference
- β Activity Tracking - Monitor user engagement and participation
- β @Mentions - Mention users with @+phonenumber and track mentions
- β Reminders - Set personal reminders that the bot will deliver
- β User Stats - View your own activity and contribution to groups
- β Pinned Messages - Important announcements stay visible
Managing Signal groups with 50-700+ members can be challenging. These features address common pain points:
Decision Making: In large groups, making decisions can be chaotic. Polls provide a structured way for everyone to vote and see results.
Information Overload: Important messages get lost in active chats. Announcements keep critical info pinned and accessible.
Engagement Tracking: See who's active and contributing. Stats help identify engaged members and understand group dynamics.
Coordination: Reminders help members stay on track with group activities and deadlines.
Communication: @Mentions ensure important messages reach the right people, even in busy groups.
π For detailed feature documentation and use cases, see FEATURES.md
Before you can run this bot, you need:
- Java Runtime Environment (JRE) 17+ - Required for signal-cli
- signal-cli - Command-line interface for Signal
- Go 1.21+ - To build and run the bot
- A Signal account - You'll need a phone number to register the bot
-
Clone the repository
git clone https://github.com/riyanimam/signal-bot-playground.git cd signal-bot-playground -
Set up your environment
cp .env.example .env # Edit .env and add your Signal phone number -
Register your Signal account
docker-compose run --rm signal-bot signal-cli -a YOUR_PHONE_NUMBER register # You'll receive a verification code via SMS docker-compose run --rm signal-bot signal-cli -a YOUR_PHONE_NUMBER verify CODE -
Start the bot
docker-compose up -d
On Linux:
# Download and extract signal-cli
wget https://github.com/AsamK/signal-cli/releases/download/v0.13.1/signal-cli-0.13.1-Linux.tar.gz
tar xf signal-cli-0.13.1-Linux.tar.gz -C /opt
sudo ln -sf /opt/signal-cli-0.13.1/bin/signal-cli /usr/local/bin/On macOS:
brew install signal-cliVerify installation:
signal-cli --version# Register the phone number (you'll receive an SMS with a verification code)
signal-cli -a +1234567890 register
# Verify with the code you received
signal-cli -a +1234567890 verify 123-456Replace +1234567890 with your actual phone number in international format.
# Clone the repository
git clone https://github.com/riyanimam/signal-bot-playground.git
cd signal-bot-playground
# Copy environment template
cp .env.example .env
# Edit .env and set your phone number
# SIGNAL_PHONE_NUMBER=+1234567890# Install dependencies
go mod download
# Build the bot
go build -o signal-bot
# Run the bot
./signal-botTo get your Signal bot running, you need to:
-
Phone Number: A dedicated phone number for your bot (can be a virtual number from services like Twilio, Google Voice, etc.)
- Must be in international format:
+1234567890 - This number will be registered with Signal and used exclusively for the bot
- Must be in international format:
-
Access to receive SMS: During registration, you'll need to receive an SMS verification code
-
Server/Computer: A machine to run the bot
- Can be your local machine for testing
- A cloud server (AWS EC2, DigitalOcean, etc.) for production
- Must be able to run continuously if you want 24/7 availability
Once the bot is running, you can message it on Signal. The bot responds to these commands:
!help- Show available commands!ping- Check if bot is alive!echo <text>- Echo back your message!about- Get information about the bot
!poll <question> | <option1> | <option2> | ...- Create a poll for group decisions!vote <poll_id> <option>- Vote in an active poll!pollresults <poll_id>- View current poll results with percentages!polls- List all active polls in the group
Example:
You: !poll Where should we meet? | Coffee Shop | Restaurant | Park
Bot: π Poll created! ID: poll_1234567890
Where should we meet?
Options:
1. Coffee Shop
2. Restaurant
3. Park
Vote with: !vote poll_1234567890 <option>
You: !vote poll_1234567890 Coffee Shop
Bot: β
Vote recorded!
You: !pollresults poll_1234567890
Bot: π Poll Results: Where should we meet?
Coffee Shop: 5 votes (50.0%)
βββββ
Restaurant: 3 votes (30.0%)
βββ
Park: 2 votes (20.0%)
ββ
Total votes: 10
!remind <time> <message>- Set a reminder (supports: 30s, 5m, 2h, 1d)!reminders- List your active reminders!cancelreminder <id>- Cancel a reminder
Example:
You: !remind 30m Call the team
Bot: β° Reminder set! ID: reminder_1234567890
I'll remind you in 30m
[30 minutes later]
Bot: β° Reminder: Call the team
!stats- View group statistics (message counts, active users, top contributors)!mystats- View your personal activity in the group
Example:
You: !stats
Bot: π Group Statistics
Total messages: 1,234
Active members today: 45
Total members: 678
Top contributors:
1. ****5678: 234 messages (18.9%)
2. ****9012: 198 messages (16.0%)
3. ****3456: 156 messages (12.6%)
...
!announce <message>- Pin an important announcement!announcements- View all pinned announcements
Example:
You: !announce Meeting moved to 3 PM today
Bot: π Announcement pinned! ID: announcement_1234567890
You: !announcements
Bot: π Pinned Announcements:
1. Meeting moved to 3 PM today
(by ****5678, 2 hours ago)
2. Welcome to the group! Please introduce yourself.
(by ****1234, 1 day ago)
- Use
@+1234567890to mention someone in your message !mentions- View your recent mentions!clearmentions- Clear your mention notifications
Example:
You: Hey @+1234567890, can you review this?
[The mentioned user receives a notification]
Mentioned User: !mentions
Bot: π¬ Your Mentions (1):
1. From ****5678 (5 minutes ago)
Hey @+1234567890, can you review this?
Example:
You: !ping
Bot: π Pong!
You: !echo Hello World
Bot: Hello World
The bot is configured via environment variables. See .env.example for all options:
| Variable | Description | Default |
|---|---|---|
SIGNAL_PHONE_NUMBER |
Your bot's Signal phone number | Required |
SIGNAL_DATA_DIR |
Directory for Signal data | ./signal-data |
BOT_COMMAND_PREFIX |
Prefix for bot commands | ! |
LOG_LEVEL |
Logging level (debug, info, warn, error) | info |
signal-bot-playground/
βββ main.go # Main application entry point
βββ config.go # Configuration management
βββ handler.go # Message handling and command routing
βββ polls.go # Polls and voting system
βββ reminders.go # Reminder scheduling and delivery
βββ groupstats.go # Group statistics and analytics
βββ slacklike.go # Announcements and mentions tracking
βββ go.mod # Go module definition
βββ go.sum # Dependency checksums
βββ .env.example # Environment variable template
βββ .gitignore # Git ignore rules
βββ Dockerfile # Docker image definition
βββ docker-compose.yml # Docker Compose configuration
βββ Makefile # Build and deployment commands
βββ README.md # Main documentation
βββ FEATURES.md # Comprehensive features guide
βββ ARCHITECTURE.md # Architecture documentation
βββ QUICKSTART.md # Quick start guide
To add your own commands, edit handler.go:
// In the HandleMessage function, add a new case:
case "mycommand":
return h.handleMyCommand(args), nil
// Then implement the handler:
func (h *MessageHandler) handleMyCommand(args []string) string {
return "My custom response!"
}Make sure signal-cli is installed and in your PATH:
which signal-cli
signal-cli --version- Ensure your phone number is in international format (+1234567890)
- Check that you can receive SMS on that number
- If using a VOIP number, some may not work with Signal
- Check that the bot is running:
docker-compose psorps aux | grep signal-bot - Check logs:
docker-compose logs -for look at terminal output - Verify your phone number in
.envmatches the registered number - Make sure you're using the correct command prefix (default is
!)
- Signal-cli needs internet connectivity
- Check firewall settings
- Ensure signal-cli data directory is writable
Create /etc/systemd/system/signal-bot.service:
[Unit]
Description=Signal Bot
After=network.target
[Service]
Type=simple
User=signalbot
WorkingDirectory=/opt/signal-bot-playground
ExecStart=/opt/signal-bot-playground/signal-bot
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable signal-bot
sudo systemctl start signal-bot
sudo systemctl status signal-bot# Build and start in detached mode
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the bot
docker-compose down- Keep your phone number private - Anyone can message your bot
- Rate limiting - The bot includes basic rate limiting, but consider adding more robust protections
- Input validation - Always validate user input in command handlers
- Environment variables - Never commit
.envfile to version control - Updates - Keep signal-cli and dependencies up to date
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
If you encounter any issues or have questions:
- Check the Troubleshooting section
- Review signal-cli documentation
- Open an issue on GitHub
Made with β€οΈ using Go and Signal