"Lenny" - The Telemarketers Nightmare

Status
Not open for further replies.

mc6650

Member
Apr 8, 2019
110
2
18
62
Hello

1st time posting so I'm not sure if I'm asking the the right thread.

I use to have "Lenny" set up on FreePBX as DN 789. Whenever a Telemarketer would call, I'd transfer them to DN 789. Can "Lenny" be set up on FusionPBX and if so can someone please post the instructions.

Thanks in advance for any help that can be provided.

Michael
 
  • Haha
Reactions: ict2842

cemotyz09

Member
Apr 23, 2020
83
7
8
I couldn't figure out how to get the script to work but Here shows a developer of freeswitch providing a script. I got the sound files from nerdvittles tutorial since I don't believe linking to the files is ok
 

mc6650

Member
Apr 8, 2019
110
2
18
62
Thanks very much for your help. I've never worked with a script. Are you able to provide details on how I get it to work? For example where do I copy the script to and what directories do I need to create. I have the sound files from the FreePBX install, but where would they go?
 

cemotyz09

Member
Apr 23, 2020
83
7
8
I've created a directory at /etc/freeswitch/scripts and place scripts in there but default location I believe is /usr/share/freeswitch/scripts/ but it may be overwritten on upgrade if placed there. You can change the dialplan but this should be the simplest way to implement it. I know the script has to be edited to where you place the sound files which I'm using centos so may be different for us.
Code:
/usr/share/freeswitch/sounds/<lennydir>
the script has a line about local path that is where you would change it to reflect the location you placed the sound files
Untitled.png
 

mc6650

Member
Apr 8, 2019
110
2
18
62
Hello
Thanks for the feed back. I'm slowly making my way through this. Can you please tell me where the I enter the information as pictured above and is it only the one line? I've included a screen shot of the above picture with a red marking indicating the line I'm referring to. I'm new to fusionPBX and so I might not recognize the windows right off the bat. Thanks.
 

Attachments

  • FusionPBX_Lenny.jpg
    FusionPBX_Lenny.jpg
    67.7 KB · Views: 19

cemotyz09

Member
Apr 23, 2020
83
7
8
dialplan > dialplan manager > add (top of screen) > name it and add 1 condition and 1 action > save. open up the dialplan that you just created and you'll see a screen similar to the screenshot you'll have to edit for your use. if lua isn't an option to select then you need to install the lua-freeswitch package or something along those lines and enable to module ( advanced > modules > under 'languages' for me
 

mc6650

Member
Apr 8, 2019
110
2
18
62
Hello
Here's an update. Thanks again for the help. I want to be able to transfer an outside call to "Lenny" which is going to be extension 789. So I've created an extension 789. In "Dial Plan Manager" I've created a plan with the name of "Lenny" and a number of "789". When I call extension 789 I'm getting VM and not the script. Where am I going wrong? I've included pictures of the various pages I've worked on. Thanks.
 

Attachments

  • Dial Plan Manager 2.jpg
    Dial Plan Manager 2.jpg
    90.5 KB · Views: 10
  • Dial Plan Manager1.jpg
    Dial Plan Manager1.jpg
    197.2 KB · Views: 12
  • Extension 789.jpg
    Extension 789.jpg
    89.1 KB · Views: 12
  • Script Directory.jpg
    Script Directory.jpg
    43.3 KB · Views: 11
  • Script.jpg
    Script.jpg
    133.2 KB · Views: 9
  • Sound Directory.jpg
    Sound Directory.jpg
    84.2 KB · Views: 10

cemotyz09

Member
Apr 23, 2020
83
7
8
Like I said I'm unable to get the script to work also, it's the first function block that fails for me. I don't know lua so I haven't been able to figure it out. I assume its not finding the files but I don't know what needs to be done to get it to work. everything you've done looks correct though.
 

mc6650

Member
Apr 8, 2019
110
2
18
62
Okay. Thanks for confirming this. I'll look into it some more and see what I come up with.
 

cemotyz09

Member
Apr 23, 2020
83
7
8
I'm pretty sure it has to do with the structure of the files but I don't know what its supposed to be. If you know lua or someone who does I'm sure its probably really easy.
 

mc6650

Member
Apr 8, 2019
110
2
18
62
Hello
Has anyone got this working on their switch and if so how did you go about setting it up. Whenever I call the number I get a popup window that displays "Temporarily Unavailable". Thanks
 

Adrian Fretwell

Well-Known Member
Aug 13, 2017
1,498
413
83
Yes, I had a play and got it working on my test box. I had to modify the LUA downloaded from the link in this thread, mainly to fix some minor issues, but also to correctly specify the sound file location.

