All pastes #728386 Raw Edit

LeifMadsen

public ini v1 · immutable
·published 2007-10-06 22:43 UTC
rendered paste body
; extensions.conf - the Asterisk dial plan;; Static extension configuration file, used by; the pbx_config module. This is where you configure all your ; inbound and outbound calls in Asterisk. ; ; This configuration file is reloaded ; - With the "dialplan reload" command in the CLI; - With the "reload" command (that reloads everything) in the CLI;; The "General" category is for certain variables.  ;[general];; If static is set to no, or omitted, then the pbx_config will rewrite; this file when extensions are modified.  Remember that all comments; made in the file will be lost when that happens. ;; XXX Not yet implemented XXX;static=yes;; if static=yes and writeprotect=no, you can save dialplan by; CLI command "dialplan save" too;writeprotect=no;; If autofallthrough is set, then if an extension runs out of; things to do, it will terminate the call with BUSY, CONGESTION; or HANGUP depending on Asterisk's best guess. This is the default.;; If autofallthrough is not set, then if an extension runs out of ; things to do, Asterisk will wait for a new extension to be dialed ; (this is the original behavior of Asterisk 1.0 and earlier).;;autofallthrough=no;; If clearglobalvars is set, global variables will be cleared ; and reparsed on an extensions reload, or Asterisk reload.;; If clearglobalvars is not set, then global variables will persist; through reloads, and even if deleted from the extensions.conf or; one of its included files, will remain set to the previous value.;; NOTE: A complication sets in, if you put your global variables into; the AEL file, instead of the extensions.conf file. With clearglobalvars; set, a "reload" will often leave the globals vars cleared, because it; is not unusual to have extensions.conf (which will have no globals); load after the extensions.ael file (where the global vars are stored).; So, with "reload" in this particular situation, first the AEL file will; clear and then set all the global vars, then, later, when the extensions.conf; file is loaded, the global vars are all cleared, and then not set, because; they are not stored in the extensions.conf file.;clearglobalvars=no;; If priorityjumping is set to 'yes', then applications that support; 'jumping' to a different priority based on the result of their operations; will do so (this is backwards compatible behavior with pre-1.2 releases; of Asterisk). Individual applications can also be requested to do this; by passing a 'j' option in their arguments.;;priorityjumping=yes;; User context is where entries from users.conf are registered.  The; default value is 'default';;userscontext=default;; You can include other config files, use the #include command; (without the ';'). Note that this is different from the "include" command; that includes contexts within other contexts. The #include command works; in all asterisk configuration files.;#include "filename.conf"; The "Globals" category contains global variables that can be referenced; in the dialplan with the GLOBAL dialplan function:; ${GLOBAL(VARIABLE)}; ${${GLOBAL(VARIABLE)}} or ${text${GLOBAL(VARIABLE)}} or any hybrid; Unix/Linux environmental variables can be reached with the ENV dialplan; function: ${ENV(VARIABLE)};[globals]VM_HOME=/var/spool/asterisk/voicemail		; root directory of the voicemail applicationRELOAD_VM_CONFIGURATION=0;FUNCTION_TEST=${SHELL(echo "foo_bar")}		; currently causes a segfault of Asterisk[phones]; Testing Area!; SAMPLE: Creation of new voicemail envelopeexten => 5,1,Answer()exten => 5,n,GoSub(setup_mailbox,s,1(default,100,INBOX))exten => 5,n,GoSub(get_msg_count,s,1())exten => 5,n,Set(MSG_COUNT=${GOSUB_RETVAL})exten => 5,n,GoSub(set_msg_number,s,1(${MSG_COUNT}))exten => 5,n,Set(MSGNUM=${GOSUB_RETVAL})exten => 5,n,System(touch ${PWD}/msg${MSGNUM}.txt); VoiceMail(mailbox[@context][&mailbox[@context]][...][|options])exten => 100,1,GoSub(voicemail,s,1())exten => 101,1,Voicemail()exten => 200,1,GoSub(voicemail,s,1(100))exten => 201,1,Voicemail(100)exten => 300,1,GoSub(voicemail,s,1(100,u))exten => 301,1,Voicemail(100,u)exten => 400,1,GoSub(voicemail,s,1(100,su))exten => 401,1,Voicemail(100,us); Invalid voicemailexten => 500,1,GoSub(voicemail,s,1(101,u))exten => 500,n,DumpChan()exten => 501,1,Voicemail(101,u)exten => 501,n,DumpChan(); VoiceMailMain([mailbox][@context][|options])exten => 1100,1,GoSub(voicemailmain,s,1())exten => 1101,1,VoicemailMain()exten => 1200,1,GoSub(voicemailmain,s,(100))exten => 1201,1,VoicemailMain(100)exten => 1,1,GoSub(read_voicemail_conf,s,1())exten => 2,1,Set(LINE_NUMBER=2)exten => 2,n,NoOp(${SHELL(sed -e '/\\\;/d' /etc/asterisk/voicemail.conf \| grep '.' \| tr "\\\n"\, "&" \| cut -d \\\& -f ${LINE_NUMBER})})exten => 2,n,NoOp(${COMMAND})exten => 3,1,Set(information=foo_bar)exten => 3,n,Set(RES=${SET(information2=foo_bar)})exten => 3,n,DumpChan()exten => 3,n,Answer()exten => 4,1,NoOp()exten => 4,n,Set(LINE_NUMBER=1)exten => 4,n,While($[${LEN(${SHELL(sed -e '/\\\;/d' /etc/asterisk/voicemail.conf \| grep '.' \| tr "\\\n" "~" \| cut -d \\\~ -f ${LINE_NUMBER})})} > 1])exten => 4,n,Verbose(1|${SHELL(sed -e '/\\\;/d' /etc/asterisk/voicemail.conf \| grep '.' \| tr "\\\n" "~" \| cut -d \\\~ -f ${LINE_NUMBER})})exten => 4,n,Set(LINE_NUMBER=$[${LINE_NUMBER} + 1])exten => 4,n,EndWhile()[voicemail]; Leif Madsen;--[Description]  VoiceMail(mailbox[@context][&mailbox[@context]][...][|options]): Thisapplication allows the calling party to leave a message for the specifiedlist of mailboxes. When multiple mailboxes are specified, the greeting willbe taken from the first mailbox specified. Dialplan execution will stop if thespecified mailbox does not exist.  The Voicemail application will exit if any of the following DTMF digits arereceived:    0 - Jump to the 'o' extension in the current dialplan context.    * - Jump to the 'a' extension in the current dialplan context.  This application will set the following channel variable upon completion:    VMSTATUS - This indicates the status of the execution of the VoiceMail               application. The possible values are:               SUCCESS | USEREXIT | FAILED  Options:    b    - Play the 'busy' greeting to the calling party.    g(#) - Use the specified amount of gain when recording the voicemail           message. The units are whole-number decibels (dB).    s    - Skip the playback of instructions for leaving a message to the           calling party.    u    - Play the 'unavailable' greeting.    j    - Jump to priority n+101 if the mailbox is not found or some other           error occurs.--;exten => s,1,NoOp(); Get the value of VM_RELOAD_CONFIGURATION so we can determine if it needs to be resetexten => s,n,Set(RESET_RELOAD_VM_CONFIGURATION=${GLOBAL(RELOAD_VM_CONFIGURATION)})exten => s,n,GoSubIf($[${RELOAD_VM_CONFIGURATION}]?read_voicemail_conf,s,1())	; Load the voicemail.conf file into the AstDB; Reset the Global variable VM_RELOAD_CONFIGURATION so we don't load it again next time a call comes inexten => s,n,Exec(${IF($[${RESET_RELOAD_VM_CONFIGURATION}]?Set(GLOBAL(RELOAD_VM_CONFIGURATION)=0):NoOp())}); Define some starter variablesexten => s,n,Set(MAX_TRIES=3) 									; default tries for when we ask the user for inputexten => s,n,Set(MAILBOX=${ARG1})								; set the mailbox numberexten => s,n,Set(VM_CTX=${IF($[${EXISTS(${CUT(MAILBOX,@,2)})}]?${CUT(MAILBOX,@,2)}:default)})	; set the voicemail contextexten => s,n,Set(OPTIONS=${ARG2})								; save the options requested for Voicemail(); Check if the voicemail exists in our configurationexten => s,n,GotoIf($[${DB_EXISTS(voicemail/conf/[${VM_CTX}]/${MAILBOX})}]?set_options)exten => s,n,Set(VMSTATUS=FAILED)	; invalid voicemail box, return with statusexten => s,n,Return(); Save status of optionsexten => s,n(set_options),NoOp()			; if we have a valid mailbox, we can continueexten => s,n,Set(b_option=${REGEX("b" ${OPTIONS})})exten => s,n,Set(g_option=${REGEX("g" ${OPTIONS})})exten => s,n,Set(s_option=${REGEX("s" ${OPTIONS})})exten => s,n,Set(u_option=${REGEX("u" ${OPTIONS})})exten => s,n,Set(j_option=${REGEX("j" ${OPTIONS})})exten => s,n,GoSubIf($[${ISNULL(${MAILBOX})}]?get_mailbox,1)	; if no mailbox passed to us, get it from the userexten => s,n,GoSub(setup_mailbox,s,1(${VM_CTX},${MAILBOX}))	; setup the mailbox present working directory (PWD); Check options so we can determine which greeting to playexten => s,n,GoSubIf($[${u_option} & !$[0${STAT(e,${PWD}/unavail.gsm)} = 0 & 0${STAT(e,${PWD}/unavail.wav)} = 0 & 0${STAT(e,${PWD}/unavail.WAV)} = 0]]?cust_greeting,1(unavail))exten => s,n,GotoIf($[${EXISTS(${RECORDED_FILE})}]?goodbye)		; if a file exists, we recorded something, and we're doneexten => s,n,GoSubIf($[${b_option} & !$[0${STAT(e,${PWD}/busy.gsm)} = 0 & 0${STAT(e,${PWD}/busy.wav)} = 0 & 0${STAT(e,${PWD}/busy.WAV)} = 0]]?cust_greeting,1(busy))exten => s,n,GotoIf($[${EXISTS(${RECORDED_FILE})}]?goodbye)		; we're done, file was recordedexten => s,n,GoSub(std_greeting,1(${IF($[${u_option}]?unavail:${IF($[${b_option}]?busy)})}))exten => s,n,GotoIf($[${EXISTS(${RECORDED_FILE})}]?goodbye)		; we're done, file was recordedexten => s,n,Verbose(1|File recording: ${IF($[${EXISTED(${RECORDED_FILE})}]?SUCCESSFUL:FAILED)})exten => s,n(goodbye),NoOp()exten => s,n,Set(VMSTATUS=SUCCESS)exten => s,n,Return()exten => get_mailbox,1,NoOp()exten => get_mailbox,n,Read(MAILBOX|vm-whichbox|||${MAX_TRIES})exten => get_mailbox,n,Return()exten => cust_greeting,1,NoOp()exten => cust_greeting,n,Set(GREETING=${ARG1})exten => cust_greeting,n,Playback(${PWD}/${GREETING})exten => cust_greeting,n,Exec(${IF($[${s_option} = 0]?Playback(vm-intro):NoOp())})exten => cust_greeting,n,GoSub(record_voicemail,s,1())exten => cust_greeting,n,Return()exten => std_greeting,1,NoOp()exten => std_greeting,n,Set(GREETING=${ARG1})exten => std_greeting,n,GotoIf($["${GREETING}" != "unavail" | "${GREETING}" != "busy"]?no_greeting)	; if no greeting requested, just play an intro fileexten => std_greeting,n,Background(vm-theperson)exten => std_greeting,n,Set(X=0)exten => std_greeting,n,While($[${X} < ${LEN(${MAILBOX})}])exten => std_greeting,n,Background(digits/${MAILBOX:${X}:1})exten => std_greeting,n,Set(X=$[${X} + 1])exten => std_greeting,n,EndWhile()exten => std_greeting,n,Background(vm-is${GREETING})exten => std_greeting,n,Exec(${IF($[${s_option} = 0]?Background(vm-intro):NoOp())})exten => std_greeting,n,Goto(record)	; don't play the intro file, just record; If we don't request a greeting type, then just play the introexten => std_greeting,n(no_greeting),Background(vm-intro)exten => std_greeting,n(record),GoSub(record_voicemail,s,1())exten => std_greeting,n,Return()[voicemailmain]; Drop in replacement for the dialplan application VoicemailMain(); Leif Madsen;--[Description]  VoiceMailMain([mailbox][@context][|options]): This application allows thecalling party to check voicemail messages. A specific mailbox, and optionalcorresponding context, may be specified. If a mailbox is not provided, thecalling party will be prompted to enter one. If a context is not specified,the 'default' context will be used.  Options:    p    - Consider the mailbox parameter as a prefix to the mailbox that           is entered by the caller.    g(#) - Use the specified amount of gain when recording a voicemail           message. The units are whole-number decibels (dB).    s    - Skip checking the passcode for the mailbox.    a(#) - Skip folder prompt and go directly to folder specified.           Defaults to INBOX--;exten => s,1,Answer()exten => s,n,GoSub(setup_mailbox,s,1(default,100,INBOX)exten => s,n,GoSub(get_msg_count,s,1())exten => s,n,Set(TOTAL_MSGS=${GOSUB_RETVAL})exten => s,n,GoSub(play_msg,s,1(0))exten => s,n,Playback(vm-goodbye)[read_voicemail_conf]; Purpose: To read the voicemail.conf file into AstDB; LIMITATION: The regex's in the SHELL() command will remove all lines that contain a comment (even if the start of the line is uncommented);             That means you'll have to make sure your comments are on separate lines from the options you want activated.;; Leif Madsen;exten => s,1,NoOp()exten => s,n,Set(LINE_NUMBER=1); While we have data, loop through the file, pulling it in one line at a timeexten => s,n,While($[${LEN(${SHELL(sed -e '/\\\;/d' /etc/asterisk/voicemail.conf \| grep '.' \| tr "\\\n" "~" \| cut -d \\\~ -f ${LINE_NUMBER})})} > 1]); Save the data to the VM_FILE_DATA channel variable (one line from voicemail.conf)exten => s,n,NoOp(${SET(VM_FILE_DATA=${SHELL(sed -e '/\\\;/d' /etc/asterisk/voicemail.conf \| grep '.' \| tr "\\\n" "~" \| cut -d \\\~ -f ${LINE_NUMBER})})}); If the line starts with an alphanumeric string (not a square brace), then goto the write_data label, otherwise, save the data to the SECTION_NAME channel varexten => s,n,Exec(${IF(${REGEX("^[a-z A-Z 0-9]" ${VM_FILE_DATA})}?Goto(write_data):Set(SECTION_NAME=${VM_FILE_DATA}))})exten => s,n,Goto(next_iteration)		; if we hit here, then we're going to go to the next iteration of the loop						; because we've already set the SECTION_NAME variable, which will be used						; as part of the family keyname in AstDB; Write the database to the AstDBexten => s,n(write_data),NoOp(); NOTE: We're using the SET() function because the Set() application will take commas and pipes as argument separators;	In order to make it literally assign the whole string to the AstDB, we have to write it out with the SET() function;	which does not have multiple arguments;; Split the data we're getting into 2 separate variables (left and right of the equals sign)exten => s,n,NoOp(${SET(VARNAME=${CUT(VM_FILE_DATA,=,1)})})exten => s,n,NoOp(${SET(VARVALUE=${CUT(VM_FILE_DATA,=,2)})}); Save the value to the AstDB because once we parse it again, Asterisk likes to forget the values for some reason...exten => s,n,NoOp(${SET(DB(voicemail/conf/${SECTION_NAME}/${VARNAME})=${VARVALUE})}); If the start of the VARVALUE variable contains a >, then we want to strip it out in the next priority. Otherwise, go to the next loop iterationexten => s,n,Exec(${IF($[${EXISTS(${CUT(VARVALUE,>,2)})}]?NoOp():Goto(next_iteration))}); If we make it here, then we've gotta strip the > from the beginning of the line and assign the remainder to the AstDBexten => s,n,NoOp(${SET(DB(voicemail/conf/${SECTION_NAME}/${VARNAME})=${CUT(VARVALUE,>,2)})})exten => s,n(next_iteration),Set(LINE_NUMBER=$[${LINE_NUMBER} + 1])exten => s,n,EndWhile()exten => s,n,Return()[get_msg_count]; get_msg_count: Get the number of messages in the current folder; Leif Madsen; exten => s,1,Verbose(1|Getting number of messages in the mailbox)exten => s,n,Set(X=0000)exten => s,n,While($[${STAT(e,${PWD}/msg${X}.txt)}])exten => s,n,Verbose(1|Current message count: ${X})exten => s,n,Set(X=$[${X} + 1])exten => s,n,GoSub(set_msg_number,s,1(${X}))exten => s,n,Set(X=${GOSUB_RETVAL})exten => s,n,EndWhile()exten => s,n,Return(${X})[set_msg_number]; set_msg_number: Pad numbers with a LEN < 4 with zeros; Leif Madsen;exten => s,1,NoOp()exten => s,n,Set(MSGNUM=${IF($[${LEN(${ARG1})} = 1]?000:${IF($[${LEN(${ARG1})} = 2]?00:${IF($[${LEN(${ARG1})} = 3]?0)})})}${ARG1})exten => s,n,Return(${MSGNUM})[setup_mailbox]; setup_mailbox: Setup the path to a folder in a mailbox to work in; Leif Madsen;exten => s,1,NoOp()exten => s,n,Set(VM_CTX=${ARG1})exten => s,n,Set(MAILBOX=${ARG2})exten => s,n,Set(FOLDER=${ARG3})exten => s,n,Set(PWD=${VM_HOME}/${VM_CTX}/${MAILBOX}${IF($[${EXISTS(${ARG3})}]?/${FOLDER})})exten => s,n,Return()[get_envelope]; get_envelope: Get the contents of an envelope an assign the contents to variables; Leif Madsen;; Returns and Sets: ; ; - origmailbox; - context; - macrocontext; - exten; - priority; - callerchan; - callerid; - origdate; - origtime; - category; - duration6;exten => s,1,NoOp()exten => s,n,Set(LINE_NUMBER=5)exten => s,n,While($[${LEN(${SHELL(tr "\\\n"\, "&" < ${PWD}/msg${ARG1}.txt \| cut -d \\\& -f ${LINE_NUMBER})})} > 1])exten => s,n,Set(DATA=${SHELL(tr "\\\n"\, "&" < ${PWD}/msg${ARG1}.txt \| cut -d \\\& -f ${LINE_NUMBER})})exten => s,n,Set(${CUT(DATA,=,1)}=${CUT(DATA,=,2)})exten => s,n,Set(LINE_NUMBER=$[${LINE_NUMBER} + 1])exten => s,n,EndWhile()exten => s,n,Return()[record_voicemail]; record_voicemail: Record audio and save to disk (saved to INBOX); Leif Madsenexten => s,1,NoOp()exten => s,n,GoSub(setup_mailbox,s,1(${VM_CTX},${MAILBOX},INBOX))		; save new voicemails to the INBOXexten => s,n,GoSub(get_msg_count,s,1(${MAILBOX}))exten => s,n,Set(TOTAL_MSGS=${GOSUB_RETVAL})exten => s,n,GoSub(set_msg_number,s,1(${TOTAL_MSGS}))exten => s,n,Set(MSGNUM=${GOSUB_RETVAL});; LIMITATIONS: ;              * Can't record to multiple formats;              * Can't save the file if the user hangs up (have to press #);              * Need duration of recording;             exten => s,n,Record(${PWD}/msg${MSGNUM}.wav)exten => s,n,Set(RECORDED_FILE=${PWD}/msg${MSGNUM}.wav)exten => s,n,GoSub(create_envelope,s,1())exten => s,n,Playback(auth-thankyou)exten => s,n,Return()[create_envelope]; create_envelope: Create the message envelope in the filesystem; Leif Madsen;exten => s,1,NoOp()exten => s,n,GoSub(setup_mailbox,s,1(default,100,INBOX))exten => s,n,GoSub(get_msg_count,s,1())exten => s,n,Set(MSG_COUNT=${GOSUB_RETVAL})exten => s,n,GoSub(set_msg_number,s,1(${MSG_COUNT}))exten => s,n,Set(MSGNUM=${GOSUB_RETVAL})exten => s,n,System(touch ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "\;" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "\; Message Information file" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "\;" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "[message]" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "origmailbox=${MAILBOX}" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "context=INACCURATE" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "exten=INACCURATE" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "priority=INACCURATE" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "callerchan=INACCURATE" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "callerid=\\"${CALLERID(name)}\\" ${CALLERID(num)}" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "origdate=${STRFTIME(${EPOCH},,%d%m%Y-%H:%M:%S)}" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "origtime=${EPOCH}" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "category=" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,System(echo "duration=${ANSWEREDTIME}" >> ${PWD}/msg${MSGNUM}.txt)exten => s,n,Return()