Developement Questions

I’m trying replace an antiquated system for a small answering service. After much headache, I have a system up and running. Now I need to create a client side solution (Didn’t like the solutions I have found).

Does FreePBX automatically record the incoming calls to MySQL? If so, does it show what ring group they go to, does it show what extension picked up that call? Also how quickly does it log this information?

FreePBX does not automatically record calls. You need to select that option from the extensions page. The recorded calls are then stored in /var/spool/asterisk/monitor (at least on centos). If a ring group contains an extension that is supposed to be recorded then all calls to that ring group, regardless of which extension answers, will be recorded (iirc). CDR’s aren’t posted until the calls is hungup, but if your ready for advanced stuff you can get ‘live info’ using the Asterisk Manager.

Er. Sorry for the confusion, but I when I was using the word recorded, I was meaning to say was “to take note”, not audio recorded.

Just need to see the DID, CID, the Extention/agent that picked it up.

Yes, the Call Detail Reports tab (CDR) does this… here is a screen shot as an example:
http://www.netlogtec.com/IMAGES/asterisk-cdr.gif

Ah. OK. So the CDR is updated real time, and I could then just pull that information from the database right?

in real time = as soon as the call is hung up

Ah… Yeah - Won’t be able to do that, since I need to know the info when it comes in, as soon as someone picks it up. So plan B - use PHP to read the stuff from the CLI. This is going be fun…

Now that I have PHP opening up the asterisk process and reading it like a file:

if(!($p=popen("(asterisk -rvvvvvv)2>&1","r")))
 {
  die('Failure: Could not open Asterisk process');
 }


while(!feof($p))
 {
  ....
}

And I have PHP stripping the ANSI colors (ANSI escape sequences)

  $subject = preg_replace('/\x1b(\[|\(|\))[;?0-9]*[0-9A-Za-z]/', "",$subject);
  $subject = preg_replace('/\x1b(\[|\(|\))[;?0-9]*[0-9A-Za-z]/', "",$subject);
  $subject = preg_replace('/[\x03|\x1a]/', "", $subject);

And I can preg_match everything I want…

