Eric Wieling aka ManxPower
2005-Jul-10 14:11 UTC
[Asterisk-Users] VM Outcall: Rube Goldberg Edition
Resent to the list since I didn't think you would mind. Kevin wrote:> Eric, > > I have been using your vm outcall script for some time and it has worked > well. Thanks for your efforts. > > I am trying to re-install and I can't seem to get a call file generated. > I have set up postfix and in the log it appears that it pipes the > message to the vmoutcall script. But that's as far as I get. > > I was hopeful that you could offer a suggestion on how to debug the > activity of the script so I can try to figure out why it isn't working.I don't provide support for any of the sample scripts, etc that I write. The original VM Outcall was very primitive. Now that Asterisk has the externnotify= option I have a much better, but still pretty primitive, script. In /etc/voicemail.conf, in [general] put: ==========================================================================externnotify=/usr/local/bin/vm-notify.pl ========================================================================== Here is the vm-notify.pl script: ==========================================================================#!/usr/bin/perl -w use Fcntl; use Fcntl ":flock"; $dial_context="local-access"; ($vm_box, $vm_context) = $ARGV[1] =~/(.*)\@(.*)/; $current_vm_context = ""; if(!sysopen($vm_conf_file_handle, "/etc/asterisk/voicemail.conf", O_RDONLY)) { printf("Cannot open /etc/asterisk/voicemail.conf!\n"); exit(1); } while($vm_conf_line = <$vm_conf_file_handle>) { chomp($vm_conf_line); if((substr($vm_conf_line,0,1) eq ";") || (length($vm_conf_line) == 0)) { next; } ($tmp_vm_context) = $vm_conf_line =~ /\[(.*)\]/; if(defined($tmp_vm_context)) { if($current_vm_context ne "") { exit(0); } if($tmp_vm_context eq $vm_context) { $current_vm_context = $vm_context; next; } } else { if($current_vm_context eq $vm_context) { ($tmp_vm_box) = $vm_conf_line =~ /(\d+)/; if($tmp_vm_box eq $vm_box) { ($dial_dest) = $vm_conf_line =~ /.*notify=(\d+)/; if(!defined($dial_dest)) { exit(0); } close($vm_conf_file_handle); # If there's already a .call file for this mailbox then don't do anything. # If there isn't already a .call file then create it. #$call_file_name = "/tmp/" . $vm_box . ".call"; $call_file_name = "/var/spool/asterisk/outgoing/" . $vm_box . ".call"; if(!sysopen($call_file_handle, "$call_file_name", O_WRONLY|O_CREAT|O_EXCL)) { exit(0); } flock($call_file_handle, LOCK_EX); # Set the access and modification times to be 10 years in the future so # Asterisk will ignore this file while we are doing stuff with it. $long_time = time() + (10 * 365 * 24 * 60 * 60); utime($long_time, $long_time, "$call_file_name"); srand; $call_delay=300 + rand(120); # Build our .call file. printf($call_file_handle "Channel: Local/^%s^%s^%s^%s\@vm-notify\n", $vm_box, $vm_context, $dial_dest, $dial_context); printf($call_file_handle "WaitTime: 30\n"); printf($call_file_handle "RetryTime: %i\n", 60 + rand(5)); printf($call_file_handle "MaxRetries: 12\n"); printf($call_file_handle "Context: vm-notify\n"); printf($call_file_handle "Extension: s\n"); printf($call_file_handle "Priority: 1\n"); printf($call_file_handle "Callerid: Voicemail Notify \<9852463509\>\n"); printf($call_file_handle "SetVar: VM_BOX=%s\n", $vm_box); printf($call_file_handle "SetVar: VM_CONTEXT=%s\n", $vm_context); # Unlock and close the file. flock($call_file_handle, LOCK_UN); close($call_file_handle); # Set the access and modification times to be 10 mins in the future so #Asterisk will delay for 10 mins before processing this .call file $short_time = time() + $call_delay; utime($short_time, $short_time, "$call_file_name"); exit(0); } } else { next; } } } ========================================================================== In /etc/asterisk/extensions.conf you need to put this: ==========================================================================[vm-notify] exten => _^X.,1,Cut(VM_BOX=EXTEN,^,2) exten => _^X.,2,Cut(VM_CONTEXT=EXTEN,^,3) exten => _^X.,3,Cut(DIAL_DEST=EXTEN,^,4) exten => _^X.,4,Cut(DIAL_CONTEXT=EXTEN,^,5) exten => _^X.,5,HasNewVoiceMail(${VM_BOX}@${VM_CONTEXT}) exten => _^X.,6,Answer exten => _^X.,7,Hangup exten => _^X.,106,Dial(Zap/g2/${DIAL_DEST},20) exten => _^X.,107,Noop(DIALSTATUS=${DIALSTATUS}) exten => _^X.,108,GotoIf($[${DIALSTATUS} = CHANUNAVAIL]?111) exten => _^X.,109,GotoIf($[${DIALSTATUS} = CONGESTION]?111) exten => _^X.,110,Answer exten => _^X.,111,Hangup exten => s,1,Wait(1) exten => s,2,HasNewVoiceMail(${VM_BOX}@${VM_CONTEXT},VM_NUMBER) exten => s,3,Hangup exten => s,103,SetVar(LOOP=1) exten => s,104,ResponseTimeout(1) exten => s,105,Background(vm-youhave) exten => s,106,SayNumber(${VM_NUMBER}) exten => s,107,Background(vm-INBOX) exten => s,108,Background(vm-messages) exten => s,109,Background(vm-for) exten => s,110,Background(extension) exten => s,111,SayDigits(${VM_BOX}) exten => s,112,Background(vm-instructions) exten => 1,1,ResponseTimeout(0) exten => 1,2,VoicemailMain(${VM_BOX}@${VM_CONTEXT}) exten => #,1,Playback(goodbye) exten => #,2,Hangup exten => t,1,GotoIf($[${LOOP} > 3]?#,1) exten => t,2,SetVar(LOOP=$[${LOOP} + 1]) exten => t,3,Goto(s,104) ========================================================================== Why all the crap with CUT and ^ asd that weird pattern match? Well, as far as I can tell when, in a .call file, you use SetVar, it does NOT set those variables for "Channel: Local/" leg of the call, only the "Context: Extension: Priority:" part of the call. This script, run by externnotify, creates a .call file that "calls" a Local/ channel. That channel runs an extension that checks to see if the user has new voicemail. Maybe they checked their voicemail between the time the .call file was created (when the message was left) and the time the .call file actually runs. The script makes sure the .call file will run about 10 mins in the future. If the user has no new voicemail, the extension answers and then hangs up the call. This makes sure the .call system knows that the call was "answered". If there is still new voicemail, then the call happens, and the person is told how many messages they have, and have a chance to log into voicemail. I would like to be able to detect voicemail answering and not start playing prompts unless a human answers. --Eric -- Eric Wieling * BTEL Consulting * 504-210-3699 x2120
Is the pager filed in the vm config still for the outcall destination or where do you specify the number to call for the outcall? -----Original Message----- From: Eric Wieling aka ManxPower [mailto:eric@fnords.org] Sent: Sunday, July 10, 2005 5:11 PM To: Kevin; asterisk-users@lists.digium.com Subject: [Asterisk-Users] VM Outcall: Rube Goldberg Edition Resent to the list since I didn't think you would mind. Kevin wrote:> Eric, > > I have been using your vm outcall script for some time and it hasworked> well. Thanks for your efforts. > > I am trying to re-install and I can't seem to get a call filegenerated.> I have set up postfix and in the log it appears that it pipes the > message to the vmoutcall script. But that's as far as I get. > > I was hopeful that you could offer a suggestion on how to debug the > activity of the script so I can try to figure out why it isn'tworking. I don't provide support for any of the sample scripts, etc that I write. The original VM Outcall was very primitive. Now that Asterisk has the externnotify= option I have a much better, but still pretty primitive, script. In /etc/voicemail.conf, in [general] put: =========================================================================externnotify=/usr/local/bin/vm-notify.pl ========================================================================= Here is the vm-notify.pl script: =========================================================================#!/usr/bin/perl -w use Fcntl; use Fcntl ":flock"; $dial_context="local-access"; ($vm_box, $vm_context) = $ARGV[1] =~/(.*)\@(.*)/; $current_vm_context = ""; if(!sysopen($vm_conf_file_handle, "/etc/asterisk/voicemail.conf", O_RDONLY)) { printf("Cannot open /etc/asterisk/voicemail.conf!\n"); exit(1); } while($vm_conf_line = <$vm_conf_file_handle>) { chomp($vm_conf_line); if((substr($vm_conf_line,0,1) eq ";") || (length($vm_conf_line) =0)) { next; } ($tmp_vm_context) = $vm_conf_line =~ /\[(.*)\]/; if(defined($tmp_vm_context)) { if($current_vm_context ne "") { exit(0); } if($tmp_vm_context eq $vm_context) { $current_vm_context = $vm_context; next; } } else { if($current_vm_context eq $vm_context) { ($tmp_vm_box) = $vm_conf_line =~ /(\d+)/; if($tmp_vm_box eq $vm_box) { ($dial_dest) = $vm_conf_line =~ /.*notify=(\d+)/; if(!defined($dial_dest)) { exit(0); } close($vm_conf_file_handle); # If there's already a .call file for this mailbox then don't do anything. # If there isn't already a .call file then create it. #$call_file_name = "/tmp/" . $vm_box . ".call"; $call_file_name = "/var/spool/asterisk/outgoing/" . $vm_box . ".call"; if(!sysopen($call_file_handle, "$call_file_name", O_WRONLY|O_CREAT|O_EXCL)) { exit(0); } flock($call_file_handle, LOCK_EX); # Set the access and modification times to be 10 years in the future so # Asterisk will ignore this file while we are doing stuff with it. $long_time = time() + (10 * 365 * 24 * 60 * 60); utime($long_time, $long_time, "$call_file_name"); srand; $call_delay=300 + rand(120); # Build our .call file. printf($call_file_handle "Channel: Local/^%s^%s^%s^%s\@vm-notify\n", $vm_box, $vm_context, $dial_dest, $dial_context); printf($call_file_handle "WaitTime: 30\n"); printf($call_file_handle "RetryTime: %i\n", 60 + rand(5)); printf($call_file_handle "MaxRetries: 12\n"); printf($call_file_handle "Context: vm-notify\n"); printf($call_file_handle "Extension: s\n"); printf($call_file_handle "Priority: 1\n"); printf($call_file_handle "Callerid: Voicemail Notify \<9852463509\>\n"); printf($call_file_handle "SetVar: VM_BOX=%s\n", $vm_box); printf($call_file_handle "SetVar: VM_CONTEXT=%s\n", $vm_context); # Unlock and close the file. flock($call_file_handle, LOCK_UN); close($call_file_handle); # Set the access and modification times to be 10 mins in the future so #Asterisk will delay for 10 mins before processing this .call file $short_time = time() + $call_delay; utime($short_time, $short_time, "$call_file_name"); exit(0); } } else { next; } } } ========================================================================= In /etc/asterisk/extensions.conf you need to put this: =========================================================================[vm-notify] exten => _^X.,1,Cut(VM_BOX=EXTEN,^,2) exten => _^X.,2,Cut(VM_CONTEXT=EXTEN,^,3) exten => _^X.,3,Cut(DIAL_DEST=EXTEN,^,4) exten => _^X.,4,Cut(DIAL_CONTEXT=EXTEN,^,5) exten => _^X.,5,HasNewVoiceMail(${VM_BOX}@${VM_CONTEXT}) exten => _^X.,6,Answer exten => _^X.,7,Hangup exten => _^X.,106,Dial(Zap/g2/${DIAL_DEST},20) exten => _^X.,107,Noop(DIALSTATUS=${DIALSTATUS}) exten => _^X.,108,GotoIf($[${DIALSTATUS} = CHANUNAVAIL]?111) exten => _^X.,109,GotoIf($[${DIALSTATUS} = CONGESTION]?111) exten => _^X.,110,Answer exten => _^X.,111,Hangup exten => s,1,Wait(1) exten => s,2,HasNewVoiceMail(${VM_BOX}@${VM_CONTEXT},VM_NUMBER) exten => s,3,Hangup exten => s,103,SetVar(LOOP=1) exten => s,104,ResponseTimeout(1) exten => s,105,Background(vm-youhave) exten => s,106,SayNumber(${VM_NUMBER}) exten => s,107,Background(vm-INBOX) exten => s,108,Background(vm-messages) exten => s,109,Background(vm-for) exten => s,110,Background(extension) exten => s,111,SayDigits(${VM_BOX}) exten => s,112,Background(vm-instructions) exten => 1,1,ResponseTimeout(0) exten => 1,2,VoicemailMain(${VM_BOX}@${VM_CONTEXT}) exten => #,1,Playback(goodbye) exten => #,2,Hangup exten => t,1,GotoIf($[${LOOP} > 3]?#,1) exten => t,2,SetVar(LOOP=$[${LOOP} + 1]) exten => t,3,Goto(s,104) ========================================================================= Why all the crap with CUT and ^ asd that weird pattern match? Well, as far as I can tell when, in a .call file, you use SetVar, it does NOT set those variables for "Channel: Local/" leg of the call, only the "Context: Extension: Priority:" part of the call. This script, run by externnotify, creates a .call file that "calls" a Local/ channel. That channel runs an extension that checks to see if the user has new voicemail. Maybe they checked their voicemail between the time the .call file was created (when the message was left) and the time the .call file actually runs. The script makes sure the .call file will run about 10 mins in the future. If the user has no new voicemail, the extension answers and then hangs up the call. This makes sure the .call system knows that the call was "answered". If there is still new voicemail, then the call happens, and the person is told how many messages they have, and have a chance to log into voicemail. I would like to be able to detect voicemail answering and not start playing prompts unless a human answers. --Eric -- Eric Wieling * BTEL Consulting * 504-210-3699 x2120 _______________________________________________ Asterisk-Users mailing list Asterisk-Users@lists.digium.com http://lists.digium.com/mailman/listinfo/asterisk-users To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users