通话记录是每个呼叫会话期间记录的数据。CDR 可能包含特定于每个呼叫会话以及最终呼叫的每个leg的属性。
CDR 包含发起呼叫和接收呼叫的电话号码、呼叫时间、呼叫持续时间和许多其他属性。
保存通话记录
存储“实时”通话记录的最佳方法是将所有数据字段写入磁盘或 内存上的临时缓存区域,并通话脚本来扫描此缓存区域,以便将它们存储在你的数据库。这可以避免在 FS 中因保存通话记录导致的挂起语音呼叫线程。
不要在拨号方案或 ESL 脚本的挂断事件中编写 CDR 脚本,因为这会延迟语音线程的终止,并且不适用于大型系统。允许语音线程只处理语音;单独、离线处理您的后端业务流程。这种方法适用于从小型到大型的所有业务。
流行的方式包括:
mod_cdr_csv
- 使用您在模板中指定的变量保存 CSV 文件。mod_cdr_mongodb
- 将详细的 CDR 数据保存到 MongoDB 数据库,格式类似于 mod_json_cdr。mod_odbc_cdr
- 保存通话中的任何通道变量至您选择的 ODBC 数据库中。mod_cdr_pg_csv
- 使用 兼容 Asterisk CDR 模块 的 PostgreSQL 数据库。mod_cdr_sqlite
- 使用您在模板中指定的变量直接保存到 sqlite DB。mod_json_cdr
- 将通道变量和调用流程通过JSON的形式保存到文件或发布到其他。它可以直接发布到 CouchDB。mod_xml_cdr
- 将通道变量和调用流程通过XML的形式保存到文件或发布到其他。Xmlcdrd
或JavaCDRLogger
可以帮助您保存结果。
mod_radius_cdr
- RADIUS CDR 模块。CDR via ESL
- 在 ESL 事件中检索 CDR- 来自bougyman 的
tiny_cdr
,位于 https://github.com/rubyists/tiny_cdr
当呼叫开始响铃时,如果它有媒体,那么 将设置progress_media_time ;如果没有, progress_time 将被设置。未设置的值将为零。因此,ring_start_time = progress_time + progress_media_time
可以计算出呼叫开始响铃的确切时间:
PDD(拨号后延迟)是呼叫开始和呼叫振铃之间的静默期,因此对于振铃的呼叫:pdd = ring_start_time - created_time
如果电话被接听,则有通话时间。如果呼叫未应答,则 应答 时间将为 0。如果 应答 时间大于零:length_of_talk_time = hangup_time - answered_time
电话响了多长时间由 hangup_time 或 answers_time确定:
if ( answered_time == 0 ) then
length_of_phone_ringing = hangup_time - created_time
else
length_of_phone_ringing = answered_time - created_time
end
通过 ESL 保存 CDR
ESL 允许实时检索 CDR。 CDR 信息在事件 CHANNEL_HANGUP_COMPLETE
中提供。
如果您设置通道变量 hangup_complete_with_xml=true
,那么该事件的主体将是完整的 XML CDR。
另见 mod_cdr_ * 模块(例如 mod_cdr_pg_csv
、mod_cdr_csv
、mod_cdr_mongodb
)。
在Perl 中使用 ESL 显示 CDR 的示例
#! /usr/bin/perl -wT
# handle_cdr.pl
# Connect to event socket, listen for CHANNEL_HANGUP_COMPLETE events
# Uses event data to create custom CDRs
use strict;
use warnings;
use lib '/usr/src/freeswitch.git/libs/esl/perl';
use ESL;
my $host = 'localhost';
my $port = '8021';
my $pass = 'ClueCon';
# Connect to event socket
my $con = ESL::ESLconnection->new($host, $port, $pass);
if ( ! $con ) {
die "Unable to establish connection to FreeSWITCH.\n";
}
# Listen for events of type CHANNEL_HANGUP_COMPLETE only
$con->events('plain','CHANNEL_HANGUP_COMPLETE');
print "Connected to FreeSWITCH $host:$port and waiting for events...\n\n";
while ( $con->connected() ) {
my $e = $con->recvEvent();
my @raw_data = split /\n/, $e->serialize();
my %cdr;
foreach my $item ( @raw_data ) {
#print "$item\n";
my ($header, $value) = split /: /, $item;
$header =~ s/^variable_//;
$cdr{$header} = $value;
}
# %cdr contains a complete list of channel variables
print 'New CDR: ';
print $cdr{uuid} . ', ' . $cdr{direction} . ', ';
print $cdr{answer_epoch} . ', ' . $cdr{end_epoch} . ', ';
print $cdr{hangup_cause} . "\n";
}
- 分类: FreeSWITCH FreeSWITCH学习 呼叫中心
- 标签: FreeSWITCH 呼叫中心