libeufin-tan-sms-clicksend.sh (3262B)
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 "Failed to send message, got response code $RESPONSE_CODE." 1>&2 50 exit 1 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 "Failed to retrieve message ID." 1>&2 58 exit 1 59 fi 60 61 MESSAGE_STATUS=$(echo "$RESPONSE" | jq -r '.data.messages[0].status') 62 63 if [ "$MESSAGE_STATUS" == "SUCCESS" ]; 64 then 65 echo "Message delivered successfully." 1>&2 66 exit 0 67 fi 68 69 MAX_ITERATIONS=12 70 71 # Poll message status 72 echo "Polling message status (message_id: $MESSAGE_ID)..." 1>&2 73 for N in $(seq 1 "$MAX_ITERATIONS") 74 do 75 STATUS_RESPONSE=$(curl --silent --show-error --fail \ 76 --url "https://rest.clicksend.com/v3/sms/receipts/$MESSAGE_ID" \ 77 --user "$CLICKSEND_USERNAME:$CLICKSEND_API_KEY") 78 79 echo "$STATUS_RESPONSE" >> "$TMPFILE" 80 81 RESPONSE_CODE=$(echo "$RESPONSE" | jq -r '.response_code') 82 83 if [ "$RESPONSE_CODE" != "SUCCESS" ]; 84 then 85 echo "Failed to get message status, assuming failure." 1>&2 86 exit 1 87 fi 88 89 STATUS_CODE=$(echo "$STATUS_RESPONSE" | jq -r '.data.status_code') 90 STATUS_TEXT=$(echo "$STATUS_RESPONSE" | jq -r '.data.status_text') 91 STATUS=$(echo "$STATUS_TEXT" | awk --field-separator ':' '{print $1}') 92 93 case "$STATUS_CODE" in 94 "200") 95 case "$STATUS" in 96 "Success"|"Sent") 97 # Message sent to the network for delivery, wait a bit 98 sleep 1 99 ;; 100 "Queued"|"Scheduled") 101 # queued for delivery, sleep a bit longer 102 sleep 10 103 ;; 104 "WaitApproval") 105 # Human in the loop (strange), sleep even longer 106 sleep 120 107 ;; 108 *) 109 # Unexpected status, keep trying 110 sleep 5 111 ;; 112 esac 113 ;; 114 "201") 115 # Message delivered to the handset 116 echo "Message delivered successfully." 1>&2 117 exit 0 118 ;; 119 "300") 120 # Temporary network error, clicksend will retry automatically, sleep a bit 121 sleep 20 122 ;; 123 "301") 124 # Delivery failed 125 echo "Message delivery failed: $DESCRIPTION" 1>&2 126 exit 1 127 ;; 128 "FAILED"|"INVALID_RECIPIENT") 129 exit 1 130 ;; 131 *) 132 sleep 5 133 ;; 134 esac 135 done 136 137 echo "Unclear message delivery status $STATUS_CODE ($DESCRIPTION) after $MAX_ITERATIONS iterations. Assuming failure." 1>&2 138 exit 1 139 140