📜 ⬆️ ⬇️

Panel sending outgoing faxes using Asterisk and Node.js

The fax is one of those things that many want to see a speedy death. Nevertheless, in the regions this method of transmitting information is still used very often. So in our organization it became necessary to simplify the process as much as possible. After studying the articles that already exist here, I came to the conclusion that the solutions presented did not quite fit in my situation. In particular, I wanted a slightly more intelligent system than just based on call files. Such that she could call back several times in case of unsuccessful sending. In this case, the user must see the current delivery status. In conjunction with the fact that I have long wanted to look at web development in general and node.js in particular, it was decided to write my outgoing fax server bike . What came out of this can be seen under the cut.

First of all, it was necessary to configure Asterisk so that it creates events that reflect the progress of the fax in real time. Below is a fragment of the Asterisk recruitment plan that will allow us to do this, as well as handle the following situations:

In addition, the dial plan allows you to limit the number of simultaneous outgoing fax calls, in order not to accidentally take up all free SIP channels.

[OutgoingFaxInit] ;        exten => _X.,1,NoOp() same => n,Set(GROUP()=faxout) ;    -   Asterisk, ;  failed       , ;     . same => n,Set(DB(fax_group_count/${UUID})=${GROUP_COUNT(faxout)}) same => n,GotoIf($[${DB(fax_group_count/${UUID})}<=${MAX_PARALLELISM}]?call) same => n,UserEvent(Fax,uuid: ${UUID},Status: CALL SUSPENDED) same => n,HangUp() same => n(call),Dial(Local/${EXTEN}@OutgoingCalls) same => n,HangUp() ;          exten => router,1,NoOp() same => n,Set(__UUID=${UUID}) same => n,Set(__DATA=${DATA}) same => n,Dial(Local/fax@OutgoingFax) same => n,HangUp() exten => failed,1,NoOp() ;  ,     -    UserEvent ;    same => n,GotoIf($[${DB_DELETE(fax_group_count/${UUID})}<=${MAX_PARALLELISM}]?:end) same => n,UserEvent(Fax,uuid: ${UUID},Status: CALL PICKUP FAILED) same => n(end),HangUp() [OutgoingFax] exten => fax,1,NoOp() same => n,UserEvent(Fax,uuid: ${UUID},Status: CALL PICKUP SUCCESS); ;     .  . same => n,Set(DB(fax_sendstatus/${UUID})=0) same => n,Playback(autofax) same => n,Set(FAXOPT(headerinfo)=Company) same => n,Set(FAXOPT(localstationid)=XXX-XX-XX) ;    same => n,Set(DB(fax_sendstatus/${UUID})=1) same => n,SendFax(${DATA}) same => n,HangUp() exten => h,1,NoOp() ;      ,    ;   same => n,GotoIf($[${DB_DELETE(fax_sendstatus/${UUID})}]?sendstatus) same => n,UserEvent(Fax,uuid: ${UUID},Status: FAX SEND FAILED) same => n,Goto(end) ;     ,     ${FAXOPT} same => n(sendstatus),UserEvent(Fax,uuid: ${UUID},Status: FAX SEND ${FAXOPT(status)}) same => n(end),NoOp() 

The main part of our fax server, as noted above, will work on node.js. With Asterisk we will interact via AMI. For full-fledged work, the client will have enough rights to create calls and read UserEvents. Thus, manager.conf will look like this:

 [general] enabled=yes [FAX] secret=password read=user write=originate 

To work with AMI, the nami module was selected. In contrast, the analogue, he bribes a fairly large functionality out of the box. There are already ready methods for working with most events and generating actions. It is worth noting that the author of this module has implementations of AMI interfaces for other languages ​​besides JS.
')
The general mechanism of the fax server is the following:

Redis is used to implement the queue and the database itself. The storage structure is as follows:

To create a nice looking web form, twitter bootstrap was chosen. Displaying information to the user is done via jQuery datatables . There was a problem waiting for me with the fact that jQuery datatables is not adapted to the current version of bootstrap 3. Fortunately, on github there was a repository of the fixed version.
The end result is the following:
image
image
All basic settings are located in config.json:
 { "logLevel": "info", "port": 80, //    "FAX": { "uploadDir": "/tmp/faxout", //    "storageDir": "/tmp/faxout", //    TIFF   "gsCommand": "gs", //   Ghostscript (   ) "maxParallelism": 3, //     "maxRetry": 5, //     "retryInterval": 420, //    "delayedProcessingInterval": 5 //      }, "AMI": { //     AMI "host": "192.168.1.1", "port": 5038, "username": "FAX", "secret": "password" } 

Get the source code on github . To work, you need to add the fragment described above to the Asterisk set plan as well as have redis and node.js on the server. I hope my “Hello world” (aka fax server) on node.js will be useful to you.

Source: https://habr.com/ru/post/207080/


All Articles