Record incoming calls
a Few months ago my friend asked me to help to solve the issue with the recording of incoming calls. All necessary or was available, or promised to provide.

If interested, my experience of implementation on python with the code below.
A friend provides support services and computer maintenance. The nature of employees ' work – crew. Private Manager no, all calls are accepted by employees in order to save. There are situations when the employee cannot answer the call (on the road, in dialogue with the client) or the employee received a claim from the client (did that, or not all that was requested). Such a situation should "resolve". In General, it was necessary for him to centralize the incoming calls, not taking on the job of Manager.
At the acquaintance all incidents and changes are recorded and managed in accordance with the requirements of ITIL. Automated processes using easla.com. Only thing missing was a call.br>
Any full-fledged call-center were not discussed, because the analysis of calls is performed "after the fact". So the requirements were simple:
the
Provided in easla.com the database was already created the object "call" and all the necessary attributes. Stipulated only statuses. Added a status of "Impossible" in case if the phone account ran out of money.
First of all, agreed on the fact that you still have to spend money on the purchase of city numbers and the upgrade of asterisk servers to handle incoming calls. Purchased the room from a local provider of IP telephony and asterisk server raised on a separate virtual server using existing hardware. On your asterisk server, set up forwarding of all incoming on the cell assistant, thus making him the Manager.
It was decided to use Twisted as a FastAGI server that have received the information about the completed call, and gave information to easla.com via SOAP. All the procedures described in administrator guide system.
The conversation is being recorded, use the command MixMonitor, as the name of the file use the variable ${UNIQUEID}.
At the end of the conversation, stop recording the conversation and pass control to FastAGI server:
To implement a FastAGI Protocol used the library starpy. Information on the duration of the call received via CDR records. After receiving all the necessary information in a separate thread recorded it in easla.com.
Once returned to asterisk-call control, you can do convert wav to mp3 and sending information easla.com. Here it is necessary to explain, why not use MixMonitor to convert, as suggested in many guides. MixMonitor runs third-party applications in a separate process and does not inform the FastAGI that the application has executed and could easily happen that at the time of sending information about the call will not have access to mp3 file. To convert a library is used pydub and suds as a SOAP client.
The module was able to break in the first week of operation. First, on account of not enough funds, and have successfully verified the phone records with a status of "Impossible." Then the account was added and verified the phone records with other statuses.
Looks like the registry of incoming calls, something like:

After the start of recording failed to add the function of determining subscriber in the register call, and the incident is created on the basis of the registered call.
If someone come in handy this decision, I will be glad.
Article based on information from habrahabr.ru