I downloaded the sound files, they were all in one directory and called lenny1, lenny2, lenny3 etc... They were in ULAW, so I converted them to WAV and renamed them to match what the LUA script was looking for.

If you look at the LUA script you will realise that it runs two loops, one for responses and one for no responses. You will also notice that the sound files are divided into three sub directories: greeting, mainloop, and noinputloop. I had to work out which sound files belong in each directory.

I made a directory called /usr/share/freeswitch/en/au/lenny/ and loaded the sound files into there. If I ever put this into production, I would record my own sound files to avoid any licensing issues.

My modified LUA is shown below and located at /usr/share/freeswitch/scripts/ A screenshot of the dialplan below that. Have fun...

Code:
--[[
It's Lenny in Lua
--]]

local path = '/usr/share/freeswitch/sounds/en/au/lenny/';
local counter_mainloop = 1;
local counter_noinput  = 1;
local counter_consec_noinput = 0;

function get_filename (aType, aNumber)
   local file = path .. aType .. '/' .. aNumber .. '.wav';
--   local fd = io.open(file, "r");
--   if fd == nil then
--      file = path .. aType .. '/' .. aNumber .. '.gsm';
--   end
--   io.close(fd);
   return file;
end

function wait_for_silence(aTimeoutIncrement)
   if aTimeoutIncrement == nil then
      aTimeoutIncrement = 2000;
   end
   freeswitch.consoleLog( 'DEBUG', "Lenny - ENTER wait_for_silence " .. aTimeoutIncrement .. "\n" );
   if session:ready() ~= true then
      return false;
   end
   session:setVariable("wait_for_silence_timeout" , "");
   session:setVariable("wait_for_silence_listenhits", "0");
   session:setVariable("wait_for_silence_silence_hits", "0" );
   session:execute( "wait_for_silence", "300 30 5 " .. aTimeoutIncrement);

   local timeout = tonumber(session:getVariable("wait_for_silence_timeout"));
   local speech  = tonumber(session:getVariable("wait_for_silence_listenhits"));
   local silence = tonumber(session:getVariable("wait_for_silence_silence_hits"));

   freeswitch.consoleLog( 'DEBUG', "Lenny - Speech : " .. speech .. " Silence : " .. silence .. "\n" );
   if speech > 20 then
      wait_for_silence( aTimeoutIncrement );
      return true;
   else
      return false;
   end
end

function play_next_mainloop ()
   session:execute( "playback", get_filename( 'mainloop', counter_mainloop ) );
   counter_mainloop = counter_mainloop + 1;
   local fd = io.open( get_filename( 'mainloop', counter_mainloop ) , "r");
   if fd == nil then
      counter_mainloop = 1;
   else
      io.close(fd);
   end
   counter_consec_noinput = 0;
   return 2000;
end

function play_next_noinput ()
   session:execute("playback", get_filename( 'noinputloop', counter_noinput ) );
   counter_noinput = counter_noinput + 1;
   counter_consec_noinput = counter_consec_noinput + 1;
   local fd = io.open( get_filename( 'noinputloop', counter_noinput ) , "r");
   if fd == nil then
      counter_noinput = 1;
   else
      io.close(fd);
   end
   freeswitch.consoleLog( 'DEBUG', "Lenny - counter_consec_noinput " .. counter_consec_noinput .. "\n" );
   if counter_consec_noinput > 3 then
      counter_mainloop = 1;
   end
   return 3200;
end

session:answer();
session:execute( "playback", get_filename( 'greeting', 1 ) );
local SilenceTimeout = 4000;
while session:ready() == true do
   if wait_for_silence( SilenceTimeout ) ~= true then
      if counter_consec_noinput > 6 then
         break;
      end
      SilenceTimeout = play_next_noinput();
   else
      SilenceTimeout = play_next_mainloop();
   end
end
session:hangup();


Screenshot from 2021-03-26 09-57-34.png
 
  • Like
Reactions: cemotyz09

mc6650

Member
Apr 8, 2019
110
2
18
62
Hello
Thanks for the help. I'm struggling a bit and hoping you can help out.

1.) Firstly, I don't see the three directories (in the script) your referring to: greeting, mainloop, and noinputloop. Can you highlight these in the scrip.
2.) What directories did you put lenny1, lenny2 etc. into? Are you able to provide a list of which greetings go in which directory? For example, lenny1 goes into the mainloop directory and lenny3 goes into the noinput directory.
3.) What did you use to to convert the ulaw files to wav format? I've tried Audacity, Goldwave and G711.org. None of them recognize the file. Are you able to upload the converted wav files?

