Fax

Faxing is still a critical business requirement for many industries. The faxes app provides a set of faxing related features to 2600Hz accounts and supports sending and receiving faxes directly from email or the API. The fax entities can be tied to a callflow to terminate incoming faxes without having to use a fax machine.

Receive Fax Callflow Element

The original fax application feature added the ability to create a call flow receive_fax element that can be attached to a phone number and used to terminate faxes, generating an email to the user with the received faxed document attached. This feature has been replaced by the faxbox feature set, but the receive fax call flow element is still supported currently as a legacy feature.

Faxbox

The faxbox acts as a virtual fax machine. The faxbox is used for both receiving and sending faxes. The faxbox is tied into the API and Email Notification systems and will send receipts or error notifications when a fax is sent or fails to send, send notifications when a fax is received and history and content of sent and received faxes can be retrieved via the faxes API. Faxboxes can be added to call flow just like receive fax, but unlike receive fax, multiple email addresses can be added to the notification list. Unlike receive fax, faxboxes can be used to send faxes, which can either be uploaded via the faxes API directly, or submitted by sending an email to the faxbox smtp_email_address or custom_smtp_email_address or the account realm. The faxbox supports multiple file formats for sending faxes, most commonly, pdfand tiff, but OpenXML and other OpenOffice compatible documents can be configured as well.

The faxes API also provide an email inbox/sent items type interface for accessing sent and received faxes and debugging failed fax transmission attempts. Checkout the Faxbox documentation for more details on how the faxbox works.

Faxes HTTP API

In addition to sending faxes via Email to Fax, the Crossbar provides Faxes API that can be used to deliver faxes using two methods: url and multipart.

Url

If the url method is used, a url to access the document must be provided in the request body using a url that is reachable by 2600Hz.

Multipart

If multipart method is used, the fax document is attached as part of a multipart body, which also contains a JSON object which provides the from and to numbers for the fax.

Sending Faxes

Two methods are provided for sending faxes, api fax and faxbox. Faxbox can use either google cloud printer, or the fax_smtp server to handle requests to send faxes. Api fax uses the crossbar API to provide the fax content. When the request is received via any method, the requested fax document is processed, a document is created in the faxes database, and the document is set to a pending status putting it into queue per account by fax_monitor, by spawning an instance of fax_jobs using the unique name fax_outbound_{account_id}.

The fax jobs module provides a queuing and rate limiting mechanism per account, defaulting to max_outbound at 10 active jobs per account. For the permitted number of jobs in queue, fax_jobs spawns an instance of fax_worker under the global name fax_outbound_{destination phone number} or if serialize_outbound_number is disabled fax_outbound_{random_uuid}. By default only one fax job per outbound number can be executed system wide, if serialize_outbound_number is false, only the per-account limitation is used to serialize jobs and multiple outbound faxes to the same number can be initiated.

Fax worker fetches a fax compatible file from the queued fax job, the file is then written to the configured file_cache_path, this file is served via the fax_file_proxy module which provides an HTTP file server accessible from the FreeSWITCH servers in the cluster, and transmitted using a FreeSWITCH originate to the destination phone number. Upon receiving the originate request, the FreeSWITCH fetches the fax document from the fax_file_proxy and attempts to transmit it using the T.30 or T.38 protocol based on configuration and negotiation with the far end.

If fax transmission fails, and the system_config.fax document has reschedule rules configured, these are applied, based on the type of failure. For example, a reschedule rule can be added for user-busy condition that will result in a re-transmission after a configured retry-after period. If no reschedule rules are applied the transmission will be re-attempted until the configured number of retries on the faxbox is exhausted.

When all retries are exhausted, the fax will be put into state failed and an email notification will be sent indicating the cause of the error. If the fax transmission is successful, a receipt will be sent to the user and/or any email addresses specified in the faxbox outbound notification list.

Receiving Faxes

For receiving faxes, either the receive_fax or faxbox callflow elements must be attached to a callflow. When an incoming call is placed to the callflow’s phone number, FreeSWITCH receives the call, passes this up to the call control layer via ecallmgr. The callflow is matched via the callflow app the fax reception is then handled via the fax_request module. The t38 configuration and the filename is provided to FreeSWITCH to use to cache the file and then the fax handshake and transmission is handled via the FreeSWITCH.

When the transmission succeeds, the file is put in the directory defined in the fax_file_path in system_config.ecallmgr. A document is created in the db then fax_request instructs the FreeSWITCH to upload the document to the database, using the naming scheme received_fax-<fax-id>.tiff. Once the fax content is uploaded to the db, a notification is generated with the message attached in the format defined in fax.attachment_format defined in system_config.kazoo_convert (tiff or pdf).

