I hope that this article will turn the articles on the Asterisk configuration into a whole series of articles, the beginning of which I, for myself, put about 2 years ago in
this article.
I try to describe my development (and perhaps someone and lift the curtain of secrecy) non-trivial, or simply interesting, in my opinion, dialplans.
I will immediately make a reservation that I will not describe the configuration of modules, database connection configuration files, and the like, since this is not the purpose of the article, much less it is in the
wiki and in Asterisk books. Also, I will immediately say that I am doing all this on bare Asterisk without freePBX, as I consider the implementation of this web interface to be incorrect, illogical and flawed.
')
I will begin with one of the scenarios in organizations - secretary discharge. The same logic will be possible to apply to Call centers and taxi dispatchers (slightly changing Dialplan).
Scenario:- Call the secretary.
- The secretary picks up the phone - ask to connect with the sales department.
- The secretary transfers the call to a group of managers.
-Manager talking to a client.
-When calling again within 24 hours, the client goes immediately to the manager who received him for the first time.
Who cares please under the cat.
Retreat:
Anticipating the question Why? in comments:
As a rule, clients with managers have fairly close communication, but it is not always convenient to give your personal phone number — it can be forgotten or lost. The manager may forget and not give him something or something else will happen to him and the client will be left without a direct connection. The secretary also has a number of responsibilities and it’s expensive for him / her to work as a telephonist full-time. Even with an internal number, it is always easier for each manager to memorize 6-10 digits of the telephone number instead of 13-15.Task:- Save the secretary from transferring the same client to the managers for a certain period of time.
- Link the client to the designated manager
Implementation logic:After the manager picked up the phone, Asterisk “remembers” the client number and when it calls again in the next 24 hours it connects the client with the manager who spoke with him.
Implementation.Asterisk should somehow recognize the client who is calling him, as well as should remember the manager who picked up the phone. This information will be stored in a database and will be available to the asterisk upon request.
Create a database or create a table in an existing one (I used mysql).
The created table has 4 fields:
id Unique string value
number Customer number
date Date in UTC
agent Agent number who accepted the call
I put all the necessary references to the table in 4 queries:
GET_DATA As the name implies: we receive data about the customer who called and using his number
SELECT agent, date, number FROM dbname.clients WHERE number= .
SET_DATA We write data to base
INSERT INTO dbname.clients (number,date,agent) VALUES (' ',' UTC',' ')
UPDATE_TIME We update the time when you call again
UPDATE dbname.clients SET date= WHERE number=
DELETE_DATA Delete client from database
DELETE FROM dbname.clients WHERE number= AND date= UTC
Now, the code for working with the database is ready to write dialplan that will handle this connection.
Step one - we identify the client:All incoming calls initially come to the secretary (from-external context). Each such call is a potential client, so we will check - and didn’t he call us already?
To do this, we first request in the table the values ​​of the agent number, date and caller number using the GET_DATA request
[from-external]
exten=>_X.,1,Set(ARRAY(AGENT,DATE,NUMBER)=${ODBC_GET_DATA(${CALLERID(num)})")
If there is no such number in the database, then the number variable will remain empty - this will be our main comparison parameter in order to understand which way the dialplan will go next:
exten=>_X.,n,GotoIf($[${NUMBER}!=""]?comparedate:dialexten)
If the variable number is not empty, then the client has already called us, the next step is to find out how long ago he called us. To do this, compare the date in the table with the current date, to do this, follow the comparedate branch, subtract the value of the date variable obtained at the very first step from the current date and save it all in the DATERESULT variable:
exten=>_X.,n(comparedate),Set(DATERESULT=${MATH(${EPOCH}-${DATE},i)})
Then we compare it with the magic number 86400 (I will not disclose the secret of this number, those who know themselves will understand, and those who don’t know will look at Wikipedia what Unix Time Stamp is, expand their horizons and remember mathematics), and based on what result we get, we’ll go on dialagent branches and deleteagent. It is important to pay attention to the syntax - without quotes and with a gap between the "<" and values, if you write GotoIf differently, it will not work correctly:
exten=>_X.,n,GotoIf($[${DATERESULT} < 86400]?dialagent:deleteagent)
The dialagent label is responsible for calling the manager to which the client is attached. After the call, we update the time value, as the collaboration continues:
exten=>_X.,n(dialagent),Dial(SIP/${AGENT},,Ttg)
exten=>_X.,n,Set(ODBC_UPDATE_TIME()=${EPOCH},${NUMBER})
exten=>_X.,n,Hangup()
The deleteagent label transfers the dialplan to the secret call removal branch with the preliminary deletion from the user’s database, this happens when the user has not called the company for more than 24 hours.
exten=>_X.,n(deleteagent),Set(ODBC_DELETE_DATA()=${NUMBER},${DATE})
exten=>_X.,n(dialexten),Dial(SIP/${EXTEN},,Ttg)
Note:
I didn’t write the deletion of the record from the database after the time through the asterisk dialplan because in this implementation it is a crutch and it would be much more correct to run a cron script once a day at least on the same php and clean the database from the delayed entriesThis completes the caller status determination and the user is transferred to the queue.
It is important when translating to use blindtransfer, so that the CALLERID of the calling client is highlighted by the manager. If you really need to use extended transfer, then before transfer, set the secretary's CALLERID to the client's CALLERID value so that the client number, not the secretary, should appear in the table in the
number field. This is the first decision that has occurred to me. If anyone has any more ideas, I will be glad to hear.
And so, when transferring by blindtransfer to the queue number, you need to take into account 1 moment:
We will need the number of the manager who picked up the phone. Here I’ll go away from the rule not to go deep into configs, because in order to get this value in the configuration file of the queue you need to set the value
setinterfacevar = yes . This setting allows you to see the value of the variable
MEMBERINTERFACE , which in itself just stores the number of a member of the queue that picked up the phone.
To process it you can go in 2 ways:
1. Use a macro in the queue call:
exten=>500,1,Queue(Queue1,t,,,,,queue-answer)
[macro-queue-answer]
exten => s,1,Set(AGENT=${CUT(MEMBERINTERFACE,/,2)})
2. Use hangup extensions
exten=>500,1,Queue(Queue1,t)
exten => h,1,Set(AGENT=${CUT(MEMBERINTERFACE,/,2)})
The problem is that after the end of the call, to bring the manager to the database you need to get his CALLERID. Method
2 does not forward the CALLERID manager to the macors, and passing a parameter to the macro when calling it from the queue is impossible - as I did not try, I did not succeed in forwarding it. Therefore, the method was obmateren and damned, and I stopped at method
1 .
With this method there is also a nuance - if I catch the hangup event in the context of
from-external , then any
hangup (be it a manager or a secretary) will be processed, but this is not necessary. Therefore, when transferring a call to a queue, the queue itself is translated into a new context, in which it processes:
exten=>500,1,Answer()
exten=>500,n,Goto(queue-answering,s,1)
[queue-answering]
exten=>s,1,Queue(Queue1,t)
exten => h,1,Set(AGENT=${CUT(MEMBERINTERFACE,/,2)})
After the readable number of the manager was received, it remains to write the data to the database:
exten => h,n,Set(ODBC_SET_DATA()="${CALLERID(num)}","${EPOCH}","${AGENT}")
On this dialplan is over. it can be improved and improved by adding an IVR when processing a call to an already calling customer and offering him various options for making a call. You can also add a call announcement for the manager when he picks up the phone so that he knows that this is a call from a new client, or simply from a client.
In general, this dialplan is the basis on which you can deploy a very convenient and inexpensive solution for asterisk performance (without resorting to AGI for example), which is used by both taxi companies and some call-centers.