But I’m stuck at trying to figure out how to track a call coming in and when it gets picked up. I’ve copied the ‘asterisk -rvvvvvv’ output when the call comes in all the way to till the end when it’s hung up.

    -- Executing [8175551000@from-internal:1] Macro("SIP/1005-09cbaac8", "user-callerid|SKIPTTL|") in new stack
    -- Executing [s@macro-user-callerid:1] NoOp("SIP/1005-09cbaac8", "user-callerid: device 1005") in new stack
    -- Executing [s@macro-user-callerid:2] Set("SIP/1005-09cbaac8", "AMPUSER=1005") in new stack
    -- Executing [s@macro-user-callerid:3] GotoIf("SIP/1005-09cbaac8", "0?report") in new stack
    -- Executing [s@macro-user-callerid:4] ExecIf("SIP/1005-09cbaac8", "1|Set|REALCALLERIDNUM=1005") in new stack
    -- Executing [s@macro-user-callerid:5] NoOp("SIP/1005-09cbaac8", "REALCALLERIDNUM is 1005") in new stack
    -- Executing [s@macro-user-callerid:6] Set("SIP/1005-09cbaac8", "AMPUSER=1005") in new stack
    -- Executing [s@macro-user-callerid:7] Set("SIP/1005-09cbaac8", "AMPUSERCIDNAME=1005") in new stack
    -- Executing [s@macro-user-callerid:8] GotoIf("SIP/1005-09cbaac8", "0?report") in new stack
    -- Executing [s@macro-user-callerid:9] Set("SIP/1005-09cbaac8", "AMPUSERCID=1005") in new stack
    -- Executing [s@macro-user-callerid:10] Set("SIP/1005-09cbaac8", "CALLERID(all)="1005" <1005>") in new stack
    -- Executing [s@macro-user-callerid:11] Set("SIP/1005-09cbaac8", "REALCALLERIDNUM=1005") in new stack
    -- Executing [s@macro-user-callerid:12] ExecIf("SIP/1005-09cbaac8", "0|Set|CHANNEL(language)=") in new stack
    -- Executing [s@macro-user-callerid:13] NoOp("SIP/1005-09cbaac8", "TTL:  ARG1: SKIPTTL") in new stack
    -- Executing [s@macro-user-callerid:14] GotoIf("SIP/1005-09cbaac8", "1?continue") in new stack
    -- Goto (macro-user-callerid,s,23)
    -- Executing [s@macro-user-callerid:23] NoOp("SIP/1005-09cbaac8", "Using CallerID "1005" <1005>") in new stack
    -- Executing [8175551000@from-internal:2] Set("SIP/1005-09cbaac8", "_NODEST=") in new stack
    -- Executing [8175551000@from-internal:3] Macro("SIP/1005-09cbaac8", "record-enable|1005|OUT|") in new stack
    -- Executing [s@macro-record-enable:1] GotoIf("SIP/1005-09cbaac8", "0?2:4") in new stack
    -- Goto (macro-record-enable,s,4)
    -- Executing [s@macro-record-enable:4] AGI("SIP/1005-09cbaac8", "recordingcheck|20080710-181527|1215731727.34") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/recordingcheck
  recordingcheck|20080710-181527|1215731727.34: Outbound recording not enabled
    -- AGI Script recordingcheck completed, returning 0
    -- Executing [s@macro-record-enable:5] NoOp("SIP/1005-09cbaac8", "No recording needed") in new stack
    -- Executing [8175551000@from-internal:4] Macro("SIP/1005-09cbaac8", "dialout-trunk|1|8175551000||") in new stack
    -- Executing [s@macro-dialout-trunk:1] Set("SIP/1005-09cbaac8", "DIAL_TRUNK=1") in new stack
    -- Executing [s@macro-dialout-trunk:2] ExecIf("SIP/1005-09cbaac8", "0|Authenticate|") in new stack
    -- Executing [s@macro-dialout-trunk:3] GotoIf("SIP/1005-09cbaac8", "0?disabletrunk|1") in new stack
    -- Executing [s@macro-dialout-trunk:4] Set("SIP/1005-09cbaac8", "DIAL_NUMBER=8175551000") in new stack
    -- Executing [s@macro-dialout-trunk:5] Set("SIP/1005-09cbaac8", "DIAL_TRUNK_OPTIONS=tr") in new stack
    -- Executing [s@macro-dialout-trunk:6] Set("SIP/1005-09cbaac8", "GROUP()=OUT_1") in new stack
    -- Executing [s@macro-dialout-trunk:7] GotoIf("SIP/1005-09cbaac8", "1?nomax") in new stack
    -- Goto (macro-dialout-trunk,s,9)
    -- Executing [s@macro-dialout-trunk:9] GotoIf("SIP/1005-09cbaac8", "0?skipoutcid") in new stack
    -- Executing [s@macro-dialout-trunk:10] Set("SIP/1005-09cbaac8", "DIAL_TRUNK_OPTIONS=") in new stack
    -- Executing [s@macro-dialout-trunk:11] Macro("SIP/1005-09cbaac8", "outbound-callerid|1") in new stack
    -- Executing [s@macro-outbound-callerid:1] ExecIf("SIP/1005-09cbaac8", "0|SetCallerPres|") in new stack
    -- Executing [s@macro-outbound-callerid:2] GotoIf("SIP/1005-09cbaac8", "1?start") in new stack
    -- Goto (macro-outbound-callerid,s,4)
    -- Executing [s@macro-outbound-callerid:4] NoOp("SIP/1005-09cbaac8", "REALCALLERIDNUM is 1005") in new stack
    -- Executing [s@macro-outbound-callerid:5] GotoIf("SIP/1005-09cbaac8", "1?normcid") in new stack
    -- Goto (macro-outbound-callerid,s,10)
    -- Executing [s@macro-outbound-callerid:10] Set("SIP/1005-09cbaac8", "USEROUTCID=") in new stack
    -- Executing [s@macro-outbound-callerid:11] Set("SIP/1005-09cbaac8", "EMERGENCYCID=") in new stack
    -- Executing [s@macro-outbound-callerid:12] Set("SIP/1005-09cbaac8", "TRUNKOUTCID=") in new stack
    -- Executing [s@macro-outbound-callerid:13] GotoIf("SIP/1005-09cbaac8", "1?trunkcid") in new stack
    -- Goto (macro-outbound-callerid,s,17)
    -- Executing [s@macro-outbound-callerid:17] GotoIf("SIP/1005-09cbaac8", "1?usercid") in new stack
    -- Goto (macro-outbound-callerid,s,19)
    -- Executing [s@macro-outbound-callerid:19] GotoIf("SIP/1005-09cbaac8", "1?report") in new stack
    -- Goto (macro-outbound-callerid,s,23)
    -- Executing [s@macro-outbound-callerid:23] NoOp("SIP/1005-09cbaac8", "CallerID set to "1005" <1005>") in new stack
    -- Executing [s@macro-dialout-trunk:12] AGI("SIP/1005-09cbaac8", "fixlocalprefix") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/fixlocalprefix
    -- AGI Script fixlocalprefix completed, returning 0
    -- Executing [s@macro-dialout-trunk:13] Set("SIP/1005-09cbaac8", "OUTNUM=8175551000") in new stack
    -- Executing [s@macro-dialout-trunk:14] Set("SIP/1005-09cbaac8", "custom=ZAP/g1") in new stack
    -- Executing [s@macro-dialout-trunk:15] GotoIf("SIP/1005-09cbaac8", "1?gocall") in new stack
    -- Goto (macro-dialout-trunk,s,17)
    -- Executing [s@macro-dialout-trunk:17] Macro("SIP/1005-09cbaac8", "dialout-trunk-predial-hook|") in new stack
    -- Executing [s@macro-dialout-trunk:18] GotoIf("SIP/1005-09cbaac8", "0?bypass|1") in new stack
    -- Executing [s@macro-dialout-trunk:19] GotoIf("SIP/1005-09cbaac8", "0?customtrunk") in new stack
    -- Executing [s@macro-dialout-trunk:20] Dial("SIP/1005-09cbaac8", "ZAP/g1/8175551000|300|") in new stack
    -- Requested transfer capability: 0x00 - SPEECH
    -- Called g1/8175551000
    -- Accepting call from '1005' to '8175551000' on channel 0/1, span 2
    -- Executing [8175551000@zaptel-incoming:1] Set("Zap/25-1", "__FROM_DID=8175551000") in new stack
    -- Executing [8175551000@zaptel-incoming:2] GotoIf("Zap/25-1", "1 ?cidok") in new stack
    -- Goto (zaptel-incoming,8175551000,4)
    -- Executing [8175551000@zaptel-incoming:4] NoOp("Zap/25-1", "CallerID is "1005" <1005>") in new stack
    -- Executing [8175551000@zaptel-incoming:5] Set("Zap/25-1", "__CALLINGPRES_SV=allowed_not_screened") in new stack
    -- Executing [8175551000@zaptel-incoming:6] SetCallerPres("Zap/25-1", "allowed_not_screened") in new stack
    -- Executing [8175551000@zaptel-incoming:7] Goto("Zap/25-1", "ext-group|600|1") in new stack
    -- Goto (ext-group,600,1)
    -- Executing [600@ext-group:1] Macro("Zap/25-1", "user-callerid|") in new stack
    -- Executing [s@macro-user-callerid:1] NoOp("Zap/25-1", "user-callerid: 1005 1005") in new stack
    -- Executing [s@macro-user-callerid:2] Set("Zap/25-1", "AMPUSER=1005") in new stack
    -- Executing [s@macro-user-callerid:3] GotoIf("Zap/25-1", "0?report") in new stack
    -- Executing [s@macro-user-callerid:4] ExecIf("Zap/25-1", "1|Set|REALCALLERIDNUM=1005") in new stack
    -- Executing [s@macro-user-callerid:5] NoOp("Zap/25-1", "REALCALLERIDNUM is 1005") in new stack
    -- Executing [s@macro-user-callerid:6] Set("Zap/25-1", "AMPUSER=1005") in new stack
    -- Executing [s@macro-user-callerid:7] Set("Zap/25-1", "AMPUSERCIDNAME=1005") in new stack
    -- Zap/1-1 is proceeding passing it to SIP/1005-09cbaac8
    -- Executing [s@macro-user-callerid:8] GotoIf("Zap/25-1", "0?report") in new stack
    -- Executing [s@macro-user-callerid:9] Set("Zap/25-1", "AMPUSERCID=1005") in new stack
    -- Executing [s@macro-user-callerid:10] Set("Zap/25-1", "CALLERID(all)="1005" <1005>") in new stack
    -- Executing [s@macro-user-callerid:11] Set("Zap/25-1", "REALCALLERIDNUM=1005") in new stack
    -- Executing [s@macro-user-callerid:12] ExecIf("Zap/25-1", "0|Set|CHANNEL(language)=") in new stack
    -- Executing [s@macro-user-callerid:13] NoOp("Zap/25-1", "TTL:  ARG1: ") in new stack
    -- Executing [s@macro-user-callerid:14] GotoIf("Zap/25-1", "0?continue") in new stack
    -- Executing [s@macro-user-callerid:15] Set("Zap/25-1", "__TTL=64") in new stack
    -- Executing [s@macro-user-callerid:16] GotoIf("Zap/25-1", "1?continue") in new stack
    -- Goto (macro-user-callerid,s,23)
    -- Executing [s@macro-user-callerid:23] NoOp("Zap/25-1", "Using CallerID "1005" <1005>") in new stack
    -- Executing [600@ext-group:2] GotoIf("Zap/25-1", "1?skipdb") in new stack
    -- Goto (ext-group,600,4)
    -- Executing [600@ext-group:4] Set("Zap/25-1", "__NODEST=") in new stack
    -- Executing [600@ext-group:5] Set("Zap/25-1", "__BLKVM_OVERRIDE=BLKVM/600/Zap/25-1") in new stack
    -- Executing [600@ext-group:6] Set("Zap/25-1", "__BLKVM_BASE=600") in new stack
    -- Executing [600@ext-group:7] Set("Zap/25-1", "DB(BLKVM/600/Zap/25-1)=TRUE") in new stack
    -- Executing [600@ext-group:8] Set("Zap/25-1", "RRNODEST=") in new stack
    -- Executing [600@ext-group:9] Set("Zap/25-1", "__NODEST=600") in new stack
    -- Executing [600@ext-group:10] Set("Zap/25-1", "RecordMethod=Group") in new stack
    -- Executing [600@ext-group:11] Macro("Zap/25-1", "record-enable|1000-1001-1002-1003-1004|Group") in new stack
    -- Executing [s@macro-record-enable:1] GotoIf("Zap/25-1", "0?2:4") in new stack
    -- Goto (macro-record-enable,s,4)
    -- Executing [s@macro-record-enable:4] AGI("Zap/25-1", "recordingcheck|20080710-181528|1215731728.36") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/recordingcheck
    -- AGI Script recordingcheck completed, returning 0
    -- Executing [s@macro-record-enable:5] NoOp("Zap/25-1", "No recording needed") in new stack
    -- Executing [600@ext-group:12] Set("Zap/25-1", "RingGroupMethod=ringall") in new stack
    -- Executing [600@ext-group:13] Macro("Zap/25-1", "dial|20|tr|1000-1001-1002-1003-1004") in new stack
    -- Executing [s@macro-dial:1] GotoIf("Zap/25-1", "1?dial") in new stack
    -- Goto (macro-dial,s,3)
    -- Executing [s@macro-dial:3] AGI("Zap/25-1", "dialparties.agi") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/dialparties.agi
  dialparties.agi: Starting New Dialparties.agi
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
  dialparties.agi: Caller ID name is '1005' number is '1005'
  dialparties.agi: USE_CONFIRMATION:  'FALSE'
  dialparties.agi: RINGGROUP_INDEX:   ''
  dialparties.agi: Methodology of ring is  'ringall'
    --  dialparties.agi: Added extension 1000 to extension map
    --  dialparties.agi: Added extension 1001 to extension map
    --  dialparties.agi: Added extension 1002 to extension map
    --  dialparties.agi: Added extension 1003 to extension map
    --  dialparties.agi: Added extension 1004 to extension map
    --  dialparties.agi: Extension 1000 cf is disabled
    --  dialparties.agi: Extension 1001 cf is disabled
    --  dialparties.agi: Extension 1002 cf is disabled
    --  dialparties.agi: Extension 1003 cf is disabled
    --  dialparties.agi: Extension 1004 cf is disabled
    --  dialparties.agi: Extension 1000 do not disturb is disabled
    --  dialparties.agi: Extension 1001 do not disturb is disabled
    --  dialparties.agi: Extension 1002 do not disturb is disabled
    --  dialparties.agi: Extension 1003 do not disturb is disabled
    --  dialparties.agi: Extension 1004 do not disturb is disabled
       >  dialparties.agi: extnum 1000 has:  cw: 1; hascfb: 0 [] hascfu: 0 []
    --  dialparties.agi: dbset CALLTRACE/1000 to 1005
       >  dialparties.agi: extnum 1001 has:  cw: 1; hascfb: 0 [] hascfu: 0 []
    --  dialparties.agi: dbset CALLTRACE/1001 to 1005
       >  dialparties.agi: extnum 1002 has:  cw: 1; hascfb: 0 [] hascfu: 0 []
    --  dialparties.agi: dbset CALLTRACE/1002 to 1005
       >  dialparties.agi: extnum 1003 has:  cw: 1; hascfb: 0 [] hascfu: 0 []
    --  dialparties.agi: dbset CALLTRACE/1003 to 1005
       >  dialparties.agi: extnum 1004 has:  cw: 1; hascfb: 0 [] hascfu: 0 []
    --  dialparties.agi: dbset CALLTRACE/1004 to 1005
    --  dialparties.agi: Filtered ARG3: 1000-1001-1002-1003-1004
       >  dialparties.agi: NODEST: 600 adding M(auto-blkvm) to dialopts: trM(auto-blkvm)
       >  dialparties.agi: NODEST: 600 blkvm enabled macro already in dialopts: trM(auto-blkvm)
  == Manager 'admin' logged off from 127.0.0.1
    -- AGI Script dialparties.agi completed, returning 0
    -- Executing [s@macro-dial:7] Dial("Zap/25-1", "SIP/1000&SIP/1001&SIP/1002&SIP/1003&SIP/1004|20|trM(auto-blkvm)") in new stack
    -- Called 1000
    -- Zap/1-1 is ringing
    -- SIP/1000-09cc45b0 is ringing
    -- SIP/1000-09cc45b0 answered Zap/25-1
    -- Executing [s@macro-auto-blkvm:1] Set("SIP/1000-09cc45b0", "__MACRO_RESULT=") in new stack
    -- Executing [s@macro-auto-blkvm:2] Set("SIP/1000-09cc45b0", "__CWIGNORE=") in new stack
    -- Executing [s@macro-auto-blkvm:3] DBdel("SIP/1000-09cc45b0", "BLKVM/600/Zap/25-1") in new stack
    -- DBdel: family=BLKVM, key=600/Zap/25-1
    -- Zap/1-1 answered SIP/1005-09cbaac8
  == Spawn extension (macro-dial, s, 7) exited non-zero on 'Zap/25-1' in macro 'dial'
  == Spawn extension (macro-dial, s, 7) exited non-zero on 'Zap/25-1'
    -- Executing [h@macro-dial:1] Macro("Zap/25-1", "hangupcall") in new stack
    -- Executing [s@macro-hangupcall:1] ResetCDR("Zap/25-1", "w") in new stack
    -- Executing [s@macro-hangupcall:2] NoCDR("Zap/25-1", "") in new stack
    -- Executing [s@macro-hangupcall:3] GotoIf("Zap/25-1", "1?skiprg") in new stack
    -- Goto (macro-hangupcall,s,6)
    -- Executing [s@macro-hangupcall:6] GotoIf("Zap/25-1", "0?skipblkvm") in new stack
    -- Executing [s@macro-hangupcall:7] NoOp("Zap/25-1", "Cleaning Up Block VM Flag: BLKVM/600/Zap/25-1") in new stack
    -- Executing [s@macro-hangupcall:8] DBdel("Zap/25-1", "BLKVM/600/Zap/25-1") in new stack
    -- DBdel: family=BLKVM, key=600/Zap/25-1
    -- DBdel: Error deleting key from database.
    -- Executing [s@macro-hangupcall:9] GotoIf("Zap/25-1", "1?theend") in new stack
    -- Goto (macro-hangupcall,s,11)
    -- Executing [s@macro-hangupcall:11] Hangup("Zap/25-1", "") in new stack
  == Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'Zap/25-1' in macro 'hangupcall'
  == Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'Zap/25-1'
    -- Hungup 'Zap/25-1'
    -- Channel 0/1, span 1 got hangup request, cause 16
    -- Hungup 'Zap/1-1'
  == Spawn extension (macro-dialout-trunk, s, 20) exited non-zero on 'SIP/1005-09cbaac8' in macro 'dialout-trunk'
  == Spawn extension (macro-dialout-trunk, s, 20) exited non-zero on 'SIP/1005-09cbaac8'
    -- Executing [h@macro-dialout-trunk:1] Macro("SIP/1005-09cbaac8", "hangupcall|") in new stack
    -- Executing [s@macro-hangupcall:1] ResetCDR("SIP/1005-09cbaac8", "w") in new stack
    -- Executing [s@macro-hangupcall:2] NoCDR("SIP/1005-09cbaac8", "") in new stack
    -- Executing [s@macro-hangupcall:3] GotoIf("SIP/1005-09cbaac8", "1?skiprg") in new stack
    -- Goto (macro-hangupcall,s,6)
    -- Executing [s@macro-hangupcall:6] GotoIf("SIP/1005-09cbaac8", "1?skipblkvm") in new stack
    -- Goto (macro-hangupcall,s,9)
    -- Executing [s@macro-hangupcall:9] GotoIf("SIP/1005-09cbaac8", "1?theend") in new stack
    -- Goto (macro-hangupcall,s,11)
    -- Executing [s@macro-hangupcall:11] Hangup("SIP/1005-09cbaac8", "") in new stack
  == Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/1005-09cbaac8' in macro 'hangupcall'
  == Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'SIP/1005-09cbaac8'

Any help will be appreciated.

well, plan B is doomed form the start, so on to plan C: Use the asterisk manager. Search voip-info.org for more info

There are several products out there that will show real time call data, perhaps if you will explain a little bit about how you are going to use this.

Bill

I’m trying to use this for an Answering service. They have 100+ DID’s on a single T1.
I need to get the call information - DID, CID and Extension of who picked the call up. Another script that will search the MySQL DB for the agent call and then pop up the call script and notes and some other things relating to the DID number. Once I get part one done, then the second script “should be” easy. I’ve already created a simple script that does COMET based communication based on the multipart/x-mixed-replace header.

Also this is a ringall group.

It looks like from the Manger API docs, I would search for the ‘AgentConnect’ Event. I’ll look more into this tonight when I get home.

I figured it out with using the API method. “AgentConnect” isn’t what I was looking for, NewEvent (I think that was it… )and Link where the key words I was looking for. Thanks for your help all.