diff --git a/README.md b/README.md index 269f668..f331cec 100644 --- a/README.md +++ b/README.md @@ -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 @@ -35,10 +36,14 @@ For the textbelt version replace `` and `` sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main/install.sh)" -- # Textbelt Version -sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main/install_textbelt.sh)" -- +sh -c "$(curl -fsSL https://raw.githubusercontent.com/techrelay/GL.iNet-CellularModels-SMSonBoot/main/install_textbelt.sh)" -- [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 --textbelt-key --webhook-url ``` ![35BF6268-8DBB-4A14-99C2-8406653029FB_1_105_c](https://github.com/user-attachments/assets/0372f6cc-ef24-485f-a133-c45d68f73a19) @@ -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 @@ -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 @@ -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 ``` @@ -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` diff --git a/install.sh b/install.sh index 50d7310..8e05c9c 100644 --- a/install.sh +++ b/install.sh @@ -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 @@ -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 diff --git a/install_combined.sh b/install_combined.sh index f82e8ae..2798eaa 100644 --- a/install_combined.sh +++ b/install_combined.sh @@ -7,6 +7,7 @@ CONF="/etc/sms_on_boot_combined.conf" PREFER="" PHONE="" TEXTBELT_KEY="" +WEBHOOK_URL="" usage() { cat <<'EOF' @@ -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 } @@ -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 @@ -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 @@ -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..." diff --git a/install_textbelt.sh b/install_textbelt.sh index 9fcc923..5acbf8d 100644 --- a/install_textbelt.sh +++ b/install_textbelt.sh @@ -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 @@ -11,8 +12,8 @@ if [ "$(id -u)" -ne 0 ]; then fi if [ -z "$PHONE" ] || [ -z "$KEY" ]; then - echo "Usage: install_textbelt.sh " >&2 - echo "Example: install_textbelt.sh +17192291657 your_key_here" >&2 + echo "Usage: install_textbelt.sh [WEBHOOK_URL]" >&2 + echo "Example: install_textbelt.sh +17192291657 your_key_here https://example.com/webhook" >&2 exit 1 fi @@ -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 diff --git a/sms_on_boot.sh b/sms_on_boot.sh index 9f845bb..49eec34 100644 --- a/sms_on_boot.sh +++ b/sms_on_boot.sh @@ -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) @@ -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." diff --git a/sms_on_boot_combined.sh b/sms_on_boot_combined.sh index 264b478..ea2db94 100644 --- a/sms_on_boot_combined.sh +++ b/sms_on_boot_combined.sh @@ -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 @@ -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 @@ -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" diff --git a/sms_on_boot_textbelt.sh b/sms_on_boot_textbelt.sh index 54480d3..39c069f 100644 --- a/sms_on_boot_textbelt.sh +++ b/sms_on_boot_textbelt.sh @@ -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}}')" @@ -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 \