Setting up shared voicemail on Asterisk – part 2

Part 1 laid the foundations for creating and accessing a shared voicemail box. In this, part 2, I explain how the lamp on the BLF key is switched on and off to show there are messages waiting in the shared box. Note that this is separate from any existing MWI lamp used for personal voicemail. It uses a custom device state within Asterisk switched by an external application. The external application in this case is a bash script that is called by another part of Asterisk using the externnotify option of the voicemail module.

Setting externnotify to call an external application

Edit the file /etc/asterisk/voicemail.conf and search for the parameter externnotify. In the sample file it is usually commented out – remove the comment character. If it is not already in the file, just add it as a new line. It is located in the [general] section. We require it to be like this:

externnotify=/usr/bin/groupmwi.sh

Creating the script run by externnotify

Using your favourite editor, create a new file in /usr/bin and name it groupmwi.sh

Copy and paste the following lines into the file and save it.

#!/bin/sh
#
# Control script to change the status of a custom device state in Asterisk
# Called from Asterisk whenever a voicemail message is left
#
VM_CONTEXT=$1
EXTEN=$2
VM_COUNT=$3

ASTCMD="/usr/sbin/asterisk -rx"

if [ $EXTEN -ne 4444 ]; then
    exit 0
fi

if [[ $VM_COUNT = "0" ]]; then
    logger -t groupmwi "Switching OFF Group mailbox message"
    $ASTCMD "originate Local/s@groupmwi-off extension 4@default"
else
    logger -t groupmwi "Switching ON Group mailbox message"
    $ASTCMD "originate Local/s@groupmwi-on extension 4@default"
fi

exit 0

Set the file as executable using the Linux command chmod 755 /usr/bin/groupmwi.sh

What does the script do?

Writing scripts called by externnotify is already documented elsewhere, so I will not repeat it all here. Just check these links if you are interested in the general principles of operation:

http://www.voip-info.org/wiki/view/Asterisk+config+voicemail.conf

http://asterisk.mdaniel.net/2006/12/06/mwi-notification/

The specific script we are using here simply checks if there are any new messages in box 4444. If the box is not 4444, it exits and does nothing. For box 4444, it executes a small section of Asterisk dialplan code using the originate command. If there are messages in the box it executes some dialplan commands in a context called groupmwi-on and if there are no messages it executes the code in groupmwi-off. As well as executing the dialplan commands, it also writes a line of text to the system log file to assist with debugging (see the lines starting logger -t).

Adding the status switching code to your dialplan

Generally, Asterisk dialplans are stored in the file /etc/asterisk/extensions.conf. However, if you are using Trixbox or some other FreePBX variant, then you must not directly edit extensions.conf. Instead, you will need to edit the file /etc/asterisk/extensions_custom.conf. Just add the following code:

[groupmwi-on]
; Switch custom device state to show group voicemail has messages waiting
exten => _X.,1,Goto(s,1)
exten => s,1,Set(DEVICE_STATE(Custom:groupmwi)=INUSE)
exten => s,2,Noop(New state for groupmwi is ${DEVICE_STATE(Custom:groupmwi)})

[groupmwi-off]
; Switch custom device state to show group voicemail has no messages waiting
exten => _X.,1,Goto(s,1)
exten => s,1,Set(DEVICE_STATE(Custom:groupmwi)=NOT_INUSE)
exten => s,2,Noop(New state for groupmwi is ${DEVICE_STATE(Custom:groupmwi)})

See this companion article for more detailed information about using Custom Device States.

Testing the script

First make sure the subscription request from the programmable BLF key on the phone has been accepted by Asterisk. At the CLI, type the command “sip show subscriptions”. You should see something like this:

Peer         User Call ID  Extension       Last state Type            Mailbox
192.168.1.57 4444 3903f2c8 974444@from-int Idle       dialog-info+xml <none>
1 active SIP subscription

If you cannot see the subscription, try rebooting the IP phone. If it is still not there, check that the phone is registering ok and check the settings on the BLF key as explained in part 1. Make sure you defined the hint and added it in the right place – can you see it when you type “core show hints” at the CLI?

Assuming the subscription has worked ok, you can test that the bash script is able to turn on and turn off the BLF lamp, by calling the script directly from the Linux command prompt. To turn the lamp on:

/usr/bin/groupmwi.sh default 4444 2

To turn the lamp off:

/usr/bin/groupmwi.sh default 4444 0

And finally…

It should all be working now. The lamp comes on when new messages are waiting and goes off when they have been checked or deleted. You can access the voicemail box by pressing the BLF button and entering the mailbox password when prompted (I suggested 1471 as the password in part 1).

Now you can see how to control a BLF lamp using a custom device state that is switched by an external program, you will probably be able to think of many other useful applications using the same mechanism. Please remember to leave comments and to vote if you found the article useful. Remember too that Smartvox can provide expert assistance with setting up large or small Asterisk applications and with the OpenSIPS SIP proxy server and with the design of resilient VoIP and ITSP infrastructure – call John on +44 1727 221221 or email us at info(at)smartvox.co.uk.

