January 29, 2008

A quick and dirty way to know current locale's decimal separator

Those who work with locales, where decimal separator is not a "." might have ran into issues doing calculations in script. From what I've seen, developers usually hard-code replacements for their local decimal separator to be substituted with a ".", which is expected by the script.

Let's assume you are parsing an XML file and you need to do some calculations:

   1:  'Let's assume your locale's decimal separator is a comma
   2:  strSomeValue = "3.1415" 'the value retrived from xml
   3:  'Now let's assume you need to multiply it by 2
   4:  result = strSomeValue * 2 'result is 62830

The problem is that script does not recognize "." as a decimal separator in a string if your locale's separator is different. Certainly, you can replace "." in your strings with your decimal separator (e.g. ","), but what if you don't know the decimal separator at design time? A quick and easy way to figure out what the current locale's decimal separator is: divide 1 by 2 (we know that if we convert this division result to string, a decimal separator would be the second character). Here's a handy function that can be used in scripts:

   1:  Public Function GetDouble(strNumeric)
   2:      strDecSep = Mid(CStr(1/2),2,1)
   3:      strNumeric = Replace(strNumeric, strDecSep, ".")
   4:      If IsNumeric(strNumeric) Then 
   5:          GetDouble = CDbl(strNumeric)
   6:      Else
   7:          GetDouble = 0.00
   8:      End If
   9:  End Function

January 10, 2008

Switchvox new voicemail email -> SMS notification

Switchvox offers a wonderful email notification feature for new voicemail messages, but what if you are not at your computer? Naturally, the first thing that comes to mind is to forward those email notifications to your cell-phone via SMS.


Email notification sent by the PBX looks approximately like the one below:

From: SwitchvoxPBX
Sent: Thursday, January 10, 2008 2:42 PM
To: John Doe
Subject: New message 8 in mailbox 102

Dear John Doe:

Just wanted to let you know you just received a 0:02 long message (number 8) in mailbox 102 from "MARY JANE" <18001234567>, on Thursday, January 10, 2008 at 02:42:04 PM so you might want to check it when you get a chance.

You can check your message via the phone or use the links below to download your message:

Use the link below to just download the voicemail.
*Note* This does not mark it as read in the system.
https://SwitchvoxPBX/main?cmd=play_voicemail&msgnum=1

Use this link below to download the voicemail and mark it as read.
*Note* This will move this voicemail message to your Old folder and this link will no longer work.
https://SwitchvoxPBX/main?cmd=play_voicemail&msgnum=1&mark=read

Use this link below to download the voicemail and delete it.
*Note* This will completely remove the voicemail from the system and this link will no longer work.
https://SwitchvoxPBX/main?cmd=play_voicemail&msgnum=1&mark=delete

Thanks!

The quick and dirty way to forward this to your cell-phone is by using Outlook’s rules: this would simply forward the message to your cell-phone’s email address (most wireless providers offer this feature). However, all you will get is most likely part of the message that ends with words “… received message (number 8) in mailbox”, because SMS message has a limit on the number of characters (sender’s email, subject will also be included and will eat up characters. Isn’t it frustrating? You receive SMS notification about new voicemail, but you don’t know who called, when, and if they actually left a message, or hung up realizing you are not there, because the message got trimmed due to character limit.

If you look at the Outlook’s rule actions, you might notice “run a script” option, which is triggered when rule conditions are true, and this is exactly what I need: grab a message, take only the information I need and send it to my cell-phone.

So, launch your Outlook if it is not already running and hit Alt-F11 or go to Tools > Macro > Visual Basic Editor and paste the following script:

   1:  Public Sub ForwardSMS(Item As MailItem)
   2:      ' Do not run during business hours
   3:       If Time() < #8:00:00 AM# Or Time() > #5:00:00 PM# Then
   4:      ' Check to make sure it is an Outlook mail message, otherwise
   5:      ' subsequent code will probably fail depending on what type
   6:      ' of item it is.
   7:      If TypeName(Item) = "MailItem" Then
   8:          Dim msgBody As String : msgBody = Item.Body
   9:          Dim oRegExp, oMatches, oMatch, strDuration, strMsgNumber, strMsgInfo, strResult
  10:          strResult = ""
  11:          Set oRegExp = CreateObject("VBScript.RegExp")
  12:          oRegExp.Pattern = ".*\n\s*.*you just received a (.*) long message \(number ([\d:]*)\) in mailbox \d\d\d from (.*) so you might want to check it.*"
  13:          Set oMatches = oRegExp.Execute(msgBody)
  14:          For Each oMatch In oMatches
  15:          If oMatch.SubMatches.Count = 3 Then
  16:                  strDuration = oMatch.SubMatches(0)
  17:                  strMsgNumber = oMatch.SubMatches(1)
  18:                  strMsgInfo = oMatch.SubMatches(2)
  19:              strResult = strResult & "Message number " & strMsgNumber & " (" & strDuration & ") received from " & strMsgInfo & VbCrLf
  20:          Else
  21:              strResult = strResult & oMatch.Value & vbCrLf
  22:          End If
  23:          Next
  24:          Set oMatches = Nothing
  25:          Set oRegExp = Nothing
  26:          
  27:          Dim oEmail As Object
  28:          Set oEmail = Application.CreateItem(olMailItem)
  29:          oEmail.Body = strResult
  30:          oEmail.Recipients.Add "1234567@my_wireless_provider.com"
  31:          oEmail.Send
  32:          Set oEmail = Nothing
  33:        End If
  34:        End If
  35:  End Sub

Customize if necessary. Few notes:

  1. Line 3 checks for business hours (so that script runs only when you are away from the computer). In case you want the script to always do its job, then remove line 3 and the corresponding line 34.
  2. Line 12 has a regular expression to get only required information from notification email's body. Change the expression if your notification text is different from the one displayed at the beginning of this post.
  3. Line 30 specifies email address of your cell-phone. You can also create a contact in Outlook (with the needed email) and instead of specifying email address in the script, you can specify contact's name here.

Close the Visual Basic Editor. Then go to Tools > Rules and Alerts in your Outlook to create a rule, that would take notification messages from your Switchvox PBX and then select “run a script” for the rule’s action. When you click on the word ‘script’, a dialog box should pop up, showing the list of scripts. Select ForwardSMS (script’s name is specified in line 1 in the code above). Please note, that this is a client-side rule. This means that Outlook must be running for the rule and script to work!

Now, when you receive your next notification email, the rule you created should trigger the script. As a result, you will receive SMS message on your cell-phone which would look like this:

johndoe@domain.com Message number 8 (0:02) received from "MARY JANE" <18001234567>, on Thursday, January 10, 2008 at 02:42:04 PM

Now, when you get such SMS it is clear who called, when, and that the person didn't actually leave a message (very short duration time is a hint).

Hope someone will find this useful :-)

UPDATE: As it was pointed out in the first comment to this post, Switchvox SMB allows you to achieve the described behavior (custom notifications) via bult-in functionality. However, the one used in our office is a Switchvox SOHO, which apparently does not offer the Custom Voicemail Message Notification.