compile errors - send a SMS

Re: compile errors

Postby Enrico Maria Giordano » Thu Apr 11, 2024 4:43 pm

No, this is fine till you switch to BCC 7.70. Then you can remove it.
User avatar
Enrico Maria Giordano
 
Posts: 8718
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: compile errors

Postby Jeff Barnes » Thu Apr 11, 2024 4:48 pm

Perfect. Thanks all for the help. I was able to send myself an SMS :D
Thanks,
Jeff Barnes

(FWH 16.11, xHarbour 1.2.3, Bcc730)
User avatar
Jeff Barnes
 
Posts: 929
Joined: Sun Oct 09, 2005 1:05 pm
Location: Ontario, Canada


Re: compile errors - send a SMS

Postby TimStone » Fri Apr 12, 2024 5:38 pm

I have run SMS with Twilio for the past 15 months. Here is my complete code implementation. * & # are used in spaces where specific client values must be substituted.

Code: Select all  Expand view  RUN


Communications
curl.exe -X POST https://api.twilio.com/2010-04-01/Accounts/****************/Messages.json ^
--data-urlencode "Body=Hello from Twilio" ^
--data-urlencode "From=+########" ^
--data-urlencode "To=+##########" ^
-u *********************:$TWILIO_cAuthToken

*/

/*   TWILIO text messaging utility -
            Updated:  11/29/2022 3:01:49 PM   */


#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 )
        ::cAuthToken := TRIM( oConfig:sysus26 )
        ::cAcctPhone := TRIM( oConfig:sysus27 )
        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



/*
// Resource DIALOG

TWILIO DIALOG 0, 0, 350, 120
STYLE  WS_POPUP | WS_CAPTION
CAPTION "Twillio Account Setup"
{
    LTEXT           "Account SSID",-1,10,10,80,10
    EDITTEXT        339,110,10,160,10
    LTEXT           "Account AUTH ",-1,10,25,80,10
    EDITTEXT        338,110,25,160,10
    LTEXT           "Account Phone ",-1,10,40,80,10
    EDITTEXT        337,110,40,160,10
    CONTROL         " Use Twilio for SMS Text ?",336,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,55,160,10
    PUSHBUTTON      "",332,125,70,40,40
    PUSHBUTTON      "",333,185,70,40,40
}


*/
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
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: compile errors - send a SMS

Postby Antonio Linares » Sat Apr 13, 2024 5:59 am

Dear Tim,

many thanks for sharing it!
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42111
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Previous

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 73 guests