Thanks again for the help.
Michael
 

Adrian Fretwell

Well-Known Member
Aug 13, 2017
1,498
413
83
Ok I will try to answer in order.

1.) The directories are the aType parameter variable in the get_filename function. Eg. get_filename( 'greeting', 1 ) , get_filename( 'mainloop', counter_mainloop ) etc.

2.) I renamed lenny1.wav, lenny2.wav etc. to simply 1.wav, 2.wav etc. As for files in directories, your lenny files may be different to the ones I have. but this is what worked for me:
After I converted to .wav and renamed the files I had 1.wav through to 16.wav. I moved 1.wav to the greetings directory and then moved 2-16.wav to the mainloop directory but renamed them 1 to 15. I then copied 1 to 4 from the mainloop directory to the noinputloop directory.

3.) I used Audacity to convert the files. Use file->import->Raw Data. Choose ulaw encoding and a sample rate of 8000Hz. Screenshot below:

Screenshot from 2021-03-26 19-35-21.png

I hope that helps.
 
  • Like
Reactions: cemotyz09

mc6650

Member
Apr 8, 2019
110
2
18
62
Hello
Thanks for the response and here's an update. I've managed to convert the ulaw sound files into wav format and organize them into the directories you've suggested. Now when I dial 789 the script answers but I don't hear anything. I ran a DEBUG session and think I have a permissions issue as it appears the 1.wav file can't be opened. I've included screen shots of this as well at the debug session and the directory set up. Can you confirm if the issue does lie with permissions and if so how / what do I set the folders or files to? I can set the permissions via the Debian GUI or from command line, however I don't know what the commands are or what permission I should be giving the files. Thanks.
 

Attachments

  • Permissions Issue.png
    Permissions Issue.png
    282.2 KB · Views: 7
  • Script.png
    Script.png
    117 KB · Views: 6
  • Scripts location.png
    Scripts location.png
    90.4 KB · Views: 5
  • Sounds Directory.png
    Sounds Directory.png
    67.7 KB · Views: 5
  • Sounds Directory with wav files.png
    Sounds Directory with wav files.png
    165.2 KB · Views: 7

Adrian Fretwell

Well-Known Member
Aug 13, 2017
1,498
413
83
Sorry, I forgot to mention permissions, the following should do the trick:

chown -R www-data:www-data /usr/share/freeswitch/sounds/en/au/lenny/

If you created the au directory also, then get the permissions correct on that too.

chown -R www-data:www-data /usr/share/freeswitch/sounds/en/au/
 

mc6650

Member
Apr 8, 2019
110
2
18
62
"My eldest, Rachel, wouldn't speak to me for a week!"

This is excellent. Thank you very much for your help. I guess I can play around with the order of the wav files simply by renumbering them. For example number 14 or 15 is the file with the ducks in the background, If I wanted to I could move it up the order to play sooner. Also, like you mentioned I could record my own files and upload them?
 

Jiz

Member
Mar 29, 2021
50
1
8
41
Yes, I had a play and got it working on my test box. I had to modify the LUA downloaded from the link in this thread, mainly to fix some minor issues, but also to correctly specify the sound file location.

I downloaded the sound files, they were all in one directory and called lenny1, lenny2, lenny3 etc... They were in ULAW, so I converted them to WAV and renamed them to match what the LUA script was looking for.

If you look at the LUA script you will realise that it runs two loops, one for responses and one for no responses. You will also notice that the sound files are divided into three sub directories: greeting, mainloop, and noinputloop. I had to work out which sound files belong in each directory.

I made a directory called /usr/share/freeswitch/en/au/lenny/ and loaded the sound files into there. If I ever put this into production, I would record my own sound files to avoid any licensing issues.

My modified LUA is shown below and located at /usr/share/freeswitch/scripts/ A screenshot of the dialplan below that. Have fun...

Code:
--[[
It's Lenny in Lua
--]]

local path = '/usr/share/freeswitch/sounds/en/au/lenny/';
local counter_mainloop = 1;
local counter_noinput  = 1;
local counter_consec_noinput = 0;

function get_filename (aType, aNumber)
   local file = path .. aType .. '/' .. aNumber .. '.wav';
--   local fd = io.open(file, "r");
--   if fd == nil then
--      file = path .. aType .. '/' .. aNumber .. '.gsm';
--   end
--   io.close(fd);
   return file;
end

