Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This project targets **GL.iNet / OpenWrt firmware** that includes the built-in `
- 🌐 Automatically detects the active cellular WAN interface
- 🕒 Built-in cooldown to prevent SMS spam
- 🛠 Uses GL.iNet’s native `sendsms` backend (same path as the web UI)
- 🔔 Optional webhook POST with JSON payload on boot
---

## ✅ Prerequisites
Expand All @@ -35,10 +36,14 @@ For the textbelt version replace `<YOURNUMBER>` and `<YOUR_TEXTBELT_KEY>`
sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main/install.sh)" -- <YOURNUMBER>

# Textbelt Version
sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main/install_textbelt.sh)" -- <YOURNUMBER> <YOUR_TEXTBELT_KEY>
sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main/install_textbelt.sh)" -- <YOURNUMBER> <YOUR_TEXTBELT_KEY> [WEBHOOK_URL]

# Combined Version (interactive, no arguments)
sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main/install_combined.sh)"

# Combined Version (non-interactive with webhook)
sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main/install_combined.sh)" -- \
--prefer textbelt --phone <YOURNUMBER> --textbelt-key <YOUR_TEXTBELT_KEY> --webhook-url <WEBHOOK_URL>
```

![35BF6268-8DBB-4A14-99C2-8406653029FB_1_105_c](https://github.com/user-attachments/assets/0372f6cc-ef24-485f-a133-c45d68f73a19)
Expand All @@ -50,7 +55,8 @@ sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-Cellular
### Option A: sendsms (Cellular SIM)
1. Copy `sms_on_boot.sh` to `/usr/bin/sms_on_boot.sh`
2. Edit the `PHONE` value inside the script.
3. Create an init script:
3. Optional: set `WEBHOOK_URL` to receive a JSON payload.
4. Create an init script:
```sh
cat > /etc/init.d/sms_on_boot <<'EOF'
#!/bin/sh /etc/rc.common
Expand All @@ -66,7 +72,8 @@ sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-Cellular
### Option B: Textbelt
1. Copy `sms_on_boot_textbelt.sh` to `/usr/bin/sms_on_boot_textbelt.sh`
2. Edit `PHONE` and `TEXTBELT_KEY` inside the script.
3. Create an init script:
3. Optional: set `WEBHOOK_URL` to receive a JSON payload.
4. Create an init script:
```sh
cat > /etc/init.d/sms_on_boot_textbelt <<'EOF'
#!/bin/sh /etc/rc.common
Expand All @@ -87,6 +94,7 @@ sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-Cellular
PHONE="+17192291657"
PREFER="textbelt" # or sendsms
TEXTBELT_KEY="textbelt"
WEBHOOK_URL=""
EOF
chmod 600 /etc/sms_on_boot_combined.conf
```
Expand All @@ -108,6 +116,7 @@ sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-Cellular
## 🔧 Configuration & Logs

- **Cooldown:** Each script has a `COOLDOWN` setting (default 300s) to prevent SMS spam.
- **Webhook:** Set `WEBHOOK_URL` to POST a JSON payload on boot (uses curl, logs response code/body).
- **Logs:**
- `/tmp/sms_on_boot.log`
- `/tmp/sms_on_boot_textbelt.log`
Expand Down
6 changes: 6 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
set -eu

PHONE="${1:-}"
WEBHOOK_URL="${2:-}"
REPO_RAW_BASE="https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main"

if [ "$(id -u)" -ne 0 ]; then
Expand All @@ -28,6 +29,11 @@ else
echo "[!] No phone provided. Edit /usr/bin/sms_on_boot.sh later."
fi

if [ -n "$WEBHOOK_URL" ]; then
sed -i "s|^WEBHOOK_URL=\".*\"|WEBHOOK_URL=\"$WEBHOOK_URL\"|g" /usr/bin/sms_on_boot.sh
echo "[*] Set WEBHOOK_URL to: $WEBHOOK_URL"
fi

echo "[*] Creating init.d service..."
cat > /etc/init.d/sms_on_boot <<'EOF'
#!/bin/sh /etc/rc.common
Expand Down
10 changes: 9 additions & 1 deletion install_combined.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CONF="/etc/sms_on_boot_combined.conf"
PREFER=""
PHONE=""
TEXTBELT_KEY=""
WEBHOOK_URL=""

usage() {
cat <<'EOF'
Expand All @@ -16,11 +17,12 @@ Interactive:
install_combined.sh

Non-interactive:
install_combined.sh --prefer textbelt|sendsms --phone +17192291657 [--textbelt-key KEY]
install_combined.sh --prefer textbelt|sendsms --phone +17192291657 [--textbelt-key KEY] [--webhook-url URL]

Examples:
install_combined.sh --prefer textbelt --phone +17192291657 --textbelt-key textbelt
install_combined.sh --prefer sendsms --phone +17192291657
install_combined.sh --prefer textbelt --phone +17192291657 --textbelt-key textbelt --webhook-url https://example.com
EOF
}

Expand All @@ -31,6 +33,7 @@ while [ $# -gt 0 ]; do
--prefer) PREFER="${2:-}"; shift 2 ;;
--phone) PHONE="${2:-}"; shift 2 ;;
--textbelt-key) TEXTBELT_KEY="${2:-}"; shift 2 ;;
--webhook-url) WEBHOOK_URL="${2:-}"; shift 2 ;;
--) shift; break ;;
*) echo "Unknown arg: $1" >&2; usage; exit 1 ;;
esac
Expand Down Expand Up @@ -71,6 +74,10 @@ if [ -z "${PREFER:-}" ] || [ -z "${PHONE:-}" ]; then
echo "You can also use: textbelt (limited free tier)"
printf "Textbelt key: "
read TEXTBELT_KEY

echo "Webhook URL (optional). Leave blank to skip."
printf "Webhook URL: "
read WEBHOOK_URL
fi

# Validate
Expand All @@ -95,6 +102,7 @@ umask 077
echo "PHONE=\"$PHONE\""
echo "PREFER=\"$PREFER\""
echo "TEXTBELT_KEY=\"$TEXTBELT_KEY\""
echo "WEBHOOK_URL=\"$WEBHOOK_URL\""
} > "$CONF"

echo "[*] Creating init.d service..."
Expand Down
10 changes: 8 additions & 2 deletions install_textbelt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set -eu

PHONE="${1:-}"
KEY="${2:-}"
WEBHOOK_URL="${3:-}"
REPO_RAW_BASE="https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main"

if [ "$(id -u)" -ne 0 ]; then
Expand All @@ -11,8 +12,8 @@ if [ "$(id -u)" -ne 0 ]; then
fi

if [ -z "$PHONE" ] || [ -z "$KEY" ]; then
echo "Usage: install_textbelt.sh <PHONE> <TEXTBELT_KEY>" >&2
echo "Example: install_textbelt.sh +17192291657 your_key_here" >&2
echo "Usage: install_textbelt.sh <PHONE> <TEXTBELT_KEY> [WEBHOOK_URL]" >&2
echo "Example: install_textbelt.sh +17192291657 your_key_here https://example.com/webhook" >&2
exit 1
fi

Expand All @@ -32,6 +33,11 @@ chmod +x /usr/bin/sms_on_boot_textbelt.sh
sed -i "s|^PHONE=\".*\"|PHONE=\"$PHONE\"|g" /usr/bin/sms_on_boot_textbelt.sh
sed -i "s|^TEXTBELT_KEY=\".*\"|TEXTBELT_KEY=\"$KEY\"|g" /usr/bin/sms_on_boot_textbelt.sh

if [ -n "$WEBHOOK_URL" ]; then
sed -i "s|^WEBHOOK_URL=\".*\"|WEBHOOK_URL=\"$WEBHOOK_URL\"|g" /usr/bin/sms_on_boot_textbelt.sh
echo "[*] Set WEBHOOK_URL to: $WEBHOOK_URL"
fi

echo "[*] Creating init.d service..."
cat > /etc/init.d/sms_on_boot_textbelt <<'EOF'
#!/bin/sh /etc/rc.common
Expand Down
42 changes: 42 additions & 0 deletions sms_on_boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ STATE="/etc/sms_on_boot.last"
COOLDOWN=300 # seconds (5 min)

PHONE="+13038675309" # <-- change if needed
WEBHOOK_URL="" # optional: POST JSON payload to this URL
WEBHOOK_CONNECT_TIMEOUT=5
WEBHOOK_TIMEOUT=15

log() { echo "[$(date '+%F %T')] $*" >> "$LOG"; }

json_escape() {
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e ':a;N;$!ba;s/\n/\\n/g'
}

# Try to find the active WAN interface (cellular/wan) in a model-agnostic way.
# Priority:
# 1) default route device (common + accurate)
Expand Down Expand Up @@ -66,6 +73,41 @@ WAN IF: $WAN_IFACE"
[ -n "$WAN_IP" ] && MSG="$MSG
Cell IP: $WAN_IP"

send_webhook() {
[ -z "$WEBHOOK_URL" ] && return 0
if ! command -v curl >/dev/null 2>&1; then
log "Webhook: curl not found"
return 1
fi

payload="$(printf '{"event":"boot","time":"%s","wan_iface":"%s","wan_ip":"%s","message":"%s"}' \
"$(date '+%F %T %Z')" \
"$(json_escape "${WAN_IFACE:-}")" \
"$(json_escape "${WAN_IP:-}")" \
"$(json_escape "$MSG")")"

resp="$(curl -sS --connect-timeout "$WEBHOOK_CONNECT_TIMEOUT" --max-time "$WEBHOOK_TIMEOUT" \
-H "Content-Type: application/json" -d "$payload" -w '\n%{http_code}' \
"$WEBHOOK_URL" 2>>"$LOG" || true)"

body="$(printf '%s' "$resp" | sed '$d')"
code="$(printf '%s' "$resp" | tail -n 1)"

[ -n "$body" ] && log "Webhook response body: $body"
[ -n "$code" ] && log "Webhook response code: $code"

case "$code" in
2*|3*) return 0 ;;
esac
return 1
}

if send_webhook; then
log "Webhook sent."
else
log "Webhook failed."
fi

log "Sending SMS to $PHONE"
if sendsms "$PHONE" "$MSG" international; then
log "SMS sent."
Expand Down
42 changes: 42 additions & 0 deletions sms_on_boot_combined.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ COOLDOWN=300
PHONE="+11234567890"
PREFER="textbelt"
TEXTBELT_KEY=""
WEBHOOK_URL=""
WEBHOOK_CONNECT_TIMEOUT=5
WEBHOOK_TIMEOUT=15

CONF="/etc/sms_on_boot_combined.conf"
if [ -f "$CONF" ]; then
Expand All @@ -17,6 +20,10 @@ fi
log() { echo "[$(date '+%F %T')] $*" >> "$LOG"; }
log "Script start"

json_escape() {
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e ':a;N;$!ba;s/\n/\\n/g'
}

find_wan_iface() {
dev="$(ip route 2>/dev/null | awk '/^default /{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}')"
if [ -n "$dev" ]; then
Expand Down Expand Up @@ -96,6 +103,41 @@ WAN IF: $WAN_IFACE"
[ -n "$WAN_IP" ] && MSG="$MSG
WAN IP: $WAN_IP"

send_webhook() {
[ -z "$WEBHOOK_URL" ] && return 0
if ! command -v curl >/dev/null 2>&1; then
log "Webhook: curl not found"
return 1
fi

payload="$(printf '{"event":"boot","time":"%s","wan_iface":"%s","wan_ip":"%s","message":"%s"}' \
"$(date '+%F %T %Z')" \
"$(json_escape "${WAN_IFACE:-}")" \
"$(json_escape "${WAN_IP:-}")" \
"$(json_escape "$MSG")")"

resp="$(curl -sS --connect-timeout "$WEBHOOK_CONNECT_TIMEOUT" --max-time "$WEBHOOK_TIMEOUT" \
-H "Content-Type: application/json" -d "$payload" -w '\n%{http_code}' \
"$WEBHOOK_URL" 2>>"$LOG" || true)"

body="$(printf '%s' "$resp" | sed '$d')"
code="$(printf '%s' "$resp" | tail -n 1)"

[ -n "$body" ] && log "Webhook response body: $body"
[ -n "$code" ] && log "Webhook response code: $code"

case "$code" in
2*|3*) return 0 ;;
esac
return 1
}

if send_webhook; then
log "Webhook sent."
else
log "Webhook failed."
fi

# If no WAN IP, skip Textbelt
if [ -z "$WAN_IP" ]; then
log "No WAN IP detected; skipping Textbelt"
Expand Down
42 changes: 42 additions & 0 deletions sms_on_boot_textbelt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@ COOLDOWN=300 # seconds (5 min)

PHONE="+11234567890" # change if needed
TEXTBELT_KEY="textbelt" # set your key here
WEBHOOK_URL="" # optional: POST JSON payload to this URL
WEBHOOK_CONNECT_TIMEOUT=5
WEBHOOK_TIMEOUT=15

log() { echo "[$(date '+%F %T')] $*" >> "$LOG"; }

json_escape() {
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e ':a;N;$!ba;s/\n/\\n/g'
}

# Find active WAN interface (best-effort)
find_wan_iface() {
dev="$(ip route 2>/dev/null | awk '/^default /{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}')"
Expand Down Expand Up @@ -64,6 +71,41 @@ WAN IF: $WAN_IFACE"
[ -n "$WAN_IP" ] && MSG="$MSG
WAN IP: $WAN_IP"

send_webhook() {
[ -z "$WEBHOOK_URL" ] && return 0
if ! command -v curl >/dev/null 2>&1; then
log "Webhook: curl not found"
return 1
fi

payload="$(printf '{"event":"boot","time":"%s","wan_iface":"%s","wan_ip":"%s","message":"%s"}' \
"$(date '+%F %T %Z')" \
"$(json_escape "${WAN_IFACE:-}")" \
"$(json_escape "${WAN_IP:-}")" \
"$(json_escape "$MSG")")"

resp="$(curl -sS --connect-timeout "$WEBHOOK_CONNECT_TIMEOUT" --max-time "$WEBHOOK_TIMEOUT" \
-H "Content-Type: application/json" -d "$payload" -w '\n%{http_code}' \
"$WEBHOOK_URL" 2>>"$LOG" || true)"

body="$(printf '%s' "$resp" | sed '$d')"
code="$(printf '%s' "$resp" | tail -n 1)"

[ -n "$body" ] && log "Webhook response body: $body"
[ -n "$code" ] && log "Webhook response code: $code"

case "$code" in
2*|3*) return 0 ;;
esac
return 1
}

if send_webhook; then
log "Webhook sent."
else
log "Webhook failed."
fi

log "Sending via Textbelt to $PHONE"

RESP="$(curl -sS -X POST https://textbelt.com/text \
Expand Down