When the transmission fails, an error notification is generated indicating the cause of the failure.

2600Hz Fax Converter And Attachment Storage Handling And Configuration

If a document is submitted for an outbound fax request in a format unsuitable for faxing (word or OpenXML document, pdf or tiff in a non-faxable format), the attachment will be converted to a fax compliant tiff. The conversions by default will occur whenever a fax document is received via the API or fax_smtp server.

The parameters store_fax_tiff, store_fax_pdf and store_fax_url are used to dictate if the results of the conversions should be stored in the database, or if conversions should take place on the fly when a file in one of these formats are required. By default 2600Hz will store the original document, a faxable tiff version of the document, and a pdf generated from the faxable version of the document.

If these settings are NOT enabled, 2600Hz will fetch the original document either via the original file or if a url document is specified, fetching the document from the url using HTTP. 2600Hz will then execute any conversions required for the type of file requested (faxable tiff or pdf) and do those conversions each time the fax is requested. This is much slower, especially for the API, but does reduce the size of the database documents since only the original document or document url is stored in the database. If url fax documents are provided and store_fax_url is set to false, every time the file is requested, it will be downloaded from the url, converted to the format required and that document will be returned.

Configuration Parameters

system_config.fax global settings

KeyDescriptionTypeDefaultRequiredSupport Level
allow_all_addresses_when_emptyfax allow all addresses when emptyboolean()falsefalse
allowed_content_types.[]string()false
allowed_content_typesfax allowed content typesarray(string())["application/pdf", "image/tiff", "{"prefix":"image"}", "{"prefix":"application/vnd.openxmlformats-officedocument."}", "{"prefix":"application/vnd.oasis.opendocument."}", "application/msword", "application/vnd.ms-excel", "application/vnd.ms-powerpoint"]false
cloud_registration_pool_intervalfax cloud registration pool intervalinteger()5000false
default_compare_fieldfax default compare fieldstring()result_causefalse
default_fax_extensionfax default fax extensionstring().tifffalse
default_retry_countfax default retry countinteger()3false
default_retry_periodfax default retry periodinteger()300false
default_smtp_domainfax default smtp domainstring()fax.kazoo.iofalse
delete_empty_faxesfax delete empty faxesboolean()falsefalse
denied_content_typesfax denied content typesarray(object())["{"prefix":"image/"}"]false
endpoint_timeoutfax endpoint timeoutinteger()40false
ensure_valid_caller_idfax ensure valid caller idboolean()truefalse
fax_file_pathfax fax file pathstring()/tmp/false
fax_settingsfax fax settingsobject(){"override_fax_identity":true,"override_callee_number":false}false
file_cache_pathfax file cache pathstring()/tmp/false
ignore_early_mediafax ignore early mediaboolean()falsefalse
image_min_sizefax image minimum sizestring()700x10false
image_size_cmd_formatfax image size cmd formatstring()`echo -n ```identify -format ”%[fx:w]x%[fx:h]” ~s“false
inbound_t38_defaultfax inbound t38 defaultstring()truefalse
log_faxbox_errorsfax log faxbox errorsboolean()truefalse
max_outboundfax max outboundinteger()10false
max_storage_retryfax maximum storage retryinteger()5false
portfax portinteger()30950false
report_anonymous_system_errorsfax report anonymous system errorsboolean()falsefalse
report_faxbox_system_errorsfax report faxbox system errorsboolean()truefalse
report_smtp_errorsReport SMTP-related errors via notificationsboolean()truefalse
reschedulefax rescheduleobject(){}false
serialize_outbound_numbersSerialize fax transmissions by outbound number globallyboolean()truefalse
smtp_max_msg_sizefax smtp maximum msg sizeinteger()10485670false
smtp_portfax smtp portinteger()19025false
smtp_sessionsfax smtp sessionsinteger()50false
store_fax_pdfstore the post processed fax documentboolean()truefalse
store_fax_tiffstore a pdf copy of the post processed fax documentboolean()truefalse
store_url_documentstore the document url result in the databaseboolean()truefalse
wait_for_fax_timeout_msfax wait for fax timeout in millisecondsinteger()3600000false
workersfax workersinteger()50false
xmpp_intervalfax xmpp intervalinteger()600000false

Useful Sup Commands

To see the pending faxes currently in queue:

sup fax_maintenance pending_jobs

To see the active faxes:

sup fax_maintenance active_jobs

To see the jobs currently pending in an account:

sup fax_maintenance account_jobs {ACCOUNT_ID}