Email call recordings

Status
Not open for further replies.

DigitalDaz

Administrator
Staff member
Sep 29, 2016
3,044
565
113
We have a request to email a call recording upon call completion to the person who was on the call.

Does anyone have any idea how to best determine that user?

I'm thinking of setting a variable when the call is answered perhaps, I'm not really sure, there doesn't seem to be a consistent value with the different call types eg, rung groups, directly dialled etc.
 
  • Like
Reactions: krooney

junction1153

Member
Jul 15, 2020
52
11
8
33
I don’t know exactly how to determine that user but essentially when you do try to figure it out, it should be the last person who took the call. Perhaps the FS API has such a feature?
keep in mind that calls get parked, transferred around ,etc. So literally the extension that hung up the call
 

KonradSC

Active Member
Mar 10, 2017
166
98
28
Just hook a lua script to the end of the call using something like this:

<action application="set" data="api_hangup_hook=lua app.lua email_recording"/>

You'll probably need to pass the uuid of the call and the recording name & path to the script, lookup the email address, blah, blah, blah.

I think you are looking for the "api_hangup_hook" though.
 

Robert Birch

Member
Mar 16, 2017
111
4
18
52
I managed to get this to work by adding the following lines to the user_record dialplan
Code:
    <condition field="${record_session}" expression="^true$">
        <action application="set" data="email_recordings_to=email@domain.com" inline="true"/>
        <action application="set" data="email_recordings_subject=Recording of a call from ${caller_id_number} to ${destination_number}" inline="true"/>
        <action application="set" data="email_recordings_delete_after=false" inline="true"/>
        <action application="export" data="record_post_process_exec_app=lua:email_recordings.lua ${record_path}/${record_name}" inline="false"/>
    </condition>

It works fine for both inbound and outbound, but if the call goes to a RingGroup first, I don't get the recording emailed. I am assuming that the RingGroup doesn't pass the call to the user_record section.

Is there a better way to do this so it catches all calls? I'd also like to be able to have it pull the extensions email address and email the call there, if possible. I tried a couple things, but was unable to get that variable to come in.

@KonradSC I couldn't figure out where to add your api_hangup_hook call. Not really sure on the call flows to know where to look.

Any ideas would be greatly appreciated.

Thanks,
 
  • Like
Reactions: krooney

Robert Birch

Member
Mar 16, 2017
111
4
18
52
Thanks for pointing that out to me.

Would I want to change that api_hangup_hook or add one before ot after it for doing the email_recordings lua script?

Thanks.
 
  • Like
Reactions: dogankirdemir

KonradSC

Active Member
Mar 10, 2017
166
98
28
I would not modify that one. Keep in mind that the hook I sent is for extensions too. So adding another hook in that dialplan step is not going to work for things like ring groups.
 

Robert Birch

Member
Mar 16, 2017
111
4
18
52
OK. I was thinking about modifying the dialplan for the ringgroup, but it doesn't show any of the lines in the page for it. If I go to the XML view I see them. My thinking is if I modify the XML side, it will get overwritten if I change the ring group. Am I correct in that thinking?

I guess in the end I am confused on why it work where I have it for regular calls, but not with RingGroup calls as I would expect that when the call is answered, it would be just like a regular call.

Thanks.
 

Nik3000

New Member
May 23, 2021
11
0
1
39
I managed to get this to work by adding the following lines to the user_record dialplan
Code:
    <condition field="${record_session}" expression="^true$">
        <action application="set" data="email_recordings_to=email@domain.com" inline="true"/>
        <action application="set" data="email_recordings_subject=Recording of a call from ${caller_id_number} to ${destination_number}" inline="true"/>
        <action application="set" data="email_recordings_delete_after=false" inline="true"/>
        <action application="export" data="record_post_process_exec_app=lua:email_recordings.lua ${record_path}/${record_name}" inline="false"/>
    </condition>

It works fine for both inbound and outbound, but if the call goes to a RingGroup first, I don't get the recording emailed. I am assuming that the RingGroup doesn't pass the call to the user_record section.

Is there a better way to do this so it catches all calls? I'd also like to be able to have it pull the extensions email address and email the call there, if possible. I tried a couple things, but was unable to get that variable to come in.

@KonradSC I couldn't figure out where to add your api_hangup_hook call. Not really sure on the call flows to know where to look.

Any ideas would be greatly appreciated.

Thanks,
Good day! Could you post the content of email_recordings.lua? I was able to achieve execution on incoming calls to groups, I just added lines after record_session and before the transfer, but the letters do not come, although the script works completely in the logs, I think my problem is with the contents of the lua...
 

Robert Birch

Member
Mar 16, 2017
111
4
18
52
Hey @Nik3000

Here is the code for my email_recordings.lua script. Make sure to set the owner as www-data:www-data

Code:
--    email.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.

