This is Reinaldo's code.
#INCLUDE "hbClass.ch"
#include "hbcurl.ch"
#define ACCOUNT_SID "xxxxxxxxxx$#B<SHJGHKxxxx"
#define AUTH_TOKEN "x@#$F&^%DEE"
#define TEL_FROM "555-555-55555"
CLASS TTwilioSMS
DATA hCurl
DATA httpcode
DATA cLogFile INIT "Twilio.log"
DATA cResponse
DATA cDestinationNum
DATA cSMSText
DATA cUrl INIT "https://api.twilio.com/2010-04-01/Accounts/" + ACCOUNT_SID + "/Messages.json"
DATA cVoiceUrl INIT "https://api.twilio.com/2010-04-01/Accounts/" + ACCOUNT_SID + "/Calls.json"
DATA nError INIT 0
DATA nMaxLogSize INIT 32768
DATA cDateStart, cDateEnd
DATA cvoiceMail, cReplyEmail
DATA lDebug INIT .F.
METHOD New()
METHOD End()
METHOD Send()
METHOD Reset()
METHOD MakePhoneCall()
METHOD GetMessagesLog()
ENDCLASS
//------------------------------------------------------------------------------------------------
METHOD New() CLASS TTwilioSMS
::hCurl := curl_easy_init()
RETURN Self
//------------------------------------------------------------------------------------------------
METHOD Send() CLASS TTwilioSMS
Local cPostFields
Local httpcode
curl_easy_setopt( ::hCurl, HB_CURLOPT_POST, 1 )
curl_easy_setopt( ::hCurl, HB_CURLOPT_URL, ::cUrl )
curl_easy_setopt( ::hCurl, HB_CURLOPT_USERPWD, ACCOUNT_SID + ':' + AUTH_TOKEN )
curl_easy_setopt( ::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt( ::hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
cPostFields := 'To=' + ::cDestinationNum + ; // Line[ 3 ] +;
'&From=' + TEL_FROM +;
'&Body=' + curl_easy_escape( ::hCurl, AllTrim( ::cSMSText ) )
If ::lDebug
LogFile( ::cLogFile, { cPostFields } )
endif
curl_easy_setopt( ::hcurl, HB_CURLOPT_POSTFIELDS, cPostFields )
::nError := curl_easy_perform( ::hCurl )
curl_easy_getinfo( ::hCurl, HB_CURLINFO_RESPONSE_CODE, @httpcode )
::httpcode := httpcode
IF ::nError = HB_CURLE_OK
::cResponse = curl_easy_dl_buff_get( ::hCurl )
Else
LogData( ::cLogFile, { "Twilio error sending SMS. Details below:" }, ::nMaxLogSize )
LogData( ::cLogFile, { "To", ::cDestinationNum, "SMS Text:", ::cSMSText }, ::nMaxLogSize )
LogData( ::cLogFile, { "Error Num:", ::nError, "Httpcode:", ::httpcode }, ::nMaxLogSize )
LogData( ::cLogFile, curl_easy_strerror( ::nError ), ::nMaxLogSize )
ENDIF
return NIL
//------------------------------------------------------------------------------------------------
METHOD Reset() CLASS TTwilioSMS
curl_easy_reset( ::hCurl )
return NIL
//------------------------------------------------------------------------------------------------
METHOD End() CLASS TTwilioSMS
curl_easy_cleanup( ::hCurl )
::hCurl := Nil
hb_gcAll( .t. )
return NIL
//------------------------------------------------------------------------------------------------
//must define ::cDateStart and ::cDateEnd before calling this method.
METHOD GetMessagesLog() CLASS TTwilioSMS
Local cparms := '?DateSent%3E=' + ::cDateStart + "&DateSent%3C=" + ::cDateEnd + "&PageSize=600"
Local httpcode
curl_easy_setopt( ::hCurl, HB_CURLOPT_HTTPGET, 1 )
curl_easy_setopt( ::hCurl, HB_CURLOPT_URL, ::cUrl + cParms )
curl_easy_setopt( ::hCurl, HB_CURLOPT_USERPWD, ACCOUNT_SID + ':' + AUTH_TOKEN )
curl_easy_setopt( ::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt( ::hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
::nError := curl_easy_perform( ::hCurl )
curl_easy_getinfo( ::hCurl, HB_CURLINFO_RESPONSE_CODE, @httpcode )
::httpcode := httpcode
IF ::nError = HB_CURLE_OK
::cResponse = curl_easy_dl_buff_get( ::hCurl )
::cResponse := StrTran( ::cResponse, Chr(10), "" )
Else
LogData( ::cLogFile, { "Twilio error sending SMS. Details below:" }, ::nMaxLogSize )
LogData( ::cLogFile, { "To", ::cDestinationNum, "SMS Text:", ::cSMSText }, ::nMaxLogSize )
LogData( ::cLogFile, { "Error Num:", ::nError, "Httpcode:", ::httpcode }, ::nMaxLogSize )
LogData( ::cLogFile, curl_easy_strerror( ::nError ), ::nMaxLogSize )
ENDIF
//MemoWrit( "Twilio.log", ::cResponse )
RETURN NIL
//------------------------------------------------------------------------------------------------
/*sample makeing a call using url to fetch parameters
https://www.twilio.com/docs/voice/api/call-resource
EXCLAMATION_MARK='!'
curl -X POST https://api.twilio.com/2010-04-01/Accou ... Calls.json \
--data-urlencode "Twiml=<Response><Say>Ahoy there$EXCLAMATION_MARK</Say></Response>" \
--data-urlencode "To=+15558675310" \
--data-urlencode "From=+15552223214" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
*/
//Twilml sample parameter "Twiml=<Response><Say>Ahoy there$EXCLAMATION_MARK</Say></Response>"
METHOD MakePhoneCall() CLASS TTwilioSMS
Local cPostFields
Local httpcode
curl_easy_setopt( ::hCurl, HB_CURLOPT_POST, 1 )
curl_easy_setopt( ::hCurl, HB_CURLOPT_URL, ::cVoiceUrl )
curl_easy_setopt( ::hCurl, HB_CURLOPT_USERPWD, ACCOUNT_SID + ':' + AUTH_TOKEN )
curl_easy_setopt( ::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt( ::hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
cPostFields := 'To=' + ::cDestinationNum + ; // Line[ 3 ] +;
'&From=' + TEL_FROM +;
'&CallReason=' + "medical appointment reminder" +;
'&Twiml=<Say voice="alice" language="es-MX">' + ::cVoiceMail + '</Say>' +;
'&CallerId=' + ::cReplyEmail
curl_easy_setopt( ::hcurl, HB_CURLOPT_POSTFIELDS, cPostFields )
::nError := curl_easy_perform( ::hCurl )
curl_easy_getinfo( ::hCurl, HB_CURLINFO_RESPONSE_CODE, @httpcode )
::httpcode := httpcode
IF ::nError = HB_CURLE_OK
::cResponse = curl_easy_dl_buff_get( ::hCurl )
Else
LogData( ::cLogFile, { "Twilio error making voice call. Details below:" }, ::nMaxLogSize )
LogData( ::cLogFile, { "To", ::cDestinationNum, "Message:", ::cVoiceMail }, ::nMaxLogSize )
LogData( ::cLogFile, { "Error Num:", ::nError, "Httpcode:", ::httpcode }, ::nMaxLogSize )
LogData( ::cLogFile, curl_easy_strerror( ::nError ), ::nMaxLogSize )
ENDIF
RETURN NIL
Here is what I modified:
1). #Define items: I changed these to DATA items. My clients will have their own accounts, so I created a Dialog for them to save those values in a file, and then within the Send routine, I bring in those values to use for sending the text. Those are the Account SSDI, AUTH, and PHONE.
2). I do not use the CALL feature so I removed it.
3). I have my own logging utility, so I substituted in my own process for his log routine.
4). I've made a couple of other changes specific to my implementation.
5). I modified the Send() Method to accept the text and phone number to be used in sending the SMS.
I would suggest setting up the account, then testing with Reinaldo's code, substituting in your own account info, then modifying it in steps.