function wait_for_silence(aTimeoutIncrement)
   if aTimeoutIncrement == nil then
      aTimeoutIncrement = 2000;
   end
   freeswitch.consoleLog( 'DEBUG', "Lenny - ENTER wait_for_silence " .. aTimeoutIncrement .. "\n" );
   if session:ready() ~= true then
      return false;
   end
   session:setVariable("wait_for_silence_timeout" , "");
   session:setVariable("wait_for_silence_listenhits", "0");
   session:setVariable("wait_for_silence_silence_hits", "0" );
   session:execute( "wait_for_silence", "300 30 5 " .. aTimeoutIncrement);

   local timeout = tonumber(session:getVariable("wait_for_silence_timeout"));
   local speech  = tonumber(session:getVariable("wait_for_silence_listenhits"));
   local silence = tonumber(session:getVariable("wait_for_silence_silence_hits"));

   freeswitch.consoleLog( 'DEBUG', "Lenny - Speech : " .. speech .. " Silence : " .. silence .. "\n" );
   if speech > 20 then
      wait_for_silence( aTimeoutIncrement );
      return true;
   else
      return false;
   end
end

function play_next_mainloop ()
   session:execute( "playback", get_filename( 'mainloop', counter_mainloop ) );
   counter_mainloop = counter_mainloop + 1;
   local fd = io.open( get_filename( 'mainloop', counter_mainloop ) , "r");
   if fd == nil then
      counter_mainloop = 1;
   else
      io.close(fd);
   end
   counter_consec_noinput = 0;
   return 2000;
end

function play_next_noinput ()
   session:execute("playback", get_filename( 'noinputloop', counter_noinput ) );
   counter_noinput = counter_noinput + 1;
   counter_consec_noinput = counter_consec_noinput + 1;
   local fd = io.open( get_filename( 'noinputloop', counter_noinput ) , "r");
   if fd == nil then
      counter_noinput = 1;
   else
      io.close(fd);
   end
   freeswitch.consoleLog( 'DEBUG', "Lenny - counter_consec_noinput " .. counter_consec_noinput .. "\n" );
   if counter_consec_noinput > 3 then
      counter_mainloop = 1;
   end
   return 3200;
end

session:answer();
session:execute( "playback", get_filename( 'greeting', 1 ) );
local SilenceTimeout = 4000;
while session:ready() == true do
   if wait_for_silence( SilenceTimeout ) ~= true then
      if counter_consec_noinput > 6 then
         break;
      end
      SilenceTimeout = play_next_noinput();
   else
      SilenceTimeout = play_next_mainloop();
   end
end
session:hangup();


View attachment 2179
Thank you... It works pretty well
 

mc6650

Member
Apr 8, 2019
110
2
18
62
Thank you... It works pretty well
Hello
I compared your script to the one I'm using and I found three lines had a * beside them. I've highlighted the specific code in red. I'm not a coder so what would the reason be for the difference? I use a speaker phone and it seems to be picking up a lot of backgroud noise and will sometime interject the "noinputloop" greetings into the conversation. Is there anyway to prevent this and only play greetings from the mainloop directory or increase some type of sensetivity settings to make it harder for greetings to be played from the "noinputloop" directory?

My Script:
session:answer();
session:execute( "playback", get_filename( 'greeting', 1 ) );
local SilenceTimeout = 4000;
while session:ready() == true do
if wait_for_silence( SilenceTimeout ) ~= true then
*if counter_consec_noinput > 6 then
*break;
*end

SilenceTimeout = play_next_noinput();
else
SilenceTimeout = play_next_mainloop();
end
end
session:hangup();

Your Script:
session:answer();
session:execute( "playback", get_filename( 'greeting', 1 ) );
local SilenceTimeout = 4000;
while session:ready() == true do
if wait_for_silence( SilenceTimeout ) ~= true then
if counter_consec_noinput > 6 then
break;
end

SilenceTimeout = play_next_noinput();
else
SilenceTimeout = play_next_mainloop();
end
end
session:hangup();
 

Adrian Fretwell

Well-Known Member
Aug 13, 2017
1,498
413
83
As far as I am aware, a line beginning with * would be a syntax error in LUA. The * is an arithmetic operator for multiply. It may have been an attempt to comment out the lines, but if that were the case then a double dash should have been used i.e. -- There is a C language API available in LUA where the * is used as a pointer i.e "address of" but that is certainly not the case in this script.

The sensitivity for the silence is controlled by the wait_for_silence function. wait_for_silence is a FreeSWITCH mod_dptools function (API Call) and it can take a silence threshold parameter, see the help page below:

https://freeswitch.org/confluence/display/FREESWITCH/mod_dptools:+wait_for_silence
 
Status
Not open for further replies.