UAS API - Inbound Receive Fax Sample Application
-
Filename:
samples/inbound_receive_fax.py
Description:
A sample application that will answer an inbound call and receive a fax. The sample first creates a
FaxToReceive
object which is the wrapper for the fax document. This object is used to set the name of the file to which the fax will be received. It is assumed that the name of the fax file will be read from theapplication_parameters
variable which is configured on the Inbound Services page (Manage -> Inbound Services). To this is added theapplication_instance_id
to make it unique.After creating the fax document object, the call is answered and the function
channel.FaxReceiver.start()
is called to start receiving the fax. The start function is passed a reference to the fax document object.The sample then waits for the fax settings to be negotiated,
channel.FaxReceiver.wait_for_negotiated_settings()
, and prints them to the screen. It then useschannel.FaxReceiver.wait_for_next_page()
to wait for each page to be received, it does this until the last page has been indicated, and prints out the quality of the page. The page quality, along with several other things, is available on the fax document object.Finally, the function
channel.FaxReceiver.wait_until_finished()
is used to wait until the fax session has completed. After that, the call is hung up.Code:
""" A simple example that will answer an inbound call, and receive a fax. Actions: - check the channel state - answer - receive a fax - hang up It is assumed that the name of the fax file is given in application_parameters. To this is added the application_instance_id to make it unique. """ from prosody.uas import Hangup, Error, FaxToSend, FaxToReceive __uas_identify__ = "application" __uas_version__ = "0.01b" def main(channel, application_instance_id, file_man, my_log, application_parameters): try: return_code = 0 # This outbound application is going to receive a fax, so we create # a FaxToReceive object, known as a fax document object my_fax = FaxToReceive() # Now set the name of the file to which the fax will be saved. cause = my_fax.set_file_name('{0}_{1}.tif'.format(application_parameters, application_instance_id)) # The cause will be of type FileCause and should be checked. if cause != my_fax.FileCause.NORMAL: raise Error("failed to set the file name, cause is {0}".format(cause)) # Answer the inbound call in the normal way if channel.state() == channel.State.CALL_INCOMING: channel.answer() # this can raise a Hangup exception else: raise Hangup('No inbound call') # Now we can start to receive the fax. if channel.FaxReceiver.start(fax_to_receive=my_fax) != True: cause = channel.FaxReceiver.cause() raise Error("fax receiver failed to start receiving the fax, cause is {0}.".format(cause)) # The fax endpoints will negotiate the parameters for the fax session - which modem # and the modem speed, among other things. We can wait until these have been published # and then have a look. Note that the dictionary will be empty if fax negotiation fails. negotiated_settings = channel.FaxReceiver.wait_for_negotiated_settings() if negotiated_settings == {}: cause = channel.FaxReceiver.cause() if cause == channel.FaxReceiver.Cause.NOTFAX: raise Hangup("The transmitter was not a fax machine.") else: raise Error("Fax negotiation failed with cause {0}".format(cause)) my_log.debug("Negotiated Settings") for setting, value in negotiated_settings.items(): my_log.debug("{0:>15.15} : {1}".format(setting, value)) # Now we can wait for each page to be received, we do this until we've been told # that no more pages will be received. For each page we log the page quality. # This, and more, detail is available on the fax document object. # It is important to note that the last_page flag does not indicate success, it simply # means that no more pages will be processed. while channel.FaxReceiver.Details.last_page is not True: pages = channel.FaxReceiver.wait_for_next_page() my_log.debug("Received {0} pages so far".format(pages)) my_log.debug("Last received page quality: {0}".format(my_fax.PageDetails[-1].receive_quality)) # Now we need to wait until the fax session has finished. We need to do this even though # the last page flag has been set. Remember to check the cause, the last_page indicator # may have been set, but this does not mean that every page was received. cause = channel.FaxReceiver.wait_until_finished() if cause != channel.FaxReceiver.Cause.NORMAL: raise Error("Fax receiver failed with cause {0}".format(cause)) except Hangup as exc: my_log.info("Hangup exception reports {0}".format(exc)) return_code = -101 except Error as exc: my_log.error("Error exception reports {0}".format(exc)) return_code = -100 except Exception as exc: my_log.exception("Got unexpected exception {0}".format(exc)) return_code = -102 finally: if channel.state() != channel.State.IDLE: channel.hang_up() return return_code
-
Filename:
Samples\C#\InboundReceiveFax\InboundReceiveFax.cs
Description:
For this sample application, the 'Enable fax receive' option needs to be ticked in the fax tab of your inbound service that will invoke it. Typically the default fax options provided will result in a fax being received successfully.
The filename for the fax to be received is formed by extracting the user part of the CallFrom property of the incoming call and adding the current date.
Having called Ring and Answer the sample sets the fax document's filename. The UASApplication object exposes the single fax document that can be received on the incoming call. It then calls the
channel.FaxReceiver.Receive()
method to perform the fax reception. If successful this will returnFaxCause.Normal
and the received fax will have been saved under the specified filename. The sample then waits for the remote end to be hung up.Code:
using System; using System.Threading; using AMSClassLibrary; using UASAppAPI; // An inbound application that answers a call and receives a fax from that call. // // The received fax is saved to a .tif file name constructed from the user part of the // callFrom field and the current date. // // Fax receiving can be enabled for a particular service by editing the service entry // from the platform Inbound Services page. // // Requires: // [Fax Receive to be enabled in the service invoking this application] namespace InboundReceiveFax { // The application class. // This must have the same name as the assembly and must inherit from either // UASInboundApplication or UASOutboundApplication. // It must override the Run method. public class InboundReceiveFax : UASInboundApplication { // Possible return codes enum ReturnCode { // Success Codes: Success = 0, // Fail Codes: // -1 to -99 reserved ExceptionThrown = -100, FaxReceiveNotEnabled = -101, FaxReceiveFailed = -102, FaxReceiveTimedOut = -103 } // This is the entry point for the application public override int Run(UASCallChannel channel, string applicationParameters) { this.Trace.TraceInfo("Start - appParms [{0}]", applicationParameters); ReturnCode reply = ReturnCode.Success; // Check that fax receiving has been enabled in the calling service. if (this.FaxDocumentToReceive == null) { this.Trace.TraceError("This app requires that fax receiving is enabled in the calling service"); return (int)ReturnCode.FaxReceiveNotEnabled; } // Get the user from CallFrom string callFromUser = channel.CallDetails.CallFrom; callFromUser = callFromUser.Remove(callFromUser.LastIndexOf('@')); callFromUser = callFromUser.Substring(callFromUser.IndexOf(':') + 1); // Construct the file name of the fax to be received DateTime now = DateTime.Now; string receivedFaxFileName = String.Format("/faxs/received/{0}_{1}:{2}:{3}.tif", callFromUser, now.Year, now.Month, now.Day); try { // Ring for 2 seconds channel.Ring(2); // Answer the call CallState state = channel.Answer(); if (state == CallState.Answered) { this.Trace.TraceInfo("Answered"); // Set the file name target for the received fax this.FaxDocumentToReceive.SetFileName(receivedFaxFileName); // Set fax options: // Just set this end's subscriber id. // (this overrides any set in the service registration) FaxOptions options = new FaxOptions("SubscriberId", "1234"); // Now receive the fax this.Trace.TraceInfo("Receiving fax to {0}", receivedFaxFileName); FaxCause cause = channel.FaxReceiver.Receive(this.FaxDocumentToReceive, options); if (cause != FaxCause.Normal) { this.Trace.TraceInfo("Failed to receive fax: cause {0}", channel.FaxSender.Cause.ToString()); reply = ReturnCode.FaxReceiveFailed; } else { // Received ok, now retrieve some of the negotiated fax options // used to send/receive the fax. FaxOptions negotiatedOptions = this.FaxDocumentToReceive.Details.NegotiatedOptions; String sendingSubscriberId = negotiatedOptions["remotesubscriberid"]; this.Trace.TraceInfo("Received fax from subscriber Id: {0}", sendingSubscriberId); } } // Wait for the call to be hung up by the far end channel.WaitForIdle(Timeout.Infinite); } catch (Exception e) { this.Trace.TraceError("Exception thrown {0}", e.Message); reply = ReturnCode.ExceptionThrown; } this.Trace.TraceInfo("Completed"); return (int)reply; } } }
-
Filename:
Samples\VB\InboundReceiveFax\InboundReceiveFax.vb
Description:
For this sample application, the 'Enable fax receive' option needs to be ticked in the fax tab of your inbound service that will invoke it. Typically the default fax options provided will result in a fax being received successfully.
The filename for the fax to be received is formed by extracting the user part of the CallFrom property of the incoming call and adding the current date.
Having called Ring and Answer the sample sets the fax document's filename. The UASApplication object exposes the single fax document that can be received on the incoming call. It then calls the
channel.FaxReceiver.Receive()
method to perform the fax reception. If successful this will returnFaxCause.Normal
and the received fax will have been saved under the specified filename. The sample then waits for the remote end to be hung up.Code:
Imports System Imports AMSClassLibrary Imports UASAppAPI ' An inbound application that answers a call and receives a fax from that call. ' ' The received fax is saved to a .tif file name constructed from the user part of the ' callFrom field and the current date and time. ' ' Requires: ' [Fax Receive to be enabled in the service invoking this application] Namespace InboundReceiveFax ' The application class. ' This must have the same name as the assembly and must inherit from either ' UASInboundApplication or UASOutboundApplication. ' It must override the Run method. Public Class InboundReceiveFax Inherits UASInboundApplication ' Possible return codes Enum ReturnCode ' Success Codes: Success = 0 ' ... any positive integer ' Fail Codes: ' -1 to -99 reserved ExceptionThrown = -100 FaxReceiveFailed = -101 FaxReceiveTimedOut = -102 End Enum ' This is the entry point for the application Overrides Function Run(ByVal channel As UASCallChannel, _ ByVal applicationParameters As String) _ As Integer Me.Trace.TraceInfo("Start - appParms [{0}]", applicationParameters) Dim reply As ReturnCode = ReturnCode.Success ' Get the user from CallFrom Dim callFromUser = channel.CallDetails.CallFrom callFromUser = callFromUser.Remove(callFromUser.LastIndexOf("@")) callFromUser = callFromUser.Substring(callFromUser.IndexOf(":") + 1) ' Construct the file name of the fax to be received Dim now As DateTime = DateTime.Now Dim receivedFaxFileName = String.Format("/faxs/received/{0}_{1}:{2}:{3}_{4}.tif", _ callFromUser, _ now.Year, _ now.Month, _ now.Day, _ now.ToShortTimeString()) Try ' Ring for 2 seconds channel.Ring(2) ' Answer the call Dim state As CallState state = channel.Answer() If state = CallState.Answered Then Me.Trace.TraceInfo("Call answered") ' Set the file name target for the received fax Me.FaxDocumentToReceive.SetFileName(receivedFaxFileName) ' Now receive the fax Me.Trace.TraceInfo("Receiving fax to {0}", receivedFaxFileName) Dim cause As FaxCause = channel.FaxReceiver.Receive(Me.FaxDocumentToReceive) If Not cause = FaxCause.Normal Then Me.Trace.TraceInfo("Failed to receive fax: cause {0}", channel.FaxSender.Cause.ToString()) reply = ReturnCode.FaxReceiveFailed End If End If ' Wait for the call to be hung up by the far end channel.WaitForIdle(Timeout.Infinite) Catch ex As Exception Me.Trace.TraceError("Exception thrown {0}", ex.Message) reply = ReturnCode.ExceptionThrown End Try Me.Trace.TraceInfo("Completed") Return reply End Function End Class End Namespace