home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / voice2.zip / LIB_FOD.CMD < prev    next >
OS/2 REXX Batch file  |  1996-09-09  |  16KB  |  397 lines

  1. /* LIB_FOD.CMD - Fax-on-demand procedure for FaxWorks/PMfax (REXX) */
  2. /* 
  3.                   Keller Group Inc.  September 9, 1996
  4.    You may freely use or modify this script for use with licensed
  5.         products which are developed by Keller Group Inc.
  6. */
  7. /*******************************************************************
  8. LIB_FOD.CMD - Fax-on-demand procedure - to be called from scripts
  9.  
  10. This is NOT a script file.  It is a procedure which has been placed
  11. in this separate file so it can be easily called from several other
  12. Voice/Fax Answer Scripts.  See the calling scripts, such as
  13. V_FOD.CMD, for information and an example of calling the procedure.
  14.  
  15. Supported features:
  16.     Can use documents from a fax log directory or another directory
  17.     Both one-call and two-call fax-on-demand (FOD)
  18.     Interactive fax response (generate data and fax it on-the-fly)
  19.     Both text file and fax image file support
  20.     Voice-on-demand (VOD)
  21.     Drag/drop creation of FOD/VOD document library
  22.     Full source code in REXX - modify as needed
  23.  
  24. DESCRIPTION:
  25. -----------
  26. This procedure does much more than just "fax-on-demand" since it also
  27. supports "voice-on-demand" (playing user-selected voice message
  28. files) and "text-on-demand" (converting user-selected text files to
  29. fax and faxing them).  It also demonstrates how you can execute your
  30. own programs to dynamically gather data (such as from your database)
  31. and send it as a fax document.  So it's really a powerful "document
  32. on demand" system that you can customize to meet your needs.
  33.  
  34. USAGE:
  35. -----
  36. Call this external REXX procedure using a statement similar to the
  37. following:
  38.  
  39. call "LIB_FOD" FODDIR, VOXDIR1, VOXDIR2, CALLER, FAXFILE, FFCOMMENT, FFNOTE
  40.  
  41. where the parameters are as follows:
  42.  
  43.     FODDIR - pathname of directory which contains "on-demand"
  44.     files, including the trailing \ character.
  45.  
  46.     VOXDIR1 - pathname of primary directory which contains voice
  47.     prompt files.  This is the first place checked for a prompt.
  48.  
  49.     VOXDIR2 - (optional) pathname of secondary directory which
  50.     contains voice prompt files.  This directory is checked only
  51.     if a prompt file is not found in the VOXDIR1
  52.  
  53.     CALLER - (optional) the name of the caller, if known, for use
  54.     on cover sheets.  Defaults to "Person" if not provided.
  55.  
  56.     FAXFILE - (optional) a pre-selected fax file (or log index#,
  57.     or comma-separated list of fax files or log indices) to send.
  58.     If provided, this bypasses the document selection procedure
  59.     and just interacts with caller to fax them the fax file.
  60.  
  61.     FFCOMMENT - (optional) the Comment string for the cover sheet
  62.     when FAXFILE is specified and the caller has the FAXFILE
  63.     queued for sending to a fax number.
  64.  
  65.     FFNOTE - (optional) the Notes string for the spooled fax job.
  66.         Default is "FOD".
  67.  
  68. RETURNS:
  69. -------
  70. This procedure returns one of the following values.  These values can
  71. be used in a "SIGNAL VALUE RESULT" call to branch to labels of these
  72. same names if desired.
  73.  
  74.     HELLO - meaning: done, and perhaps give user another prompt
  75.  
  76.     BYEBYE - meaning: error, so quit with error termination
  77.  
  78.     OUT - meaning: done, so quit with normal termination
  79.  
  80. VOICE PROMPT FILES:
  81. ------------------
  82. To record or modify your own voice prompt files, use your OS/2
  83. Multimedia microphone and record voice prompts using the "Fax/New
  84. message" command then save them to a .WAV file with the "Fax/Save
  85. file/Wave" command.  You can also use the OS/2 Digital Audio program
  86. to record, save, edit and modify the Wave files (be sure to use
  87. "Type" of Mono, 8-bit, 11.025 kHz).
  88.  
  89.     ENTR_DOC.WAV - Short: "Enter document number and # key, or
  90.     press the # key if done."
  91.     Long: "Please enter the document number followed by the # key,
  92.     or press the # key if done.  To receive an index of available
  93.     documents, enter document 1000."
  94.  
  95.     HOW_FAX.WAV - Short: "Enter 1 if calling from fax machine, 2
  96.     if not."
  97.     Long: "If you are calling from your fax machine and are ready
  98.     to receive the fax press 1, to send the fax to a different
  99.     number press 2." 
  100.  
  101.     ENTR_FAX.WAV - Short: "Enter fax number and # key."
  102.     Long: "Please enter your fax number followed by the # key,
  103.     including 1 and area code if this is not a local call." 
  104.  
  105.     NO_FILE.WAV - Short: "File not found."
  106.     Long: "That document was not found, please try again."
  107.  
  108.     WAIT.WAV - Short: "Please wait."
  109.     Long: "Please wait while we process your request."
  110.  
  111.     THANKYOU.WAV - Short: "Thank you."
  112.     Long: "Thank you.  Your fax is queued for sending."
  113.  
  114.  
  115. FAX/VOICE/TEXT-ON-DEMAND DOCUMENTS:
  116. ----------------------------------
  117. This procedure allows the user to enter document numbers to select one
  118. or more documents.  Each document can be a fax, text or voice message
  119. document.  When voice documents are selected, they are played to the
  120. caller.  When fax and text documents are selected, they are gathered
  121. as a list and then either faxed to the caller on this current call
  122. ("one-call" fax-on-demand - if caller called from a fax machine) or
  123. faxed to a number which the caller enters ("two-call" fax-on-demand).
  124.  
  125. The program's standard document file name format is used for the
  126. "on-demand" documents (FX000001.FAX for fax documents, FX000001.TXT
  127. for text documents, FX000001.MSG for voice message documents).  Any
  128. fax, voice or text item that can appear in the log can be used as an
  129. "on-demand" document.  You can create the documents in many different
  130. ways (faxing to the program, printing through the FxPrint printer
  131. driver, using the program's editing tools, recording voice messages
  132. using Fax/New message or the answering machine features, etc.).
  133.  
  134. If the FODDIR parameter is set to the fax log directory, then this
  135. procedure can use the documents from the log and the "document
  136. number" is the "ID" number in the program's log display ("Fax/Open
  137. log" command).
  138.  
  139. If the FODDIR parameter is set to a different directory, then
  140. this script uses the documents which are found in that directory.
  141. For many uses, you will usually want to do this so that you can
  142. control the document numbers yourself.  For example, you may wish to
  143. have an "index fax" as document 1000 (file FX001000.FAX) so that
  144. callers can order a list of all available documents, then have
  145. different categories of documents as document 1100, 1101, 1200,
  146. 1201, etc.  This is easy to do using your choice of techniques:
  147.  
  148.     1) DRAG/DROP - Create a folder, drag (to move) or Ctrl-drag
  149.     (to copy) the documents from the log to your folder, and use
  150.     direct editing (Alt-Click) to edit the file names to use your
  151.     desired ID values.  Set the FODDIR script variable to the
  152.     pathname of the folder's directory (including trailing \).
  153.  
  154.     2) COMMAND LINE - Create a directory, then copy the desired
  155.     files from the log directory to your desired file names in
  156.     your directory (or use the Fax/Save file command in the fax
  157.     program).  Set the FODDIR script variable to the pathname of
  158.     the directory's pathname (including trailing \ character).
  159.  
  160. The procedure uses ID 9999 as a special case to demonstrate how you
  161. can dynamically call another program to generate text, convert the
  162. text to a fax and send the fax to the caller.  For this
  163. demonstration, we simply use the OS/2 DIR command, but you could
  164. change this to do something more interesting (a database query, etc.).
  165.  
  166. TO MODIFY:
  167. ---------
  168. This is REXX and uses calls from the Keller REXX API which are
  169. automatically loaded into the OS/2 REXX environment by the retail
  170. versions of Keller's fax products (version 3.0 and later).  See the
  171. Reference Manual for documentation of the FxRx and FxLn calls.  You
  172. may modify this procedure (and the scripts which call it) as desired,
  173. and then use it as the "Answer script" with Keller fax software
  174. products.
  175.  
  176. *******************************************************************/
  177.  
  178.  
  179.  
  180. lib_fod:
  181.   parse arg FODDIR, VOXDIR1, VOXDIR2, CALLER, FAXFILE, FFCOMMENT, FFNOTE
  182.  
  183.   call FxLnMsg "Fax-on-demand"
  184.   call FxLnVout 'Lib_fod called with params:' FODDIR '-' VOXDIR1 '-' ,
  185.          VOXDIR2 '-' CALLER '-' FAXFILE '-' FFCOMMENT '-' FFNOTE
  186.  
  187.   /* initialize our variables which will hold lists of files */
  188.   fodfilelist = ''    /* comma-separated list of documents to fax */
  189.   fodlist = 'Your requested documents are attached:' /* for cover sheet */
  190.   foddelete. = ''    /* stem variable list of temp files to delete */ 
  191.   foddelete.0 = 0    /* list is initially empty */
  192.  
  193.   /* if CALLER and FFNOTES strings not provided, then default them */
  194.   if CALLER = '' then CALLER = 'Person'
  195.   if FFNOTE = '' then FFNOTE = 'FOD'
  196.  
  197.   /* if FAXFILE was provided, use it and skip to sending */
  198.   if FAXFILE <> '' then do
  199.     fodfilelist = FAXFILE
  200.     fodlist = FFCOMMENT
  201.     signal fodsend
  202.   end
  203.  
  204.   /* otherwise, let the user select the documents */
  205.   do forever
  206.     if stream(VOXDIR1||'ENTR_DOC.WAV', 'C', 'QUERY EXISTS' ) <> ''
  207.     then call FxLnPlay VOXDIR1||'ENTR_DOC.WAV'
  208.     else call FxLnPlay VOXDIR2||'ENTR_DOC.WAV'
  209.       if result = 'NOTOK' then signal fodbyebye
  210.     
  211.     fodnum = GetNumber( 7 )        /* get up to 6-digit doc # */
  212.     if fodnum = '' then leave        /* if no number entered ... */
  213.  
  214.     /* Treat number 9999 as a special case for this demonstration */
  215.     if fodnum = 9999 then do
  216.       call FxLnMsg "Query #9999"
  217.       if stream(VOXDIR1||'WAIT.WAV', 'C', 'QUERY EXISTS' ) <> ''
  218.       then call FxLnPlay VOXDIR1||'WAIT.WAV'
  219.       else call FxLnPlay VOXDIR2||'WAIT.WAV'
  220.         if result = 'NOTOK' then signal fodbyebye
  221.       tmp1 = FODDIR||TmpFile()||'.TXT'
  222.       call RememberToDelete tmp1
  223.       /* You could do a database query or something interesting. */
  224.       /* For demo, we will just use DIR command to get text info */
  225.       'DIR \ >"'||tmp1||'"'        /* put text in tmp1 file */
  226.       tmp2 = FODDIR||TmpFile()||'.FAX'
  227.       call RememberToDelete tmp2
  228.       call FxRxTextToFax tmp1, tmp2    /* convert text to fax */
  229.         if result = 'NOTOK' then signal fodbyebye
  230.       fodlist = fodlist fodnum
  231.       fodfilelist = AddToCsvList( tmp2, fodfilelist )
  232.       iterate
  233.     end
  234.  
  235.     fodfile = DocFile( fodnum, FODDIR )        /* normal doc #... */
  236.     fodtype = DocType( fodfile )        /* look for the file */
  237.     call FxLnMsg 'FOD Doc:' fodfile||fodtype
  238.  
  239.     if fodtype = '' then do            /* file not found */
  240.       if stream(VOXDIR1||'NO_FILE.WAV', 'C', 'QUERY EXISTS' ) <> ''
  241.       then call FxLnPlay VOXDIR1||'NO_FILE.WAV'
  242.       else call FxLnPlay VOXDIR2||'NO_FILE.WAV'
  243.       iterate
  244.     end
  245.  
  246.     if fodtype = '.MSG' then do            /* voice document */
  247.       call FxLnPlay fodfile||fodtype
  248.       iterate
  249.     end
  250.  
  251.     if fodtype = '.TXT' then do            /* text document */
  252.       if stream(VOXDIR1||'WAIT.WAV', 'C', 'QUERY EXISTS' ) <> ''
  253.       then call FxLnPlay VOXDIR1||'WAIT.WAV'
  254.       else call FxLnPlay VOXDIR2||'WAIT.WAV'
  255.         if result = 'NOTOK' then signal fodbyebye
  256.       tmp2 = FODDIR||TmpFile()||'.FAX'
  257.       call RememberToDelete tmp2
  258.       call FxRxTextToFax fodfile||fodtype, tmp2    /* convert text to fax */
  259.         if result = 'NOTOK' then signal fodbyebye
  260.       /* Note: FxRxTextToFax uses FxPrint queue by default */
  261.       /* You can specify "print queue" (physical name) as third parameter */
  262.       /* The queue's job properties are used, so long text lines will not */
  263.       /* wrap if in PCL emulation (like a LaserJet), but will wrap if in  */
  264.       /* >>FONT emulation mode.                                           */
  265.       fodlist = fodlist fodnum
  266.       fodfilelist = AddToCsvList( tmp2, fodfilelist )
  267.       iterate
  268.     end
  269.  
  270.     if fodtype = '.FAX' then do            /* fax document */
  271.       fodlist = fodlist fodnum
  272.       fodfilelist = AddToCsvList( fodfile||fodtype, fodfilelist )
  273.       iterate
  274.     end
  275.  
  276.   end
  277.  
  278. fodsend:
  279.   if fodfilelist = '' then signal fodhello    /* if nothing to fax */
  280.   call FxLnMsg 'FOD How?'
  281.   if stream(VOXDIR1||'HOW_FAX.WAV', 'C', 'QUERY EXISTS' ) <> ''
  282.   then call FxLnPlay VOXDIR1||'HOW_FAX.WAV'
  283.   else call FxLnPlay VOXDIR2||'HOW_FAX.WAV'
  284.     if result = 'NOTOK' then signal fodbyebye
  285.   call FxLnDtmf 1, 15, 'faxnow'
  286.     if result = 'NOTOK' then signal fodbyebye
  287.     if result <> 'DTMF' then signal fodqueue
  288.   if faxnow <> 1 then signal fodqueue
  289.   call FxLnSend fodfilelist            /* fax - current call */
  290.   signal fodout
  291.  
  292. fodqueue:                    /* fax - second call */
  293.   call FxLnMsg 'FOD Queue'
  294.   if stream(VOXDIR1||'ENTR_FAX.WAV', 'C', 'QUERY EXISTS' ) <> ''
  295.   then call FxLnPlay VOXDIR1||'ENTR_FAX.WAV'
  296.   else call FxLnPlay VOXDIR2||'ENTR_FAX.WAV'
  297.     if result = 'NOTOK' then signal fodbyebye
  298.   
  299.   faxnum = GetNumber( 12 )
  300.   call FxLnMsg 'Fax number:' faxnum
  301.  
  302.   if faxnum <> '' then do
  303.     /* Send with default cover sheet and default "From" information */
  304.     call FxRxQueue fodfilelist, ,
  305.        'TO='||CALLER||' at fax: '||faxnum||',,'||faxnum, ,
  306.        'INFO='||'"'||fodlist||'"'||',*,'||FFNOTE||',*,1,2', ,
  307.        'FROM=*,*,*,*'
  308.     if stream(VOXDIR1||'THANKYOU.WAV', 'C', 'QUERY EXISTS' ) <> ''
  309.     then call FxLnPlay VOXDIR1||'THANKYOU.WAV'
  310.     else call FxLnPlay VOXDIR2||'THANKYOU.WAV'
  311.       if result = 'NOTOK' then signal fodbyebye
  312.     signal fodhello
  313.   end
  314.   else call FxLnVout 'No fax number was entered'
  315.   signal fodhello
  316.  
  317.  
  318. fodbyebye:                /* for error cases */
  319.   call cleanup
  320.   call FxLnVout 'Lib_fod returns BYEBYE'
  321.   return 'BYEBYE'
  322.  
  323. fodhello:                /* done, reprompt user? */ 
  324.   call cleanup
  325.   call FxLnVout 'Lib_fod returns HELLO'
  326.   return 'HELLO'
  327.  
  328. fodout:                    /* for normal cases */
  329.   call cleanup
  330.   call FxLnVout 'Lib_fod returns OUT'
  331.   return 'OUT'
  332.  
  333. cleanup:
  334.   /* clean up temporary files from .TXT processing */
  335.   call FxLnVout 'Deleting' foddelete.0 'temp files.'
  336.   do i = 1 to foddelete.0 by 1
  337.     call FxLnVout 'Deleting:' foddelete.i
  338.     'DEL "'||foddelete.i||'"'
  339.   end
  340.   return
  341.  
  342.  
  343.  
  344. /************************ Procedures ************************/
  345.  
  346. GetNumber: procedure
  347.   /* Gets DTMF input until # or * key or "digits" are entered. */
  348.   /* TimeOut is seconds to wait for each digit (default 15).       */
  349.   parse arg digits, TimeOut
  350.   number = ''
  351.   if TimeOut = '' then TimeOut = 15  /* default to 15 seconds */
  352.   do digits
  353.     call FxLnDtmf 1, TimeOut, 'newkey'
  354.       if result <> 'DTMF' | newkey = '#' | newkey = '*' then leave
  355.     number = number||newkey
  356.   end
  357.   return number
  358.  
  359. DocFile: procedure
  360.   /* Given a document id and directory, returns pathname of the doc */
  361.   /* file (without extension).  File names are FX000001.xxx format. */
  362.   parse arg id, dir
  363.   return ( dir||'FX'||right( id, 6, '0' ) )
  364.  
  365. DocType: procedure
  366.   /* Given a document pathname (without extension), returns the */
  367.   /* extension of the existing file or '' if file doesn't exist */
  368.   parse arg basefile
  369.   if stream( basefile||'.FAX', 'C', 'QUERY EXISTS' ) <> ''
  370.     then return '.FAX'
  371.   if stream( basefile||'.MSG', 'C', 'QUERY EXISTS' ) <> ''
  372.     then return '.MSG'
  373.   if stream( basefile||'.TXT', 'C', 'QUERY EXISTS' ) <> ''
  374.     then return '.TXT'
  375.   return ''
  376.  
  377. TmpFile: procedure
  378.   /* Generate a unique base file name using seconds since midnight */
  379.   return 'TMP'||time( S )
  380.  
  381. RememberToDelete: procedure expose foddelete.
  382.   /* Adds a file to the list of tmp files to be deleted */
  383.   parse arg newfile
  384.   foddelete.0 = foddelete.0 + 1
  385.   i = foddelete.0
  386.   foddelete.i = newfile
  387.   call FxLnVout 'Remembering to delete' foddelete.i
  388.   return
  389.  
  390. AddToCsvList: procedure
  391.   /* returns a comma-separated value list with item added */
  392.   parse arg item, list
  393.   if list = ''
  394.     then list = item
  395.     else list = list||','||item
  396.   return list
  397.