CLI SMS Tool with Go
Build a command-line SMS sender in Go — useful for scripts, cron jobs, and CI/CD pipelines
CLI SMS Tool with Go
This tutorial builds a standalone Go CLI that sends SMS messages from your terminal, shell scripts, and CI/CD pipelines.
# Send a single message
sms-send -to +244923000000 -msg "Deploy to production succeeded"
# Notify multiple recipients
sms-send -to +244923000000,+244912000001 -msg "Nightly backup completed"
# Read message from stdin (pipe-friendly)
echo "Disk usage at 90%" | sms-send -to +244923000000Prerequisites
- Go 1.21+
- A CastBrick API key from the dashboard
Setup
mkdir sms-send && cd sms-send
go mod init sms-send
go get github.com/IldySilva/castbrick-goThe code
Create main.go:
package main
import (
"bufio"
"context"
"flag"
"fmt"
"io"
"os"
"strings"
"time"
"github.com/IldySilva/castbrick-go/castbrick"
)
func main() {
to := flag.String("to", "", "Recipient phone number(s), comma-separated (e.g. +244923000000,+244912000001)")
msg := flag.String("msg", "", "Message text. Omit to read from stdin.")
sender := flag.String("sender", "", "Optional sender ID (e.g. MyApp)")
flag.Parse()
if *to == "" {
fmt.Fprintln(os.Stderr, "error: -to is required")
flag.Usage()
os.Exit(1)
}
recipients := splitRecipients(*to)
content := *msg
// Read from stdin if no -msg flag provided
if content == "" {
content = readStdin()
}
if strings.TrimSpace(content) == "" {
fmt.Fprintln(os.Stderr, "error: message is empty")
os.Exit(1)
}
apiKey := os.Getenv("CASTBRICK_API_KEY")
if apiKey == "" {
fmt.Fprintln(os.Stderr, "error: CASTBRICK_API_KEY environment variable is not set")
os.Exit(1)
}
cb := castbrick.New(apiKey)
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
opts := castbrick.SendSmsOptions{
To: recipients,
Content: content,
}
if *sender != "" {
opts.SenderID = *sender
}
result, err := cb.SMS.Send(ctx, opts)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
fmt.Printf("Sent to %d recipient(s). Message ID: %s\n", result.RecipientCount, result.MessageID)
}
func splitRecipients(s string) []string {
parts := strings.Split(s, ",")
out := make([]string, 0, len(parts))
for _, p := range parts {
if t := strings.TrimSpace(p); t != "" {
out = append(out, t)
}
}
return out
}
func readStdin() string {
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) != 0 {
return "" // nothing piped
}
data, _ := io.ReadAll(bufio.NewReader(os.Stdin))
return strings.TrimSpace(string(data))
}Build and install
go build -o sms-send .
# Install globally (optional)
go install .Export your API key:
export CASTBRICK_API_KEY=your_api_key_hereUsage examples
# Basic send
./sms-send -to +244923000000 -msg "Hello from the terminal"
# Multiple recipients
./sms-send -to "+244923000000,+244912000001" -msg "Server restarted successfully"
# Custom sender ID
./sms-send -to +244923000000 -msg "Deployment done" -sender "CI/CD"
# Pipe from a command
df -h | grep "90%" | ./sms-send -to +244923000000
# Pipe a file
cat report.txt | ./sms-send -to +244923000000Using in shell scripts
#!/bin/bash
set -e
# Run your task
./run-backup.sh
STATUS=$?
if [ $STATUS -eq 0 ]; then
./sms-send -to +244923000000 -msg "Backup completed successfully at $(date)"
else
./sms-send -to "+244923000000,+244912000001" -msg "BACKUP FAILED with exit code $STATUS — check logs"
fiUsing in a Cron job
# Edit crontab
crontab -e
# Send a daily report at 8am
0 8 * * * CASTBRICK_API_KEY=your_key /usr/local/bin/sms-send -to +244923000000 -msg "Good morning! Daily report: $(uptime)"Using in CI/CD (GitHub Actions example)
- name: Notify team on deploy
env:
CASTBRICK_API_KEY: ${{ secrets.CASTBRICK_API_KEY }}
run: |
./sms-send -to ${{ secrets.ONCALL_PHONE }} \
-msg "Deploy of ${{ github.repository }}@${{ github.sha }} succeeded" \
-sender "GitHub"Store your API key as a secret in your CI/CD platform — never hardcode it in scripts or commit it to version control.
Next steps
- Go SDK reference — scheduling, contacts, broadcasts
- Webhooks — confirm delivery status programmatically
- API overview — call the REST API directly if you need custom integrations