Run a LUA script when voicemail received
This sounds like a FAQ, but my searches found nothing. I'd like to run a LUA script when a message is left on voicemail. My alternative is to write my own mailer-app script that would scan the message to see if it's from mod_voicemail, do what I want to do, or call exim otherwise, but this seems like something that could be done from the dialplan. Is there a way in the dialplan to run an action with parameters from the voicemail message left? The reason I'm asking this is that I want to use the new Flowroute SMS API to send a text message when a voicemail is received, with the caller-ID info from the message. -- Steve
Did you look in api_hangup_hook. You can call lua script with. Example set api_hangup_hook=lua sendmsg.lua *Jai Rangi* Cebod Technologies LLC dba DIDforSale/Cebod Telecom O 949-471-0102 | C 949-419-7634 <1-949-419-7634> | F 949-269-0449 / 949-232-1410 | jprangi@didforsale.com www.cebod.com | www.didforsale.com |3200 Bristol St Suite 615, Costa Mesa, CA 92626 | On Fri, May 20, 2016 at 5:59 PM, Steven Schoch < schoch+freeswitch.org@xwin32.com> wrote:
This sounds like a FAQ, but my searches found nothing. I'd like to run a LUA script when a message is left on voicemail.
My alternative is to write my own mailer-app script that would scan the message to see if it's from mod_voicemail, do what I want to do, or call exim otherwise, but this seems like something that could be done from the dialplan.
Is there a way in the dialplan to run an action with parameters from the voicemail message left?
The reason I'm asking this is that I want to use the new Flowroute SMS API to send a text message when a voicemail is received, with the caller-ID info from the message.
-- Steve
_________________________________________________________________________ Professional FreeSWITCH Consulting Services: consulting@freeswitch.org http://www.freeswitchsolutions.com
Official FreeSWITCH Sites http://www.freeswitch.org http://confluence.freeswitch.org http://www.cluecon.com
FreeSWITCH-users mailing list FreeSWITCH-users@lists.freeswitch.org http://lists.freeswitch.org/mailman/listinfo/freeswitch-users UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users http://www.freeswitch.org
That's promising. Now how can this script determine the length of the message left or if no message was left at all? -- Steve On Fri, May 20, 2016 at 6:04 PM, Jai Rangi <jprangi@didforsale.com> wrote:
Did you look in api_hangup_hook. You can call lua script with. Example set api_hangup_hook=lua sendmsg.lua
Think more elegant way is call lua script when user is not responded. This script play announcment and save voicemail message. At end of call this script save/send message. Sergey сб, 21 мая 2016 г. в 4:13, Steven Schoch <schoch+freeswitch.org@xwin32.com>:
That's promising. Now how can this script determine the length of the message left or if no message was left at all?
-- Steve
On Fri, May 20, 2016 at 6:04 PM, Jai Rangi <jprangi@didforsale.com> wrote:
Did you look in api_hangup_hook. You can call lua script with. Example set api_hangup_hook=lua sendmsg.lua
_________________________________________________________________________ Professional FreeSWITCH Consulting Services: consulting@freeswitch.org http://www.freeswitchsolutions.com
Official FreeSWITCH Sites http://www.freeswitch.org http://confluence.freeswitch.org http://www.cluecon.com
FreeSWITCH-users mailing list FreeSWITCH-users@lists.freeswitch.org http://lists.freeswitch.org/mailman/listinfo/freeswitch-users UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users http://www.freeswitch.org
The way I've done this in the past is to just use the mailer script. It was simple and strait forward and didn't require a running daemon to handle it. The alternate would be to use events maybe or to make sure vars were set in dial plan and post process like your describing, both have a set of gotchas and I wouldn't reccomend that path On Friday, May 20, 2016, Steven Schoch <schoch+freeswitch.org@xwin32.com> wrote:
This sounds like a FAQ, but my searches found nothing. I'd like to run a LUA script when a message is left on voicemail.
My alternative is to write my own mailer-app script that would scan the message to see if it's from mod_voicemail, do what I want to do, or call exim otherwise, but this seems like something that could be done from the dialplan.
Is there a way in the dialplan to run an action with parameters from the voicemail message left?
The reason I'm asking this is that I want to use the new Flowroute SMS API to send a text message when a voicemail is received, with the caller-ID info from the message.
-- Steve
https://wiki.freeswitch.org/wiki/Mod_lua#Event_Hooks On Sat, May 21, 2016 at 12:38 PM, Michael Jerris <mike@jerris.com> wrote:
The way I've done this in the past is to just use the mailer script. It was simple and strait forward and didn't require a running daemon to handle it. The alternate would be to use events maybe or to make sure vars were set in dial plan and post process like your describing, both have a set of gotchas and I wouldn't reccomend that path
On Friday, May 20, 2016, Steven Schoch <schoch+freeswitch.org@xwin32.com> wrote:
This sounds like a FAQ, but my searches found nothing. I'd like to run a LUA script when a message is left on voicemail.
My alternative is to write my own mailer-app script that would scan the message to see if it's from mod_voicemail, do what I want to do, or call exim otherwise, but this seems like something that could be done from the dialplan.
Is there a way in the dialplan to run an action with parameters from the voicemail message left?
The reason I'm asking this is that I want to use the new Flowroute SMS API to send a text message when a voicemail is received, with the caller-ID info from the message.
-- Steve
_________________________________________________________________________ Professional FreeSWITCH Consulting Services: consulting@freeswitch.org http://www.freeswitchsolutions.com
Official FreeSWITCH Sites http://www.freeswitch.org http://confluence.freeswitch.org http://www.cluecon.com
FreeSWITCH-users mailing list FreeSWITCH-users@lists.freeswitch.org http://lists.freeswitch.org/mailman/listinfo/freeswitch-users UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users http://www.freeswitch.org
Thanks! Another thing to point me in the right direction. Investigating the source, I found in the routine deliver_vm(), it makes these calls: switch_event_create_subclass(&message_event, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT); switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "VM-Action", "leave-message"); ... switch_event_fire(&message_event); This led me to the example autoload_configs/lua.conf.xml file, which has this line: <!--<hook event="CUSTOM" subclass="conference::maintenance" script="catch-event.lua"/>--> I should be able to write a script that gets called whenever something happens to a voicemail box with this line: <hook event="CUSTOM" subclass="vm::maintenance" script="voicemail-event.lua"/> Then, in my lua script, I should be able to call event:getHeader("VM-Action"), and exit unless it's "leave-message". There are other headers in the event that should have information such as the length of the recording. Just a little confused about the "event" variable. Is that a global variable that's already set when my script is called? -- Steve On Sun, May 22, 2016 at 9:34 AM, Abaci B <abaci64@gmail.com> wrote:
I got it working. Ignore the rest of this message unless you want to know how I solved it. My problem was that I was using "reloadxml" after I added the "hook" line, but after reading the mod_lua.cpp file, I found that while "reloadxml" loaded the whole XML include tree into the Freeswitch config structure, The mod_lua code used that config structure only on startup. The solution was to shut down freeswitch. (And thanks to the new systemd on Debian 8, it started back up by itself.) -------- It didn't work.I tried putting this line in autoload_configs/lua.conf.xml: <hook event="CUSTOM" subclass="vm::maintenance" script="voicemail-event.lua"/> I then created a "voicemail-event.lua" file with the following: action = event:getHeader("VM-Action") freeswitch.consoleLog("info", "VM Action: " .. action) However, the log file has nothing about this script: 91307edb-28d3-4d1d-bd80-95654a327c8b 2016-05-27 15:07:47.533629 [DEBUG] switch_core_state_machine.c:710 (sofia/external/+1408xxxxxxx@fl.gg) State DESTROY going to sleep 2016-05-27 15:07:47.533629 [DEBUG] mod_voicemail.c:1946 Update MWI: Messages Waiting yes 2016-05-27 15:07:47.533629 [DEBUG] mod_voicemail.c:1947 Update MWI: Update Reason NEW 2016-05-27 15:07:47.533629 [DEBUG] mod_voicemail.c:1948 Update MWI: Message Account 408xxxxxxx@starnet.com 2016-05-27 15:07:47.533629 [DEBUG] mod_voicemail.c:1949 Update MWI: Voice Message 1/0 2016-05-27 15:07:47.953635 [DEBUG] switch_utils.c:1180 Emailed file [/tmp/mail.14643868674630] to [voicemail@xxxx.com] 2016-05-27 15:07:47.953635 [DEBUG] mod_voicemail.c:3038 Sending message to voicemail@xxxx.com 2016-05-27 15:07:48.393632 [DEBUG] switch_utils.c:1182 Emailed data to [vm-page] 2016-05-27 15:07:48.393632 [DEBUG] mod_voicemail.c:3088 Sending notify message to vm-page The deliver_vm() function in src/mod/applications/mod_voicemail/mod_voicemail.c sends the event before the MWI update. It also sends the event at other times, including after voicemail authentication, but I don't see that it the log either. Investigating a little further, in src/mod/languages/mod_lua/mod_lua.cpp, there is a function that seems to process the autoload_configs/lua.conf.xml file. It has a loop that appears to process the "hook" elements that includes this line: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "hook params: '%s' | '%s' | '%s'\n", event, subclass, script); -- Steve On Mon, May 23, 2016 at 10:20 AM, Steven Schoch < schoch+freeswitch.org@xwin32.com> wrote:
Thanks! Another thing to point me in the right direction. Investigating the source, I found in the routine deliver_vm(), it makes these calls: switch_event_create_subclass(&message_event, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT); switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "VM-Action", "leave-message"); ... switch_event_fire(&message_event); This led me to the example autoload_configs/lua.conf.xml file, which has this line:
<!--<hook event="CUSTOM" subclass="conference::maintenance" script="catch-event.lua"/>-->
I should be able to write a script that gets called whenever something happens to a voicemail box with this line: <hook event="CUSTOM" subclass="vm::maintenance" script="voicemail-event.lua"/>
Then, in my lua script, I should be able to call event:getHeader("VM-Action"), and exit unless it's "leave-message". There are other headers in the event that should have information such as the length of the recording.
Just a little confused about the "event" variable. Is that a global variable that's already set when my script is called?
-- Steve
On Sun, May 22, 2016 at 9:34 AM, Abaci B <abaci64@gmail.com> wrote:
I'm back to working on the voicemail notification. The lua script is being called, and I can get important variables with these calls: action = event:getHeader("VM-Action") if action ~= "leave-message" then return end user = event:getHeader("VM-User") caller_id_name = event:getHeader("VM-Caller-ID-Name") caller_id_number = event:getHeader("VM-Caller-ID-Number") uuid = event:getHeader("VM-UUID") message_len = event:getHeader("VM-Message-Len") timestamp = event:getHeader("VM-Timestamp") I have some of the important information here, like which voicemail box got the message, who's it from, when, and how long it was. At this point I'd like to send this information as an SMS message using a CURL call into the Flowroute SMS API. The important bit of data is to whom to send the SMS message. I put the SMS number into the directory XML structure, like this: <include> <user id="1004"> <params> <param name="vm-mailto" value="user@example.com"/> </params> <variables> <variable name="effective_caller_id_name" value="Joe Smith"/> <variable name="effective_caller_id_number" value="1004"/> <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/> <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/> <variable name="vm-notify-sms" value="1408497xxxx"/> </variables> </user> </include> I'd like to pull that vm-notify-sms variable that I created. The documented way to get variables from a lua script is the session:getVariable() function, but the session variable is not defined when this event hook is called. However, the log file shows my script is being called before the session is destroyed, so I'm thinking perhaps I can access it from the uuid variable. How do I do this? I also looked for an "env" object, which is created when a hangup hook is called, but it seems that is only set on a hangup hook, not an event hook. How can I access the session or directory variables? -- Steve
I may have just answered my own question again. I found a way, but please let me know if you know of a cleaner way: user = event:getHeader("VM-User") domain = event:getHeader("VM-Domain") api = freeswitch.API(); from = api:executeString("user_data " ..user .. "@" .. domain .. " var outbound_caller_id_number") to = api:executeString("user_data " .. user .. "@" .. domain .. " param vm-notify-sms") This should get me what I need to send the text. -- Steve
This is the correct way to get user data, why do you consider this unclean? On Tue, May 31, 2016 at 8:10 PM, Steven Schoch < schoch+freeswitch.org@xwin32.com> wrote:
I may have just answered my own question again. I found a way, but please let me know if you know of a cleaner way:
user = event:getHeader("VM-User") domain = event:getHeader("VM-Domain") api = freeswitch.API(); from = api:executeString("user_data " ..user .. "@" .. domain .. " var outbound_caller_id_number") to = api:executeString("user_data " .. user .. "@" .. domain .. " param vm-notify-sms")
This should get me what I need to send the text.
-- Steve
_________________________________________________________________________ Professional FreeSWITCH Consulting Services: consulting@freeswitch.org http://www.freeswitchsolutions.com
Official FreeSWITCH Sites http://www.freeswitch.org http://confluence.freeswitch.org http://www.cluecon.com
FreeSWITCH-users mailing list FreeSWITCH-users@lists.freeswitch.org http://lists.freeswitch.org/mailman/listinfo/freeswitch-users UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users http://www.freeswitch.org
I guess I'm doing it right. I've been programming in perl for the last few months, so I'm just not used to the lua way. I'm pretty close to a solution, but what I would like to get now is the callee number - that is, the main number dialed before it was transferred to an extension. I tried "show detailed_calls", but the only numbers that gave me were the caller-ID number (which I already have from the event), and the number called (which is only the extension, and is also already present in the event). It's not a big deal, since I can use the outbound_caller_id_number variable, but there are some voice mailboxes here where 2 different called numbers end up at the same extension, and same voice box. -- Steve On Tue, May 31, 2016 at 6:46 PM, Abaci B <abaci64@gmail.com> wrote:
This is the correct way to get user data, why do you consider this unclean?
On Tue, May 31, 2016 at 8:10 PM, Steven Schoch < schoch+freeswitch.org@xwin32.com> wrote:
I may have just answered my own question again. I found a way, but please let me know if you know of a cleaner way:
user = event:getHeader("VM-User") domain = event:getHeader("VM-Domain") api = freeswitch.API(); from = api:executeString("user_data " ..user .. "@" .. domain .. " var outbound_caller_id_number") to = api:executeString("user_data " .. user .. "@" .. domain .. " param vm-notify-sms")
This should get me what I need to send the text.
-- Steve
_________________________________________________________________________ Professional FreeSWITCH Consulting Services: consulting@freeswitch.org http://www.freeswitchsolutions.com
Official FreeSWITCH Sites http://www.freeswitch.org http://confluence.freeswitch.org http://www.cluecon.com
FreeSWITCH-users mailing list FreeSWITCH-users@lists.freeswitch.org http://lists.freeswitch.org/mailman/listinfo/freeswitch-users UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users http://www.freeswitch.org
_________________________________________________________________________ Professional FreeSWITCH Consulting Services: consulting@freeswitch.org http://www.freeswitchsolutions.com
Official FreeSWITCH Sites http://www.freeswitch.org http://confluence.freeswitch.org http://www.cluecon.com
FreeSWITCH-users mailing list FreeSWITCH-users@lists.freeswitch.org http://lists.freeswitch.org/mailman/listinfo/freeswitch-users UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users http://www.freeswitch.org
I got it working! The goal was to run a script to inform users via a text message when they get a voicemail. This script looks for a "vm-notify-sms" param in the user's directory information. It sends the text from user's outbound caller-ID number, which is set in the standard FS configuration. I'm using the SMS API from Flowroute.com. --[[ This script is called by configuration in autoload_configs/lua.conf.xml. It is called on a "vm:maintenance" event. ]] -- The following is specifc to the Flowroute SMS API, -- documented at https://developer.flowroute.com/docs/messaging url = "https://api.flowroute.com/v2/messages" authentication = "user:password" action = event:getHeader("VM-Action") if action ~= "leave-message" then return end user = event:getHeader("VM-User") domain = event:getHeader("VM-Domain") caller_id_name = event:getHeader("VM-Caller-ID-Name") caller_id_number = event:getHeader("VM-Caller-ID-Number") --[[ We don't care about these: file_path = event:getHeader("VM-File-Path") flags = event:getHeader("VM-Flags") folder = event:getHeader("VM-Folder") uuid = event:getHeader("VM-UUID") --]] message_len = event:getHeader("VM-Message-Len") timestamp = event:getHeader("VM-Timestamp") api = freeswitch.API(); from = api:execute("user_data", user .. "@" .. domain .. " var outbound_caller_id_number") to = api:execute("user_data", user .. "@" .. domain .. " param vm-notify-sms") if to == "" then return end if caller_id_name == '' or caller_id_name == 'UNKNOWN' or caller_id_name == 'UNASSIGNED' or caller_id_name == 'WIRELESS CALLER' or caller_id_name == 'TOLL FREE CALL' or caller_id_name == 'Anonymous' or caller_id_name == 'Unavailable' then caller_id_name = nil end if caller_id_number == '' then caller_id_number = nil end message = "Voicemail " if caller_id_name then message = message .. "from " .. caller_id_name .. " (" .. caller_id_number .. ")" elseif caller_id_number then message = message .. "from " .. caller_id_number end message = message .. " at " .. os.date("%I:%M %p", timestamp) message = message .. " length " .. message_len .. " seconds" message = message .. " to box " .. user message = message .. "." -- Blindly send the text data = '{ "to": "' .. to .. '", "from": "' .. from .. '", "body": "' .. message .. '"}' --[[ Until either Freeswitch has the ability to pass authentication data to the mod_curl API (FS-9223), or the Flowroute API has the ability to take authentication data in the POST body (they are working on it), we are forced to spawn a shell to use the curl from our OS. ]] -- api.execute("curl", url .. " auth " .. authentication .. " post " .. data) os.execute("curl -u " .. authentication .. " -H 'Content-Type: application/json' -X POST -d '" .. data .. "' " .. url)
In browsing through the source to mod_curl, I found an option that allows me to use curl without invoking a shell. I made some minor changes to the script, changing the url to this: url = "https://user:password@api.flowroute.com/v2/messages" ... adding some escaping after the message is composed... message = message .. "." -- Add JSON string escapes to the message message = string.gsub(message, "([\\\"'])", "\\%1") ...and using the mod_curl API call to send the text to Flowroute: api:execute("curl", url .. " content-type application/json post '" .. data .. "'") Works, easy, efficient. -- Steve On Thu, Jun 2, 2016 at 3:26 PM, Steven Schoch < schoch+freeswitch.org@xwin32.com> wrote:
I got it working! The goal was to run a script to inform users via a text message when they get a voicemail. This script looks for a "vm-notify-sms" param in the user's directory information. It sends the text from user's outbound caller-ID number, which is set in the standard FS configuration. I'm using the SMS API from Flowroute.com.
--[[ This script is called by configuration in autoload_configs/lua.conf.xml. It is called on a "vm:maintenance" event. ]]
-- The following is specifc to the Flowroute SMS API, -- documented at https://developer.flowroute.com/docs/messaging url = "https://api.flowroute.com/v2/messages" authentication = "user:password"
action = event:getHeader("VM-Action") if action ~= "leave-message" then return end user = event:getHeader("VM-User") domain = event:getHeader("VM-Domain") caller_id_name = event:getHeader("VM-Caller-ID-Name") caller_id_number = event:getHeader("VM-Caller-ID-Number") --[[ We don't care about these: file_path = event:getHeader("VM-File-Path") flags = event:getHeader("VM-Flags") folder = event:getHeader("VM-Folder") uuid = event:getHeader("VM-UUID") --]] message_len = event:getHeader("VM-Message-Len") timestamp = event:getHeader("VM-Timestamp") api = freeswitch.API(); from = api:execute("user_data", user .. "@" .. domain .. " var outbound_caller_id_number") to = api:execute("user_data", user .. "@" .. domain .. " param vm-notify-sms") if to == "" then return end
if caller_id_name == '' or caller_id_name == 'UNKNOWN' or caller_id_name == 'UNASSIGNED' or caller_id_name == 'WIRELESS CALLER' or caller_id_name == 'TOLL FREE CALL' or caller_id_name == 'Anonymous' or caller_id_name == 'Unavailable' then caller_id_name = nil end if caller_id_number == '' then caller_id_number = nil end message = "Voicemail " if caller_id_name then message = message .. "from " .. caller_id_name .. " (" .. caller_id_number .. ")" elseif caller_id_number then message = message .. "from " .. caller_id_number end message = message .. " at " .. os.date("%I:%M %p", timestamp) message = message .. " length " .. message_len .. " seconds" message = message .. " to box " .. user message = message .. "." -- Blindly send the text data = '{ "to": "' .. to .. '", "from": "' .. from .. '", "body": "' .. message .. '"}' --[[ Until either Freeswitch has the ability to pass authentication data to the mod_curl API (FS-9223), or the Flowroute API has the ability to take authentication data in the POST body (they are working on it), we are forced to spawn a shell to use the curl from our OS. ]] -- api.execute("curl", url .. " auth " .. authentication .. " post " .. data) os.execute("curl -u " .. authentication .. " -H 'Content-Type: application/json' -X POST -d '" .. data .. "' " .. url)
participants (5)
-
Abaci B
-
Jai Rangi
-
Michael Jerris
-
Sergey Safarov
-
Steven Schoch