Self ID Prompt - Automated (Step by Step)

Status
Not open for further replies.

DrainBamaged

Forum User
Advanced Certified
Joined
Feb 21, 2019
Messages
168
Reaction score
41
Good Day,

I just went through the exercise of populating 156 users with a self_id_prompt.wav and thought others could benefit.

Warning: The Powershell code below works for me, in my environment. I present it with no guarantees or warranties. It is presented "as-is" and you use it at your own risk. Please don't dm me for support. I don't have enough time to maintain my own domain. There are many help groups out there for scripting if you lack experience yourself. Thanks.

We sent out three series of emails to our users, over a six month period, to have them create their own self_id_prompt with step by step instructions. Over half never did it. So we decided to create one for them using text to speech. Here is what I did, it may help others. This takes place on your 3CX phone server, except where specified.

1) Using 3CX console, in Extensions, export all extensions into a CSV file.

2) Open that CSV in Excel and remove all columns except:

Number,FirstName,LastName,EmailAddress

3) Save the resulting info in CSV format. I used C:\Tools\ExtList.csv You can either use this path or amend my scripts below to your own path.

4) Open a Powershell window with Administrator powers.

5) In Powershell, CD to "C:\ProgramData\3CX\Instance1\Data\IVR\Voicemail\data" (Blank output, if you do not)

6) The below code was saved in C:\Tools as NoSelfIDMessage.ps1 Run it in the Powershell window.

===================================== NoSelfIDMessage.ps1 =========================================

# PS Script to find all 3CX users without self_id_prompt.wav file.
# v1.00 - 31 Jan 2019
# Step One - Generate list of extensions without self-identifier
# Warning Change Directory (CD) to "C:\ProgramData\3CX\Instance1\Data\IVR\Voicemail\data" before running
Get-ChildItem|?{$.PSIsContainer}|?{$.GetFiles("self_id_prompt.wav").Count -eq 0} | Select-Object PSChildName,FullName | Export-Csv -NoTypeInformation -Path c:\Tools\No_Self_ID.csv
#
# Step Two - Using your previous edited 3CX export of extensions. Link using Ext field in both files and produce a list.
#
$CSV1 = Import-Csv -Path 'C:\Tools\No_Self_ID.csv' -Delimiter ','
$CSV2 = Import-Csv -Path 'C:\Tools\ExtList.csv' -Delimiter ','

$Result = Foreach($Item1 in $CSV1){
Foreach($item2 in $CSV2){
If($Item1.PSChildName -eq $item2.Number){
[PSCustomObject]@{
a = $Item1.PSChildName
b = $Item1.FullName
c = $Item2.Number
d = $Item2.FirstName
e = $Item2.LastName
f = $Item2.EmailAddress
}
}
}
}
$Result
$Result | Export-Csv -Path 'c:\Tools\NoSelfID_Email.csv' -NoTypeInformation
#
# Step Three - Destroy all humans... Just kidding; we're done. :)

===================================== NoSelfIDMessage.ps1 =========================================

This creates a file called "C:\Tools\NoSelfID_Email.csv" which is all users without a self_id_prompt wav file in their folder. EDIT this file to remove conference rooms, break rooms, etc. that you do not want to use a self ID message. It will cut down on the amount of work you need to do later...

7) In C:\Tools create a directory called WAV. CD into C:\Tools\WAV, before running the below PS script.

8) The below code was saved as "C:\Tools\MakeSelfIDMsg.ps1" It creates a WAV file for all users in the format "FirstName Lastname.wav"

===================================== MakeSelfIDMsg.ps1 =========================================

# PS Script to create self_id_prompt.wav file for all users that do not have it.
# v1.00 - 4/1/2019 (No foolin...)
#
# CD into C:\Tools\WAV, before running the script.
# Step One - Pull in list of extensions that need Self ID Msg WAV files
#
$WAV="C:\tools\WAV\"
CD $WAV
Remove-item "C:\tools\NameList.csv"
#
$SRCFile="C:\tools\NoSelfID_Email.csv"
$DestFile="C:\tools\NameList.csv"

$Ascot = Import-Csv $SRCFile

ForEach($Line in $Ascot)
{
$FirstName = [string]$Line.d
$LastName = [string]$Line.e
"First is $FirstName and second is $LastName"
[string]$OutputLine = [string]$FirstName
[string]$OutputLine += " "
[string]$OutputLine += [string]$LastName
"Name is $OutputLine"
Add-Content $DestFile $OutputLine;
}
# Now let's create the sound files.
#
function ConvertTo-WaveFile {
param(
[Parameter(Mandatory=$true)]
[String]
$Text
)
Add-Type -AssemblyName System.Speech
$synthesizer=New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer
$synthesizer.Rate = "-1"
$synthesizer.SelectVoiceByHints([System.Speech.Synthesis.VoiceGender]::Female)
$synthesizer.SetOutputToWaveFile("$PSScriptRoot\$Text.wav")
$synthesizer.Speak($Text)
}