If interested, my experience of implementation on python with the code below.
A friend provides support services and computer maintenance. The nature of employees ' work – crew. Private Manager no, all calls are accepted by employees in order to save. There are situations when the employee cannot answer the call (on the road, in dialogue with the client) or the employee received a claim from the client (did that, or not all that was requested). Such a situation should "resolve". In General, it was necessary for him to centralize the incoming calls, not taking on the job of Manager.
At the acquaintance all incidents and changes are recorded and managed in accordance with the requirements of ITIL. Automated processes using easla.com. Only thing missing was a call.br>
Task
Any full-fledged call-center were not discussed, because the analysis of calls is performed "after the fact". So the requirements were simple:
the
-
the
- Record in the database the call details (number, date, duration) the
- Record call status (answered, unanswered, busy) the
- to Record the conversation.
Provided in easla.com the database was already created the object "call" and all the necessary attributes. Stipulated only statuses. Added a status of "Impossible" in case if the phone account ran out of money.
Solution
First of all, agreed on the fact that you still have to spend money on the purchase of city numbers and the upgrade of asterisk servers to handle incoming calls. Purchased the room from a local provider of IP telephony and asterisk server raised on a separate virtual server using existing hardware. On your asterisk server, set up forwarding of all incoming on the cell assistant, thus making him the Manager.
It was decided to use Twisted as a FastAGI server that have received the information about the completed call, and gave information to easla.com via SOAP. All the procedures described in administrator guide system.
The conversation is being recorded, use the command MixMonitor, as the name of the file use the variable ${UNIQUEID}.
At the end of the conversation, stop recording the conversation and pass control to FastAGI server:
exten = > h,1,StopMixMonitor
exten = > h,n,AGI(agi://127.0.0.1:4573)
To implement a FastAGI Protocol used the library starpy. Information on the duration of the call received via CDR records. After receiving all the necessary information in a separate thread recorded it in easla.com.
Get information about the call
def fastAgiMain( agi ):
sequence = fastagi.InSequence()
# Specify which variables you want to retrieve.
cdr_vars = {
'CDR(start)':",
'CDR(disposition)}':",
'CDR(duration)':",
'CDR(end)':",
'DIALSTATUS':",
}
# Get information and there sent it in easla.com in a separate thread
sequence.append(sendCDR, None, agi, cdr_vars, iter(cdr_vars))
# After the return UPRAVLENIE in asterisk
sequence.append(agi.finish)
def onFailure( reason ):
log.error( "Failure: %s", reason.getTraceback())
agi.finish()
return sequence().addErrback( onFailure )
# Recursive function that gets all the variables specified in cdr_vars
def sendCDR(result, agi, cdr_vars, keys):
def setVar(result, key):
cdr_vars[key] = result
def not available(reason, key):
print "key" + key + "not found"
try:
key = keys.next()
except StopIteration, err:
duration = str(timedelta(seconds=int(cdr_vars['CDR(duration)'])))
# Not using getVariable to get the callerid and uniqueid
caller_id = agi.variables['agi_callerid']
wav_file = '/data/wav/' + agi.variables['agi_uniqueid'] + '.wav'
status = cdr_vars['DIALSTATUS']
# In a separate thread to be sent the call details
thread = Thread(target=sendCallInfo, args=(caller_id, duration, wav_file, status))
return None
else:
return agi.getVariable(key) \ # Get variable key
.addCallback(setVar, key) \ # Recorded it in cdr_vars
.addErrback(not available, key) \ # If an error while receiving a variable key
.addCallback(sendCDR, agi, cdr_vars, keys) # Calling yourself again
Once returned to asterisk-call control, you can do convert wav to mp3 and sending information easla.com. Here it is necessary to explain, why not use MixMonitor to convert, as suggested in many guides. MixMonitor runs third-party applications in a separate process and does not inform the FastAGI that the application has executed and could easily happen that at the time of sending information about the call will not have access to mp3 file. To convert a library is used pydub and suds as a SOAP client.
Sent
def sendCallInfo(callid, callduration, wav_file ,status):
raw_params = {
'incoming_call_number': callid,
'incoming_call_time': callduration,}
if status:
if status == 'ANSWER':
raw_params['status'] = 'incoming_call_answered'
if status == 'BUSY':
raw_params['status'] = 'incoming_call_busy'
if status == 'NOANSWER':
raw_params['status'] = 'incoming_call_unanswered'
if status == 'CANCEL':
raw_params['status'] = 'incoming_call_unanswered'
if status == 'CONGESTION':
raw_params['status'] = 'incoming_call_congestion'
url = 'http://easla.com/user/soap'
client = Client(url)
client.service.login('login','password')
call_management_proc = client.service.getProcess('call_management')
incoming_call_def = client.service.getObjectdef(call_management_proc,
'incoming_call', 0)
keyval_array = client.factory.create('KeyValuesPairSoapArray')
# Fill the array KeyValuesPairSoapArray to send in easla.com
for key, value in raw_params.iteritems():
keyval = client.factory.create('KeyValuesPairSoap')
keyval.key = key
keyval.values.item.append(value)
keyval_array.item.append(keyval)
# Create an object for the incoming call in easla.com
incoming_call_obj = client.service.createObjectref(incoming_call_def,
None keyval_array)
if os.path.exists(wav_file):
# asterisk may not see the file
while is_locked(wav_file):
time.sleep(1)
mp3_file = wav2mp3(wav_file)
with open(mp3_file, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
if encoded_string:
# Create an attribute which will lie mp3 file
file_attr = client.factory.create('KeyValuePairSoapArray')
file_name = client.factory.create('KeyValuePairSoap')
file_content = client.factory.create('KeyValuePairSoap')
file_name.key = 'srcname'
file_name.value = os.path.basename(mp3_file)
file_content.key = 'content'
file_content.value = encoded_string
file_attr.item.append(file_name)
file_attr.item.append(file_content)
# Add attribute to object
client.service.addFile(incoming_call_obj, 'incoming_call_file',
file_attr)
if wav_file:
os.remove(wav_file)
if mp3_file:
os.remove(mp3_file)
The module was able to break in the first week of operation. First, on account of not enough funds, and have successfully verified the phone records with a status of "Impossible." Then the account was added and verified the phone records with other statuses.
Looks like the registry of incoming calls, something like:

After the start of recording failed to add the function of determining subscriber in the register call, and the incident is created on the basis of the registered call.
If someone come in handy this decision, I will be glad.