commit 0804fe640b1b28c5f4b71c296fa838af0a697eff
parent 33018904026e10ea0458d3559228c6a7eacb2837
Author: Christian Grothoff <christian@grothoff.org>
Date: Wed, 1 Jul 2026 20:23:37 +0200
missing file
Diffstat:
1 file changed, 301 insertions(+), 0 deletions(-)
diff --git a/src/challenger/challenger-send-sms-aspsms b/src/challenger/challenger-send-sms-aspsms
@@ -0,0 +1,301 @@
+#!/bin/bash
+# This file is in the public domain.
+# Send an SMS using ASPSMS API.
+#
+# Usage:
+# echo "Hello world" | $0 +41791234567
+#
+# Environment:
+# ASPSMS_USERKEY
+# ASPSMS_PASSWORD
+#
+# Exit codes:
+#
+# 0 SMS delivered
+#
+# 1 Usage/configuration error
+# 2 Local/network/API communication failure
+# 3 ASPSMS authentication failure
+# 4 Invalid phone number
+# 5 Recipient unavailable (phone off / no coverage / expired)
+# 6 Mobile operator/provider failure
+# 7 ASPSMS rejected request
+# 8 Delivery timeout (status never became final)
+# 9 Unknown failure
+#
+
+set -euo pipefail
+
+# Check shared secrets
+if [ -x "$ASPSMS_USERKEY" ]
+then
+ echo "ASPSMS_USERKEY not set in environment"
+ exit 1
+fi
+
+if [ -x "$ASPSMS_PASSWORD" ]
+then
+ echo "ASPSMS_PASSWORD not set in environment"
+ exit 1
+fi
+
+
+API="https://webapi.aspsms.com"
+
+if [[ $# -ne 1 ]]
+then
+ echo "Usage: $0 <PHONE_NUMBER>" >&2
+ exit 1
+fi
+
+PHONE="$1"
+MESSAGE="$(cat -)"
+
+if [[ -z "$MESSAGE" ]]
+then
+ echo "Empty message" >&2
+ exit 1
+fi
+
+TRANSREF="$(date +%s)-$$-$RANDOM"
+
+echo "T-REF: $TRANSREF"
+
+#
+# Send SMS
+#
+SEND_JSON="$(
+curl -fsS \
+ --get \
+ "$API/SendSimpleSMS" \
+ --data-urlencode "Userkey=$ASPSMS_USERKEY" \
+ --data-urlencode "Password=$ASPSMS_PASSWORD" \
+ --data-urlencode "MSISDN=$PHONE" \
+ --data-urlencode "MessageData=$MESSAGE" \
+ --data-urlencode "TransactionReferenceNumber=$TRANSREF"
+)" || {
+ echo "Communication with ASPSMS failed" >&2
+ exit 2
+}
+
+ERROR_CODE=$(jq -r '.ErrorCode // empty' <<<"$SEND_JSON")
+ERROR_DESC=$(jq -r '.ErrorDescription // empty' <<<"$SEND_JSON")
+
+#1 OK
+#2 Connect failed.
+#3 Authorization failed.
+#4 Binary file not found. Please check the location.
+#5 Not enough credits available. Please recharge your account to proceed.
+#6 Time out error.
+#7 Transmission error. Please try it again.
+#8 Invalid UserKey. Please check the spelling of the UserKey.
+#9 Invalid Password.
+#10 Invalid originator. A maximum of 11 characters is allowed for alphanumeric originators.
+#11 Invalid message date. Please verify the data.
+#12 Invalid binary data. Please verify the data.
+#13 Invalid binary file. Please check the file type.
+#14 Invalid MCC. Please check the number.
+#15 Invalid MNC. Please check the number.
+#16 Invalid XSer.
+#17 Invalid URL buffered message notification string.
+#18 Invalid URL delivery notification string.
+#19 Invalid URL non delivery notification string.
+#20 Missing a recipient. Please specify at least one recipient.
+#21 Missing binary data. Please specify some data.
+#22 Invalid deferred delivery time. Please check the format.
+#23 Missing transaction reference number.
+#24 Service temporarely not available.
+#25 User access denied.
+#28 No Originator Restrictions.
+#29 Originator Authorization Pending.
+#30 Originator Not Authorized.
+#31 Originator already authorized.
+#32 No Notification Recipient Restrictions.
+#33 Notification Recipient Authorization Pending.
+#34 Notification Recipient Not Authorized.
+#35 Notification Recipient Already Authorized.
+#36 Security Token authorization pending.
+#37 Security Token not authorized.
+#38 Security Token not found.
+#39 Security Token already authorized.
+
+case "$ERROR_CODE" in
+ 1)
+ ;;
+ 3|8|9)
+ echo "$ERROR_DESC" >&2
+ exit 3
+ ;;
+ 20|206)
+ echo "$ERROR_DESC" >&2
+ exit 4
+ ;;
+ 24)
+ echo "$ERROR_DESC" >&2
+ exit 7
+ ;;
+ "")
+ echo "Unexpected response:" >&2
+ echo "$SEND_JSON" >&2
+ exit 2
+ ;;
+ *)
+ echo "$ERROR_DESC" >&2
+ exit 7
+ ;;
+esac
+
+#
+# Poll delivery status
+#
+#
+# DeliveryStatus:
+# -1 not yet known
+# 0 delivered
+# 1 buffered
+# 2 failed
+#
+# Reason codes of interest:
+#
+# 000 unknown subscriber
+# 101 unknown subscriber
+# 103 Call Barred
+# 107 absent subscriber
+# 108 delivery failed (buffered / not delivered)
+# 110 Protocol error
+# 111 MS not qeuipment
+# 105/113 SC congestion
+# 118-126 network/provider failures
+# 206 invalid destination address
+#
+# Full list:
+#
+#000 Unknown subscriber
+#001 Service temporary not available
+#002 Service temporary not available
+#003 Service temporary not available
+#004 Service temporary not available
+#005 Service temporary not available
+#006 Service temporary not available
+#007 Service temporary not available
+#008 Service temporary not available
+#009 Illegal error code
+#010 Network time-out
+#100 Facility not supported
+#101 Unknown subscriber
+#102 Facility not provided
+#103 Call barred
+#104 Operation barred
+#105 SC congestion
+#106 Facility not supported
+#107 Absent subscriber
+#108 Delivery fail
+#109 SC congestion
+#110 Protocol error
+#111 MS not equipped
+#112 Unknown SC
+#113 SC congestion
+#114 Illegal MS
+#115 MS not a subscriber
+#116 Error in MS
+#117 SMS lower layer not provisioned
+#118 System fail
+#119 PLMN system failure
+#120 HLR system failure
+#121 VLR system failure
+#122 Previous VLR system failure
+#123 Controlling MSC system failure
+#124 VMSC system failure
+#125 EIR system failure
+#126 System failure
+#127 Unexpected data value
+#200 Error in address service centre
+#201 Invalid absolute Validity Period
+#202 Short message exceeds maximum
+#203 Unable to Unpack GSM message
+#204 Unable to convert to IA5 ALPHABET
+#205 Invalid validity period format
+#206 Invalid destination address
+#207 Duplicate message submit
+#208 Invalid message type indicator
+
+for ((i=0;i<60;i++))
+do
+ SEC=$(($i / 10))
+ # Wait at least 100ms, then go up every second by 1 second
+ sleep ${SEC}.1
+ echo "Fetching status..."
+ STATUS_JSON="$(
+ curl -fsS \
+ --get \
+ "$API/SendingStat03/Get" \
+ --data-urlencode "Userkey=$ASPSMS_USERKEY" \
+ --data-urlencode "Password=$ASPSMS_PASSWORD" \
+ --data-urlencode "TransactionReferenceNumber=$TRANSREF"
+ )" || continue
+
+ jq <<< "$STATUS_JSON"
+ # SendingStat03/Get returns an array of SMSMessagesWebAPI objects on
+ # success, or an ASPSMSServerResult object ({"ErrorCode":..}) on error /
+ # when no sendlog entry exists yet. Guard against indexing the object form,
+ # which would make jq error out and abort the script under `set -e`.
+ # In the message objects the delivery status is the field DST (0=delivered,
+ # 1=buffered, 2=failed, absent/-1=not yet known) and the reason is RSN.
+ DELIVERY=$(jq -r 'if type=="array" then (.[0].DST // empty) else empty end' <<<"$STATUS_JSON")
+ REASON=$(jq -r 'if type=="array" then (.[0].RSN // "") else "" end' <<<"$STATUS_JSON")
+
+ case "$DELIVERY" in
+
+ 0)
+ echo "Success!" >&2
+ exit 0
+ ;;
+
+ 1)
+ continue
+ ;;
+
+ 2)
+ echo "Failure: $REASON"
+ case "$REASON" in
+
+ 206|000|101)
+ exit 4
+ ;;
+
+ 107|108)
+ exit 5
+ ;;
+
+ 105|113|118|119|120|121|122|123|124|125|126)
+ exit 6
+ ;;
+
+ *)
+ exit 9
+ ;;
+ esac
+ ;;
+
+ -1|"")
+ continue
+ ;;
+
+ esac
+
+done
+
+exit 8
+
+#| Exit | Meaning |
+#| ---- | ----------------------------------------------------------------------------- |
+#| 0 | SMS successfully delivered |
+#| 1 | Usage or local configuration error |
+#| 2 | Unable to contact ASPSMS/API/network error |
+#| 3 | Authentication failure (invalid user key/password) |
+#| 4 | Invalid or unknown recipient number |
+#| 5 | Recipient unreachable (phone switched off, out of coverage, delivery expired) |
+#| 6 | Mobile operator/network/provider failure |
+#| 7 | ASPSMS rejected the request (temporary service issues, invalid request, etc.) |
+#| 8 | Timed out waiting for a final delivery report |
+#| 9 | Delivery failed for an unclassified reason |