Add a missing file sip_profile_copy.php to the dev branch.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<configuration name="cdr_csv.conf" description="CDR CSV Format">
|
||||
<settings>
|
||||
<!-- 'cdr-csv' will always be appended to log-base -->
|
||||
<!--<param name="log-base" value="/var/log"/>-->
|
||||
<param name="default-template" value="sql"/>
|
||||
<!-- This is like the info app but after the call is hung up -->
|
||||
<!--<param name="debug" value="true"/>-->
|
||||
<param name="rotate-on-hup" value="false"/>
|
||||
<!-- may be a b or ab -->
|
||||
<param name="legs" value="a"/>
|
||||
</settings>
|
||||
<templates>
|
||||
<template name="sql">INSERT INTO v_cdr (domain_uuid, caller_id_name, caller_id_number, destination_number, context, start_stamp, answer_stamp, end_stamp, duration, billsec, hangup_cause, uuid, bleg_uuid, accountcode, read_codec, write_codec, remote_media_ip, network_addr) VALUES ("{domain_uuid}", "${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}", "${read_codec}", "${write_codec}", "${remote_media_ip}", "${network_addr}");</template>
|
||||
<template name="example">"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}"</template>
|
||||
<template name="snom">"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}", "${accountcode}","${read_codec}","${write_codec}","${sip_user_agent}","${call_clientcode}","${sip_rtp_rxstat}","${sip_rtp_txstat}","${sofia_record_file}"</template>
|
||||
<template name="linksys">"${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}","${sip_user_agent}","${sip_p_rtp_stat}"</template>
|
||||
<template name="asterisk">"${accountcode}","${caller_id_number}","${destination_number}","${context}","${caller_id}","${channel_name}","${bridge_channel}","${last_app}","${last_arg}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${amaflags}","${uuid}","${userfield}"</template>
|
||||
</templates>
|
||||
</configuration>
|
||||
|
||||
@@ -0,0 +1,832 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
NOTICE:
|
||||
|
||||
This context is usually accessed via authenticated callers on the sip profile on port 5060
|
||||
or transfered callers from the public context which arrived via the sip profile on port 5080.
|
||||
|
||||
Authenticated users will use the user_context variable on the user to determine what context
|
||||
they can access. You can also add a user in the directory with the cidr= attribute acl.conf.xml
|
||||
will build the domains ACL using this value.
|
||||
-->
|
||||
<!-- http://wiki.freeswitch.org/wiki/Dialplan_XML -->
|
||||
<include>
|
||||
<context name="default">
|
||||
|
||||
<extension name="unloop">
|
||||
<condition field="${unroll_loops}" expression="^true$"/>
|
||||
<condition field="${sip_looped_call}" expression="^true$">
|
||||
<action application="deflect" data="${destination_number}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="call_direction" continue="true">
|
||||
<condition field="${call_direction}" expression="^(inbound|outbound|local)$">
|
||||
<anti-action application="set" data="call_direction=local"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- Example of doing things based on time of day.
|
||||
|
||||
year = 4 digit year. Example year="2009"
|
||||
yday = 1-365
|
||||
mon = 1-12
|
||||
mday = 1-31
|
||||
week = 1-52
|
||||
mweek= 1-6
|
||||
wday = 1-7
|
||||
hour = 0-23
|
||||
minute = 0-59
|
||||
minute-of-day = 1-1440
|
||||
|
||||
Example:
|
||||
<condition minute-of-day="540-1080"> (9am to 6pm EVERY day)
|
||||
do something ...
|
||||
</condition>
|
||||
-->
|
||||
<extension name="tod_example" continue="true">
|
||||
<condition wday="2-6" hour="9-18">
|
||||
<action application="set" data="open=true"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- Example of routing based on holidays
|
||||
|
||||
This example covers all US Federal holidays except for inauguration day.
|
||||
-->
|
||||
|
||||
<extension name="holiday_example" continue="true">
|
||||
<condition mday="1" mon="1">
|
||||
<!-- new year's day -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition wday="2" mweek="3" mon="1">
|
||||
<!-- martin luther king day is the 3rd monday in january -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition wday="2" mweek="3" mon="2">
|
||||
<!-- president's day is the 3rd monday in february -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition wday="2" mon="5" mday="25-31">
|
||||
<!-- memorial day is the last monday in may (the only monday between the 25th and the 31st) -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition mday="4" mon="7">
|
||||
<!-- independence day -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition wday="2" mweek="1" mon="9">
|
||||
<!-- labor day is the 1st monday in september -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition wday="2" mweek="2" mon="10">
|
||||
<!-- columbus day is the 2nd monday in october -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition mday="11" mon="11">
|
||||
<!-- veteran's day -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition wday="5-6" mweek="4" mon="11">
|
||||
<!-- thanksgiving is the 4th thursday in november and usually there's an extension for black friday -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition mday="25" mon="12">
|
||||
<!-- Christmas -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
<extension name="global-intercept">
|
||||
<condition field="destination_number" expression="^\*886$">
|
||||
<action application="answer"/>
|
||||
<action application="intercept" data="${hash(select/${domain_name}-last_dial/global)}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
<extension name="group-intercept">
|
||||
<condition field="destination_number" expression="^\*8$">
|
||||
<action application="answer"/>
|
||||
<action application="intercept" data="${hash(select/${domain_name}-last_dial/${call_group})}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="redial">
|
||||
<condition field="destination_number" expression="^(redial|\*870)$">
|
||||
<action application="transfer" data="${hash(select/${domain_name}-last_dial/${caller_id_number})}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="global" continue="true">
|
||||
<condition field="${call_debug}" expression="^true$" break="never">
|
||||
<action application="info"/>
|
||||
</condition>
|
||||
<!--
|
||||
This is an example of how to auto detect if telephone-event is missing and activate inband detection
|
||||
-->
|
||||
<!--
|
||||
<condition field="${switch_r_sdp}" expression="a=rtpmap:(\d+)\stelephone-event/8000" break="never">
|
||||
<action application="set" data="rtp_payload_number=$1"/>
|
||||
<anti-action application="start_dtmf"/>
|
||||
</condition>
|
||||
-->
|
||||
<condition field="${sip_has_crypto}" expression="^(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)$" break="never">
|
||||
<action application="set" data="sip_secure_media=true"/>
|
||||
<!-- Offer SRTP on outbound legs if we have it on inbound. -->
|
||||
<!-- <action application="export" data="sip_secure_media=true"/> -->
|
||||
</condition>
|
||||
|
||||
<condition>
|
||||
<action application="hash" data="insert/${domain_name}-spymap/${caller_id_number}/${uuid}"/>
|
||||
<action application="hash" data="insert/${domain_name}-last_dial/${caller_id_number}/${destination_number}"/>
|
||||
<action application="hash" data="insert/${domain_name}-last_dial/global/${uuid}"/>
|
||||
<action application="set" data="RFC2822_DATE=${strftime(%a, %d %b %Y %T %z)}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- If sip_req_host is not a local domain then this has to be an external sip uri -->
|
||||
<!--
|
||||
<extension name="external_sip_uri" continue="true">
|
||||
<condition field="source" expression="mod_sofia"/>
|
||||
<condition field="${outside_call}" expression="^$"/>
|
||||
<condition field="${domain_exists(${sip_req_host})}" expression="true">
|
||||
<anti-action application="bridge" data="sofia/${use_profile}/${sip_to_uri}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
<!--
|
||||
Snom button demo, call 9000 to make button 2 mapped to transfer the current call to a conference
|
||||
-->
|
||||
|
||||
<extension name="snom-demo-2">
|
||||
<condition field="destination_number" expression="^\*9001$">
|
||||
<action application="eval" data="${snom_bind_key(2 off DND ${sip_from_user} ${sip_from_host} ${sofia_profile_name} message notused)}"/>
|
||||
<action application="transfer" data="3000"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="snom-demo-1">
|
||||
<condition field="destination_number" expression="^\*9000$">
|
||||
<!--<key> <light> <label> <user> <host> <profile> <action_name> <action>-->
|
||||
<action application="eval" data="${snom_bind_key(2 on DND ${sip_from_user} ${sip_from_host} ${sofia_profile_name} message api+uuid_transfer ${uuid} 9001)}"/>
|
||||
<action application="playback" data="$${hold_music}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
<extension name="eavesdrop">
|
||||
<condition field="destination_number" expression="^\*88(\d{2,7})$|^\*0(.*)$">
|
||||
<action application="answer"/>
|
||||
<action application="eavesdrop" data="${hash(select/${domain_name}-spymap/$1)}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<extension name="eavesdrop">
|
||||
<condition field="destination_number" expression="^\*779$">
|
||||
<action application="answer"/>
|
||||
<action application="set" data="eavesdrop_indicate_failed=tone_stream://%(500, 0, 320)"/>
|
||||
<action application="set" data="eavesdrop_indicate_new=tone_stream://%(500, 0, 620)"/>
|
||||
<action application="set" data="eavesdrop_indicate_idle=tone_stream://%(250, 0, 920)"/>
|
||||
<action application="eavesdrop" data="all"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
<extension name="call_privacy">
|
||||
<condition field="destination_number" expression="^\*67(\d+)$">
|
||||
<action application="privacy" data="full"/>
|
||||
<action application="set" data="sip_h_Privacy=id"/>
|
||||
<action application="set" data="privacy=yes"/>
|
||||
<action application="transfer" data="$1 XML default"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="call_return">
|
||||
<condition field="destination_number" expression="^\*69$|^869$|^lcr$">
|
||||
<action application="transfer" data="${hash(select/${domain_name}-call_return/${caller_id_number})}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="del-group">
|
||||
<condition field="destination_number" expression="^\*\*80(\d{2})$">
|
||||
<action application="answer"/>
|
||||
<action application="group" data="delete:$1@${domain_name}:${sofia_contact(${sip_from_user}@${domain_name})}"/>
|
||||
<action application="gentones" data="%(1000, 0, 320)"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="add-group">
|
||||
<condition field="destination_number" expression="^\*\*81(\d{2})$">
|
||||
<action application="answer"/>
|
||||
<action application="group" data="insert:$1@${domain_name}:${sofia_contact(${sip_from_user}@${domain_name})}"/>
|
||||
<action application="gentones" data="%(1000, 0, 640)"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="call-group-simo">
|
||||
<condition field="destination_number" expression="^\*\*82(\d{2})$">
|
||||
<action application="bridge" data="{leg_timeout=15,ignore_early_media=true}${group(call:$1@${domain_name})}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="call-group-order">
|
||||
<condition field="destination_number" expression="^\*83(\d{2})$">
|
||||
<action application="bridge" data="{leg_timeout=15,ignore_early_media=true}${group(call:$1@${domain_name}:order)}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="intercept-ext">
|
||||
<condition field="destination_number" expression="^\*\*(\d+)$">
|
||||
<action application="answer"/>
|
||||
<action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/$1)}"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
<extension name="extension-intercom">
|
||||
<condition field="destination_number" expression="^\*8(\d{2,7})$">
|
||||
<action application="set" data="dialed_extension=$1"/>
|
||||
<action application="export" data="sip_auto_answer=true"/>
|
||||
<action application="bridge" data="user/${dialed_extension}@${domain_name}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
<extension name="Local_Extension_Skinny">
|
||||
<condition field="destination_number" expression="^(11[01][0-9])$">
|
||||
<action application="bridge" data="skinny/internal/${destination_number}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="send_to_voicemail">
|
||||
<condition field="destination_number" expression="^\*99(\d{2,7})$">
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<action application="set" data="dialed_extension=$1"/>
|
||||
<action application="export" data="dialed_extension=$1"/>
|
||||
<action application="voicemail" data="default ${domain_name} ${dialed_extension}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<X-PRE-PROCESS cmd="include" data="default/*.xml"/>
|
||||
|
||||
<extension name="group_dial_sales">
|
||||
<condition field="destination_number" expression="^\*2000$">
|
||||
<action application="bridge" data="${group_call(sales@${domain_name})}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="group_dial_support">
|
||||
<condition field="destination_number" expression="^\*2001$">
|
||||
<action application="bridge" data="group/support@${domain_name}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="group_dial_billing">
|
||||
<condition field="destination_number" expression="^\*2002$">
|
||||
<action application="bridge" data="group/billing@${domain_name}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- voicemail operator extension -->
|
||||
<extension name="operator">
|
||||
<condition field="destination_number" expression="^operator$">
|
||||
<action application="set" data="transfer_ringback=$${hold_music}"/>
|
||||
<action application="transfer" data="1000 XML features"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- voicemail main extension, used when * is pressed from an external number -->
|
||||
<extension name="vmain">
|
||||
<condition field="destination_number" expression="^vmain$">
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<action application="voicemail" data="check default ${domain_name} ${dialed_extension}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- voicemail main extension -->
|
||||
<extension name="vmain1">
|
||||
<condition field="destination_number" expression="^vmain1$|^\*97$|^\*4000$">
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<action application="voicemail" data="check default ${domain_name}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- voicemail main1 extension -->
|
||||
<extension name="vmain2">
|
||||
<condition field="destination_number" expression="^vmain2$|^\*98$">
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<action application="voicemail" data="check default ${domain_name} ${sip_from_user}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
This extension is used by mod_portaudio so you can pa call sip:someone@example.com
|
||||
mod_portaudio will pass the entire string to the dialplan for routing.
|
||||
-->
|
||||
<extension name="sip_uri">
|
||||
<condition field="destination_number" expression="^sip:(.*)$">
|
||||
<action application="bridge" data="sofia/${use_profile}/$1"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
start a dynamic conference with the settings of the "default" conference profile in conference.conf.xml
|
||||
-->
|
||||
<extension name="nb_conferences">
|
||||
<condition field="destination_number" expression="^\*(30\d{2})$">
|
||||
<action application="answer"/>
|
||||
<action application="conference" data="$1-${domain_name}@default"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="wb_conferences">
|
||||
<condition field="destination_number" expression="^\*(31\d{2})$">
|
||||
<action application="answer"/>
|
||||
<action application="conference" data="$1-${domain_name}@wideband"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="uwb_conferences">
|
||||
<condition field="destination_number" expression="^\*(32\d{2})$">
|
||||
<action application="answer"/>
|
||||
<action application="conference" data="$1-${domain_name}@ultrawideband"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- MONO 48kHz conferences -->
|
||||
<extension name="cdquality_conferences">
|
||||
<condition field="destination_number" expression="^\*(33\d{2})$">
|
||||
<action application="answer"/>
|
||||
<action application="conference" data="$1-${domain_name}@cdquality"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- dial the FreeSWITCH conference via SIP-->
|
||||
<extension name="freeswitch_public_conf_via_sip">
|
||||
<condition field="destination_number" expression="^\*9(888|8888|1616|3232)$">
|
||||
<action application="export" data="hold_music=silence"/>
|
||||
<!--
|
||||
This will take the SAS from the b-leg and send it to the display on the a-leg phone.
|
||||
Known working with Polycom and Snom maybe others.
|
||||
-->
|
||||
<!--
|
||||
<action application="set" data="exec_after_bridge_app=${sched_api(+4 zrtp expand uuid_display ${uuid} \${uuid_getvar(\${uuid_getvar(${uuid} signal_bond)} zrtp_sas1_string )} \${uuid_getvar(\${uuid_getvar(${uuid} signal_bond)} zrtp_sas2_string )} )}"/>
|
||||
<action application="export" data="nolocal:zrtp_secure_media=true"/>
|
||||
-->
|
||||
<action application="bridge" data="sofia/${use_profile}/$1@conference.freeswitch.org"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
This extension will start a conference and invite a group.
|
||||
At anytime the participant can dial *2 to bridge directly to the boss.
|
||||
All other callers are then hung up on.
|
||||
-->
|
||||
<!--
|
||||
<extension name="mad_boss_intercom">
|
||||
<condition field="destination_number" expression="^\*0911$">
|
||||
<action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss1"/>
|
||||
<action application="set" data="conference_auto_outcall_caller_id_number=0911"/>
|
||||
<action application="set" data="conference_auto_outcall_timeout=60"/>
|
||||
<action application="set" data="conference_auto_outcall_flags=mute"/>
|
||||
<action application="set" data="conference_auto_outcall_prefix={sip_auto_answer=true,execute_on_answer='bind_meta_app 2 a s1 transfer::intercept:${uuid} inline'}"/>
|
||||
<action application="set" data="sip_exclude_contact=${network_addr}"/>
|
||||
<action application="conference_set_auto_outcall" data="${group_call(sales)}"/>
|
||||
<action application="conference" data="madboss_intercom1@default+flags{endconf|deaf}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
<!--
|
||||
This extension will start a conference and invite a few of people.
|
||||
At anytime the participant can dial *2 to bridge directly to the boss.
|
||||
All other callers are then hung up on.
|
||||
-->
|
||||
<!--
|
||||
<extension name="mad_boss_intercom">
|
||||
<condition field="destination_number" expression="^\*0912$">
|
||||
<action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss2"/>
|
||||
<action application="set" data="conference_auto_outcall_caller_id_number=0912"/>
|
||||
<action application="set" data="conference_auto_outcall_timeout=60"/>
|
||||
<action application="set" data="conference_auto_outcall_flags=mute"/>
|
||||
<action application="set" data="conference_auto_outcall_prefix={sip_auto_answer=true,execute_on_answer='bind_meta_app 2 a s1 transfer::intercept:${uuid} inline'}"/>
|
||||
<action application="set" data="sip_exclude_contact=${network_addr}"/>
|
||||
<action application="conference_set_auto_outcall" data="loopback/*9664"/>
|
||||
<action application="conference" data="madboss_intercom2@default+flags{endconf|deaf}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
<!--This extension will start a conference and invite several people upon entering -->
|
||||
<!--These params effect the outcalls made once you join-->
|
||||
<!--<action application="set" data="conference_auto_outcall_announce=say:You have been called into an emergency conference"/>-->
|
||||
<!--Add as many of these as you need, These are the people you are going to call-->
|
||||
<!--
|
||||
<extension name="mad_boss">
|
||||
<condition field="destination_number" expression="^\*0913$">
|
||||
<action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss"/>
|
||||
<action application="set" data="conference_auto_outcall_caller_id_number=0911"/>
|
||||
<action application="set" data="conference_auto_outcall_timeout=60"/>
|
||||
<action application="set" data="conference_auto_outcall_flags=none"/>
|
||||
<action application="conference_set_auto_outcall" data="loopback/*9664"/>
|
||||
<action application="conference" data="madboss3@default"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
<!-- a sample IVR -->
|
||||
<extension name="ivr_demo">
|
||||
<condition field="destination_number" expression="^\*5000$">
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="2000"/>
|
||||
<action application="ivr" data="demo_ivr"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- Create a conference on the fly and pull someone in at the same time. -->
|
||||
<extension name="dynamic_conference">
|
||||
<condition field="destination_number" expression="^\*5001$">
|
||||
<action application="conference" data="bridge:mydynaconf:sofia/${use_profile}/1234@conference.freeswitch.org"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="rtp_multicast_page">
|
||||
<condition field="destination_number" expression="^pagegroup$|^\*7243$">
|
||||
<action application="answer"/>
|
||||
<action application="esf_page_group"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
Parking extensions... transferring calls to *5900 - *5999 will park them in a queue.
|
||||
-->
|
||||
<extension name="parking_slots">
|
||||
<condition field="destination_number" expression="^(\*59[0-9][0-9])$" break="on-false">
|
||||
<!-- Get count of callers in the specified parking slot (FIFO) -->
|
||||
<action inline="true" application="set" data="slot_count=${fifo(count $1@${domain_name})}"/>
|
||||
<action inline="true" application="set" data="slot_count=${slot_count:-3:2}"/>
|
||||
</condition>
|
||||
<condition field="${slot_count}" expression="^\:0$" break="always">
|
||||
<!-- FIFO settings for parking FIFOs -->
|
||||
<action application="unset" data="fifo_chime_list"/>
|
||||
<action application="set" data="fifo_chime_freq=0"/>
|
||||
<!-- FIFO is empty, so park the caller: -->
|
||||
<action application="fifo" data="${destination_number}@${domain_name} in undef local_stream://moh"/>
|
||||
<!-- FIFO has a caller, so un-park the caller: -->
|
||||
<anti-action application="fifo" data="${destination_number}@${domain_name} out nowait"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
Valet Park Drop off
|
||||
The valet parking will find the first stall between 6001 and 6099,
|
||||
park the call there, and then voice the stall number to the transferring user.
|
||||
The call can then be retrieved in the normal fashion by dialing the slot number:
|
||||
-->
|
||||
<extension name="valet_park_in">
|
||||
<condition field="destination_number" expression="^\*(6000)$">
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<action application="valet_park" data="valet_parking_lot auto in 6001 6099"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
Valet Park Pick Up
|
||||
Call the number that was announced when parking the call prefix it with a * to pickup the call.
|
||||
After the call is retrieved the valet parking slot is free for another call.
|
||||
-->
|
||||
<extension name="valet_park_out">
|
||||
<condition field="destination_number" expression="^\*(60\d\d)$">
|
||||
<action application="answer"/>
|
||||
<action application="valet_park" data="valet_parking_lot $1"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
This extension is used with Snom phones.
|
||||
|
||||
Set a function key to park+lot (lot being a number or name.)
|
||||
Set type to Park+Orbit. You can then park and pickup using
|
||||
the softkey on the phone. Should work with other phones.
|
||||
-->
|
||||
<extension name="park">
|
||||
<condition field="source" expression="mod_sofia"/>
|
||||
<condition field="destination_number" expression="park\+(\d+)">
|
||||
<action application="fifo" data="$1@${domain_name} in undef $${hold_music}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
<!--
|
||||
The extension is parking pickup with a to param of the fifo we are calling
|
||||
Some phones send things like orbit= and you can extract that info.
|
||||
-->
|
||||
<extension name="unpark">
|
||||
<condition field="source" expression="mod_sofia"/>
|
||||
<condition field="destination_number" expression="^parking$"/>
|
||||
<condition field="${sip_to_params}" expression="fifo\=(\d+)">
|
||||
<action application="answer"/>
|
||||
<action application="fifo" data="$1@${domain_name} out nowait"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
This extension is used with Linksys phones.
|
||||
|
||||
Set a Phone tab option Call Park Serv to yes. You can park and
|
||||
pickup using soft keys "park" and "unpark" found during
|
||||
active call when moving navigation button. The other option
|
||||
is to use phone's star codes (defaults to *38 and *39).
|
||||
-->
|
||||
<extension name="park">
|
||||
<condition field="source" expression="mod_sofia"/>
|
||||
<condition field="destination_number" expression="callpark"/>
|
||||
<condition field="${sip_refer_to}">
|
||||
<expression><![CDATA[<sip:callpark@${domain_name};orbit=(\d+)>]]></expression>
|
||||
<action application="fifo" data="$1@${domain_name} in undef $${hold_music}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
This extension is used with Linksys phones.
|
||||
|
||||
The extension is parking pickup with a to param of the fifo
|
||||
we are calling. Linksys sends orbit=<parkingslotnumber>
|
||||
and we extract that info.
|
||||
-->
|
||||
<extension name="unpark">
|
||||
<condition field="source" expression="mod_sofia"/>
|
||||
<condition field="destination_number" expression="pickup"/>
|
||||
<condition field="${sip_to_params}" expression="orbit\=(\d+)">
|
||||
<action application="answer"/>
|
||||
<action application="fifo" data="$1@${domain_name} out nowait"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
Here are some examples of how to override the ringback heard by the
|
||||
far end. You have two variables that you can use to override this.
|
||||
|
||||
ringback - used when a call isn't answered. (early media)
|
||||
transfer_ringback - used when the call is already answered. (post answer)
|
||||
-->
|
||||
|
||||
<!-- Demonstration of how to override the ringback in various situations -->
|
||||
<extension name="wait">
|
||||
<condition field="destination_number" expression="^wait$">
|
||||
<action application="pre_answer"/>
|
||||
<action application="sleep" data="20000"/>
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<action application="playback" data="voicemail/vm-goodbye.wav"/>
|
||||
<action application="hangup"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="fax_receive">
|
||||
<condition field="destination_number" expression="^\*9178$">
|
||||
<action application="answer" />
|
||||
<action application="playback" data="silence_stream://2000"/>
|
||||
<action application="rxfax" data="/tmp/rxfax.tif"/>
|
||||
<action application="hangup"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="fax_transmit">
|
||||
<condition field="destination_number" expression="^\*9179$">
|
||||
<action application="txfax" data="/tmp/txfax.tif"/>
|
||||
<action application="hangup"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- Send a 180 and let the far end generate ringback. -->
|
||||
<extension name="ringback_180">
|
||||
<condition field="destination_number" expression="^\*9180$">
|
||||
<action application="ring_ready"/>
|
||||
<action application="sleep" data="20000"/>
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<action application="playback" data="voicemail/vm-goodbye.wav"/>
|
||||
<action application="hangup"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- Send a 183 and send uk-ring as the ringtone. (early media) -->
|
||||
<extension name="ringback_183_uk_ring">
|
||||
<condition field="destination_number" expression="^\*9181$">
|
||||
<action application="set" data="ringback=$${uk-ring}"/>
|
||||
<action application="bridge" data="{ignore_early_media=true}loopback/wait"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- Send a 183 and use music as the ringtone. (early media) -->
|
||||
<extension name="ringback_183_music_ring">
|
||||
<condition field="destination_number" expression="^\*9182$">
|
||||
<action application="set" data="ringback=$${hold_music}"/>
|
||||
<action application="bridge" data="{ignore_early_media=true}loopback/wait"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- Answer the call and use music as the ringtone. (post answer) -->
|
||||
<extension name="ringback_post_answer_uk_ring">
|
||||
<condition field="destination_number" expression="^\*9183$">
|
||||
<action application="set" data="transfer_ringback=$${uk-ring}"/>
|
||||
<action application="answer"/>
|
||||
<action application="bridge" data="{ignore_early_media=true}loopback/wait"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- Answer the call and use music as the ringtone. (post answer) -->
|
||||
<extension name="ringback_post_answer_music">
|
||||
<condition field="destination_number" expression="^\*9184$">
|
||||
<action application="set" data="transfer_ringback=$${hold_music}"/>
|
||||
<action application="answer"/>
|
||||
<action application="bridge" data="{ignore_early_media=true}loopback/wait"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="ClueCon">
|
||||
<condition field="destination_number" expression="^\*9191$">
|
||||
<action application="set" data="effective_caller_id_name=ClueCon IVR"/>
|
||||
<action application="bridge" data="sofia/$${domain}/2000@bkw.org"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="show_info">
|
||||
<condition field="destination_number" expression="^\*9192$">
|
||||
<action application="answer"/>
|
||||
<action application="info"/>
|
||||
<action application="sleep" data="250"/>
|
||||
<action application="hangup"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="video_record">
|
||||
<condition field="destination_number" expression="^\*9193$">
|
||||
<action application="answer"/>
|
||||
<action application="record_fsv" data="/tmp/testrecord.fsv"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="video_playback">
|
||||
<condition field="destination_number" expression="^\*9194$">
|
||||
<action application="answer"/>
|
||||
<action application="play_fsv" data="/tmp/testrecord.fsv"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="delay_echo">
|
||||
<condition field="destination_number" expression="^\*9195$">
|
||||
<action application="answer"/>
|
||||
<action application="delay_echo" data="5000"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="echo">
|
||||
<condition field="destination_number" expression="^\*9196$">
|
||||
<action application="answer"/>
|
||||
<action application="echo"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="milliwatt">
|
||||
<condition field="destination_number" expression="^\*9197$">
|
||||
<action application="answer"/>
|
||||
<action application="playback" data="tone_stream://%(251,0,1004);loops=-1"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="tone_stream">
|
||||
<condition field="destination_number" expression="^\*9198$">
|
||||
<action application="answer"/>
|
||||
<action application="playback" data="tone_stream://path=${base_dir}/conf/tetris.ttml;loops=10"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!-- install zrtp_agent.lua into scripts (ZRTP == 9787) -->
|
||||
<extension name="zrtp_enrollement">
|
||||
<condition field="destination_number" expression="^\*9787$">
|
||||
<action application="answer"/>
|
||||
<action application="lua" data="zrtp_agent.lua"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
You will no longer hear the bong tone. The wav file is playing stating the call is secure.
|
||||
The file will not play unless you have both TLS and SRTP active.
|
||||
-->
|
||||
|
||||
<extension name="hold_music">
|
||||
<condition field="destination_number" expression="^\*9664$"/>
|
||||
<condition field="${sip_has_crypto}" expression="^(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)$">
|
||||
<action application="answer"/>
|
||||
<action application="execute_extension" data="is_secure XML features"/>
|
||||
<action application="playback" data="$${hold_music}"/>
|
||||
<anti-action application="set" data="zrtp_secure_media=true"/>
|
||||
<anti-action application="answer"/>
|
||||
<anti-action application="playback" data="silence_stream://2000"/>
|
||||
<anti-action application="execute_extension" data="is_zrtp_secure XML features"/>
|
||||
<anti-action application="playback" data="$${hold_music}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
dial the extension (1000-1019) for 30 seconds and go to voicemail if the
|
||||
call fails (continue_on_fail=true), otherwise hang up after a successful
|
||||
bridge (hangup_after-bridge=true)
|
||||
-->
|
||||
<extension name="Local_Extension">
|
||||
<condition field="destination_number" expression="(^\d{2,7}$)">
|
||||
<action application="set" data="dialed_extension=$1"/>
|
||||
<action application="export" data="dialed_extension=$1"/>
|
||||
<action application="limit" data="hash ${domain_name} $1 ${limit_max} ${limit_destination}"/>
|
||||
<!-- bind_meta_app can have these args <key> [a|b|ab] [a|b|o|s] <app> -->
|
||||
<action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>
|
||||
<action application="bind_meta_app" data="2 b s record_session::$${recordings_dir}/archive/${strftime(%Y)}/${strftime(%b)}/${strftime(%d)}/${uuid}.wav"/>
|
||||
<action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
|
||||
<action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/>
|
||||
<action application="set" data="ringback=${us-ring}"/>
|
||||
<action application="set" data="transfer_ringback=$${hold_music}"/>
|
||||
<action application="set" data="call_timeout=30"/>
|
||||
<!-- <action application="set" data="sip_exclude_contact=${network_addr}"/> -->
|
||||
<action application="set" data="hangup_after_bridge=true"/>
|
||||
<!--<action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,USER_BUSY,NO_ANSWER,TIMEOUT,NO_ROUTE_DESTINATION"/> -->
|
||||
<action application="set" data="continue_on_fail=true"/>
|
||||
<action application="hash" data="insert/${domain_name}-call_return/${dialed_extension}/${caller_id_number}"/>
|
||||
<action application="hash" data="insert/${domain_name}-last_dial_ext/${dialed_extension}/${uuid}"/>
|
||||
<action application="set" data="called_party_call_group=${user_data(${dialed_extension}@${domain_name} var call_group)}"/>
|
||||
<!--<action application="export" data="nolocal:sip_secure_media=${user_data(${dialed_extension}@${domain_name} var sip_secure_media)}"/>-->
|
||||
<action application="hash" data="insert/${domain_name}-last_dial/${called_party_call_group}/${uuid}"/>
|
||||
<!-- standard method -->
|
||||
<!--<action application="bridge" data="user/${dialed_extension}@${domain_name}"/> -->
|
||||
<!-- sofia contact -->
|
||||
<!--<action application="bridge" data="${sofia_contact(${dialed_extension}@${domain_name})}"/>-->
|
||||
<!-- number-alias / http://wiki.freeswitch.com/wiki/XML_User_Directory_Guide -->
|
||||
<action application="bridge" data="user/${user_data(${destination_number}@${domain_name} attr id)}@${domain_name}"/>
|
||||
<action application="answer"/>
|
||||
<action application="sleep" data="1000"/>
|
||||
<!--<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>-->
|
||||
<action application="voicemail" data="default ${domain_name} ${dialed_extension}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<!--
|
||||
You can place files in the default directory to get included.
|
||||
-->
|
||||
<!--<X-PRE-PROCESS cmd="include" data="default/*.xml"/>-->
|
||||
|
||||
|
||||
<!--
|
||||
<extension name="refer">
|
||||
<condition field="${sip_refer_to}">
|
||||
<expression><![CDATA[<sip:${destination_number}@${domain_name}>]]></expression>
|
||||
</condition>
|
||||
<condition field="${sip_refer_to}">
|
||||
<expression><![CDATA[<sip:(.*)@(.*)>]]></expression>
|
||||
<action application="set" data="refer_user=$1"/>
|
||||
<action application="set" data="refer_domain=$2"/>
|
||||
<action application="info"/>
|
||||
<action application="bridge" data="sofia/${use_profile}/${refer_user}@${refer_domain}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
<!--
|
||||
This is an example of how to override the RURI on an outgoing invite to a registered contact.
|
||||
-->
|
||||
<!--
|
||||
<extension name="ruri">
|
||||
<condition field="destination_number" expression="^ruri$">
|
||||
<action application="bridge" data="sofia/${ruri_profile}/${ruri_user}${regex(${sofia_contact(${ruri_contact})}|^[^\@]+(.*)|%1)}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="7004">
|
||||
<condition field="destination_number" expression="^7004$">
|
||||
<action application="set" data="ruri_profile=default"/>
|
||||
<action application="set" data="ruri_user=2000"/>
|
||||
<action application="set" data="ruri_contact=1001@${domain_name}"/>
|
||||
<action application="execute_extension" data="ruri"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="enum">
|
||||
<condition field="${module_exists(mod_enum)}" expression="true"/>
|
||||
<condition field="destination_number" expression="^(.*)$">
|
||||
<action application="transfer" data="$1 enum"/>
|
||||
</condition>
|
||||
</extension>
|
||||
-->
|
||||
|
||||
</context>
|
||||
</include>
|
||||
@@ -0,0 +1,10 @@
|
||||
Copyright (c) 2005, Fabricio Zuardi
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
<p>
|
||||
You can find more infos about slim.swf here:
|
||||
</p>
|
||||
<p>
|
||||
http://musicplayer.sourceforge.net/#documentation
|
||||
</p>
|
||||
<p>
|
||||
<br/>
|
||||
Please remember that you should record your MP3s at 11Khz for slim.swf to play correctly
|
||||
|
||||
A quick example follows:
|
||||
</p>
|
||||
|
||||
<object type="application/x-shockwave-flash" width="400" height="17"
|
||||
data="/slim.swf?song_url=/data.mp3&song_title=This%20is%20the%20title">
|
||||
<param name="movie" value="/slim.swf?song_url=/data.mp3&song_title=This%20is%20the%20title" />
|
||||
<param name="quality" value="high"/>
|
||||
<param name="bgcolor" value="#E6E6E6"/>
|
||||
</object>
|
||||
|
||||
<p>
|
||||
Remember that if this is not working for you, you should most probably point the song_url GET parameter to a real MP3 file that should be reachable through the web server.
|
||||
</p>
|
||||
@@ -0,0 +1,15 @@
|
||||
<include>
|
||||
<language name="en" say-module="en" sound-prefix="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
|
||||
<phrases>
|
||||
<macros>
|
||||
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
|
||||
<!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
|
||||
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
|
||||
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
|
||||
<X-PRE-PROCESS cmd="include" data="ivr/*.xml"/> <!-- IVR and custom phrases go here -->
|
||||
<X-PRE-PROCESS cmd="include" data="wakeup/*.xml"/> <!-- IVR and custom phrases go here -->
|
||||
<X-PRE-PROCESS cmd="include" data="vm/voicemail_ivr.xml"/>
|
||||
</macros>
|
||||
</phrases>
|
||||
</language>
|
||||
</include>
|
||||
@@ -0,0 +1,129 @@
|
||||
<include>
|
||||
<macro name="wakeup-greeting">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<!-- To schedule a wakeup call enter a 4 digit number -->
|
||||
<!-- For 6:30 am press 0630. Enter the digits now. -->
|
||||
<action function="execute" data="sleep(750)"/>
|
||||
<action function="play-file" data="custom/to.wav"/>
|
||||
<action function="play-file" data="custom/schedule.wav"/>
|
||||
<action function="play-file" data="custom/a.wav"/>
|
||||
<action function="play-file" data="custom/wakeup.wav"/>
|
||||
<action function="play-file" data="custom/call.wav"/>
|
||||
<action function="play-file" data="custom/enter.wav"/>
|
||||
<action function="play-file" data="custom/a.wav"/>
|
||||
<action function="play-file" data="custom/4.wav"/>
|
||||
<action function="play-file" data="custom/digit.wav"/>
|
||||
<action function="play-file" data="custom/number.wav"/>
|
||||
|
||||
<action function="execute" data="sleep(750)"/>
|
||||
<action function="play-file" data="custom/for.wav"/>
|
||||
<action function="play-file" data="digits/6.wav"/>
|
||||
<action function="play-file" data="digits/30.wav"/>
|
||||
<action function="play-file" data="custom/a.wav"/>
|
||||
<action function="play-file" data="custom/m.wav"/>
|
||||
|
||||
<action function="execute" data="sleep(750)"/>
|
||||
<action function="play-file" data="custom/press.wav"/>
|
||||
<action function="play-file" data="digits/0.wav"/>
|
||||
<action function="play-file" data="digits/6.wav"/>
|
||||
<action function="play-file" data="digits/3.wav"/>
|
||||
<action function="play-file" data="digits/0.wav"/>
|
||||
|
||||
<action function="execute" data="sleep(750)"/>
|
||||
<action function="play-file" data="custom/enter.wav"/>
|
||||
<action function="play-file" data="custom/the.wav"/>
|
||||
<action function="play-file" data="custom/digits.wav"/>
|
||||
<action function="play-file" data="custom/now.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
<macro name="wakeup-get-extension">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<!-- Tnter the extension number now -->
|
||||
<action function="execute" data="sleep(750)"/>
|
||||
<action function="play-file" data="custom/enter.wav"/>
|
||||
<action function="play-file" data="custom/the.wav"/>
|
||||
<action function="play-file" data="custom/extension.wav"/>
|
||||
<action function="play-file" data="custom/number.wav"/>
|
||||
<action function="play-file" data="custom/now.wav"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
<macro name="wakeup-scheduled">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<!-- Your wakeup call has been scheduled for 0715 -->
|
||||
<action function="execute" data="sleep(750)"/>
|
||||
<action function="play-file" data="custom/your.wav"/>
|
||||
<action function="play-file" data="custom/wakeup.wav"/>
|
||||
<action function="play-file" data="custom/call.wav"/>
|
||||
<action function="play-file" data="custom/has.wav"/>
|
||||
<action function="play-file" data="custom/been.wav"/>
|
||||
<action function="play-file" data="custom/scheduled.wav"/>
|
||||
<action function="play-file" data="custom/for.wav"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
<macro name="wakeup-accept">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<!-- To accept press 1 to cancel press 2 -->
|
||||
<action function="execute" data="sleep(750)"/>
|
||||
<action function="play-file" data="custom/to.wav"/>
|
||||
<action function="play-file" data="custom/accept.wav"/>
|
||||
<action function="play-file" data="custom/press.wav"/>
|
||||
<action function="play-file" data="digits/1.wav"/>
|
||||
<action function="play-file" data="custom/to.wav"/>
|
||||
<action function="play-file" data="custom/cancel.wav"/>
|
||||
<action function="play-file" data="custom/press.wav"/>
|
||||
<action function="play-file" data="digits/2.wav"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
<macro name="wakeup-cancel">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<!-- To cancel the wakeup call press * -->
|
||||
<action function="execute" data="sleep(750)"/>
|
||||
<action function="play-file" data="custom/to.wav"/>
|
||||
<action function="play-file" data="custom/cancel.wav"/>
|
||||
<action function="play-file" data="custom/the.wav"/>
|
||||
<action function="play-file" data="custom/wakeup.wav"/>
|
||||
<action function="play-file" data="custom/call.wav"/>
|
||||
<action function="play-file" data="custom/press.wav"/>
|
||||
<action function="play-file" data="digits/*.wav"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
<macro name="wakeup-call">
|
||||
<input pattern="(.*)">
|
||||
<match>
|
||||
<!-- This is your wakeup call to exit press 1 to snooze for 10 minutes press 2 -->
|
||||
<action function="execute" data="sleep(1000)"/>
|
||||
<action function="play-file" data="custom/this.wav"/>
|
||||
<action function="play-file" data="custom/is.wav"/>
|
||||
<action function="play-file" data="custom/your.wav"/>
|
||||
<action function="play-file" data="custom/wakeup.wav"/>
|
||||
<action function="play-file" data="custom/call.wav"/>
|
||||
<action function="play-file" data="custom/to.wav"/>
|
||||
<action function="play-file" data="custom/exit.wav"/>
|
||||
<action function="play-file" data="custom/press.wav"/>
|
||||
<action function="play-file" data="digits/1.wav"/>
|
||||
<action function="play-file" data="custom/to.wav"/>
|
||||
<action function="play-file" data="custom/snooze.wav"/>
|
||||
<action function="play-file" data="custom/for.wav"/>
|
||||
<action function="play-file" data="digits/10.wav"/>
|
||||
<action function="play-file" data="custom/minutes.wav"/>
|
||||
<action function="play-file" data="custom/press.wav"/>
|
||||
<action function="play-file" data="digits/2.wav"/>
|
||||
<action function="execute" data="sleep(100)"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
</include>
|
||||
@@ -0,0 +1,80 @@
|
||||
include("config.js");
|
||||
//var sounds_dir
|
||||
//var admin_pin
|
||||
//var tmp_dir
|
||||
//var recordings_dir
|
||||
|
||||
var sipuri = argv[0];
|
||||
var recording = argv[1];
|
||||
var caller_id_name = argv[2];
|
||||
var caller_id_number = argv[3];
|
||||
var call_timeout = argv[4];
|
||||
var call_count_var_name = argv[5];
|
||||
var tmp_sipuri;
|
||||
|
||||
caller_id_name = caller_id_name.replace("+", " ");
|
||||
console_log( "info", "sipuri: "+sipuri+"\n" );
|
||||
console_log( "info", "recording: "+recording+"\n" );
|
||||
console_log( "info", "caller_id_name: "+caller_id_name+"\n" );
|
||||
console_log( "info", "caller_id_number: "+caller_id_number+"\n" );
|
||||
console_log( "info", "call_timeout: "+call_timeout+"\n" );
|
||||
console_log( "info", "call_count_var_name: "+call_count_var_name+"\n" );
|
||||
|
||||
|
||||
|
||||
//function on_hangup(hup_session, how)
|
||||
//{
|
||||
// console_log("err", how + " HOOK" + " name: " + hup_session.name + " cause: " + hup_session.cause + "\n");
|
||||
// //exit here would end the script so you could cleanup and just be done
|
||||
// exit();
|
||||
//}
|
||||
|
||||
function originate (sipuri, recording, caller_id_name, caller_id_number, call_timeout, count_var_name) {
|
||||
|
||||
var dtmf = new Object();
|
||||
var cid;
|
||||
dtmf.digits = "";
|
||||
cid = ",origination_caller_id_name="+caller_id_name+",origination_caller_id_number="+caller_id_number;
|
||||
|
||||
new_session = new Session("{ignore_early_media=true,hangup_after_bridge=false,call_timeout="+call_timeout+""+cid+"}"+sipuri);
|
||||
//new_session = new Session(sipuri);
|
||||
|
||||
//new_session.execute("set", "api_after_bridge=reloadxml");
|
||||
//set the on_hangup function to be called when this session is hungup
|
||||
//new_session.setHangupHook(on_hangup);
|
||||
//result = new_session.setAutoHangup(true);
|
||||
|
||||
//console_log( "info", "followme: new_session uuid "+new_session.uuid+"\n" );
|
||||
//console_log( "info", "followme: no dtmf detected\n" );
|
||||
|
||||
digitmaxlength = 1;
|
||||
while (new_session.ready()) {
|
||||
if (recording.length > 0) {
|
||||
//new_session.streamFile( recordings_dir+"/"+recording);
|
||||
new_session.execute("playback",recordings_dir+"/"+recording);
|
||||
//new_session.hangup("NORMAL_CLEARING");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var hangup_cause = new_session.getVariable("bridge_hangup_cause");
|
||||
console_log( "info", "hangup cause: "+hangup_cause+"\n" );
|
||||
var count = getGlobalVariable(call_count_var_name);
|
||||
setGlobalVariable(call_count_var_name, (parseInt(count)-1));
|
||||
console_log( "info", "action: hangup, count: "+count+"\n" );
|
||||
|
||||
}
|
||||
|
||||
sipuri_array = sipuri.split(",");
|
||||
for (i = 0; i < sipuri_array.length; i++){
|
||||
//var count = getGlobalVariable(call_count_var_name);
|
||||
//setGlobalVariable(call_count_var_name, (parseInt(count)+1));
|
||||
|
||||
tmp_sipuri = sipuri_array[i];
|
||||
console_log("info", "tmp_sipuri: "+tmp_sipuri);
|
||||
result = originate (tmp_sipuri, recording, caller_id_name, caller_id_number, call_timeout, call_count_var_name);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit();
|
||||
@@ -0,0 +1,127 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
|
||||
function file_exists(fname)
|
||||
local f = io.open(fname, "r")
|
||||
if (f and f:read()) then return true end
|
||||
end
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
--session:execute("info", "");
|
||||
extension = session:getVariable("user_name");
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
dialplan_default_dir = session:getVariable("dialplan_default_dir");
|
||||
call_forward_number = session:getVariable("call_forward_number");
|
||||
extension_required = session:getVariable("extension_required");
|
||||
context = session:getVariable("context");
|
||||
if (not context ) then context = 'default'; end
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--if extension_requires is true then get the extension number
|
||||
if (extension_required) then
|
||||
if (extension_required == "true") then
|
||||
extension = session:playAndGetDigits(3, 6, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_extension_number.wav", "", "\\d+");
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (file_exists(dialplan_default_dir.."/000_call_forward_"..extension..".xml")) then
|
||||
--file exists
|
||||
|
||||
--remove the call forward dialplan entry
|
||||
os.remove (dialplan_default_dir.."/000_call_forward_"..extension..".xml");
|
||||
|
||||
--stream file
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/call_forward_has_been_deleted.wav");
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
session:sleep(1000);
|
||||
|
||||
else
|
||||
--file does not exist
|
||||
|
||||
dtmf = ""; --clear dtmf digits to prepare for next dtmf request
|
||||
if (call_forward_number) then
|
||||
-- do nothing
|
||||
else
|
||||
-- get the call forward number
|
||||
call_forward_number = session:playAndGetDigits(3, 15, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_phone_number.wav", "", "\\d+");
|
||||
end
|
||||
if (string.len(call_forward_number) > 0) then
|
||||
--write the xml file
|
||||
xml = "<extension name=\"call_forward_"..extension.."\" >\n";
|
||||
xml = xml .. " <condition field=\"destination_number\" expression=\"^"..extension.."$\">\n";
|
||||
xml = xml .. " <action application=\"transfer\" data=\""..call_forward_number.." XML "..context.."\"/>\n";
|
||||
xml = xml .. " </condition>\n";
|
||||
xml = xml .. "</extension>\n";
|
||||
session:execute("log", xml);
|
||||
local file = assert(io.open(dialplan_default_dir.."/000_call_forward_"..extension..".xml", "w"));
|
||||
file:write(xml);
|
||||
file:close();
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
--session:sleep(20000);
|
||||
|
||||
--stream file
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/call_forward_has_been_set.wav");
|
||||
end
|
||||
end
|
||||
|
||||
--reloadxml
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString("reloadxml");
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
session:sleep(1000);
|
||||
|
||||
session:hangup();
|
||||
|
||||
end
|
||||
@@ -0,0 +1,156 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
predefined_destination = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
caller_id_name = session:getVariable("caller_id_name");
|
||||
caller_id_number = session:getVariable("caller_id_number");
|
||||
predefined_destination = session:getVariable("predefined_destination");
|
||||
digit_min_length = session:getVariable("digit_min_length");
|
||||
digit_max_length = session:getVariable("digit_max_length");
|
||||
gateway = session:getVariable("gateway");
|
||||
context = session:getVariable("context");
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
|
||||
--set defaults
|
||||
if (digit_min_length) then
|
||||
--do nothing
|
||||
else
|
||||
digit_min_length = "2";
|
||||
end
|
||||
|
||||
if (digit_max_length) then
|
||||
--do nothing
|
||||
else
|
||||
digit_max_length = "11";
|
||||
end
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-please_enter_pin_followed_by_pound.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-pin_or_extension_is-invalid.wav");
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-im_sorry.wav");
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/voicemail/vm-goodbye.wav");
|
||||
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--if a predefined_destination is provided then set the number to the predefined_destination
|
||||
if (predefined_destination) then
|
||||
destination_number = predefined_destination;
|
||||
else
|
||||
dtmf = ""; --clear dtmf digits to prepare for next dtmf request
|
||||
destination_number = session:playAndGetDigits(digit_min_length, digit_max_length, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-enter_destination_telephone_number.wav", "", "\\d+");
|
||||
--if (string.len(destination_number) == 10) then destination_number = "1"..destination_number; end
|
||||
end
|
||||
|
||||
--set the caller id anme and number
|
||||
if (string.len(destination_number) < 7) then
|
||||
if (caller_id_name) then
|
||||
--caller id name provided do nothing
|
||||
else
|
||||
caller_id_number = session:getVariable("effective_caller_id_name");
|
||||
end
|
||||
if (caller_id_number) then
|
||||
--caller id number provided do nothing
|
||||
else
|
||||
caller_id_number = session:getVariable("effective_caller_id_number");
|
||||
end
|
||||
else
|
||||
if (caller_id_name) then
|
||||
--caller id name provided do nothing
|
||||
else
|
||||
caller_id_number = session:getVariable("outbound_caller_id_name");
|
||||
end
|
||||
if (caller_id_number) then
|
||||
--caller id number provided do nothing
|
||||
else
|
||||
caller_id_number = session:getVariable("outbound_caller_id_number");
|
||||
end
|
||||
end
|
||||
|
||||
--transfer or bridge the call
|
||||
if (string.len(destination_number) < 7) then
|
||||
--local call
|
||||
session:execute("transfer", destination_number .. " XML " .. context);
|
||||
else
|
||||
--remote call
|
||||
if (gateway) then
|
||||
gateway_table = explode(",",gateway);
|
||||
for index,value in pairs(gateway_table) do
|
||||
session:execute("bridge", "{continue_on_fail=true,hangup_after_bridge=true,origination_caller_id_name="..caller_id_name..",origination_caller_id_number="..caller_id_number.."}sofia/gateway/"..value.."/"..destination_number);
|
||||
end
|
||||
else
|
||||
session:execute("set", "effective_caller_id_name="..caller_id_name);
|
||||
session:execute("set", "effective_caller_id_number="..caller_id_number);
|
||||
session:execute("transfer", destination_number .. " XML " .. context);
|
||||
end
|
||||
end
|
||||
|
||||
--alternate method
|
||||
--local session2 = freeswitch.Session("{ignore_early_media=true}sofia/gateway/flowroute.com/"..destination_number);
|
||||
--t1 = os.date('*t');
|
||||
--call_start_time = os.time(t1);
|
||||
--freeswitch.bridge(session, session2);
|
||||
end
|
||||
|
||||
--function HangupHook(s, status, arg)
|
||||
--session:execute("info", "");
|
||||
--freeswitch.consoleLog("NOTICE", "HangupHook: " .. status .. "\n");
|
||||
--end
|
||||
--session:setHangupHook("HangupHook", "");
|
||||
@@ -0,0 +1,101 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
extension = argv[1];
|
||||
|
||||
--database
|
||||
--connect to the database
|
||||
--local dbh = freeswitch.Dbh("dsn","user","pass"); -- when using ODBC
|
||||
local dbh = freeswitch.Dbh("core:core"); -- when using sqlite
|
||||
|
||||
--exits the script if we didn't connect properly
|
||||
assert(dbh:connected());
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
|
||||
--set defaults
|
||||
if (digit_min_length) then
|
||||
--do nothing
|
||||
else
|
||||
digit_min_length = "2";
|
||||
end
|
||||
|
||||
if (digit_max_length) then
|
||||
--do nothing
|
||||
else
|
||||
digit_max_length = "11";
|
||||
end
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--check the database to get the uuid
|
||||
--eavesdrop
|
||||
sql = "select uuid from channels where presence_id = '"..extension.."@"..domain_name.."' ";
|
||||
dbh:query(sql, function(result)
|
||||
for key, val in pairs(result) do
|
||||
freeswitch.consoleLog("NOTICE", "result "..key.." "..val.."\n");
|
||||
end
|
||||
uuid = result.uuid;
|
||||
end);
|
||||
|
||||
end
|
||||
|
||||
--eavesdrop
|
||||
if (uuid) then
|
||||
session:execute("eavesdrop", uuid); --call barge
|
||||
end
|
||||
|
||||
--notes
|
||||
--originate a call
|
||||
--cmd = "originate user/1007@voip.example.com &eavesdrop("..uuid..")";
|
||||
--cmd = "uuid_bridge "..caller_uuid.." "..uuid;
|
||||
--api = freeswitch.API();
|
||||
--result = api:executeString(cmd);
|
||||
@@ -0,0 +1,70 @@
|
||||
--set default variables
|
||||
fax_retry_sleep = 10;
|
||||
fax_retry_limit = 3;
|
||||
|
||||
-- show all channel variables
|
||||
--dat = env:serialize()
|
||||
--freeswitch.consoleLog("INFO","info:\n" .. dat .. "\n")
|
||||
|
||||
-- example channel variables relating to fax
|
||||
--variable_fax_success: 0
|
||||
--variable_fax_result_code: 49
|
||||
--variable_fax_result_text: The%20call%20dropped%20prematurely
|
||||
--variable_fax_ecm_used: off
|
||||
--variable_fax_local_station_id: SpanDSP%20Fax%20Ident
|
||||
--variable_fax_document_transferred_pages: 0
|
||||
--variable_fax_document_total_pages: 0
|
||||
--variable_fax_image_resolution: 0x0
|
||||
--variable_fax_image_size: 0
|
||||
--variable_fax_bad_rows: 0
|
||||
--variable_fax_transfer_rate: 14400
|
||||
|
||||
-- set channel variables to lua variables
|
||||
uuid = env:getHeader("uuid");
|
||||
fax_success = env:getHeader("fax_success");
|
||||
fax_result_text = env:getHeader("fax_result_text");
|
||||
fax_ecm_used = env:getHeader("fax_ecm_used");
|
||||
fax_retry_attempts = tonumber(env:getHeader("fax_retry_attempts"));
|
||||
fax_retry_limit = tonumber(env:getHeader("fax_retry_limit"));
|
||||
fax_retry_sleep = tonumber(env:getHeader("fax_retry_sleep"));
|
||||
fax_uri = env:getHeader("fax_uri");
|
||||
fax_file = env:getHeader("fax_file");
|
||||
fax_extension_number = env:getHeader("fax_extension_number");
|
||||
origination_caller_id_name = env:getHeader("origination_caller_id_name");
|
||||
origination_caller_id_number = env:getHeader("origination_caller_id_number");
|
||||
|
||||
--set default values
|
||||
if (not origination_caller_id_name) then
|
||||
origination_caller_id_name = '000000000000000';
|
||||
end
|
||||
if (not origination_caller_id_number) then
|
||||
origination_caller_id_number = '000000000000000';
|
||||
end
|
||||
|
||||
-- send the selected variables to the console
|
||||
freeswitch.consoleLog("INFO","fax_success: '" .. fax_success .. "'\n");
|
||||
freeswitch.consoleLog("INFO","fax_result_text: '" .. fax_result_text .. "'\n");
|
||||
freeswitch.consoleLog("INFO","fax_file: '" .. fax_file .. "'\n");
|
||||
freeswitch.consoleLog("INFO","uuid: '" .. uuid .. "'\n");
|
||||
freeswitch.consoleLog("INFO","fax_ecm_used: '" .. fax_ecm_used .. "'\n");
|
||||
freeswitch.consoleLog("INFO","fax_retry_attempts: " .. fax_retry_attempts.. "\n");
|
||||
freeswitch.consoleLog("INFO","fax_retry_limit: " .. fax_retry_limit.. "\n");
|
||||
freeswitch.consoleLog("INFO","fax_retry_sleep: " .. fax_retry_sleep.. "\n");
|
||||
freeswitch.consoleLog("INFO","fax_uri: '" .. fax_uri.. "'\n");
|
||||
freeswitch.consoleLog("INFO","origination_caller_id_name: " .. origination_caller_id_name .. "\n");
|
||||
freeswitch.consoleLog("INFO","origination_caller_id_number: " .. origination_caller_id_number .. "\n");
|
||||
|
||||
-- if the fax failed then try again
|
||||
if (fax_success == "0") then
|
||||
if (fax_retry_attempts < fax_retry_limit) then
|
||||
-- sleep
|
||||
freeswitch.msleep(fax_retry_sleep * 1000);
|
||||
--increment the retry attempts
|
||||
fax_retry_attempts = fax_retry_attempts + 1;
|
||||
cmd = "originate {origination_caller_id_name='"..origination_caller_id_name.. "',origination_caller_id_number="..origination_caller_id_number..",fax_uri="..fax_uri..",fax_retry_attempts="..fax_retry_attempts..",fax_retry_limit="..fax_retry_limit..",fax_retry_sleep="..fax_retry_sleep..",fax_verbose=true,fax_file='"..fax_file.."',fax_use_ecm=off,api_hangup_hook='lua fax_retry.lua'}"..fax_uri.." &txfax('"..fax_file.."')";
|
||||
--cmd = "sofia/internal/"..fax_number.."@"..domain_name.." &txfax('"..fax_file.."') XML default ";
|
||||
freeswitch.consoleLog("INFO","retry cmd: " .. cmd .. "\n");
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString(cmd);
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,99 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
sounds_dir = "";
|
||||
recordings_dir = "";
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
--session:execute("info", "");
|
||||
user_name = session:getVariable("user_name");
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
queue_name = session:getVariable("queue_name");
|
||||
fifo_simo = session:getVariable("fifo_simo");
|
||||
fifo_timeout = session:getVariable("fifo_timeout");
|
||||
fifo_lag = session:getVariable("fifo_lag");
|
||||
|
||||
--pin_number = "1234"; --for testing
|
||||
--queue_name = "5900@voip.fusionpbx.com";
|
||||
--fifo_simo = 1;
|
||||
--fifo_timeout = 10;
|
||||
--fifo_lag = 10;
|
||||
|
||||
if (pin_number) then
|
||||
digits = session:playAndGetDigits(3, 8, 3, digit_timeout, "#", sounds_dir.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
|
||||
--press 1 to login and 2 to logout
|
||||
menu_selection = session:playAndGetDigits(1, 1, max_tries, digit_timeout, "#", sounds_dir.."/custom/please_enter_the_phone_number.wav", "", "\\d+");
|
||||
freeswitch.consoleLog("NOTICE", "menu_selection: "..menu_selection.."\n");
|
||||
if (menu_selection == "1") then
|
||||
session:execute("set", "fifo_member_add_result=${fifo_member(add "..queue_name.." {fifo_member_wait=nowait}user/"..user_name.." "..fifo_simo.." "..fifo_timeout.." "..fifo_lag.."} )"); --simo timeout lag
|
||||
fifo_member_add_result = session:getVariable("fifo_member_add_result");
|
||||
freeswitch.consoleLog("NOTICE", "fifo_member_add_result: "..fifo_member_add_result.."\n");
|
||||
session:streamFile("ivr/ivr-you_are_now_logged_in.wav");
|
||||
end
|
||||
if (menu_selection == "2") then
|
||||
session:execute("set", "fifo_member_del_result=${fifo_member(del "..queue_name.." {fifo_member_wait=nowait}user/"..user_name.."} )");
|
||||
session:streamFile("ivr/ivr-you_are_now_logged_out.wav");
|
||||
end
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
-- session:sleep(1000);
|
||||
|
||||
session:hangup();
|
||||
|
||||
else
|
||||
session:streamFile(sounds_dir.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
end
|
||||
else
|
||||
|
||||
--pin number is not required
|
||||
|
||||
--press 1 to login and 2 to logout
|
||||
menu_selection = session:playAndGetDigits(1, 1, max_tries, digit_timeout, "#", sounds_dir.."/custom/please_enter_the_phone_number.wav", "", "\\d+");
|
||||
freeswitch.consoleLog("NOTICE", "menu_selection: "..menu_selection.."\n");
|
||||
if (menu_selection == "1") then
|
||||
session:execute("set", "fifo_member_add_result=${fifo_member(add "..queue_name.." {fifo_member_wait=nowait}user/"..user_name.." "..fifo_simo.." "..fifo_timeout.." "..fifo_lag.."} )"); --simo timeout lag
|
||||
fifo_member_add_result = session:getVariable("fifo_member_add_result");
|
||||
freeswitch.consoleLog("NOTICE", "fifo_member_add_result: "..fifo_member_add_result.."\n");
|
||||
session:streamFile("ivr/ivr-you_are_now_logged_in.wav");
|
||||
end
|
||||
if (menu_selection == "2") then
|
||||
session:execute("set", "fifo_member_del_result=${fifo_member(del "..queue_name.." {fifo_member_wait=nowait}user/"..user_name.."} )");
|
||||
session:streamFile("ivr/ivr-you_are_now_logged_out.wav");
|
||||
end
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
-- session:sleep(1000);
|
||||
|
||||
session:hangup();
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,108 @@
|
||||
--get the argv values
|
||||
domain_name = argv[1];
|
||||
uuid = argv[2];
|
||||
sipuri = argv[3];
|
||||
extension = argv[4];
|
||||
caller_id_name = argv[5];
|
||||
caller_id_number = argv[6];
|
||||
caller_announce = argv[7];
|
||||
|
||||
--variable preparation
|
||||
tmp_sipuri = '';
|
||||
caller_id_name = string.gsub(caller_id_name, "+", " ");
|
||||
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
function originate (domain_name, session, sipuri, extension, caller_announce, caller_id_name, caller_id_number)
|
||||
|
||||
cid = ",origination_caller_id_name="..caller_id_name..",origination_caller_id_number="..caller_id_number;
|
||||
local new_session = freeswitch.Session("{ignore_early_media=true"..cid.."}"..sipuri);
|
||||
new_session:execute("set", "call_timeout=60");
|
||||
new_session:execute("sleep", "1000");
|
||||
|
||||
--if the session is not ready wait longer
|
||||
if ( new_session:ready() ) then
|
||||
--do nothing
|
||||
else
|
||||
new_session:execute("sleep", "1000");
|
||||
end
|
||||
|
||||
if ( new_session:ready() ) then
|
||||
--get the session id
|
||||
uuid = new_session:getVariable("uuid");
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = new_session:getVariable("default_language");
|
||||
default_dialect = new_session:getVariable("default_dialect");
|
||||
default_voice = new_session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
|
||||
--caller announce
|
||||
if (caller_announce) then
|
||||
new_session:streamFile(caller_announce);
|
||||
end
|
||||
|
||||
--set the sounds directory
|
||||
sounds_dir = new_session:getVariable("sounds_dir");
|
||||
|
||||
--check the fifo status if it is empty hangup the call
|
||||
api = freeswitch.API();
|
||||
cmd = "fifo count "..extension.."@"..domain_name;
|
||||
result = api:executeString(cmd);
|
||||
--freeswitch.consoleLog("notice", "result " .. result .. "\n");
|
||||
result_table = explode(":",result);
|
||||
if (result_table[3] == "0") then
|
||||
--session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
new_session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
|
||||
--prompt user for action
|
||||
dtmf_digits = new_session:playAndGetDigits(1, 1, 2, 3000, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/8000/press_1_to_accept_2_to_reject_or_3_for_voicemail.wav", "", "\\d+");
|
||||
freeswitch.consoleLog("NOTICE", "followme: "..dtmf_digits.."\n");
|
||||
|
||||
if ( dtmf_digits == "1" ) then
|
||||
freeswitch.consoleLog("NOTICE", "followme: call accepted\n");
|
||||
freeswitch.consoleLog("NOTICE", extension.."@"..domain_name.." out nowait\n");
|
||||
new_session:execute("fifo", extension.."@"..domain_name.." out nowait");
|
||||
return true;
|
||||
end
|
||||
if ( dtmf_digits == "2" ) then
|
||||
freeswitch.consoleLog("NOTICE", "followme: call rejected\n");
|
||||
new_session:hangup();
|
||||
return false;
|
||||
end
|
||||
if ( dtmf_digits == "3" ) then
|
||||
freeswitch.consoleLog("NOTICE", "followme: call sent to voicemail\n");
|
||||
cmd = "uuid_transfer "..uuid.." *99"..extension;
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString(cmd);
|
||||
return true;
|
||||
end
|
||||
if ( dtmf_digits == "" ) then
|
||||
freeswitch.consoleLog("NOTICE", "followme: no dtmf detected\n");
|
||||
return false;
|
||||
end
|
||||
else
|
||||
freeswitch.consoleLog("err", "followme: session not ready\n");
|
||||
end
|
||||
end
|
||||
|
||||
sipuri_table = explode(",",sipuri);
|
||||
for index,tmp_sip_uri in pairs(sipuri_table) do
|
||||
freeswitch.consoleLog("NOTICE", "sip_uri: "..tmp_sip_uri.."\n");
|
||||
result = originate (domain_name, session, tmp_sip_uri, extension, caller_announce, caller_id_name, caller_id_number);
|
||||
if (result) then
|
||||
break;
|
||||
--exit;
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,100 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
extension = argv[1];
|
||||
|
||||
--database
|
||||
--connect to the database
|
||||
--local dbh = freeswitch.Dbh("dsn","user","pass"); -- when using ODBC
|
||||
local dbh = freeswitch.Dbh("core:core"); -- when using sqlite
|
||||
|
||||
--exits the script if we didn't connect properly
|
||||
assert(dbh:connected());
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
|
||||
--set defaults
|
||||
if (digit_min_length) then
|
||||
--do nothing
|
||||
else
|
||||
digit_min_length = "2";
|
||||
end
|
||||
|
||||
if (digit_max_length) then
|
||||
--do nothing
|
||||
else
|
||||
digit_max_length = "11";
|
||||
end
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--check the database to get the uuid
|
||||
--intercept
|
||||
sql = "select call_uuid as uuid from channels where presence_id = '"..extension.."@"..domain_name.."' and callstate = 'RINGING' ";
|
||||
dbh:query(sql, function(result)
|
||||
for key, val in pairs(result) do
|
||||
freeswitch.consoleLog("NOTICE", "result "..key.." "..val.."\n");
|
||||
end
|
||||
uuid = result.uuid;
|
||||
end);
|
||||
|
||||
end
|
||||
|
||||
--intercept a call that is ringing
|
||||
if (uuid) then
|
||||
session:execute("intercept", uuid);
|
||||
end
|
||||
|
||||
--notes
|
||||
--originate a call
|
||||
--cmd = "originate user/1007@voip.example.com &intercept("..uuid..")";
|
||||
--api = freeswitch.API();
|
||||
--result = api:executeString(cmd);
|
||||
@@ -0,0 +1,43 @@
|
||||
include("config.js");
|
||||
//var sounds_dir
|
||||
//var admin_pin
|
||||
//var tmp_dir
|
||||
|
||||
var sipuri = argv[0];
|
||||
var caller_id_name = argv[1];
|
||||
var caller_id_number = argv[2];
|
||||
var tmp_sipuri;
|
||||
|
||||
caller_id_name = caller_id_name.replace("+", " ");
|
||||
//console_log( "info", "caller_announce: "+caller_announce+"\n" );
|
||||
|
||||
function originate (sipuri, caller_id_name, caller_id_number) {
|
||||
|
||||
var dtmf = new Object();
|
||||
var cid;
|
||||
dtmf.digits = "";
|
||||
cid = ",origination_caller_id_name="+caller_id_name+",origination_caller_id_number="+caller_id_number;
|
||||
|
||||
new_session = new Session("{ignore_early_media=true"+cid+"}"+sipuri);
|
||||
new_session.execute("set", "call_timeout=30");
|
||||
|
||||
if ( new_session.ready() ) {
|
||||
new_session.streamFile( sounds_dir+"/custom/press_1_to_accept_2_to_reject_or_3_for_voicemail.wav");
|
||||
digitmaxlength = 1;
|
||||
while (new_session.ready()) {
|
||||
//console_log( "info", "originate succeeded\n" );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sipuri_array = sipuri.split(",");
|
||||
for (i = 0; i < sipuri_array.length; i++){
|
||||
tmp_sipuri = sipuri_array[i];
|
||||
console_log("info", "tmp_sipuri: "+tmp_sipuri);
|
||||
result = originate (tmp_sipuri, caller_id_name, caller_id_number);
|
||||
if (result) {
|
||||
break;
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
-- page.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- All rights reserved.
|
||||
--
|
||||
-- Redistribution and use in source and binary forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- 1. Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- 2. Redistributions in binary form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
--get the dialplan variables and set them as local variables
|
||||
destination_number = session:getVariable("destination_number");
|
||||
pin_number = session:getVariable("pin_number");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
extension_list = session:getVariable("extension_list");
|
||||
caller_id_name = session:getVariable("caller_id_name");
|
||||
caller_id_number = session:getVariable("caller_id_number");
|
||||
extension_table = explode(",",extension_list);
|
||||
sip_from_user = session:getVariable("sip_from_user");
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
|
||||
if (caller_id_name) then
|
||||
--caller id name provided do nothing
|
||||
else
|
||||
effective_caller_id_name = session:getVariable("effective_caller_id_name");
|
||||
caller_id_number = effective_caller_id_name;
|
||||
end
|
||||
|
||||
if (caller_id_number) then
|
||||
--caller id number provided do nothing
|
||||
else
|
||||
effective_caller_id_number = session:getVariable("effective_caller_id_number");
|
||||
caller_id_number = effective_caller_id_number;
|
||||
end
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
api = freeswitch.API();
|
||||
for index,value in pairs(extension_table) do
|
||||
if (string.find(value, "-") == nill) then
|
||||
value = value..'-'..value;
|
||||
end
|
||||
sub_table = explode("-",value);
|
||||
for extension=sub_table[1],sub_table[2] do
|
||||
--extension_exists = "username_exists id "..extension.."@"..domain_name;
|
||||
--reply = trim(api:executeString(extension_exists));
|
||||
--if (reply == "true") then
|
||||
extension_status = "show channels like "..extension.."@";
|
||||
reply = trim(api:executeString(extension_status));
|
||||
if (reply == "0 total.") then
|
||||
--freeswitch.consoleLog("NOTICE", "extension "..extension.." available\n");
|
||||
if (extension == tonumber(sip_from_user)) then
|
||||
--this extension is the caller that initated the page
|
||||
else
|
||||
--originate the call
|
||||
cmd_string = "bgapi originate {sip_auto_answer=true,hangup_after_bridge=false,origination_caller_id_name='"..caller_id_name.."',origination_caller_id_number="..caller_id_number.."}user/"..extension.."@"..domain_name.." conference:page-"..destination_number.."@page+flags{mute} inline";
|
||||
api:executeString(cmd_string);
|
||||
end
|
||||
--freeswitch.consoleLog("NOTICE", "cmd_string "..cmd_string.."\n");
|
||||
else
|
||||
--look inside the reply to check for the correct domain_name
|
||||
if string.find(reply, domain_name) then
|
||||
--found: extension number is busy
|
||||
else
|
||||
--not found
|
||||
if (extension == tonumber(sip_from_user)) then
|
||||
--this extension is the caller that initated the page
|
||||
else
|
||||
--originate the call
|
||||
cmd_string = "bgapi originate {sip_auto_answer=true,hangup_after_bridge=false,origination_caller_id_name='"..caller_id_name.."',origination_caller_id_number="..caller_id_number.."}user/"..extension.."@"..domain_name.." conference:page-"..destination_number.."@page+flags{mute} inline";
|
||||
api:executeString(cmd_string);
|
||||
end
|
||||
end
|
||||
end
|
||||
--end
|
||||
end
|
||||
end
|
||||
|
||||
--send main call to the conference room
|
||||
session:execute("conference", "page-"..destination_number.."@page+flags{endconf}");
|
||||
|
||||
end
|
||||
@@ -0,0 +1,229 @@
|
||||
--example usage
|
||||
--basic
|
||||
--condition destination_number 5900
|
||||
--action set park_extension=5901
|
||||
--advanced
|
||||
--condition destination_number ^59(\d{2})$
|
||||
--action set park_extension=$1
|
||||
--additional settings
|
||||
--action set park_range=5
|
||||
--action set park_direction=in (in/out/both)
|
||||
--action set park_announce=true (not implemented yet)
|
||||
--action set park_timeout_seconds=30 (not implemented yet)
|
||||
--action set park_timeout_extension=1001 (not implemented yet)
|
||||
--action set park_music=$${hold_music}
|
||||
--action lua park.lua
|
||||
|
||||
--connect to the database
|
||||
--ODBC - data source name
|
||||
--local dbh = freeswitch.Dbh("name","user","pass");
|
||||
--FreeSWITCH core db
|
||||
local dbh = freeswitch.Dbh("core:park");
|
||||
|
||||
--get the session variables
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
park_direction = session:getVariable("park_direction");
|
||||
uuid = session:getVariable("uuid");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
park_extension = session:getVariable("park_extension");
|
||||
park_range = session:getVariable("park_range");
|
||||
park_announce = session:getVariable("park_announce");
|
||||
park_timeout_type = session:getVariable("park_timeout_type");
|
||||
park_timeout_destination = session:getVariable("park_timeout_destination");
|
||||
park_timeout_seconds = session:getVariable("park_timeout_seconds");
|
||||
park_music = session:getVariable("park_music");
|
||||
|
||||
--add the explode function
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
--add the trim function
|
||||
function trim(s)
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
--if park_timeout_seconds is not defined set the timeout to 5 minutes
|
||||
if (not park_timeout_seconds) then
|
||||
park_timeout_seconds = 300;
|
||||
end
|
||||
|
||||
--if park_timeout_type is not defined set to transfer
|
||||
if (not park_timeout_type) then
|
||||
park_timeout_type = "transfer";
|
||||
end
|
||||
|
||||
--prepare the api
|
||||
api = freeswitch.API();
|
||||
|
||||
--answer the call
|
||||
session:answer();
|
||||
|
||||
--database
|
||||
--exits the script if we didn't connect properly
|
||||
assert(dbh:connected());
|
||||
|
||||
--create the table if it doesn't exist
|
||||
--pgsql
|
||||
dbh:test_reactive("SELECT * FROM park", "", "CREATE TABLE park (id SERIAL, lot TEXT, domain TEXT, uuid TEXT, CONSTRAINT park_pk PRIMARY KEY(id))");
|
||||
--sqlite
|
||||
dbh:test_reactive("SELECT * FROM park", "", "CREATE TABLE park (id INTEGER PRIMARY KEY, lot TEXT, domain TEXT, uuid TEXT)");
|
||||
--mysql
|
||||
dbh:test_reactive("SELECT * FROM park", "", "CREATE TABLE park (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, lot TEXT, domain TEXT, uuid TEXT)");
|
||||
|
||||
--if park_range is defined then loop through the range to find an available parking lot
|
||||
if (park_range) then
|
||||
park_extension_start = park_extension;
|
||||
park_extension_end = ((park_extension+park_range)-1);
|
||||
extension = park_extension_start;
|
||||
while true do
|
||||
--exit the loop at the end of the range
|
||||
if (tonumber(extension) > park_extension_end) then
|
||||
break;
|
||||
end
|
||||
--check the database for an available slot
|
||||
lot_status = "available";
|
||||
sql = "SELECT count(*) as count FROM park WHERE lot = '"..extension.."' and domain = '"..domain_name.."' ";
|
||||
dbh:query(sql, function(result)
|
||||
--for key, val in pairs(result) do
|
||||
-- freeswitch.consoleLog("NOTICE", "parking result "..key.." "..val.."\n");
|
||||
--end
|
||||
count = result.count;
|
||||
end);
|
||||
--if count is 0 then the parking lot is available end the loop
|
||||
if (count == "0") then
|
||||
lot_status = "available";
|
||||
park_extension = ""..extension;
|
||||
break;
|
||||
end
|
||||
--increment the value
|
||||
extension = extension + 1;
|
||||
end
|
||||
end
|
||||
|
||||
--check the database to see if the slot is available or unavailable
|
||||
lot_status = "available";
|
||||
sql = "SELECT id, lot, uuid FROM park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ";
|
||||
dbh:query(sql, function(row)
|
||||
lot_uuid = row.uuid;
|
||||
lot_status = "unavailable";
|
||||
end);
|
||||
|
||||
--if park direction is set to out then unpark by bridging it to the caller
|
||||
if (park_direction == "out") then
|
||||
if (lot_uuid) then
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..lot_uuid.." park_status unparked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: unparked "..park_extension.."\n");
|
||||
--unpark the call with bridge
|
||||
cmd = "uuid_bridge "..uuid.." "..lot_uuid;
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
else
|
||||
--check if the uuid_exists, if it does not exist then delete the uuid from the db and set presence to terminated
|
||||
if (lot_uuid) then
|
||||
cmd = "uuid_exists "..lot_uuid;
|
||||
result = trim(api:executeString(cmd));
|
||||
if (result == "false") then
|
||||
--set presence out
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", lot_uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--delete from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
--freeswitch.consoleLog("NOTICE", "Park - Affected rows: " .. dbh:affected_rows() .. "\n");
|
||||
|
||||
--set the status to available
|
||||
lot_status = "available";
|
||||
end
|
||||
end
|
||||
|
||||
--check if the parking lot is available, if it is then add it to the db, set presenence to confirmed and park the call
|
||||
if (lot_status == "available") then
|
||||
--park the call
|
||||
cmd = "uuid_park "..uuid;
|
||||
result = trim(api:executeString(cmd));
|
||||
if (park_music) then
|
||||
cmd = "uuid_broadcast "..uuid.." "..park_music.." aleg";
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status parked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: parked "..park_extension.."\n");
|
||||
|
||||
--add to the database
|
||||
dbh:query("INSERT INTO park (lot, domain, uuid) VALUES('"..park_extension.."', '"..domain_name.."', '"..uuid.."')");
|
||||
|
||||
--set presence in
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip"); --park
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("status", "Active (1 waiting)");
|
||||
event:addHeader("rpid", "unknown");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("event_count", "1");
|
||||
event:addHeader("unique-id", uuid);
|
||||
--event:addHeader("Presence-Call-Direction", "outbound")
|
||||
event:addHeader("answer-state", "confirmed");
|
||||
event:fire();
|
||||
|
||||
else
|
||||
--bridge the current call to the call that is parked
|
||||
--set the presence to terminated
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
--event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--delete the lot from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
--freeswitch.consoleLog("NOTICE", "Park 200- Affected rows: " .. dbh:affected_rows() .. "\n");
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..lot_uuid.." park_status unparked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: unparked "..park_extension.."\n");
|
||||
|
||||
--connect the calls
|
||||
cmd = "uuid_bridge "..uuid.." "..lot_uuid;
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
|
||||
--continue running when the session ends
|
||||
session:setAutoHangup(false);
|
||||
|
||||
--start the fifo monitor on its own so that it doesn't block the script execution
|
||||
api = freeswitch.API();
|
||||
cmd = "luarun park_monitor.lua "..uuid.." "..domain_name.." "..park_extension.." "..park_timeout_type.." "..park_timeout_seconds.." "..park_timeout_destination;
|
||||
result = api:executeString(cmd);
|
||||
end
|
||||
|
||||
--close the database connection
|
||||
dbh:release();
|
||||
@@ -0,0 +1,149 @@
|
||||
--park_monitor.lua
|
||||
--Date: 4 Oct. 2011
|
||||
--Description:
|
||||
--if the call has been answered
|
||||
--then send presence terminate, and delete from the database
|
||||
|
||||
--connect to the database
|
||||
--ODBC - data source name
|
||||
--local dbh = freeswitch.Dbh("name","user","pass");
|
||||
--FreeSWITCH core db
|
||||
local dbh = freeswitch.Dbh("core:park");
|
||||
|
||||
--get the argv values
|
||||
script_name = argv[0];
|
||||
uuid = argv[1];
|
||||
domain_name = argv[2];
|
||||
park_extension = argv[3];
|
||||
park_timeout_type = argv[4];
|
||||
park_timeout_seconds = argv[5];
|
||||
park_timeout_destination = argv[6];
|
||||
|
||||
--prepare the api
|
||||
api = freeswitch.API();
|
||||
|
||||
--add a trim function
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
--monitor the parking lot if the call has hungup send a terminated event, and delete from the db
|
||||
x = 0
|
||||
while true do
|
||||
--sleep a moment to prevent using unecessary resources
|
||||
freeswitch.msleep(1000);
|
||||
|
||||
if (api:executeString("uuid_exists "..uuid) == "false") then
|
||||
--set the presence to terminated
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status cancelled";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: cancelled\n");
|
||||
|
||||
--delete the lot from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
|
||||
|
||||
--end the loop
|
||||
break;
|
||||
else
|
||||
cmd = "uuid_getvar "..uuid.." park_status";
|
||||
result = trim(api:executeString(cmd));
|
||||
--freeswitch.consoleLog("notice", "" .. result .. "\n");
|
||||
if (result == "parked") then --_undef_
|
||||
--set presence in
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip"); --park
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("status", "Active (1 waiting)");
|
||||
event:addHeader("rpid", "unknown");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("event_count", "1");
|
||||
event:addHeader("unique-id", uuid);
|
||||
--event:addHeader("Presence-Call-Direction", "outbound")
|
||||
event:addHeader("answer-state", "confirmed");
|
||||
event:fire();
|
||||
else
|
||||
--set the presence to terminated
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--delete the lot from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
--freeswitch.consoleLog("NOTICE", "Affected rows: park ext "..park_extension.." " .. dbh:affected_rows() .. "\n");
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status unparked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: unparked "..park_extension.."\n");
|
||||
|
||||
--end the loop
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
--limit the monitor to watching 60 seconds
|
||||
x = x + 1;
|
||||
if (x > tonumber(park_timeout_seconds)) then
|
||||
--set the presence to terminated
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--delete the lot from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status timeout";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: timeout\n");
|
||||
|
||||
--end the loop
|
||||
break;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--if the timeout was reached transfer the call
|
||||
cmd = "uuid_getvar "..uuid.." park_status";
|
||||
park_status = trim(api:executeString(cmd));
|
||||
if (park_timeout_type == "transfer" and park_status == "timeout") then
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status unparked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: unparked\n");
|
||||
--transfer the call when it has timed out
|
||||
cmd = "uuid_transfer "..uuid.." "..park_timeout_destination;
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,162 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
sounds_dir = "";
|
||||
recordings_dir = "";
|
||||
file_name = "";
|
||||
recording_number = "";
|
||||
recording_slots = "";
|
||||
recording_prefix = "";
|
||||
|
||||
--dtmf call back function detects the "#" and ends the call
|
||||
function onInput(s, type, obj)
|
||||
if (type == "dtmf" and obj['digit'] == '#') then
|
||||
return "break";
|
||||
end
|
||||
end
|
||||
|
||||
--start the recording
|
||||
function begin_record(session, sounds_dir, recordings_dir)
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
recording_slots = session:getVariable("recording_slots");
|
||||
recording_prefix = session:getVariable("recording_prefix");
|
||||
recording_name = session:getVariable("recording_name");
|
||||
|
||||
--select the recording number
|
||||
if (recording_slots) then
|
||||
min_digits = 1;
|
||||
max_digits = 20;
|
||||
recording_number = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_recording_number.wav", "", "\\d+");
|
||||
recording_name = recording_prefix..recording_number..".wav";
|
||||
end
|
||||
|
||||
--set the default recording name if one was not provided
|
||||
if (recording_name) then
|
||||
--recording name is provided do nothing
|
||||
else
|
||||
--set a default recording_name
|
||||
recording_name = "temp_"..session:get_uuid()..".wav";
|
||||
end
|
||||
|
||||
--prompt for the recording
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/begin_recording.wav");
|
||||
session:execute("set", "playback_terminators=#");
|
||||
|
||||
--begin recording
|
||||
session:execute("record", recordings_dir.."/"..recording_name.." 180 200");
|
||||
|
||||
--preview the recording
|
||||
session:streamFile(recordings_dir.."/"..recording_name);
|
||||
|
||||
--approve the recording, to save the recording press 1 to re-record press 2
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "voicemail/vm-save_recording.wav", "", "\\d+");
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "voicemail/vm-press.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "digits/1.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "voicemail/vm-rerecord.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "voicemail/vm-press.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="1" max_digits="1" max_tries = "1"; digit_timeout = "5000";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "digits/2.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (digits == "1") then
|
||||
--recording saved, hangup
|
||||
session:streamFile("voicemail/vm-saved.wav");
|
||||
return;
|
||||
elseif (digits == "2") then
|
||||
--delete the old recording
|
||||
os.remove (recordings_dir.."/"..recording_name);
|
||||
--session:execute("system", "rm "..);
|
||||
--make a new recording
|
||||
begin_record(session, sounds_dir, recordings_dir);
|
||||
else
|
||||
--recording saved, hangup
|
||||
session:streamFile("voicemail/vm-saved.wav");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
|
||||
--get the dialplan variables and set them as local variables
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
recordings_dir = session:getVariable("recordings_dir");
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (not default_language) then default_language = 'en'; end
|
||||
if (not default_dialect) then default_dialect = 'us'; end
|
||||
if (not default_voice) then default_voice = 'callie'; end
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--start recording
|
||||
begin_record(session, sounds_dir, recordings_dir);
|
||||
|
||||
session:hangup();
|
||||
end
|
||||
@@ -0,0 +1,98 @@
|
||||
-- intercom.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- All rights reserved.
|
||||
--
|
||||
-- Redistribution and use in source and binary forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- 1. Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- 2. Redistributions in binary form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--include the lua script
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
include = assert(loadfile(scripts_dir .. "/resources/config.lua"));
|
||||
include();
|
||||
|
||||
--connect to the database
|
||||
--ODBC - data source name
|
||||
if (dsn_name) then
|
||||
dbh = freeswitch.Dbh(dsn_name,dsn_username,dsn_password);
|
||||
end
|
||||
--FreeSWITCH core db handler
|
||||
if (db_type == "sqlite") then
|
||||
dbh = freeswitch.Dbh("core:"..db_path.."/"..db_name);
|
||||
end
|
||||
|
||||
--get the variables
|
||||
domain_name = session:getVariable("domain_name");
|
||||
ring_group_uuid = session:getVariable("ring_group_uuid");
|
||||
|
||||
--get the extension list
|
||||
sql =
|
||||
[[ SELECT g.ring_group_extension_uuid, e.extension_uuid, e.extension,
|
||||
r.ring_group_strategy, r.ring_group_timeout_sec, r.ring_group_timeout_app, r.ring_group_timeout_data
|
||||
FROM v_ring_groups as r, v_ring_group_extensions as g, v_extensions as e
|
||||
where g.ring_group_uuid = r.ring_group_uuid
|
||||
and g.ring_group_uuid = ']]..ring_group_uuid..[['
|
||||
and e.extension_uuid = g.extension_uuid
|
||||
and r.ring_group_enabled = 'true'
|
||||
order by e.extension asc ]]
|
||||
--freeswitch.consoleLog("notice", "SQL:" .. sql .. "\n");
|
||||
app_data = "";
|
||||
|
||||
x = 0;
|
||||
dbh:query(sql, function(row)
|
||||
ring_group_timeout_sec = row.ring_group_timeout_sec;
|
||||
ring_group_timeout_app = row.ring_group_timeout_app;
|
||||
ring_group_timeout_data = row.ring_group_timeout_data;
|
||||
if (row.ring_group_strategy == "sequence") then
|
||||
delimiter = "|";
|
||||
end
|
||||
if (row.ring_group_strategy == "simultaneous") then
|
||||
delimiter = ",";
|
||||
end
|
||||
if (x == 0) then
|
||||
app_data = "[leg_timeout="..ring_group_timeout_sec.."]user/" .. row.extension .. "@" .. domain_name;
|
||||
else
|
||||
app_data = app_data .. delimiter .. "[leg_timeout="..ring_group_timeout_sec.."]user/" .. row.extension .. "@" .. domain_name;
|
||||
end
|
||||
x = x + 1;
|
||||
end);
|
||||
|
||||
--close the database connection
|
||||
dbh:release();
|
||||
|
||||
--app_data
|
||||
--freeswitch.consoleLog("notice", "Debug:\n" .. app_data .. "\n");
|
||||
|
||||
--session actions
|
||||
if (session:ready()) then
|
||||
session:answer();
|
||||
session:execute("set", "hangup_after_bridge=true");
|
||||
session:execute("set", "continue_on_fail=true");
|
||||
session:execute("bridge", app_data);
|
||||
session:execute(ring_group_timeout_app, ring_group_timeout_data);
|
||||
end
|
||||
|
||||
--actions
|
||||
--ACTIONS = {}
|
||||
--table.insert(ACTIONS, {"set", "hangup_after_bridge=true"});
|
||||
--table.insert(ACTIONS, {"set", "continue_on_fail=true"});
|
||||
--table.insert(ACTIONS, {"bridge", app_data});
|
||||
--table.insert(ACTIONS, {ring_group_timeout_app, ring_group_timeout_data});
|
||||
@@ -0,0 +1,91 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
predefined_destination = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
port = "8080";
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
host = session:getVariable("host");
|
||||
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
default_voice = session:getVariable("default_voice");
|
||||
if (default_language) then else default_language = 'en'; end
|
||||
if (default_dialect) then else default_dialect = 'us'; end
|
||||
if (default_voice) then else default_voice = 'callie'; end
|
||||
|
||||
digitmaxlength = 0;
|
||||
timeoutpin = 7500;
|
||||
timeouttransfer = 7500;
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
digits = "";
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if (session:ready()) then
|
||||
session:answer();
|
||||
min_digits = 1;
|
||||
max_digits = 1;
|
||||
digitmaxlength = 1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_phone_number.wav", "", "\\d+");
|
||||
|
||||
x = 0;
|
||||
while (session:ready() == true) do
|
||||
if (string.len(digits) == 0) then
|
||||
--getDigits(length, terminators, timeout, digit_timeout, abs_timeout)
|
||||
digits = session:getDigits(1, "#", 40000);
|
||||
end
|
||||
if (string.len(digits) > 0) then
|
||||
--press star to exit
|
||||
if (digits == "*") then
|
||||
break;
|
||||
end
|
||||
--send the command to php
|
||||
session:execute("system","/usr/local/bin/php /usr/local/www/fusionpbx/mod/roku/roku.php "..digits.." "..host.." "..port);
|
||||
end
|
||||
digits = "";
|
||||
if (x > 17500) then
|
||||
break;
|
||||
end
|
||||
end
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,203 @@
|
||||
--
|
||||
-- FusionPBX
|
||||
-- Version: MPL 1.1
|
||||
--
|
||||
-- The contents of this file are subject to the Mozilla Public License Version
|
||||
-- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
-- http://www.mozilla.org/MPL/
|
||||
--
|
||||
-- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
-- for the specific language governing rights and limitations under the
|
||||
-- License.
|
||||
--
|
||||
-- The Original Code is FusionPBX
|
||||
--
|
||||
-- The Initial Developer of the Original Code is
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- Copyright (C) 2010
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
--get the argv values
|
||||
script_name = argv[0];
|
||||
domain_name = argv[1];
|
||||
wakeup_number = argv[2];
|
||||
|
||||
--add the trim function
|
||||
function trim(s)
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
--add is_numeric
|
||||
function is_numeric(text)
|
||||
if type(text)~="string" and type(text)~="number" then return false end
|
||||
return tonumber(text) and true or false
|
||||
end
|
||||
|
||||
--set the default values for the variables
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
sounds_dir = "";
|
||||
extension_type = ""; --number,caller_id_number,prompt
|
||||
extension_number = "";
|
||||
|
||||
if (wakeup_number) then
|
||||
--begin the wakeup call
|
||||
if ( session:ready() ) then
|
||||
--prepare the api object
|
||||
api = freeswitch.API();
|
||||
|
||||
--set session settings
|
||||
session:answer();
|
||||
session:setAutoHangup(false);
|
||||
|
||||
--wakeup confirm press 1 to 3
|
||||
min_digits = 1;
|
||||
max_digits = 1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:wakeup-call", "", "\\d+");
|
||||
|
||||
--reschedule the call for snooze
|
||||
if (digits == "2") then
|
||||
freeswitch.consoleLog("NOTICE", "wakeup call: snooze selected - rescheduled the call\n");
|
||||
api = freeswitch.API();
|
||||
caller_id_name = "wakeup call";
|
||||
caller_id_number = wakeup_number;
|
||||
sched_api_time = "600";
|
||||
cmd_string = "sched_api +"..sched_api_time.." wakeup-call-"..wakeup_number.." originate {hangup_after_bridge=false,origination_caller_id_name='"..caller_id_name.."',origination_caller_id_number="..caller_id_number.."}user/"..wakeup_number.."@"..domain_name.." &lua('wakeup.lua "..domain_name.." "..wakeup_number.."') ";
|
||||
freeswitch.consoleLog("NOTICE", "wakeup: "..cmd_string.."\n");
|
||||
reply = api:executeString(cmd_string);
|
||||
end
|
||||
end
|
||||
else
|
||||
--prompt for the wakeup call information
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
session:setAutoHangup(false);
|
||||
|
||||
--get the dialplan variables and set them as local variables
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
extension_number = session:getVariable("extension_number");
|
||||
extension_type = session:getVariable("extension_type");
|
||||
time_zone_offset = session:getVariable("time_zone_offset");
|
||||
sip_number_alias = session:getVariable("sip_number_alias");
|
||||
sip_from_user = session:getVariable("sip_from_user");
|
||||
if (is_numeric(sip_number_alias)) then
|
||||
wakeup_number = sip_number_alias;
|
||||
else
|
||||
wakeup_number = sip_from_user;
|
||||
end
|
||||
|
||||
--get the extension number
|
||||
if (extension_type == "prompt") then
|
||||
min_digits = 1;
|
||||
max_digits = 11;
|
||||
wakeup_time = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:wakeup-get-extension", "", "\\d+");
|
||||
end
|
||||
|
||||
--get the wakeup time
|
||||
min_digits = 4;
|
||||
max_digits = 4;
|
||||
wakeup_time = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:wakeup-greeting", "", "\\d+");
|
||||
freeswitch.consoleLog("NOTICE", "wakeup time: "..wakeup_time.."\n");
|
||||
|
||||
--get the current time
|
||||
current_hours = tonumber(os.date("%H"));
|
||||
current_minutes = tonumber(os.date("%M"));
|
||||
current_seconds = tonumber(os.date("%S"));
|
||||
|
||||
--adjust the time zone offset
|
||||
if (time_zone_offset) then
|
||||
current_hours = time_zone_offset + current_hours;
|
||||
if (current_hours < 0) then
|
||||
current_hours = current_hours + 24;
|
||||
end
|
||||
if (current_hours > 23) then
|
||||
current_hours = current_hours - 24;
|
||||
end
|
||||
end
|
||||
|
||||
--show the current hours minutes and seconds to the log
|
||||
--freeswitch.consoleLog("NOTICE", "Hours: " .. current_hours .. "\n");
|
||||
--freeswitch.consoleLog("NOTICE", "Mins: " .. current_minutes .. "\n");
|
||||
--freeswitch.consoleLog("NOTICE", "Seconds: " .. current_seconds .. "\n");
|
||||
|
||||
--prepare the current time
|
||||
current_time = (current_hours * 100) + current_minutes;
|
||||
|
||||
--get the wakeup hours and minutes
|
||||
wakeup_hours = string.sub(wakeup_time, 1, 2);
|
||||
wakeup_minutes = string.sub(wakeup_time, 3);
|
||||
|
||||
--show the wakeup time, hours, and minutes to the log
|
||||
--freeswitch.consoleLog("NOTICE", "wakeup_time "..wakeup_time.."\n");
|
||||
--freeswitch.consoleLog("NOTICE", "wakeup_hours "..wakeup_hours.."\n");
|
||||
--freeswitch.consoleLog("NOTICE", "wakeup_minutes "..wakeup_minutes.."\n");
|
||||
|
||||
--convert the time, hours and minutes to numbers
|
||||
wakeup_time = tonumber(wakeup_time);
|
||||
wakeup_hours = tonumber(wakeup_hours);
|
||||
wakeup_minutes = tonumber(wakeup_minutes);
|
||||
if (current_time > wakeup_time) then
|
||||
--get the current_time_in_seconds
|
||||
current_time_in_seconds = (current_hours * 3600) + (current_minutes * 60);
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = ("..current_hours.." * 3600) + ("..current_minutes.." * 60)\n");
|
||||
--get the seconds until midnight
|
||||
seconds_until_midnight = (24 * 3600) - current_time_in_seconds;
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = (24 * 3600) - "..current_time_in_seconds.."\n");
|
||||
--get the wakeup_time_in_seconds
|
||||
wakeup_time_in_seconds = (wakeup_hours * 3600) + (wakeup_minutes * 60);
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = ("..wakeup_hours.." * 3600) + ("..wakeup_minutes.." * 60)\n");
|
||||
--add the seconds_until_midnight to the wakeup_time_in_seconds
|
||||
sched_api_time = wakeup_time_in_seconds + seconds_until_midnight;
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = "..wakeup_time_in_seconds.." + "..seconds_until_midnight.."\n");
|
||||
else
|
||||
--get the current_time_in_seconds
|
||||
current_time_in_seconds = (current_hours * 3600) + (current_minutes * 60);
|
||||
--freeswitch.consoleLog("NOTICE", "current_time_in_seconds = ("..current_hours.." * 3600) + ("..current_minutes.." * 60);\n");
|
||||
--get the wakeup_time_in_seconds
|
||||
wakeup_time_in_seconds = (wakeup_hours * 3600) + (wakeup_minutes * 60);
|
||||
--freeswitch.consoleLog("NOTICE", "wakeup_time_in_seconds = ("..wakeup_hours.." * 3600) + ("..wakeup_minutes.." * 60);\n");
|
||||
--subtract the current time from wakeup_time_in_seconds
|
||||
sched_api_time = wakeup_time_in_seconds - current_time_in_seconds;
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = "..wakeup_time_in_seconds.." - "..current_time_in_seconds.."\n");
|
||||
end
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time "..sched_api_time.."\n");
|
||||
|
||||
--wakeup call has been scheduled
|
||||
session:streamFile("phrase:wakeup-scheduled");
|
||||
session:say(wakeup_time, "en", "number", "ITERATED");
|
||||
|
||||
--wakeup confirm press 1 to 3
|
||||
min_digits = 1;
|
||||
max_digits = 1;
|
||||
wakeup_accept = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:wakeup-accept", "", "\\d+");
|
||||
--accept
|
||||
if (wakeup_accept == "1") then
|
||||
--send a message to the console
|
||||
freeswitch.consoleLog("NOTICE", "wakeup: accepted\n");
|
||||
--schedule the wakeup call
|
||||
caller_id_name = "wakeup call";
|
||||
caller_id_number = wakeup_number;
|
||||
cmd_string = "sched_api +"..sched_api_time.." wakeup-call-"..wakeup_number.." originate {hangup_after_bridge=false,origination_caller_id_name='"..caller_id_name.."',origination_caller_id_number="..caller_id_number.."}user/"..wakeup_number.."@"..domain_name.." &lua('wakeup.lua "..domain_name.." "..wakeup_number.."') ";
|
||||
freeswitch.consoleLog("NOTICE", "wakeup: "..cmd_string.."\n");
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString(cmd_string);
|
||||
--hangup
|
||||
session:hangup();
|
||||
end
|
||||
--cancel
|
||||
if (wakeup_accept == "2") then
|
||||
--send a message to the console
|
||||
freeswitch.consoleLog("NOTICE", "wakeup: cancelled\n");
|
||||
--hangup
|
||||
session:hangup();
|
||||
end
|
||||
end
|
||||
end
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user