anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

anastasis-authorization-sms-telesign.sh (4652B)


      1 #!/bin/bash
      2 # This file is in the public domain.
      3 # Send an SMS using Telesign API
      4 set -eu
      5 
      6 # Check shared secrets
      7 if [ -x "$TELESIGN_AUTH_TOKEN" ]
      8 then
      9     echo "TELESIGN_AUTH_TOKEN not set in environment"
     10     exit 1
     11 fi
     12 
     13 if [ $# -ne 1 ]; then
     14     echo "Usage: $0 <phone_number>" 1>&2
     15     exit 1
     16 fi
     17 
     18 PHONE_NUMBER="$1"
     19 MESSAGE=$(cat -)
     20 
     21 TMPFILE=$(mktemp /tmp/telesign-sms-logging-XXXXXX)
     22 
     23 RESPONSE=$(curl --silent --show-error --fail \
     24   --url https://rest-api.telesign.com/v1/messaging \
     25   --request POST \
     26   --header "Authorization: Basic $TELESIGN_AUTH_TOKEN" \
     27   --header "Content-Type: application/x-www-form-urlencoded" \
     28   --data account_livecycle_event=transact \
     29   --data "phone_number=$PHONE_NUMBER" \
     30   --data-urlencode "message=$MESSAGE" \
     31   --data "message_type=OTP")
     32 
     33 echo "$RESPONSE" > "$TMPFILE"
     34 REFERENCE_ID=$(jq -r '.reference_id' "$TMPFILE")
     35 
     36 if [ "$REFERENCE_ID" == "null" ];
     37 then
     38     echo "Telesign: failed to retrieve reference ID for message to $PHONE_NUMBER." 1>&2
     39     echo "$RESPONSE" 1>&2
     40     exit 1
     41 fi
     42 
     43 STATUS_CODE=$(echo "$RESPONSE" | jq -r '.status.code')
     44 
     45 case "$STATUS_CODE" in
     46     "200")
     47 	# Delivered to headset. Should basically never happen here.
     48         echo "Telesign: message delivered successfully to $PHONE_NUMBER." 1>&2
     49 	exit 0
     50         ;;
     51     "203"|"292"|"295")
     52 	# Delivered to gateway
     53 	sleep 2
     54         ;;
     55     "207"|"211"|"220"|"221"|"222"|"231"|"237"|"238")
     56 	# Failure to deliver (hard)
     57 	echo "Telesign: could not deliver message to $PHONE_NUMBER: $STATUS_CODE" 1>&2
     58 	exit 1
     59         ;;
     60     "210")
     61 	# Temporary phone error
     62 	;;
     63     "250")
     64 	# Final status unknown
     65 	echo "Telesign: final status unknown for message to $PHONE_NUMBER, assuming success" 1>&2
     66 	exit 0
     67 	;;
     68     "290")
     69 	# Message in progress, go into loop below
     70 	sleep 2
     71         ;;
     72     "502"|"503"|"504"|"505"|"506"|"507"|"508"|"509"|"510"|"511"|"512"|"513"|"514"|"515"|"517"|"520"|"521")
     73 	echo "Telesign: carrier problem ($STATUS_CODE) delivering to $PHONE_NUMBER" 1>&2
     74 	exit 1
     75 	;;
     76     "10000")
     77 	# Internal error at telesign...
     78 	echo "Telesign: internal error delivering to $PHONE_NUMBER" 1>&2
     79         echo "$RESPONSE" 1>&2
     80 	exit 1
     81 	;;
     82     "10019"|"10020")
     83 	# Rate limit exceeded. Treating as hard failure for now.
     84 	echo "Telesign: Rate limit exceeded ($STATUS_CODE) delivering to $PHONE_NUMBER" 1>&2
     85         echo "$RESPONSE" 1>&2
     86 	exit 1
     87 	;;
     88     *)
     89 	# Many possible status codes for failure...
     90 	echo "Telesign: Message delivery to $PHONE_NUMBER failed: $STATUS_CODE" 1>&2
     91         echo "$RESPONSE" 1&>2
     92 	exit 1
     93 	;;
     94 esac
     95 
     96 MAX_ITERATIONS=12
     97 
     98 # Poll for message status
     99 echo "Polling message status (reference_id: $REFERENCE_ID)..." 1>&2
    100 for N in $(seq 1 "$MAX_ITERATIONS")
    101 do
    102     STATUS_RESPONSE=$(curl --silent --show-error --fail \
    103       --url "https://rest-api.telesign.com/v1/messaging/$REFERENCE_ID" \
    104       --header "Authorization: Basic $TELESIGN_AUTH_TOKEN")
    105 
    106     echo "$STATUS_RESPONSE" >> "$TMPFILE"
    107 
    108     STATUS_CODE=$(echo "$STATUS_RESPONSE" | jq -r '.status.code')
    109     DESCRIPTION=$(echo "$STATUS_RESPONSE" | jq -r '.status.description')
    110 
    111     case "$STATUS_CODE" in
    112 	"200")
    113 	    # Delivered to headset. Great!
    114             echo "Telesign: message delivered successfully to $PHONE_NUMBER." 1>&2
    115             exit 0
    116             ;;
    117 	"203"|"290"|"292"|"295")
    118 	    # Delivered to gateway, wait a bit for an update
    119 	    sleep 2
    120             ;;
    121 	"210")
    122 	    # Temporary phone error
    123 	    sleep 15
    124 	    ;;
    125 	"207"|"211"|"220"|"221"|"222"|"231"|"237"|"238")
    126 	    # Failure to deliver (hard)
    127 	    echo "Telesign: could not deliver message to $PHONE_NUMBER ($STATUS_CODE)" 1>&2
    128 	    exit 8
    129             ;;
    130 	"250")
    131 	    # Final status unknown
    132 	    echo "Telesign: final status for delivery to $PHONE_NUMBER unknown, assuming success" 1>&2
    133 	    exit 0
    134 	    ;;
    135 	"502"|"503"|"504"|"505"|"506"|"507"|"508"|"509"|"510"|"511"|"512"|"513"|"514"|"515"|"517"|"520"|"521")
    136 	    echo "Telesign: carrier problem ($STATUS_CODE) for message to $PHONE_NUMBER" 1>&2
    137 	    exit 7
    138 	    ;;
    139 	"10000")
    140 	    # Internal error at telesign...
    141 	    echo "Telesign: internal error for message to $PHONE_NUMBER" 1>&2
    142 	    exit 9
    143 	    ;;
    144 	"10019"|"10020")
    145 	    # Rate limit exceeded. Treating as hard failure for now.
    146 	    echo "Telesign: rate limit exceeded for message to $PHONE_NUMBER" 1>&2
    147 	    exit 10
    148 	    ;;
    149 	*)
    150 	    # Many possible status codes for failure...
    151 	    echo "Telesign: message delivery to $PHONE_NUMBER failed: $STATUS_CODE" 1>&2
    152             echo "$RESPONSE" 1&>2
    153 	    exit 11
    154 	    ;;
    155     esac
    156 done
    157 
    158 echo "Telesign: unclear delivery status ${STATUS_CODE:-} (${DESCRIPTION:-}) for message to $PHONE_NUMBER after ${MAX_ITERATIONS:-} iterations. Assuming failure." 1>&2
    159 exit 12