Add a missing file sip_profile_copy.php to the dev branch.

This commit is contained in:
Mark Crane
2012-06-04 14:58:40 +00:00
commit af103e9c41
1240 changed files with 164946 additions and 0 deletions
@@ -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>
+832
View File
@@ -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>
+10
View File
@@ -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.
+23
View File
@@ -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>
+15
View File
@@ -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>
+129
View File
@@ -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();
+127
View File
@@ -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
+156
View File
@@ -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", "");
+101
View File
@@ -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);
+70
View File
@@ -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
+99
View File
@@ -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
+100
View File
@@ -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);
+43
View File
@@ -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;
}
}
+138
View File
@@ -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
+229
View File
@@ -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();
+149
View File
@@ -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
+54
View File
@@ -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
+162
View File
@@ -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
+98
View File
@@ -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});
+91
View File
@@ -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
+203
View File
@@ -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

Some files were not shown because too many files have changed in this diff Show More