/*
sendfax.p
Program to encrypt and send a Microsoft Word document to faxage.com.
Written in Progress 4GL, version 10.1A.  Earlier versions of Progress may
   require a different method of base-64 encoding (see Progress web site) or
   socket handling.
*/

/* replace "xxxxx" with your faxage-assigned username */
define variable username  as character  no-undo initial "xxxxx".

/* replace "xxxxx" with your faxage-assigned company credential - the one
   you use during the login process at www.faxage.com */
define variable company   as character  no-undo initial "xxxxx".

/* replace "xxxxx" with your faxage-assigned password */
define variable password  as character  no-undo initial "xxxxx".

define variable recipname as character  no-undo initial "Test Recipient Name".

/* replace nnnnnnnnnn with the number to which you want to send your test fax.
   Include the area code, do not prefix with "1", do not use any punctuation 
   characters */
define variable faxno     as character  no-undo initial "nnnnnnnnnn".

define variable operation as character  no-undo initial "sendfax".

/* replace this file name with the name of any Microsoft Word document 
   locally available to this program */
define variable faxfile1  as character  no-undo initial "C:\temp\test.doc".

/* replace "xxxxx" with the Sender name which will appear in the header of 
   each fax */
define variable tagname   as character  no-undo initial "xxxxx".

/* replace "xxxxx" with the Sender number which will appear in the header of
   each fax */
define variable tagnumber as character  no-undo initial "xxxxx".

/* used for base-64 encoding */
define variable mem64     as memptr     no-undo.
define variable b64data   as longchar   no-undo.

define variable hSocket   as handle     no-undo.
/* remove the "-debug" when done testing */
define variable postURL   as character  no-undo initial
   "https://api.faxage.com/httpsfax-debug.php". 


/* copy the disk file we're going to fax into memory */
copy-lob file faxfile1 to mem64.
/* encode it in memory and assign the result to a variable ready for faxing */
b64data = base64-encode(mem64).


/* create a socket and connect */
create socket hSocket.

/* if you are having problems, and want to eliminate SSL, etc., as a source
   of difficulty, try hSocket:connect("-H api.faxage.com -S 80").  This will NOT
   be a secure connection - for that you need the line of code below */
hSocket:connect("-ssl -H api.faxage.com -S 443").


/* first message exists just to verify while testing */
if hSocket:connected() then message "Socket connected."
   view-as alert-box info buttons ok.
else do:
   message "Problem connecting to socket."
      view-as alert-box info buttons OK.
   delete object hSocket.
   return.
end. /* problem: clean up and abort */

/* set the socket object to use the internal procedure (defined below) 
   named "getResponse" to read the host's response */
hSocket:set-read-response-procedure('getResponse').

/* post our request */
run postRequest (
   input postURL,
   input "username="        + username  + "&" +
         "company="         + company   + "&" +
         "password="        + password  + "&" +
         "recipname="       + recipname + "&" +
         "faxno="           + faxno     + "&" +
         "operation="       + operation + "&" +
         "tagname="         + tagname   + "&" +
         "tagnumber="       + tagnumber + "&" +
         "faxfilenames[0]=" + faxfile1  + "&" +
         "faxfiledata[0]="  + b64data).

/* see what comes back from the host, using getResponse */
wait-for read-response of hSocket.

/* done */
hSocket:disconnect() no-error.
delete object hSocket.
quit.

/* ------------------------ internal procedures ------------------------ */

PROCEDURE getResponse:
   
   /* holds response from host */
   define variable mResponse     as memptr           no-undo.
   /* for screen display */
   define variable responseText  as character        no-undo.
   
   if hSocket:connected() = false then do:
       message 'In getResponse: socket not connected.' view-as alert-box.
       return.
   end.
      
   do while hSocket:get-bytes-available() > 0:
      set-size(mResponse) = hSocket:get-bytes-available() + 1.
      set-byte-order(mResponse) = big-endian.
      hSocket:read(mResponse,1,1,hSocket:get-bytes-available()).
      responseText = responseText + get-string(mResponse,1).
   end.

   /* for testing */
   message responseText
      view-as alert-box info buttons OK.

   /*
    *
    *
    * put code here to manipulate the response in responseText
    *
    */
                      
END. /* getResponse */

PROCEDURE PostRequest:
   /* URL that will send the data. It must be all the path after the server.
      IE: /scripts/cgiip.exe/WService=wsbroker1/myApp.htm */
   define input  parameter postUrl  as character  no-undo.
   /* Parameters to be sent in the format
      paramName=value&paramName=value&paramName=value */
   define input  parameter postData as longchar   no-undo.

   define variable postRequest as longchar   no-undo.
   define variable mRequest  as memptr     no-undo.


   /* formulate the post request:  this is sensitive down to the last space:
      don't mess with it unless you know what you're doing */
   postRequest = 
      'POST ' + postUrl + ' HTTP/1.0~r~n' +
      'Content-Type: application/x-www-form-urlencoded~r~n' +
      'Content-Length:' + string(length(postData)) + '~r~n' +
      '~r~n' + 
      postData + '~r~n'.
   
   /* do the actual post */
   set-size(mRequest)            = 0.
   set-size(mRequest)            = length(postRequest) + 1.
   set-byte-order(mRequest)      = big-endian.
   put-string(mRequest,1)        = postRequest.
   hSocket:WRITE(mRequest, 1, LENGTH(postRequest)).
END PROCEDURE.