--Description:
    --purpose: send an email
    --freeswitch.email(to, from, headers, body, file, convert_cmd, convert_ext)
        --to (mandatory) a valid email address
        --from (mandatory) a valid email address
        --headers (mandatory) for example "subject: you've got mail!\n"
        --body (optional) your regular mail body
        --file (optional) a file to attach to your mail
        --convert_cmd (optional) convert file to a different format before sending
        --convert_ext (optional) to replace the file's extension

--Example
    --luarun email.lua to@domain.com from@domain.com 'headers' 'subject' 'body'

local Settings = require "resources.functions.lazy_settings"
local Database = require "resources.functions.database"
local db = dbh or Database.new('system')
local settings = Settings.new(db, domain_name, domain_uuid)

--get the argv values
    script_name = argv[0];
    to = session:getVariable("email_recordings_to");
    from = settings:get('email', 'smtp_from_name', 'text')
    headers = "";
    subject = session:getVariable("email_recordings_subject");
    body = "";
    file = argv[1];
    delete = session:getVariable("email_recordings_delete_after");
    if delete == nil then
            delete = "false";
    end
    --convert_cmd = argv[8];
    --convert_ext = argv[9];

--replace the &#39 with a single quote
    body = body:gsub("&#39;", "'");

--replace the &#34 with double quote
    body = body:gsub("&#34;", [["]]);

--send the email
    if (file == nil) then
        freeswitch.email(to,
            from,
            "To: "..to.."\nFrom: "..from.."\nX-Headers: "..headers.."\nSubject: "..subject,
            body
            );
    else
        if (convert_cmd == nil) then
            freeswitch.email(to,
                from,
                "To: "..to.."\nFrom: "..from.."\nX-Headers: "..headers.."\nSubject: "..subject,
                body,
                file
                );
        else
            freeswitch.email(to,
                from,
                "To: "..to.."\nFrom: "..from.."\nX-Headers: "..headers.."\nSubject: "..subject,
                body,
                file,
                convert_cmd,
                convert_ext
                );
        end
    end

--delete the file
    if (delete == "true") then
        os.remove(file);
    end

I don't actually remember where I got the code from, I didn't write it. Most likely I found it here on the forums when I was working on this.

What exactly did you change to get RingGroups to record? Can you post the changes?

Thanks.
 

Nik3000

New Member
May 23, 2021
11
0
1
39
Thank you very much for the script, outgoing works and incoming too, hurray!
<extension name="mtest" continue="false" uuid="78f0e7c7-6059-4386-ba4f-">
<condition field="destination_number" expression="^(mtest)$">
<action application="export" data="call_direction=inbound" inline="true"/>
<action application="set" data="domain_uuid=76b1d6a7-c11c-48f1-abba-" inline="true"/>
<action application="set" data="domain_name=sip.ortco.ru" inline="true"/>
<action application="set" data="record_path=${recordings_dir}/${domain_name}/archive/${strftime(%Y)}/${strftime(%b)}/${strftime(%d)}" inline="true"/>
<action application="set" data="record_name=${uuid}.${record_ext}" inline="true"/>
<action application="set" data="record_append=true" inline="true"/>
<action application="set" data="record_in_progress=true" inline="true"/>
<action application="set" data="recording_follow_transfer=true" inline="true"/>
<action application="record_session" data="${record_path}/${record_name}" inline="false"/>
<action application="set" data="email_recordings_to=youemail@mail.com" inline="true"/>
<action application="set" data="email_recordings_subject=Recording of a call from ${caller_id_number} to ${destination_number}" inline="true"/>
<action application="set" data="email_recordings_delete_after=false" inline="true"/>
<action application="export" data="record_post_process_exec_app=lua:email_recordings.lua ${record_path}/${record_name}" inline="false"/>

<action application="transfer" data="3000 XML sip.test.com"/>
</condition>
</extension>
 

Robert Birch

Member
Mar 16, 2017
111
4
18
52
Is that a ringgroup or an extension? Did you alter the XML directly or do it through the GUI of Fusion? Reason I ask is if I modify he XML directly of a ring group then make a change, those previous changes are gone.

Thanks,
 

Nik3000

New Member
May 23, 2021
11
0
1
39
This is the dialplan of the incoming line that is created after adding the direction. I edit the dialplan exclusively from the web interface, because If I edit xml, then the changes are not displayed in the web interface.
 

Robert Birch

Member
Mar 16, 2017
111
4
18
52
Not sure I follow. I'm still fairly new to digging into dialplans.

So under the DialPlan -> Dialplan Manager menu, which item are you editing? The item for the Ring Group or something different?

Thanks
 

Robert Birch

Member
Mar 16, 2017
111
4
18
52
Oh OK. I see you took out the "hangup_after_bridge" and "continue_on_fail" lines from the original route definition. Are they not needed?

Thanks.
 
Status
Not open for further replies.