mod_voicemail
About
mod_voicemail is a Dialplan Application that provides voicemail services via Diaplans. It lets you send calls to voicemail, which allows callers to leave messages for users and allows users to retrieve and manage any messages left by callers.
Click here to expand Table of Contents
- 1 Synopsis
- 2 Dialplan variables
- 3 Controlling User Parameters & Variables
- 3.1 vm-enabled
- 3.2 vm-alternate-greet-id
- 3.3 voicemail_alternate_greet_id
- 3.4 voicemail_greeting_number
- 3.5 http-allowed-api
- 3.6 vm-disk-quota
- 3.7 vm-mailto
- 3.8 vm-mailfrom
- 3.9 vm-notify-mailto
- 3.10 vm-password
- 3.11 vm-a1-hash
- 3.12 vm-email-all-messages
- 3.13 vm-notify-email-all-messages
- 3.14 vm_cc
- 3.15 vm-keep-local-after-email
- 3.16 vm-attach-file
- 3.17 vm-message-ext
- 3.18 vm_message_ext
- 3.19 vm-skip-instructions
- 3.20 notify-template-file
- 3.21 vm-storage-dir
- 3.22 vm-storage-dir-shared
- 3.23 vm-domain-storage-dir
- 4 Using Outside Programs to Send Voicemail to Email
- 5 Send_mail setting
- 6 Exim4 settings
- 7 Windows settings
- 8 Mail via PHP
- 9 nullmailer settings
- 10 sSMTP settings
- 11 Debugging an external mailer
- 12 Example
- 13 Configuration Parameters
- 13.1 file-extension
- 13.2 Key FS Mapping
- 13.3 callback-dialplan
- 13.4 callback-context
- 13.5 terminator-key
- 13.6 max-login-attempts
- 13.7 digit-timeout
- 13.8 max-record-len
- 13.9 tone-spec
- 13.10 play-new-messages-key
- 13.11 play-saved-messages-key
- 13.12 main-menu-key
- 13.13 config-menu-key
- 13.14 record-greeting-key
- 13.15 choose-greeting-key
- 13.16 record-name-key
- 13.17 record-file-key
- 13.18 listen-file-key
- 13.19 save-file-key
- 13.20 delete-file-key
- 13.21 undelete-file-key
- 13.22 email-key
- 13.23 pause-key
- 13.24 restart-key
- 13.25 ff-key
- 13.26 rew-key
- 13.27 odbc-dsn
- 13.28 record-silence-threshold
- 13.29 record-silence-hits
- 13.30 email-from
- 13.31 db-password-override
- 13.32 dbname
- 13.33 allow-empty-password-auth
- 13.34 auto-playback-recordings
- 14 Database Schema
- 15 API
- 15.1 vm_boxcount
- 15.2 voicemail_inject
- 15.3 vm_prefs
- 15.4 vm_list
- 15.5 vm_delete
- 15.6 vm_read
- 16 Advanced API
- 16.1 vm_fsdb_pref_password_set
- 16.2 vm_fsdb_pref_greeting_set
- 16.3 vm_fsdb_pref_recname_set
- 16.4 vm_fsdb_msg_list
- 16.5 vm_fsdb_msg_email
- 16.6 vm_fsdb_msg_purge
- 16.7 vm_fsdb_msg_delete
- 16.8 vm_fsdb_msg_save
- 16.9 vm_fsdb_msg_undelete
- 16.10 vm_fsdb_auth_login
- 16.11 vm_fsdb_msg_get
- 16.12 vm_fsdb_msg_count
- 17 FAQ
- 18 How do I reload new configuration without restarting FreeSWITCH?
- 19 Do I need a text-to-speech engine installed?
- 20 How do I install sound files?
- 21 Voicemail Voice Prompt / Troubleshooting Problems
- 22 How to update keys for accessing voicemail from outside?
- 23 How can I disable remote login/access to voicemail?
- 24 Can I share voicemail boxes between multiple phones/users?
- 24.1 To Monitor Voicemail
- 24.1.1 1. SUBSCRIBE feature method
- 24.1.2 SNOM 320 configuration
- 24.1.3 2. Force MWI Info in Sofia
- 24.1.1 1. SUBSCRIBE feature method
- 24.2 To Receive Voicemail
- 24.3 Voicemail Callback
- 24.1 To Monitor Voicemail
- 25 Transcribing Voicemail
Synopsis
voicemail,Voicemail,[check] [auth] <profile_name> <domain_name> [<id>]
Dialplan variables
skip_greeting
Skips playback of greeting message when leaving messages. Variable is unset after voicemail application finishes.
If using a command to access voicemail, you can use the following to direct the playout of a custom greeting to the caller:
<action application="set" data="skip_greeting=true"/>
<action application="voicemail" data="default $${domain} $1"/>
However, if using bridge to get to voicemail, you need to use "export" instead of "set" to get the channel variable to the correct leg of the call
<action application="export" data="skip_greeting=true"/>
<action application="bridge" data="loopback/app=voicemail:default $${domain} $1"/>
skip_instructions
Skips playback of instructions when leaving messages. Variable is unset after voicemail application finishes.
<action application="set" data="skip_instructions=true"/>
<action application="voicemail" data="default $${domain} $1"/>
However, if using bridge to get to voicemail, you need to use "export" instead of "set" to get the channel variable to the correct leg of the call
<action application="export" data="skip_greeting=true"/>
<action application="bridge" data="loopback/app=voicemail:default $${domain} $1"/>
For instance, in dialplan/default.xml under <extension name="Local_Extension">, you would modify the xml by:
<action application="export" data="skip_instructions=true"/>
<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>
voicemail_callback_dialplan
Set's the dialplan for the voicemail callback. This channel variable will override the parameter 'callback_dialplan' in voicemail.conf.xml
<action application="set" data="voicemail_callback_dialplan=XML"/>
voicemail_callback_context
Set's the dialplan context for the voicemail callback. This channel variable will override the parameter 'callback_context' in voicemail.conf.xml
<action application="set" data="voicemail_callback_context=mydomain.com"/>
Controlling User Parameters & Variables
When the following parameters are set in the extension conf files located in (conf/directory/'extension'.xml or conf/directory/default/'extension'.xml), they set options for your voicemail users
vm-enabled
When set to false this user will not have a voicemail box. This means busy and no answer calls will not forward to a voicemail box, nor will the user be able to log in to a voicemail box.
vm-alternate-greet-id
voicemail_alternate_greet_id
The parameter allows you to override the default extension or phone number spoken by the system in the voicemail greeting. This can also be set in the dialplan before calling the voicemail app.
This controls system greetings that read back a phone number, not user recorded greetings. To change to a different recorded greeting, use voicemail_greeting_number below.
Example setting the parameter in the user's directory entry. This example will say "8661234567" in the voicemail generic system greeting instead of the extension number 1004.
Parameter set in user directory entry
<!-- note use of dashes in parameter name -->
<include>
<user id="1004">
<params>
<param name="password" value="xyzzy"/>
<param name="vm-password" value="1234"/>
<param name="vm-alternate-greet-id" value="8661234567"/>
</params>
<variables>
<variable name="toll_allow" value="domestic,local"/>
<variable name="user_context" value="default"/>
<variable name="effective_caller_id_number" value="703-591-1635"/>
<variable name="effective_caller_id_name" value="Frank Haynes"/>
<variable name="callgroup" value="tech_support"/>
</variables>
</user>
</include>
Example setting the variable before trasferring to voicemail. This example will say "2024561000" in the voicemail greeting instead of the extension number, for example 1019.
Variable set in dialplan
<!--
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="^(10[01][0-9])$">
<action application="export" data="dialed_extension=$1"/>
<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="hangup_after_bridge=true"/>
<action application="set" data="continue_on_fail=true"/>
<action application="bridge" data="user/${dialed_extension}@${domain_name}"/>
<action application="answer"/>
<!-- Note the use of underscore_ between elements of the variable name -->
<action application="export" data="voicemail_alternate_greet_id=2024561000"/>
<action application="sleep" data="1000"/>
<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>
</condition>
</extension>
voicemail_greeting_number
Selects the user-recorded greeting to play.
If using a command to access voicemail, you can use the following to direct the playout of a custom greeting to the caller:
<action application="set" data="voicemail_greeting_number=1"/>
<action application="voicemail" data="default $${domain} ${dialed_extension}"/>
However, if using bridge to get to voicemail, you need to use "export" instead of "set" to get the channel variable to the correct leg of the call
<action application="export" data="voicemail_greeting_number=1"/>
<action application="bridge" data="loopback/app=voicemail:default $${domain} ${dialed_extension}"/>
By default, either of the above would play the file in $${base_dir}/storage/voicemail/default/$${domain}/<user>/greeting_1.wav. However, this file is not created until the user has recorded a custom greeting in slot 1.
If you have defined voicemail_greeting_number in the user's XML directory entry and would like to follow that value then execute the set_user app before transferring to voicemail.
http-allowed-api
This allows the user to use the web vm
<param name="http-allowed-api" value="voicemail"/>
vm-disk-quota
This will put a limit to the length of voicemail messages a user can store. If 0 or missing doesn't make any limitation. Default is no limitation.
The following example will limit the user's voicemail box to 30 seconds. When the limit exceed, The caller will hear "mailbox is full, please try your call again later, goodbye".
<param name="vm-disk-quota" value="30"/>
vm-mailto
This is the user's email address, default: undefined.
(originally called email-addr. Use vm-mailto instead)
This is defined in the directory for the particular user as a param. Multiple email addresses can be defined using a comma-separated list.
<param name="vm-mailto" value="user101@mydomain.com" />
vm-mailfrom
This is the FROM address to send the email, default: undefined
This is defined in the directory for the particular user as a param.
<param name="vm-mailfrom" value="noreply@yourdomain.com" />
in the voicemail template you can get this value using: ${voicemail_email_from}
vm-notify-mailto
The address you want notification messages sent to, default: same as vm-mailto.
This is defined in the directory for the particular user as a param.
<param name="vm-notify-mailto" value="user101_manager@yourdomain.com" />
vm-password
This is the user's configured voicemail PIN. This is additional to the voicemail password that the user can change in the voicemail system. If the value is set to "user-choose", then there is no configured password and only the user set password is used. Note that if you set the vm_password in the directory XML, any changes to the password from a phone are stored in the voicemail_prefs table. The module does not update the XML. The result is that there will be 2 passwords that can access the mail box, the one set in XML and the one that the user set from the phone.
This is defined in the directory for the particular user as a param.
Example:
<param name="vm-password" value="12345" />
vm-a1-hash
This parameter allows you to avoid sending the voicemail password in plain text. This is the same as the user a1-hash (see [[XML_User_Directory_Guide]]). Set this parameter to the MD5 hash of "userid:domain_name:vm-password". Example:
<!-- The password has been left as a comment for example -->
<!-- <param name="vm-password" value="12345"/> -->
<!-- The MD5 hash of "101:mydomain.com:12345" -->
<param name="vm-a1-hash" value="fd5184d9d36a2009c72e1571abf0493e" />
vm-email-all-messages
Setting to true will send all messages to vm-mailto address (attachment based on vm-attach-file param), default: false
This is defined in the directory for the particular user as a param.
<param name="vm-email-all-messages" value="true" />
vm-notify-email-all-messages
Setting to true will send a notify email to vm-notify-mailto when a vm is left (never has attachment)
default: false
This is defined in the directory for the particular user as a param.
<param name="vm-notify-email-all-messages" value="true" />
vm_cc
Setting this variable will inject the message into the specified voicemail mailbox.
This is defined in the directory for the particular user as a variable.
Please note that the variable 'vm_cc' needs to be set as a channel variable before mod_voicemail is called. When set as a directory variable, it only becomes a channel variable when the UA is authenticated.
Dialplan Example (recommended):
<action application="set" data="vm_cc=1001@mydomain.com"/>
<action application="voicemail" data="default mydomain.com 1000"/>
<!--If you want to cc the message to multiple users, use a comma separated list of users:-->
<action application="set" data="vm_cc=1001@mydomain.com,1002@mydomain.com,1003@mydomain.com"/>
Directory Example:
<include>
<domain name="mydomain.com">
<user id="101">
<params>
<!--Note: for user directory you can use either vm_cc in variables or the vm-cc param-->
<param name="vm-cc" value="1001@mydomain.com,1002@mydomain.com,1003@mydomain.com" />
</params>
<varibles>
<variable name="vm_cc" value="1001@mydomain.com" />
<!--If you want to cc the message to multiple users, use a comma separated list of users:-->
<variable name="vm_cc" value="1001@mydomain.com,1002@mydomain.com,1003@mydomain.com" />
</varibles>
</user>
</domain>
</include>
vm-keep-local-after-email
Setting to false will delete the local copy of the voicemail file after transmission of the mail message. When set to true the voicemail file will be kept locally and set as New for the phone to retrieve.
default: true
Example:
<param name="vm-keep-local-after-email" value="false" />
vm-attach-file
Setting to true will attach the audio file to the main email
default: false
This is defined in the directory for the particular user as a param.
Example:
<param name="vm-attach-file" value="true" />
vm-message-ext
This Parameter determines the storage type (and email type) for voicemails received and can be set per user. In order to use MP3 you must have mod_shout installed and loaded. The default is 'wav'.
Example:
<param name="vm-message-ext" value="mp3"/>
vm_message_ext
Determines the storage type (and email type) for voicemails received and can be set per originating user or the Dial Plan. In order to use MP3 you must have mod_shout installed and loaded. The default is 'wav'. This may be set from the Dial Plan to override the file type. If this variable is set it overrides the vm-message-ext parameter.
When this variable is set on the originating user the specified file type will apply to the receiver of the message.
Example:
<variable name="vm_message_ext" value="mp3"/>
vm-skip-instructions
This disables instructions for how to leave a message, and instead just plays a beep.
<param name="vm-skip-instructions" value="true"/>
notify-template-file
The notify email will use the same template as the main email unless you define the new profile
default: undefined
<param name="notify-template-file" value="other_template"/>
vm-storage-dir
This parameter allows to force the storage directory for voicemail files received and can be set per user. By default, voicemail files are stored in 'BASE_DIR/storage/voicemail/DOMAIN_NAME/USER_ID'.
It can be set to a full path, or a path relative to the BASE_DIR (usually /usr/local/freeswitch or /opt/freeswitch for debian installs).
Example:
<param name="vm-storage-dir" value="/home/voicemail/test.com/100"/>
Note: Most users either save voicemails locally, on a network file share directory or using a distribusted network file system, like glusterFS. https://www.gluster.org You can also save the voicemails locally and transfer to different FreeSWITCH servers in any manner: scp, rsync, Borgbackup, sneakernet, etc.
Here's a users input on GlusterFS:
Essentially, gluster is a cluster distributed filesystem. It uses local storage on each 'server' node, and that can then
be mounted on clients. It's intended for high performance compute resources, but works quite nicely for freeswitch backend.
In my case, I have 4 servers accessing the cluster - 2 freeswitch nodes that are setup as an HA pair using keepalived
(article already in wiki for that), 2 web server front end nodes for a local custom UI.
On the backend, I have the three gluster nodes for file service (odd number to insure quorum) and 3 Percona XTraDB mysql
nodes also operating as a cluster.
Everything except the two freeswitch instances is running as a VM. The FS nodes are running on real hardware.
The key difference with NFS is that the filesystem itself is redundant - so you can take any one of those backend nodes
out of service and it isn't visible (except as a momentary hang) to the servers that have the filesystem mounted.
http://lists.freeswitch.org/pipermail/freeswitch-users/2016-August/121650.html
vm-storage-dir-shared
If this is set to true (default false) we assume the storage-dir is shared, organized by realm/domain, with uses other than voicemail, so we adopt a directory structure of:
<storage_dir>/<realm>/voicemail/<id>
Example:
<param name="vm-storage-dir-shared" value="true"/>
vm-domain-storage-dir
This is like vm-storage-dir but we append the user ID to the directory so if vm-domain-storage-dir is /var/lib/freeswitch/storage/example.com, it will store VM in /var/lib/freeswitch/storage/test.com/user_id.
Example:
<param name="vm-domain-storage-dir" value="/var/lib/voicemail/test.com/"/>
Using Outside Programs to Send Voicemail to Email
There are times when you don't want or need an email server on your PBX. For these times it would be nice to be able to
use an outside program to send the email.
Below is a python script that does just that. Note that it will give deprecation warnings on later versions of Python so needs to be rewritten to used MIME in place of MimeWriter.
TODO: Fix indentation
#!/usr/bin/python
#
"""
Copyright (c) 2009, ChronosTelecom, LLC
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 <organization> 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 <copyright holder> ''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 <copyright holder> 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.
"""
import smtplib
import sys
import MimeWriter
import mimetools
import mimetypes
import os
import StringIO
import re
import shutil
import time
import os.path
from optparse import OptionParser
SERVER = 'smtp.gmail.com'
PORT = 587
USER = 'YOUR_MAIL_USER'
PASSWORD = 'PASSWORD'
attach = ""
# Write data to a file given the filename. Make a backup of the file FIRST!
def write_file(filename,data):
fh = ""
cur_time = time.time()
if not fh:
if not os.path.exists(filename):
fh = open(filename,'w')
else:
#print "WARNING: %s exists! Moving it to %s.bak.%s" % (filename,filename,cur_time)
shutil.move(filename,"%s.bak.%s" % (filename,cur_time))
fh = open(filename,'w')
fh.write(data)
fh.close()
# send the mail
def send(sender,to,message,verbose=False):
smtp = smtplib.SMTP(SERVER, PORT)
if verbose:
smtp.set_debuglevel(1)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(USER,PASSWORD)
smtp.sendmail(sender, to, message)
smtp.quit()
def mail(sender='', to='', subject='', text='', attachments=None, verbose=False):
"""
Usage:
mail()
Params:
sender: sender's email address
to: receipient email address
subject: subject line
text: Email message body main part.
attachments: list of files to attach
"""
message = StringIO.StringIO()
writer = MimeWriter.MimeWriter(message)
writer.addheader('To', to)
writer.addheader('From', sender)
writer.addheader('Subject', subject)
writer.addheader('MIME-Version', '1.0')
writer.startmultipartbody('mixed')
# start with a text/plain part
part = writer.nextpart()
body = part.startbody('text/plain')
part.flushheaders()
body.write(text)
# now add the attachments
if attachments is not None:
for a in attachments:
filename = os.path.basename(a)
ctype, encoding = mimetypes.guess_type(a)
if ctype is None:
ctype = 'application/octet-stream'
encoding = 'base64'
elif ctype == 'text/plain':
encoding = 'quoted-printable'
else:
encoding = 'base64'
part = writer.nextpart()
part.addheader('Content-Transfer-Encoding', encoding)
body = part.startbody("%s; name=%s" % (ctype, filename))
print filename
mimetools.encode(open(a, 'rb'), body, encoding)
# that's all folks
writer.lastpart()
send(sender,to,message.getvalue(),verbose)
def validate_email(fromAddress):
email_addr = re.compile(r'(([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?))')
return bool(email_addr.search(fromAddress))
if __name__ == "__main__":
fromAddress = ""
to = ""
subject = ""
infile = ""
body = ""
translate = ""
tempfile = ""
usestdin = False
verbose = False
delete = False
log = False
parser = OptionParser()
parser.add_option('-f', dest='fromAddress', metavar='FROMADDRESS',help="The from address for the email")
parser.add_option('-t', dest='toAddress', metavar='TOADDRESS',help="The to address for the email")
parser.add_option('-s', dest='subject', metavar='SUBJECT',help="The subject for the email")
parser.add_option('-a', dest='attachment', metavar='ATTACHMENT',help="The file to attach to the email")
parser.add_option('-b', dest='body', metavar='BODY',help="The body of the email")
parser.add_option('-x', dest='translate', metavar='TRANSLATE',help="Translate the attachment using a translator program.\ntiff2pdf is the only supported option at this time.")
parser.add_option('-i', dest='use_stdin', action="store_true", default=False,help="Use standard in as the input for the email message.")
parser.add_option('-d', dest='delete', action="store_true", default=False,help="Delete the attachments when done processing.")
parser.add_option('-v', dest='verbose', action="store_true", default=False,help="Verbose output for debugging.")
parser.add_option('-l', dest='log', action="store_true", default=False,help="Log the message to a file stored in /tmp/sendemail.log")
(options, args) = parser.parse_args()
if options.fromAddress:
fromAddress = options.fromAddress
if not validate_email(fromAddress):
print "Invalid From email address. Please try again."
exit(1)
if options.toAddress:
to = options.toAddress
if not validate_email(to):
print "Invalid To email address. Please try again."
exit(1)
if options.subject: subject = options.subject
if options.attachment: infile = options.attachment
if options.body: body = options.body
if options.translate: translate = options.translate
if options.use_stdin: usestdin = options.use_stdin
if options.verbose: verbose = options.verbose
if options.delete: delete = options.delete
if options.log: log = options.log
if usestdin is True:
message = ""
attachment = infile
for line in sys.stdin:
message += line
to_field = re.compile(r'To: <(([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?))>')
if to_field.search(message):
to_match = to_field.search(message)
to = str(to_match.group(1))
if log:
write_file('/tmp/sendemail.log',message)
send(fromAddress,to,message,verbose)
else:
if translate == 'tiff2pdf':
tempfile = "/tmp/%s.pdf" % os.path.basename(infile)
command = "tiff2pdf %s -o %s" % (infile, tempfile)
os.system(command)
attachment = tempfile
else:
attachment = infile
attach=[attachment]
mail(sender=fromAddress, to=to, subject=subject, text=body, attachments=attach, verbose=verbose)
# delete our temporary file - it's up to the caller to delete the attachments, if they want
if tempfile:
os.unlink(tempfile)
if delete and attachment:
os.unlink(attachment)
Make the following changes to /usr/local/freeswitch/autoload_configs/switch.conf.xml:
<param name="mailer-app" value="/usr/local/freeswitch/scripts/sendemail.py"/>
<param name="mailer-app-args" value="-i -d -f freeswitch@mydomain.com -t"/>
Send_mail setting
To enable email setting for voicemail, make sure the following two lines are configured correctly in switch.conf.xml
<param name="mailer-app" value="sendmail"/>
<param name="mailer-app-args" value="-t"/>
'''Note''' - On CentOS and possibly other OSs, `sendmail` isn't in the non-root PATH so you'll want to specify the entire path in the mailer-app value or modify your PATH prior to running FreeSWITCH™.
Exim4 settings
There have been several reports of segfaults with Exim4 in combination with Debian and FreeSWITCH - so far no definite resolution has been posted - mostly citing the advice below - which does not help(See [http://lists.freeswitch.org/pipermail/freeswitch-users/2009-June/043660.html here],[http://lists.freeswitch.org/pipermail/freeswitch-users/2010-January/052529.html here] and [http://jira.freeswitch.org/browse/FS-1923 here]).
A default installation of '''postfix''' instead of exim4 is a workaround, if you just quickly want to setup a mailer for FreeSWITCH on Debian --[[User:Peletiah|Peletiah]] 15:19, 1 June 2011 (UTC).
Using '''msmtp''' together with exim4 on the same host works and can be used as a workaround, see the notes below in a dedicated sub-section -- [[User:Miconda|miconda]] Sep 24, 2012.
As of April 22, 2013, a patch was applied to resolve the stack size setting for child processes, which is the primary cause of this issue. See [http://jira.freeswitch.org/browse/FS-5332 here] for details.
VM to email notification can also use other MTAs such as Debian's default Exim4. For email notification basically mod_voicemail constructs an email message that is then passed to standard input of the application defined in the "mailer-app" param found in switch.conf.xml.
The MTA application then needs to be configured in a way so that the recipients of the message are obtained from the To:, Cc:, and Bcc: header lines of the message passed to it. This is achieved in Exim4 with the -t option.
However, FS also adds another argument with the To: address to the command defined in the parameters above, so that the final command would look like:
cat /tmp/mail.12336173682b88 | exim4 -t someone@someaddress.net
If you have set:
<param name="mailer-app" value="exim4"/>
<param name="mailer-app-args" value="-t"/>
This is because as documented in O'Reilly Sendmail's book, some versions of Sendmail add argument addresses to those obtained from the headers and also as a good measure to send the To: address to applications that cannot parse the headers in the email msg.
Exim's default behavior however is that these extra addresses specify addresses to which the message is NOT to be delivered. So in the command line described above "someone@someaddress.net" is the actual recipient of the email message, but exim's default behavior takes the argument from the command line and subtracts the "someone@someaddress.net" email address from the To: headers of the actual message, leaving it with no recipients at all.
Exim can be made to add the argument instead of subtracting it by setting the option extract_addresses_remove_arguments false in it's config and then you can use:
<param name="mailer-app" value="exim4"/>
<param name="mailer-app-args" value="-t"/>
But if you do not want to go through the hassle of changing exim's configuration, then you could also overcome the "extra" argument using a script such as:
eximcompat.sh:
#!/bin/bash
exec exim4 -t
And then pointing the mailer app to this script:
<param name="mailer-app" value="/usr/local/bin/eximcompat.sh"/>
<!-- <param name="mailer-app-args" value="-t"/> -->
If you're using the sysV init script from this wiki, the stack size is set to some low value (240) which can cause exim to segfault; add a line in your exim4compat.sh to increase this value (8192 works for me).
Using MSMTP for Local Relay to Exim4 on Debian
This is a possible workaround to make voicemail email notification work on Debian with Exim4 as main MTA.
MSMTP can be installed together with Exim4 on the same host and can be configured to do relay to local exim4 instance. In this way, Voicemail module can use MSMTP, but the public email relaying is taken care by Exim.
Installation of MSMTP on Debian is very simple:
apt-get install msmtp
Its configuration has to be stored in '''/etc/msmtprc'''. To relay to localhost SMTP server, just set its content to the next three lines:
account default
host 127.0.0.1
syslog LOG_MAIL
By default, exim4 accepts messages from localhost without user authentication (to allow running processes to send email alerts), so you don't need to change anything in exim4 configuration (unless you disabled that default option).
On FreeSwitch configuration side, edit switch.conf.xml to set sending emails with MSMTP:
<param name="mailer-app" value="msmtp"/>
Windows settings
Example setting in switch.conf.xml for sending email on windows.
<param name="mailer-app" value="msmtp"/>
Mail via PHP
Example setting in switch.conf.xml for sending email with PHP mailer. Make sure the path to php is correct for mailer-app.
<param name="mailer-app" value="/usr/bin/php /usr/local/www/freeswitch/mailer_app.php"/>
<param name="mailer-app-args" value=""/>
nullmailer settings
http://untroubled.org/nullmailer/ is installed sometimes as a sendmail service. Make sure the following two lines are configured correctly in switch.conf.xml
<param name="mailer-app" value="sendmail"/>
<param name="mailer-app-args" value=""/>
<-- don't comment out the args line, leave it in with no value -->
If you don't take out the ''-t'' default argument, nullmailer will create duplicate emails.
sSMTP settings
http://wiki.debian.org/sSMTP can be used as a null mailer and has the advantage over http://untroubled.org/nullmailer/ that it permits sending to mail hosts that require SSL/TLS and/or authentication. It also logs to /var/log/mail.log which is useful for debugging.
sSMTP uses the same sendmail command, ignoring some options and failing if others are specified. Within conf/autoload_configs//switch.conf.xml, you need to include:
<param name="mailer-app" value="sendmail"/>
<param name="mailer-app-args" value="-f freeswitch@mydomain.com"/>
Within /etc/ssmtp/ssmtp.conf, your mileage may vary, but to relay to a Postfix server using submission (tcp/587), the config looks like this:
root=postmaster # part of the default config
mailhub=smtp.mydomain.com:587
UseTLS=YES
UseSTARTTLS=YES
AuthUser=myusername
AuthPass=mypassword
rewriteDomain=mydomain.com # This is useful if your FS box is not in DNS or has a different domain from the sending email
hostname=myFShostname.domain
FromLineOverride=NO # This stops the mail message overriding the -f switch on the command line, useful if your FS ${domain} is an IP address
Google will help you get a config that matches your configuration.
Debugging an external mailer
FreeSWITCH does very little error reporting on emails. Basically, once the email is
accepted for queueing, FreeSWITCH has (rightly) lost interest. So, it is best to first test that mails can be sent from your FreeSWITCH box before trying to get FreeSWITCH to do it.
First, create a minimal email in a text file:
From: <freeswitch@mydomain.com>
To: <testuser@mydomain.com>
Date: Thu, 2 Feb 2012 13:13:40 +0100
Subject: Test 131340 (I always put a timestamp in the subject line when
testing email due to the queueing and routing and stuff)
Minimal test email 131340 (and I try to remember to put the same timestamp in the body of the text)
Then send it from the command line with:
cat email.txt | sendmail -f freeswitch@mydomain.com testuser@mydomain.com
Nearly all mailers have a 'sendmail' alias even if they are not sendmail itself. Depending on the local mail server you are using, you may have to include the -t switch which extracts the To address(es) from the message itself.
If this command fails, then you may not have sendmail, or a clone, installed. If you don't need the weight and features of sendmail, exim or postfix, leave them alone and use a simple null mailer like nullmailer or sSMTP as described above.
If the command works but the mail still does not reach the destination, then you know you have a mail transport issue and can solicit the assistance of your friendly postmaster or a forum appropriate to your operating system and mailer.
Once you are reliably sending email from the shell, transfer your settings into conf/autoload_configs/switch.conf.xml
For example, for sSMTP:
<param name="mailer-app" value="sendmail"/>
<param name="mailer-app-args" value="-f freeswitch@mydomain.com"/>
Note that if you need to run your mailer-app with no args, explicitly state them as <param name="mailer-app-args" value="" /> as the default if not specified is to use "-t".
With your external mailer known to be working, you can now narrow down your debugging to FreeSWITCH. Make sure that you include all the parameters required in the user directory entry. For example, in conf/directory/default/1001.xml:
<param name="vm-password" value="1001" />
<param name="vm-email-all-messages" value="true" />
<param name="vm-mailto" value="user.name@mydomain.com" />
<!-- or just notify -->
<param name="vm-notify-mailto" value="user.name@mydomain.com" />
<!-- don't need notify if you have the full voicemail -->
<param name="vm-attach-file" value="true" />
<!-- You need this if you want the voicemail attached -->
<param name="vm-message-ext" value="wav" />
<!-- Can be 'mp3' but needs mod_lame to be loaded. -->
Then, use fs_cli in /log 7 and leave a voicemail on a configured extension. After completing the voicemail, you should see something like this (both mailto and notify-mailto have been set in this case):
2012-02-02 18:21:36.494891 [DEBUG] mod_voicemail.c:2641 Deliver VM to 1001@192.168.100.100
2012-02-02 18:21:36.894770 [DEBUG] switch_utils.c:761 Emailed file [/tmp/mail.1328206896cebf] to [user.name@mydomain.com]
2012-02-02 18:21:36.894770 [DEBUG] mod_voicemail.c:2831 Sending message to user.name@mydomain.com
2012-02-02 18:21:37.394793 [DEBUG] switch_utils.c:763 Emailed data to [user.name@mydomain.com]
2012-02-02 18:21:37.394793 [DEBUG] mod_voicemail.c:2881 Sending notify message to user.name@mydomain.com
Example
Send Voice Mail to Email
The following is an example of sending a voicemail to email
<include>
<user id="1001" number-alias="1001">
<params>
<param name="password" value="1234" />
<param name="vm-password" value="4321" />
<param name="vm-email-all-messages" value="true" />
<param name="vm-attach-file" value="true" />
<param name="vm-mailto" value="example@yahoo.com" />
</params>
<variables>
<variable name="accountcode" value="1001" />
<variable name="user_context" value="default" />
</variables>
</user>
</include>
Send Call To Voice Mail
The following is an example of sending a call to voicemail after you've decided that a user isn't available.
<action application="answer"/>
<action application="voicemail" data="default $${domain} $1"/>
where '''default''' is the profile name (must be configured in voicemail.conf.xml), '''$${domain}''' is (obviously) the domain (in this case the system-wide domain setting for your switch from vars.xml) and '''$1''' is the dialed extension.
Check Voice Mail
The following is an example of checking vm (will prompt for PIN if ${voicemail_authorized} is not "true")
Please make sure the password is set in order for the mailbox to prompt for a password.
<action application="voicemail" data="check $${voicemail_profile} $${domain} $1"/>
The following example will allow the user to check vm whether they're "voicemail_authorized" or not. If voicemail_authorized=true , then user can access voicemail without prompting for password. If it's set to false, then the system will ask to enter the password. I found that even if you don't put <auth> in the following example, it will still check if it is authed. Someone please verify.
<action application="voicemail" data="check auth $${voicemail_profile} $${domain} $1"/>
To automatically pass all registered users on your domain without prompting to enter the password:
<action application="set" data="voicemail_authorized=${sip_authorized}"/>
<action application="voicemail" data="check auth $${voicemail_profile} $${domain} $1"/>
(Preliminary 2012.02.06) To speak the called party number before speaking the date of the voicemail message, enable channel variable vm_announce_cid. This only speaks the number, it does not preface it with introductory words such as "The caller's number is..." nor separate the number from the date that follows it.
<action application="set" data="vm_announce_cid=true" />
<action application="voicemail" data="check $${voicemail_profile} $${domain} $1"/>
Retrieve Voice Mail Via Web Interface
Configuration
To enable the web interface for voice mail, you must first install/enable mod_xml_rpc
You also need to enable the user or domain to use the web interface using #http-allowed-api
There are two different URLs for retrieving voice mail via a browser.
The following are functionally equivalent:
* http://fs.ip:8080/api/voicemail/web
* http://fs.ip:8080/domains/this/api/voicemail/web
Enter the username and password in the challenge box. When authorized, the list of current voice mails will be displayed.<br/>
Note: use the actual IP address (or domain name) and not something like 127.0.0.1 or "localhost" because it won't work.<br/>
Domains are used in various circumstances. Here are some scenarios:
- your.domain.com is on the public Internet
In this case you could do this:
http://your.domain.com:8080/api/voicemail/web
Log in with user and password and you are in
Alternatively, you could use the IP address:
http://1.2.3.4:8080/api/voicemail/web
Then login with user@your.domain.com and password
Finally, you could even do this:
http://1.2.3.4:8080/domains/your.domain.com/api/voicemail/web
And log in with just user and password (no @your.domain.com)
Retrieve Voice Mail Via IMAP Interface
This is not implemented yet.
See [[Bounty#IMAP integration of voicemail]]
Using voicemail to authenticate a caller's PIN
This example allows you to authenticate a user by requiring him/her to enter a PIN. If the user enters the correct PIN then dialplan processing continues. If not, then the system will play an error message and then disconnect the caller.
<action application="voicemail" data="check auth_only ${extension_number_against_which_to_check}"/>
you can also set the "vm_auth_only" channel variable to true before calling the voicemail application, instead of using the auth_only arg
Configuration Parameters
file-extension
This is the extension which you want to use for the voicemail messages to be recorded. The default is wav but can be gsm, raw, ul, al, etc.
<param name="file-extension" value="wav"/>
Key FS Mapping
[[mod_voicemail key map]]
callback-dialplan
<param name="callback-dialplan" value="XML"/>
callback-context
<param name="callback-context" value="default"/>
terminator-key
<param name="terminator-key" value="#"/>
max-login-attempts
<param name="max-login-attempts" value="3"/>
digit-timeout
<param name="digit-timeout" value="10000"/>
max-record-len
<param name="max-record-len" value="300"/>
tone-spec
<param name="tone-spec" value="%(1000, 0, 640)"/>
play-new-messages-key
<param name="play-new-messages-key" value="1"/>
play-saved-messages-key
<param name="play-saved-messages-key" value="2"/>
main-menu-key
<param name="main-menu-key" value="0"/>
config-menu-key
<param name="config-menu-key" value="5"/>
record-greeting-key
<param name="record-greeting-key" value="1"/>
choose-greeting-key
<param name="choose-greeting-key" value="2"/>
record-name-key
<param name="record-name-key" value="3"/>
record-file-key
<param name="record-file-key" value="3"/>
listen-file-key
<param name="listen-file-key" value="1"/>
save-file-key
<param name="save-file-key" value="2"/>
delete-file-key
<param name="delete-file-key" value="7"/>
undelete-file-key
<param name="undelete-file-key" value="8"/>
email-key
<param name="email-key" value="4"/>
pause-key
<param name="pause-key" value="0"/>
restart-key
<param name="restart-key" value="1"/>
ff-key
<param name="ff-key" value="6"/>
rew-key
<param name="rew-key" value="4"/>
odbc-dsn
This option allows you to override the default sqlite with an ODBC handle. You can use any valid DSN from your odbc.ini to store your voicemail configuration
<param name="odbc-dsn" value="dsn:user:pass"/>
record-silence-threshold
This parameter defines an 'energy level', it is a numeric value of how "quiet" the channel is.
See [[Misc. Dialplan Tools wait_for_silence#Description|DP Tool 'wait_for_silence']] for more info.
<param name="record-silence-threshold" value="200"/>
record-silence-hits
This parameter defines how many consecutive hits below record-silence-threshold it takes to end the recording.
See [[Misc. Dialplan Tools wait_for_silence#Description|DP Tool 'wait_for_silence']] for more info.
<param name="record-silence-hits" value="2"/>
email-from
Setting this value will set the from address on the email sent
<param name="email-from" value="${voicemail_account}@${voicemail_domain}"/>
db-password-override
If db-password-override=true, the db password will only be used if present, if not present fallback to the xml config file vm-password. By default, both values in voicemail db and xml config file work.
<param name="db-password-override" value="false"/>
dbname
If you want to have a non-standard location for the sqlite3 db, you can specify a different location for the profile.
<param name="dbname" value="/dev/shm/voicemail_default.db"/>
allow-empty-password-auth
If allow-empty-password-auth=false, it will disable login via a authentication method if there is no password set in the user account (This wont affect voicemail_authorize=true login)
<param name="allow-empty-password-auth" value="true"/>
auto-playback-recordings
<param name="auto-playback-recordings" value="true"/>
Database Schema
This will be automatically created by FreeSWITCH if it does not already exist.
Voicemail Message Settings
-- #### Voicemail Message Settings #### --
CREATE TABLE voicemail_msgs (
created_epoch INTEGER, -- when this voicemail message was created
read_epoch INTEGER, -- when this voicemail message was read, '0' means its unread
username VARCHAR(255), -- recipient's username
domain VARCHAR(255), -- recipient's domain
uuid VARCHAR(255), -- call uuid which created this voicemail message
cid_name VARCHAR(255), -- sender caller-id name
cid_number VARCHAR(255), -- sender caller-id number
in_folder VARCHAR(255), -- voicemail box folder name
file_path VARCHAR(255), -- physical path to voicemail message on disk
message_len INTEGER, -- length of voiemail message in seconds
flags VARCHAR(255), -- voicemail message status, 'save' (saved message) | 'delete' (deleted message) | ' ' (normal message)
read_flags VARCHAR(255), -- voicemail message priority, 'A_URGENT' | 'B_NORMAL'
forwarded_by VARCHAR(255) -- n/a
);
Voicemail User Preferences
-- #### Voicemail User Preferences #### --
CREATE TABLE voicemail_prefs (
username VARCHAR(255), -- voicemail user's name
domain VARCHAR(255), -- voicemail user's domain
name_path VARCHAR(255), -- named path of user defined greeting file (see [[#vm_prefs]])
greeting_path VARCHAR(255), -- physical path to user defined greeting file (see [[#vm_prefs]])
password VARCHAR(255) -- voicemail user's password
);
create index voicemail_msgs_idx1 on voicemail_msgs(created_epoch);
create index voicemail_msgs_idx2 on voicemail_msgs(username);
create index voicemail_msgs_idx3 on voicemail_msgs(domain);
create index voicemail_msgs_idx4 on voicemail_msgs(uuid);
create index voicemail_msgs_idx5 on voicemail_msgs(in_folder);
create index voicemail_msgs_idx6 on voicemail_msgs(read_flags);
create index voicemail_msgs_idx7 on voicemail_msgs(forwarded_by);
create index voicemail_msgs_idx8 on voicemail_msgs(read_epoch);
create index voicemail_msgs_idx9 on voicemail_msgs(flags);
create index voicemail_prefs_idx1 on voicemail_prefs(username);
create index voicemail_prefs_idx2 on voicemail_prefs(domain);
API
vm_boxcount
vm_boxcount can be called from console, xml_rpc or any other interface that exposes FreeSWITCH API.
The function takes the following arguments:
[profile/]<user>@<domain>[|[new|saved|new-urgent|saved-urgent|all]]
and defaults to "new" voicemails and to the "default" voicemail profile.
Examples:
vm_boxcount myprofile/0001@my.domain.com|new
vm_boxcount 0001@default|saved (defaults to "default" voicemail profile)
voicemail_inject
<user>@<domain>[@<profile>] <sound_file> [<cid_num>] [<cid_name>]
voicemail_inject is used to add an arbitrary sound file to a users voicemail mailbox.
vm_prefs
Syntax:
vm_prefs [profile/]<user>@<domain>[|[name_path|greeting_path|password]]
vm_prefs is used to check the preference changed by user
<br>
Example:
vm_prefs 1000@192.168.15.186|name_path|greeting_path|password
Output:
/etc/freeswitch.trunk/storage/voicemail/default/192.168.15.186/1000/greeting_1.wav:/etc/freeswitch.trunk/storage/voicemail/default/192.168.15.186/1000/recorded_name.wav:9999
Example:
vm_prefs 1000@192.168.15.186|greeting_path
Output:
/etc/freeswitch.trunk/storage/voicemail/default/192.168.15.186/1000/greeting_1.wav
vm_list
Syntax:
vm_list <id>@<domain>[/profile] [xml]
vm_list is used to get list of all the voicemails for the user
Example
vm_list 1000@192.168.15.186
1303500797:1303501043:1000:192.168.15.186:inbox:/etc/freeswitch.trunk/storage/voicemail/default/192.168.15.186/1000/msg_051dfd52-3318-4edc-b2ac-ba4d66dd55da.wav:051dfd52-3318-4edc-b2ac-ba4d66dd55da:Extension 1001:1001
Example
vm_list 1001@192.168.0.207 xml
<voicemail>
<message>
<created_epoch>1308582141</created_epoch>
<read_epoch>0</read_epoch>
<username>1001</username>
<domain>192.168.0.207</domain>
<folder>inbox</folder>
<path>/usr/share/freeswitch/storage/192.168.0.207/1001/msg_ae850faa-1661-4245-a551-3a8c5154fe1b.wav</path>
<uuid>ae850faa-1661-4245-a551-3a8c5154fe1b</uuid>
<cid-name>TheCaller</cid-name>
<cid-number>1001</cid-number>
<message-len>28</message-len>
</message>
</voicemail>
vm_delete
Syntax:
vm_delete <id>@<domain>[/profile] [<uuid>]
vm_read
Syntax:
vm_read <id>@<domain>[/profile] <read|unread> [<uuid>]
Advanced API
This advanced API was introduced in Apr 2011. It provides for configuring voicemail as well as the retrieval of voicemail related information. Using this api avoids needing to access voicemail_defaults.db directly. It was created for use with [[Mod_voicemail_ivr]], and was as well used in some GUI implementations.
This is also the base reference API for future [[Mod_voicemail_ivr]] improvement.
vm_fsdb_pref_password_set
Syntax
vm_fsdb_pref_password_set <profile> <domain> <userid> <new-password>
Sets the mailbox password
vm_fsdb_pref_greeting_set
Syntax
vm_fsdb_pref_greeting_set <profile> <domain> <userid> <slot> [file-path]
Sets the file in file_path as the current greeting in voicemail_prefs table (voicemail_defaults.db)
<need to determine the slot parameter action>
The voicemail_prefs table is updated to reflect the currently active greeting
Returns -ERR if the file is not present
vm_fsdb_pref_recname_set
Syntax
vm_fsdb_pref_recname_set <profile> <domain> <user> <file-path>
Sets or updates (if there is already a name file path) the file in file-path as the current name recording in voicemail_prefs
returns -ERR if the file is not present
vm_fsdb_msg_list
Syntax
vm_fsdb_msg_list <format> <profile> <domain> <user> <folder> <filter>
<format> is ignored but must be present
<folder> For future implementation but must be present
<filter> If none specified, then all messages are returned. Support the following filter :
* not-read
* new
* save
Example:
freeswitch@default> vm_fsdb_msg_list 0 default mydomain.com 1000 0 new ASC
Returns the list of unread messages for the user@domain for Inbox in JSON format
This function returns only New messages so it is not a full replacement for vm_list
vm_fsdb_msg_email
Syntax
vm_fsdb_msg_list <profile> <domain> <user> <uuid> <email address>
Example:
freeswitch@default> vm_fsdb_msg_email default mydomain.com 1000 1dfdc31c-7615-4e54-bfbc-dadacc3e5807 me@myemail.com
vm_fsdb_msg_purge
Syntax
vm_fsdb_msg_purge <profile> <domain> <user>
This function purges voicemails marked as Delete for the user@domain
Returns -OK or -ERR (if missing a parameter or profile not found)
vm_fsdb_msg_delete
Syntax
vm_fsdb_msg_delete <profile> <domain> <user> <uuid>
Deletes the message specified by uuid for user@domain
returns -OK or -ERR (if missing parameter or profile not found)
vm_fsdb_msg_save
Syntax
vm_fsdb_msg_save <profile> <domain> <user> <uuid>
Marks the file specified by uuid for user@domain to 'save'
Returns -OK or -ERR if missing a parameter or profile not found
vm_fsdb_msg_undelete
Syntax
vm_fsdb_msg_undelete <profile> <domain> <user> <uuid>
Clears the flags field (regardless of whether it was 'delete' or not)
Returns -OK or -ERR if missing a paramter or profile is not found
vm_fsdb_auth_login
Syntax
vm_fsdb_auth_login <profile> <domain> <user> <password>
password is assumed to be 64 chars or less
Seems to verify that the password in voicemail_prefs is same as in xml?????
Returns -OK or -ERR if:
#missing parameters or profile not found
#password in voicemail_prefs doesn't match password passed in call
#password in xml does not match password passed in call
#"Login Denied" if vm is disabled
If a password exists in voicemail_prefs, it is used in preference to xml
vm_fsdb_msg_get
Syntax
vm_fsdb_msg_get <format> <profile> <domain> <user> <uuid>
<format> is ignored but must be present
Returns a JSON formatted list detailing the VM
or -ERR if missing parameters or profile is not found
Assumes that the uuid can exist in more than 1 row of voicemail_msgs
vm_fsdb_msg_count
Syntax
vm_fsdb_msg_count <format> <profile> <domain> <user> <folder>
Returns a count of the number of read and unread VM's in the Inbox folder for this user@domain
Counts are returned in JSON format for
VM-Total-New-Messages
VM-Total-New-Urgent-Messages
VM-Total-Saved-Messages
VM-Total-Saved-Urgent-Messages
(VM's in other folders are not counted but includes VM's marked as delete or save)
Returns -ERR if missing a parameter or if profile is not found
FAQ
How do I reload new configuration without restarting FreeSWITCH?
If you happened to change settings in autoload_configs/voicemail.conf.xml and would like to make it effective without restarting FreeSWITCH, enter the following command in console mode in sequence:
reloadxml
reload mod_voicemail
Do I need a text-to-speech engine installed?
No, it will work with sound files or a text-to-speech engine.
How do I install sound files?
make sounds-install
Voicemail Voice Prompt / Troubleshooting Problems
Unfortunately mod_voicemail does not have a great ability to be debugged, even with logging turned up tracking down errors can be tricky and an incorrect config upgrade can leave you without working voicemail. Make sure that dialed_extension is SET and exported (you can use the info app to verify) as if this variable is not set voicemail will most likely not be working for you.
If you encounter a problem where the voice mail prompts are either missing, or fail to play with this error on the console:
switch_ivr_phrase_macro() Macro [voicemail_config_menu] did not match any patterns
or
Can't find macro
This is caused by a missing voicemail prompt sound file or invalid conf/lang files.
You will need to perform the corrective command below in the FreeSWITCH source directory:
make vm-sync
After you run the make vm-sync, you'll need to do a reloadxml at the FreeSWITCH console, or restart FreeSWITCH. If the error is in certain xml files then this may not fix it, try to temporarily replace your conf/lang folder with that from trunk (or the base install).
If you've installed french sound files, you have to do the following:
* rename `conf/lang/fr/ca/vm/sounds.xml` to `conf/lang/fr/ca/vm/tts.xml`
* copy `conf/lang/en/us/vm/sounds.xml` to `conf/lang/fr/ca/vm/sounds.xml`
How to update keys for accessing voicemail from outside?
You need to edit the /<path to freeswitch>/conf/autoload_configs/voicemail.conf.xml file.
<param name="login-keys" value="0"/>
-Key to prompt the voicemail's password
<param name="vmain-key" value="*"/>
-Key to prompt the voicemail's UserID
<br><br>
The login-keys param is the key to prompt the password, while the vmain-key is the key to prompt the UserID.
How can I disable remote login/access to voicemail?
Set the following two params in autoload_configs/voicemail.conf.xml:
<param name="vmain-key" value="a"/>
<param name="login-keys" value="a"/>
Can I share voicemail boxes between multiple phones/users?
To Monitor Voicemail
There are 2 ways to do this, the correct way would be to use the subscribe feature of your phone to monitor a particular mailbox
1. SUBSCRIBE feature method
: The phones in question all need to support using SUBSCRIBE to monitor their mailbox.<br/>
: Phones that use other methods (ie. gratuitous/parasitic "NOTIFY" style) will not work.<br/>
: Other concerns you may face include: whether you can configure the extension dialed when you press the 'retrieve' button.<br/>
: This configuration tested successfully on two SNOM 320 handsets, but fails on the Cisco 7960 because it does not use SUBSCRIBE.<br/>
SNOM 320 configuration
This configuration tested with firmware 7.1.30 and newer.<br/>
* Under 'Identity-->Login', set Mailbox to the shared box number.
2. Force MWI Info in Sofia
: To populate the param MWI-Account of the directory user (or domain) with user@domain of the voicemail you want to monitor.
: This will force sofia to send the MWI info for that mailbox even if you registred for another phone. This method only allow you to monitor mailbox
<param name="MWI-Account" value="1000@$${domain}"/>
To Receive Voicemail
''receiving voicemail into the shared mailbox (e.g. when no answer)''
In each user's directory entry, add a variable named 'mailbox' that looks like this:
<variable name="mailbox" value="1500"/>
This sets the stage for which mailbox they're actually going to use, shared or not.. it is used ONLY in the dialplan.
Change your dialplan to reflect this:
The old entry:
<action application="voicemail" data="default ${domain_name} ${dialed_extension}"/>
The new entry:
<action application="voicemail" data="default ${domain_name} ${user_data(${dialed_extension}@${domain_name} var mailbox)}"/>
Voicemail Callback
''calling back a caller while checking voicemail''
When a user is listening to voicemail messages - they are able to dial '5' and be connected to the caller of that voicemail.
You are able to control the dial plan execution of this callback method by modifying the vm_callback.xml file located under BASE_FREESWITCH_DIR/conf/dialplan
An example vm_callback.xml is as follows:
<include>
<context name="vm_callback">
<extension name="vm_return_call">
<condition field="destination_number" expression="^(\+1|\+)?(\d+)$">
<action application="info" />
<action application="bridge" data="sofia/vm/+1$2@GATEWAY" />
</condition>
</extension>
</context>
</include>
/usr/bin/python /home/chronos_client/persistent/freeswitch.app/conf/scripts/sendemail.py -l -i -d -f revolutionpbx@chronostelecom.com -t
Transcribing Voicemail
There's no real simple way to do this as of now with mod_voicemail.
If you use Fusionpbx's mailer for FS, then you can intercept the wav file mid-mailing and send it to some sort of API.
NOTE: "Transcription" is the full text, where as IVR speech recognition is to recognize audio vs a specific list of options, "grammar". These are very different things.
The available APIs for some sort of transcription are:
- twilio - 5cents/minute
- voicecloud - 10cents/minute. They seem to have a $250/month minumum.
- tropo - 3 cents/minute I think (60 second billing) BUT they need to record the file, on their system. They have all-SIP plans with alternate billing.
- quicktate - $0.0175/word, volume at 1.10cents/word. Avg of 160 words per minute = $2.80/minute.
- mycaption - 9c/minute for purely machine-based.
- mycaption - 43c/minute upto 55c/minute - 15 second increments -premium that combines machine-based speech recognition with error correction by human editors.
- Google speech API - free, but it's not that great as of right now. Some info on how to access it here.
- Add this to FusionPBX's voicemail mailer with the code from AviMarcus
Here is a script you can use for tinkering with Google Speech API:
Google Speech API
#!/bin/sh
echo "1 SoX Sound Exchange - Convert WAV to FLAC with 16000"
sox $1 message.flac pad .1 0 rate 16k
echo "2 Submit to Google Voice Recognition"
wget -q -U "Mozilla/5.0" --post-file message.flac --header="Content-Type: audio/x-flac; rate=16000" -O - "http://www.google.com/speech-api/v1/recognize?lang=en-us&client=chromium" > message.ret
echo "3 SED Extract recognized text"
cat message.ret | sed 's/.*utterance":"//' | sed 's/","confidence.*//' > message.txt
echo "4 Remove Temporary Files"
rm message.flac
# rm message.ret
echo "5 Show Text "
cat message.txt
Example:
./googlevoice.sh /usr/local/freeswitch/sounds/en/us/callie/ivr/8000/ivr-one_more_mistake.wav 1 SoX Sound Exchange - Convert WAV to FLAC with 16000 2 Submit to Google Voice Recognition 3 SED Extract recognized text 4 Remove Temporary Files 5 Show Text that's odd 1 more mistake and I will hang up on your ass
It should be "that's it" instead of "that's odd" but otherwise Google actually got it right. Try other sound prompts.
Comments:
there are few useful variables for skipping post messages: skip_record_urgent_check and skip_record_check |
---|