anastasis

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

anastasis-authorization-sms-clicksend.sh (3678B)


      1 #!/bin/bash
      2 # This file is in the public domain.
      3 # Send an SMS using ClickSend API
      4 
      5 set -eu
      6 
      7 # Check shared secrets
      8 if [ -x "$CLICKSEND_USERNAME" ]
      9 then
     10     echo "CLICKSEND_USERNAME not set in environment"
     11     exit 1
     12 fi
     13 if [ -x "$CLICKSEND_API_KEY" ]
     14 then
     15     echo "CLICKSEND_API_KEY not set in environment"
     16     exit 1
     17 fi
     18 
     19 if [ $# -ne 1 ]
     20 then
     21     echo "Usage: $0 <phone_number>" 1>&2
     22     exit 1
     23 fi
     24 
     25 PHONE_NUMBER="$1"
     26 MESSAGE=$(cat -)
     27 
     28 TMPFILE=$(mktemp /tmp/clicksend-sms-logging-XXXXXX)
     29 
     30 RESPONSE=$(curl --silent --show-error --fail \
     31   --url https://rest.clicksend.com/v3/sms/send \
     32   --request POST \
     33   --header 'Content-Type: application/json' \
     34   --user "$CLICKSEND_USERNAME:$CLICKSEND_API_KEY" \
     35   --data "{
     36     \"messages\": [{
     37       \"source\": \"bash-script\",
     38       \"to\": \"$PHONE_NUMBER\",
     39       \"body\": \"$MESSAGE\"
     40     }]
     41   }")
     42 
     43 echo "$RESPONSE" > "$TMPFILE"
     44 
     45 RESPONSE_CODE=$(echo "$RESPONSE" | jq -r '.response_code')
     46 
     47 if [ "$RESPONSE_CODE" != "SUCCESS" ];
     48 then
     49     echo "Clicksend: failed to send SMS to $PHONE_NUMBER, got response code $RESPONSE_CODE." 1>&2
     50     exit 2
     51 fi
     52 
     53 MESSAGE_ID=$(echo "$RESPONSE" | jq -r '.data.messages[0].message_id')
     54 
     55 if [ "$MESSAGE_ID" == "null" ];
     56 then
     57     echo "Clicksend: failed to retrieve message ID for message to $PHONE_NUMBER." 1>&2
     58     echo "$RESPONSE" 1>&2
     59     exit 3
     60 fi
     61 
     62 MESSAGE_STATUS=$(echo "$RESPONSE" | jq -r '.data.messages[0].status')
     63 
     64 if [ "$MESSAGE_STATUS" == "SUCCESS" ];
     65 then
     66     echo "Clicksend: message delivered successfully to $PHONE_NUMBER." 1>&2
     67     exit 0
     68 fi
     69 
     70 MAX_ITERATIONS=12
     71 
     72 # Poll message status
     73 echo "Polling message status (message_id: $MESSAGE_ID)..." 1>&2
     74 for N in $(seq 1 "$MAX_ITERATIONS")
     75 do
     76     STATUS_RESPONSE=$(curl --silent --show-error --fail \
     77       --url "https://rest.clicksend.com/v3/sms/receipts/$MESSAGE_ID" \
     78       --user "$CLICKSEND_USERNAME:$CLICKSEND_API_KEY")
     79 
     80     echo "$STATUS_RESPONSE" >> "$TMPFILE"
     81 
     82     RESPONSE_CODE=$(echo "$RESPONSE" | jq -r '.response_code')
     83 
     84     if [ "$RESPONSE_CODE" != "SUCCESS" ];
     85     then
     86 	echo "Clicksend: failed to get status for message to $PHONE_NUMBER, assuming failure." 1>&2
     87         echo "$RESPONSE" 1>&2
     88 	exit 4
     89     fi
     90 
     91     STATUS_CODE=$(echo "$STATUS_RESPONSE" | jq -r '.data.status_code')
     92     STATUS_TEXT=$(echo "$STATUS_RESPONSE" | jq -r '.data.status_text')
     93     STATUS=$(echo "$STATUS_TEXT" | awk --field-separator ':' '{print $1}')
     94 
     95     case "$STATUS_CODE" in
     96 	"200")
     97 	    case "$STATUS" in
     98 		"Success"|"Sent")
     99 		    # Message sent to the network for delivery, wait a bit
    100 		    sleep 1
    101 		    ;;
    102 		"Queued"|"Scheduled")
    103 		    # queued for delivery, sleep a bit longer
    104 		    sleep 10
    105 		    ;;
    106 		"WaitApproval")
    107 		    # Human in the loop (strange), sleep even longer
    108 		    sleep 120
    109 		    ;;
    110 		*)
    111 		    # Unexpected status, keep trying
    112 		    sleep 5
    113 		    ;;
    114 	    esac
    115 	    ;;
    116         "201")
    117 	    # Message delivered to the handset
    118 	    echo "Clicksend: message delivered successfully to $PHONE_NUMBER." 1>&2
    119 	    exit 0
    120 	    ;;
    121 	"300")
    122 	    # Temporary network error, clicksend will retry automatically, sleep a bit
    123 	    sleep 20
    124 	    ;;
    125 	"301")
    126 	    # Delivery failed
    127             echo "Clicksend: message delivery to $PHONE_NUMBER failed: $DESCRIPTION" 1>&2
    128 	    exit 1
    129 	    ;;
    130         "FAILED"|"INVALID_RECIPIENT")
    131             echo "Clicksend: message delivery to $PHONE_NUMBER failed: $DESCRIPTION" 1>&2
    132             exit 6
    133             ;;
    134         *)
    135             echo "Clicksend: message delivery to $PHONE_NUMBER failed: $DESCRIPTION" 1>&2
    136             sleep 5
    137             ;;
    138     esac
    139 done
    140 
    141 echo "Clicksend: unclear message delivery status $STATUS_CODE ($DESCRIPTION) after $MAX_ITERATIONS iterations. Assuming failure." 1>&2
    142 exit 1