$NameFile="C:\tools\NameList.csv"
$WAV="C:\tools\WAV\"
## Set to WAV output dir.
CD $WAV
$ListOfNames = Get-Content -Path $NameFile
ForEach ($Name in $ListOfNames)
{
ConvertTo-WaveFile $Name
}

=========================== MakeSelfIDMsg.ps1 =========================================

Running this script will create a wav file for every user that does not have a self_id_prompt.wav file in C:\Tools\WAV folder.

9) Copy the WAV files onto a workstation, or server that does not have 3CX server installed. I used directory "C:\Temp\3CX\Recordings\Self ID Wavs"

10) Download the 3CX Converter tool from here: https://www.3cx.com/docs/converting-wav-file/

11) Unzip the contents of the converter download file onto the workstation or server where the copied WAV files are. I used "C:\Temp\3CX\Recordings\Convert"

12) Open a CMD Window with Administrator powers. CD to "C:\Temp\3CX\Recordings\Convert"

13) In the CMD Window, run the command, 3cxConvertPrompts.exe "C:\Temp\3CX\Recordings\Self ID Wavs" "C:\Temp\3CX\Recordings\Convert\ffmpeg.exe"

14) It will warn you to stop specific 3CX services and press any key. This is why we moved the WAV files off the server, so it does not impact on production. There should be no 3CX services on the workstation, so press any key and the WAV files will be converted to 3CX compatible audio format. Scan the output for errors.

15) Now the tedious part. All of your WAV files will be in the format "Firstname LastName.wav" Open up file explorer and enter the path to your 3CX server:

"\\3CXServerName\c$\ProgramData\3CX\Instance1\Data\Ivr\Voicemail\Data\XXX" where XXX is the extension of the person you have a WAV file for. I used 3CX Admin console, looked up the extension based on the FirstName LastName.

Example: "John Smith.wav" on Ext 500

- Go to "\\3CXServerName\c$\ProgramData\3CX\Instance1\Data\Ivr\Voicemail\Data\500"

- Copy "John Smith.wav" from your workstation to that folder.

- Rename "John Smith.wav" to "self_id_prompt.wav"

Repeat as required. I did 156 users this way in under an hour. YMMV.

Good luck.
 
Last edited:
I am going to try and make this into something more versatile for other platforms.
 
This script will find extension folders without a self_id_prompt.wav and generate one based on the name in the users.json file for each extension.

This should work on *nix and macOS, and probably even Windows.

This is also available here:
https://github.com/L422Y/3cx-selfidprompt-gen

  1. Make a new directory for the project, create a data folder inside of it
  2. Place all your extension folders from /var/lib/3cxpbx/Instance1/Data/Ivr/Voicemail/Data in it.
  3. Create the self_id.py file in the porject folder.
  4. Create a users.json folder in the project folder with the format below.
  5. Install ffmpeg for your OS i.e. brew install ffmpeg
  6. Install the required Python libs: i.e. sudo pip install gTTS pydub
  7. python self_id.py
self_id.py
Python:
from pydub import AudioSegment
from gtts import gTTS
import os, json

datadir = 'data'

# load extension names from users.json
with open('users.json', 'r') as f:
    users = json.load(f)

# find missing self id prompts
for subdir, dirs, files in os.walk(datadir):
    if subdir != datadir:
        # determine name
        ext = subdir.replace("data/", "")
        # if the data contains a name for the given extension:
        if ext in users:
            # determine name
            name_text = users[ext]
            if "self_id_prompt.wav" not in files:
                print "Creating self_id_prompt for '%s' (ext. %s)" % (name_text, ext)
                # generate self_id_prompt for extension
                tts = gTTS(text=name_text, lang='en')
                tts.save("temp.mp3")
                sound = AudioSegment.from_mp3("temp.mp3")
                sound = sound.set_frame_rate(8000)
                sound.export("%s/self_id_prompt.wav" % subdir, format="wav")
            else:
                print "Skipping existing prompt for '%s' (ext. %s)" % (name_text, ext)
        else:
            print "Skipping extension with missing name (ext. %s)" % (ext)

users.json
JSON:
{
    "121": "Bobby Flay",
    "118": "Old McDonald",
    "100": "Rual Paul",
    "105": "Chris Pratt",
    "106": "Larry Williamson"
}

Edit: remember to chown phonesystem:phonesystem * -R the uploaded files in the source directory if you're using SFTP, otherwise they'll probably give you permissions problems in the future.

It probably would be very easy to make this part of 3CX, but I just need a quick fix, like above.

Enjoy :)
 
Last edited:
  • Like
Reactions: DrainBamaged
Status
Not open for further replies.

Forum statistics

Threads
111,923
Messages
589,752
Members
164,796
Latest member
Dame24