16 thoughts on “Setting up shared voicemail on Asterisk – part 2”

  1. I liked your guide very nice. I wanted two BLF keys for two different shared mailboxes so created a new custom state called mwi and one called groupmwi in my extensions_custom.conf

    and modified the groupmwi.sh script like this

    #!/bin/sh
    #
    # Control script to change the status of a custom device state in Asterisk
    # Called from Asterisk whenever a voicemail message is left
    #
    VM_CONTEXT=$1
    EXTEN=$2
    VM_COUNT=$3
    
    ASTCMD="/usr/sbin/asterisk -rx"
    
    if [ $EXTEN -eq 400 ];
    then
            if [[ $VM_COUNT = "0" ]];
            then logger -t groupmwi "Switching OFF Group mailbox message"
            $ASTCMD "devstate change Custom:groupmwi NOT_INUSE"
                    else
                            logger -t groupmwi "Switching ON Group mailbox message"
                            $ASTCMD "devstate change Custom:groupmwi INUSE"
            fi
    else
            if [ $EXTEN -eq 401 ];
            then
                    if [[ $VM_COUNT = "0" ]]; then
                    logger -t mwi "Switching OFF Group mailbox message"
                    $ASTCMD "devstate change Custom:mwi NOT_INUSE"
                            else
                                    logger -t mwi "Switching ON Group mailbox message"
                                    $ASTCMD "devstate change Custom:mwi INUSE"
                    fi
            else
                    exit 0
            fi
    fi
    exit  0
  2. Hey guys… this was a great tutorial and looks like I have everything in place that I need, but the light doesn’t turn on and off. Almost like the externnotify isn’t working – Should i be seeing the script execute if I’m in the Asterisk CLI when I leave a message? I see all the other commands scrolling by but nothing about the groupmwi.sh running. Also the script requires input, don’t we have to specify that in the externnotify= section or does Asterisk add them automatically?

    • JD, Asterisk automatically adds the three input parameters when it calls the specified externnotify script. (You only need to add them when running the script manually). To identify where the problem, please try running the script directly from the Linux command prompt as described towards the end of the article. Depending on the result, do one of the following:
      Case 1: If the lamp does not change when you run the script manually
      I suggest you change the groupmwi.sh script, as suggested by Phil Wherry and then explained in my reply to Kevin in the comments below, so it uses
      $ASTCMD “devstate change Custom:groupmwi NOT_INUSE”
      $ASTCMD “devstate change Custom:groupmwi INUSE”
      Phil’s method is simpler than my solution (using originate) and so is less error prone.

      Case 2: If the lamp does change when you run the script manually
      Check very carefully the changes made to the file /etc/asterisk/voicemail.conf
      These are described near the start of this part of this article.
      Check if anything was written to /var/log/messages. That is the purpose of including the lines in the script like
      logger -t groupmwi “Switching OFF Group mailbox message”
      If you are not using voicemail box 4444, have you changed the test at the start of the script so it checks for the right voicemail box number?
      if [ $EXTEN -ne 4444 ]; then
      exit 0
      fi

      John

  3. Is there a way to have the blf light switch if an agent is paused from a queue when they are autopaused (due to them not answering or being paused by a supervisor?) I can have the agent pause themselves through a blf key and the light changes. Any help would be appreciated.

    • I would do it by writing an application that connects to Asterisk through the AMI (Asterisk Management Interface) and registers for Agent Status Events. The application would then receive a QueueMemberPaused event which could change the status of a custom device state using the techniques described in this article.

  4. This article (and the comment(s) after from Phil) have ended a longer than 2 year journey of mine to make BLF and DEV STATE happen. I am so happy. Using a Grandstream or Yealink phone with a BLF to check addtional (other) voicemail boxes is 100% operating now.

    Thank you so much!

    • Phil is suggesting that, in the script file I called groupmwi.sh, instead of:
      $ASTCMD “originate Local/s@groupmwi-off extension 4@default”
      you could use
      $ASTCMD “devstate change Custom:groupmwi NOT_INUSE”

      Similarly, instead of:
      $ASTCMD “originate Local/s@groupmwi-on extension 4@default”
      you would use
      $ASTCMD “devstate change Custom:groupmwi INUSE”

      The advantage of doing the above is that you then no longer require the two new contexts in the dial plan that I described under the heading “Adding the status switching code to your dialplan”, so his solution is shorter and less complex.

      John

  5. Very helpful. One note: it’s not necessary to jump through hoops with the dialplan to set device state from a script. Instead, use something like:

    asterisk -rx “devstate change Custom:groupmwi INUSE”

    • You should add Hangup otherwise it will fall on next context

      ; Retrieve messages from the group message box by dialling 974444
      exten => 974444,1,Answer
      exten => 974444,2,VoicemailMain(4444@default)
      exten => 974444,3,Hangup
      ; Add hint to link to the Custom Device State
      exten => 974444,hint,Custom:groupmwi

      • Piero,
        It would do no harm to add the hangup, but is not normally required because there are no more steps in this context for extn 974444 so it will stop anyway (unless you have a non-default setting for autofallthrough).

        I do not believe Asterisk will ever go from one context to another unless explicitly instructed to do so, using a Goto.
        John

Comments are closed.