challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

commit 0804fe640b1b28c5f4b71c296fa838af0a697eff
parent 33018904026e10ea0458d3559228c6a7eacb2837
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed,  1 Jul 2026 20:23:37 +0200

missing file

Diffstat:
Asrc/challenger/challenger-send-sms-aspsms | 301+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 |