I have this example for sending a text message using cUrl:
curl --request POST \
--url https://a.eztexting.com/v1/messages \
--header 'accept: */*' \
--header 'authorization: Basic YmhvcHBAbWF0cml4Y29tcHV0ZXIuY29tOjc3U2V2ZW50eVNldmVuIQ==' \
--header 'content-type: application/json' \
--data '
{
"message": "Test of EzTexting",
"toNumbers": [
"17147263600"
]
}
How do I duplicate this in Fivewin, seems like there is a set of curl functions.
I tried doing this:
Function SendTextEZ()
Local oParms := GetEmptyHash()
Local cParms := ""
Local cEndPoint := ""
Local cResponse := ""
Local oResponse := nil
Local nResponse := 0
Local oHttp := CreateObject( "MSXML2.XmlHttp" )
Local cLogFile := Mcs_AppPath() + "JSONSend.txt"
If File( cLogFile )
Ferase( cLogFile )
Endif
Begin Sequence
oParms["message" ] := "Test Text from the EZ Texting API."
oParms["PhoneNumbers"] := { "17147263600" }
cParms := hb_JsonEncode( oParms )
cEndPoint := [https:] + [/] + [/] + [a.eztexting.com/v1/messages]
oHttp:Open( "POST",cEndPoint,.f. )
oHttp:SetRequestHeader( 'accept','*' + [/] + '*' )
oHttp:SetRequestHeader( 'authorization','Basic MyEncryptedUserNamePassWordString' )
oHttp:SetRequestHeader( 'content-type', 'application/json' )
Logit( cLogFile,"EndPoint:" + cEndPoint )
Logit( cLogFile,"Parameters:" + cParms )
oHttp:Send( cParms )
If oHttp:status == 200 .OR. oHttp:status == 201
cResponse := oHttp:ResponseText()
nResponse := hb_JsonDecode( cResponse,@oResponse )
Else
MsgStop( oHttp:status,oHttp:statusText )
Endif
End Sequence
oHttp := nil
Return nil
Always get 401 error.
Thanks,
EZTexting Send Message
-
- Posts: 388
- Joined: Sun Nov 06, 2005 3:55 pm
- Location: Southern California, USA
- Contact:
EZTexting Send Message
Thanks,
Byron Hopp
Matrix Computer Services
Byron Hopp
Matrix Computer Services
Re: EZTexting Send Message
I use Twillio for an SMS service. I wanted to see if my clients would actually use it, so I did not expand the class to include receiving replies. That is a whole other layer of complication, but I may do it.
Here is my complete program which includes logging, and also the ability to do scripts ( which I call from a button on the button bar, where it applies ).
I hope this helps.
Tim
Here is my complete program which includes logging, and also the ability to do scripts ( which I call from a button on the button bar, where it applies ).
I hope this helps.
Tim
Code: Select all | Expand
#INCLUDE "hbClass.ch"
#include "hbcurl.ch"
#include "fivewin.ch"
#include "tdata.ch"
CLASS TTwilioSMS
// Class Data
DATA cAcctSID
DATA cAuthToken
DATA cAcctPhone
DATA hCurl
DATA httpcode
DATA cLogFile INIT "Twilio.log"
DATA cResponse
DATA cDestinationNum
DATA cSMSscript
DATA cUrl
DATA nError INIT 0
DATA nMaxLogSize INIT 32768
DATA cDateStart, cDateEnd
DATA cvoiceMail, cReplyEmail
DATA lDebug INIT .F.
// Class Methods
METHOD New()
METHOD End()
METHOD Send()
METHOD Reset()
METHOD GetMessagesLog()
ENDCLASS
//------------------------------------------------------------------------------------------------
METHOD New( cTo, cText ) CLASS TTwilioSMS
// Initialize the class
::hCurl := curl_easy_init()
// Obtain data constants
oConfig := tConfig():New()
::cAcctSID := TRIM( oConfig:sysus25 ). // Account number, stored in the dbf file
::cAuthToken := TRIM( oConfig:sysus26 ) // Authorization code also stored in the dbf file
::cAcctPhone := TRIM( oConfig:sysus27 ) // The Twillio phone number assigned to the client.
oConfig:close()
::cUrl := "https://api.twilio.com/2010-04-01/Accounts/" + TRIM( ::cAcctSID ) + "/Messages.json"
RETURN Self
//------------------------------------------------------------------------------------------------
METHOD Send( cTo, cText, cAcrnum, cWrkord ) CLASS TTwilioSMS
Local cPostFields, lDidSend := .f.
Local httpcode, hInitData := { => }
// Set the text and desitination
::cDestinationNum := cTo
::cSMSscript := cText
// Setup cURL options
curl_easy_setopt( ::hCurl, HB_CURLOPT_POST, 1 )
curl_easy_setopt( ::hCurl, HB_CURLOPT_URL, ::cUrl )
curl_easy_setopt( ::hCurl, HB_CURLOPT_USERPWD, ::cAcctSID + ':' + ::cAuthToken )
curl_easy_setopt( ::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt( ::hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
cPostFields := 'To=' + ::cDestinationNum + ; // Line[ 3 ] +;
'&From=' + ::cAcctPhone +;
'&Body=' + curl_easy_escape( ::hCurl, AllTrim( ::cSMSscript ) )
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 the initialization is OK, run the process
IF ::nError = HB_CURLE_OK
::cResponse = curl_easy_dl_buff_get( ::hCurl )
lDidSend := .t.
Else
cReply := "Text send failure"
ENDIF
// Lets decode the response
hb_JsonDecode( ::cResponse, @hInitData )
cReply := HB_HGET( hInitData, "sid") // Message id
// Lets append a log entry
oUsers := tdata():new(, "twlog" )
oUsers:use()
oUsers:append()
oUsers:smsdate := DATE()
oUsers:smstime := TIME()
oUsers:smsto := ::cDestinationNum
oUsers:smsbody := ::cSMSscript
oUsers:acrnum := cAcrnum
oUsers:wrkord := cWrkord
oUsers:SMSmode := "S"
oUsers:SMStype := "G"
oUsers:SMSreply := cReply
oUsers:save()
oUsers:close()
return( lDidSend )
//------------------------------------------------------------------------------------------------
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, cAcctSID + ':' + cAuthToken )
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:", ::cSMSscript }, ::nMaxLogSize )
LogData( ::cLogFile, { "Error Num:", ::nError, "Httpcode:", ::httpcode }, ::nMaxLogSize )
LogData( ::cLogFile, curl_easy_strerror( ::nError ), ::nMaxLogSize )
*/
ENDIF
MemoWrit( "Twilio.log", ::cResponse )
RETURN NIL
/*
Send an SMS text with cTo, cBody, cAcrNum, cWrkord
*/
FUNCTION SendSMS( cTo, cAcrNum, cWrkOrd )
LOCAL oTest, lOK := .f., lDoSend := .f., cScript := " ", lx := 0, cToC := ""
LOCAL cBody := SPACE(300), aSMScode := {}, aSMSscript := {}
DEFAULT cTo := " ", cAcrNum := " ", cWrkOrd := " "
// Load scripts array
AADD( aSMScode, " ")
AADD( aSMSscript, " ")
oESMS := tData():New( ,"SMSscript" )
oESMS:Use()
oESMS:gotop()
DO WHILE ! oESMS:EOF()
AADD( aSMScode, oESMS:smscode )
AADD( aSMSscript, oESMS:SMSscript )
oESMS:skip()
ENDDO
oESMS:close()
// Provide for edit of text
DEFINE DIALOG oeText RESOURCE "ETEXT" BRUSH oBrush TRANSPARENT // OF oWnd
REDEFINE GET cTo ID 100 OF oeText PICTURE "##################" MESSAGE "Enter the phone number to which you are sending the message"
REDEFINE GET cAcrNum ID 101 OF oeText MESSAGE "Enter the client account number"
REDEFINE GET cWrkOrd ID 102 OF oeText MESSAGE "Enter the workorder number"
REDEFINE COMBOBOX oCbxA1 VAR cScript ID 106 OF oeText ;
ITEMS aSMScode ON CHANGE ( lx := oCbxA1:nAt, cBody := aSMSscript[lx], oGet1:refresh() ) ;
MESSAGE "Select a script" STYLE CBS_DROPDOWN UPDATE
REDEFINE GET oGet1 VAR cBody MEMO ID 103 OF oeText MESSAGE "Enter the text of your message" UPDATE
REDEFINE BTNBMP ID 104 OF oeText RESOURCE "HROK" PROMPT "Send" NOBORDER TRANSPARENT ;
ACTION ( lDoSend := .t., oeText:end() ) MESSAGE "Send the SMS text message"
REDEFINE BTNBMP ID 105 OF oeText RESOURCE "HREXIT" PROMPT "Cancel" NOBORDER TRANSPARENT ;
ACTION oeText:end() MESSAGE "Cancel the text message"
// Activate the dialog
ACTIVATE DIALOG oeText CENTER
IF lDoSend
// Clean the phone number
cTo := "+1" + CharOnly( "0123456789", cTo)
// Send the text
oTest := tTwilioSMS():New( )
lOK := oTest:Send( cTo, cBody, cAcrnum, cWrkord )
oTest:End()
// Show Result
IF lOK
MsgInfo( "Your text message was sent" )
ELSE
MsgInfo( "There was an error sending your message" )
ENDIF
ENDIF
RETURN NIL
FUNCTION TwilioSetup
// Declare EXTERNAL variables
MEMVAR oWnd
// Declare LOCAL variables
LOCAL ofBrush, cTitle := "Twilio SMS Account Setup", lOK := .f.
LOCAL oDlg, cAcctSID, cAuthToken, cAcctPhone, lUseTwilio
oConfig := tConfig():New()
cAcctSID := oConfig:sysus25
cAuthToken := oConfig:sysus26
cAcctPhone := oConfig:sysus27
lUseTwilio := oConfig:sysuf12
oConfig:close()
// Create the dialog
DEFINE DIALOG oDlg RESOURCE "TWILIO" BRUSH oBrush TRANSPARENT TITLE cTitle
// Create the button controls
REDEFINE BTNBMP RESOURCE "HROK" ID 332 of oDlg PROMPT "Accept" NOBORDER TRANSPARENT ;
ACTION ( lOk := .t., oDlg:End( ) ) MESSAGE "Use the values entered above"
REDEFINE BTNBMP RESOURCE "HREXIT" ID 333 of oDlg PROMPT "Cancel" NOBORDER TRANSPARENT ;
ACTION ( oDlg:End( ), lOk := .f. ) MESSAGE "Exit without using these values"
// Now add the edit controls
REDEFINE GET cAcctSID ID 339 OF oDlg
REDEFINE GET cAuthToken ID 338 OF oDlg
REDEFINE GET cAcctPhone ID 337 OF oDlg
REDEFINE CHECKBOX lUseTwilio ID 336 OF oDlg
// Activate the dialog
ACTIVATE DIALOG oDlg CENTERED
IF lOk // If desired, return the get values
oConfig := tConfig():New()
oConfig:sysus25 := cAcctSID
oConfig:sysus26 := cAuthToken
oConfig:sysus27 := cAcctPhone
oConfig:sysuf12 := lUseTwilio
oConfig:save()
oConfig:close()
ENDIF
RETURN NIL
FUNCTION TextLogView( cView, cValue )
LOCAL oELog, oBrw, bDate := DATE(), eDate := DATE( )
oELog := tData():New( ,"twlog" )
oELog:Use()
IF cView = "D"
DateGet2( "Text Date Range Browse", "Beginning date:", @bDate, "Ending date:", @eDate )
oELog:setorder(1)
oELog:setscopetop( bdate )
oELog:setscopebottom( edate )
ELSEIF cView = "A"
oELog:setorder(2)
oELog:setscopetop( cValue )
oELog:setscopebottom( cValue )
ELSEIF cView = "W"
oELog:setorder(3)
oELog:setscopetop( cValue )
oELog:setscopebottom( cValue )
ENDIF
oELog:gotop()
oBrw := XBROWSER oELog TITLE "Sent Email Log" SETUP oBrw:cHeaders := { "Date", "Time", "To", "Message", "Account", "Order", "Type", "Mode", "Response"} AUTOFIT
oELog:close( )
RETURN NIL
Function SMSscripts
// Create scripts list
// Open script database
oESMS := tData():New( ,"SMSscript" )
oESMS:Use()
oESMS:gotop()
// Open the dialog using a resource from EMS.DLL
DEFINE DIALOG oDlg RESOURCE "ESCRIPTS" BRUSH oBrush transparent OF oWnd TITLE "Text message scripts"
oDlg:nHelpID := 5
// Build the edit controls
REDEFINE SAY oSa1 PROMPT "Code" ID 4900 OF oDlg
REDEFINE GET oESMS:SMScode ID 102 OF oDlg MESSAGE "The script code" UPDATE
REDEFINE SAY oSa2 PROMPT "Script" ID 4901 OF oDlg
REDEFINE GET oESMS:SMSscript ID 103 OF oDlg MESSAGE "Enter a script for this code" UPDATE
REDEFINE XBROWSE oLbx1 ;
DATASOURCE oESMS ;
HEADERS " Code ", " SCRIPT ", " " ;
COLUMNS "SMScode", "SMSscript", " " ;
ON CHANGE oDlg:update() ;
ID 101 OF oDlg ;
UPDATE
// Provide the header gradient
oLbx1:bClrGrad := aPubGrad
// Set the styles
oLbx1:nMarqueeStyle := MARQSTYLE_HIGHLROW
oLbx1:nColDividerStyle := LINESTYLE_RAISED
oLbx1:nRowDividerStyle := LINESTYLE_RAISED
oLbx1:nHeadStrAligns := AL_CENTER
oLbx1:nStretchCol := STRETCHCOL_LAST
REDEFINE BUTTONBAR oBarLst ID 105 SIZE 60,60 OF oDlg 2015
oBarLst:bClrGrad := aPubGrad
// Build the button controls
DEFINE BUTTON OF oBarLst RESOURCE "HRADD" PROMPT "Add" TOOLTIP "Add a record" ;
ACTION ( oLbx1:gobottom(), oESMS:append( ), oESMS:blank( ), oLbx1:refresh(), oDlg:update( ) ) ;
MESSAGE "Add a new item"
DEFINE BUTTON OF oBarLst RESOURCE "HRSAVE" PROMPT "Save" TOOLTIP "Save changes" ;
ACTION ( oESMS:save( ), oDlg:update( ), oLbx1:refresh(), oLbx1:setfocus( ) ) ;
MESSAGE "Save any changes made to the current item"
DEFINE BUTTON OF oBarLst RESOURCE "HRDELETE" PROMPT "Delete" TOOLTIP "Delete selected record" ;
ACTION ( IIF( MsgYesNo( "Do you wish to delete this item ?"), ( oESMS:delete( ),;
oESMS:skip(1), oLbx1:refresh(), oDlg:update()),)) MESSAGE "Delete the current item"
DEFINE BUTTON OF oBarLst RESOURCE "HREXIT" PROMPT "Exit" TOOLTIP "Exit this list" ;
ACTION oDlg:end() MESSAGE "Exit this list" GROUP BTNRIGHT
// Activate the dialog screen
ACTIVATE DIALOG oDlg ON INIT (oReBar:hide(), oBarLst:lTransparent := .F.) CENTERED
// Redisplay the bar
oReBar:show()
// Close the database
oESMS:close()
RETURN NIL
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
-
- Posts: 388
- Joined: Sun Nov 06, 2005 3:55 pm
- Location: Southern California, USA
- Contact:
Re: EZTexting Send Message
Wow Tim, Thanks. I'll check it out.
Thanks,
Byron Hopp
Matrix Computer Services
Byron Hopp
Matrix Computer Services
-
- Posts: 388
- Joined: Sun Nov 06, 2005 3:55 pm
- Location: Southern California, USA
- Contact:
Re: EZTexting Send Message
Is there any documentation on the Curl lib in Harbour. Seems I have several examples of curl using C++ but some of the commands do not exists in the harbour curl ch file. Mr. Stone has left a very complete class, but I am working with EXTexting, and his class is for Twillo. It may be worth switching to Twillo in the long run. I already have an account with EZTexting.
Thanks,
Byron Hopp
Matrix Computer Services
Byron Hopp
Matrix Computer Services
-
- Posts: 388
- Joined: Sun Nov 06, 2005 3:55 pm
- Location: Southern California, USA
- Contact:
Re: EZTexting Send Message
Here is a code example, but I am guessing, WHACK == "/"
Function SendTextCurl()
Local aHeaders := {}
Local oCurl := curl_easy_init()
Local uRet := nil
curl_easy_setopt( oCurl,HB_CURLOPT_CUSTOM_REQUEST,"POST" )
curl_easy_setopt( oCurl,HB_CURLOPT_WRITEDATA ,stdout )
curl_easy_setopt( oCurl,HB_CURLOPT_URL ,"https:" + WHACK + WHACK +"a.eztexting.com/v1/messages" )
AAdd( aHeaders,"accept: *" + WHACK + "*")
AAdd( aHeaders,"content-type: application/json" )
AAdd( aHeaders,"authorization: Basic XXXXOOOOMyPasswordXXXXOOOO" )
curl_easy_setopt( oCurl,HB_CURLOPT_HTTPHEADER, aHeaders )
curl_easy_setopt( oCurl,HB_CURLOPT_POSTFIELDS,[{"message":"Test Text from the EZ Texting API.","PhoneNumbers":["17147263600"]}] )
uRet := curl_easy_preform( oCurl )
MsgInfo( uRet,"Curl Ret" )
Return nil
Function SendTextCurl()
Local aHeaders := {}
Local oCurl := curl_easy_init()
Local uRet := nil
curl_easy_setopt( oCurl,HB_CURLOPT_CUSTOM_REQUEST,"POST" )
curl_easy_setopt( oCurl,HB_CURLOPT_WRITEDATA ,stdout )
curl_easy_setopt( oCurl,HB_CURLOPT_URL ,"https:" + WHACK + WHACK +"a.eztexting.com/v1/messages" )
AAdd( aHeaders,"accept: *" + WHACK + "*")
AAdd( aHeaders,"content-type: application/json" )
AAdd( aHeaders,"authorization: Basic XXXXOOOOMyPasswordXXXXOOOO" )
curl_easy_setopt( oCurl,HB_CURLOPT_HTTPHEADER, aHeaders )
curl_easy_setopt( oCurl,HB_CURLOPT_POSTFIELDS,[{"message":"Test Text from the EZ Texting API.","PhoneNumbers":["17147263600"]}] )
uRet := curl_easy_preform( oCurl )
MsgInfo( uRet,"Curl Ret" )
Return nil
Thanks,
Byron Hopp
Matrix Computer Services
Byron Hopp
Matrix Computer Services
Re: EZTexting Send Message
If you look at my code you will see it implemented. I am out of the office this week but will send yo curl info as soon as possible
Sent from my iPhone using Tapatalk
Sent from my iPhone using Tapatalk
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
-
- Posts: 388
- Joined: Sun Nov 06, 2005 3:55 pm
- Location: Southern California, USA
- Contact:
Re: EZTexting Send Message
I'll look forward to it. Have a great time off.
Byron ...
Byron ...
Thanks,
Byron Hopp
Matrix Computer Services
Byron Hopp
Matrix Computer Services
- reinaldocrespo
- Posts: 979
- Joined: Thu Nov 17, 2005 5:49 pm
- Location: Fort Lauderdale, FL
Re: EZTexting Send Message
Hello Byron and Tim;
This link will show you my initial post when I shared the TTwilio class on this forum back in 2022: https://forums.fivetechsupport.com/view ... 9527c26320
And you can see I'm not using aHeaders here. Instead I allow curl_easy_setopt() do the job.
I have expanded the class to send WhatsApp, Voice calls, and receive texts back and forth. I use it to send patients reminders about their appointments and receive confirmations or cancellations back via SMS. However, at this point I'm interested on learning about how you plan on sending texts without a service like Twilio. Twilio is a paid for service. Not expensive but still there is an ongoing cost to sending and receiving texts and as you add voice calls and WhatsApp, more costs are added.
I'm interested on learning about the service you intend to use. I will be glad to write code if it turns out to be a better or less expensive option than Twilio. Please share this information.
Thank you.
This link will show you my initial post when I shared the TTwilio class on this forum back in 2022: https://forums.fivetechsupport.com/view ... 9527c26320
And you can see I'm not using aHeaders here. Instead I allow curl_easy_setopt() do the job.
I have expanded the class to send WhatsApp, Voice calls, and receive texts back and forth. I use it to send patients reminders about their appointments and receive confirmations or cancellations back via SMS. However, at this point I'm interested on learning about how you plan on sending texts without a service like Twilio. Twilio is a paid for service. Not expensive but still there is an ongoing cost to sending and receiving texts and as you add voice calls and WhatsApp, more costs are added.
I'm interested on learning about the service you intend to use. I will be glad to write code if it turns out to be a better or less expensive option than Twilio. Please share this information.
Thank you.
Re: EZTexting Send Message
Reinaldo,
I am using Twillio outbound, but would love to see your implementation for inbound text messages.
Tim
I am using Twillio outbound, but would love to see your implementation for inbound text messages.
Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit