Kannel Integration With Exchange

After this post you might be thinking I’m a one-trick pony when it comes to Kannel, but I promise to move on. I just get all these fun (and sometimes useless) ideas along the way :)

In a true case of code reuse I took the C# code for sending SMS through Kannel, and made two more implementations.

The less interesting of the two first – in case you are thinking the title is misleading. I created a client for Windows Mobile that will let you – send SMS from your mobile device! Amazing, right? With a really slick interface and everything:
CinnamonMobile

Ok, you’re thinking that must be the dumbest idea ever. Creating an extra application for something that really is simpler to do through the regular interface. Granted, I don’t expect to make a lot of money selling this application, but it was only a simple proof-of-concept, and didn’t take much time to put together.
Things you might want to use it for include:
- Being able to set arbitrary “from” addresses even though you are sending from a device.
- Sending SMS through GPRS (and converted back to SMS for the receiver of course). This might be handy if your mobile operator is gouging you for sending SMS back home when you’re out of the country. (Presuming it comes off cheaper using a data connection that is.) Actually if you put a little effort into it you can create this as a console app that integrates with the regular user interface. This way the user doesn’t notice if the message is sent one way or the other, but you would for instance check whether the device is roaming and act accordingly in the background.
- I tested the app in the emulator running Windows Mobile Classic. So you don’t need a SIM card or a real device to send SMS with this.
- If I extend the app to sending binary SMS messages in the future it might even do something useful that you can’t do with the built-in SMS facilities on the device.

Another application of the code that might be more worthwhile is integration with Exchange. I’m not going to give a lecture of Exchange architecture, or development in general, (because there are a lot of other resources out there, and many more knowledgable than me), but with Exchange 2007 it’s easy to extend some of the core functionality in Exchange. All mail that is sent through an Exchange server passes through the Hub Transport role, and possibly the Edge role if you are using that. This is where different rules are applied to the mail. For instance throwing out spam, making sure that confidential mail cannot be sent to external recipients, etc. This functionality is implemented as so-called Transport Agents, and if you don’t mind writing some code it’s actually quite simple to create your own agents. (With the definition of simple obviously being dependent on what you are trying to achieve.)

Why not have an agent that will let your Exchange server send out SMS messages based on a set of parameters? For instance tagging a mail as important will send an SMS alert. Mail alerts sent from monitoring systems being converted to SMS instead. Prefixing the subject with “SMS:” for sending it through your Kannel box. You can most likely come up with a good use of your own as well if the above are of no use to your specific scenario.

I’ve created a small example of how this can be done. It’s a “stupid” agent in the sense that it triggers on all mail that is sent, and it has a pre-defined “to address”, and message. You’d probably integrate with AD, and filter the contents in some way if you were to actually use it for something worthwhile on an actual Exchange Server.

I have tested my dll on an Exchange 2010 Beta server, but to my knowledge it should run on Exchange 2007 as well. (RTM & SP1.)

The steps you need to perform are as follows:
Create a new project in Visual Studio. You’ll want a Visual C#->Windows->Class Library. Choose .NET 3.5 if you are testing on Exchange 2010, or .NET 2.0 for Exchange 2007.

Copy off Microsoft.Exchange.Data.Common.dll & Microsoft.Exchange.Data.Transport.dll from your Exchange server to your Visual Studio box. (By default they are located in “C:\Program Files\Microsoft\Exchange Server\V14\Public” on E2K10.) Place it in the “\debug” and/or “\release” folders under your “Projectname\bin” directory.

Add references to your project – more specifically the dll files you just pasted in.

Build your code based on the following sample code, or read more over at MSDN and build from scratch:)

using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Routing;
using System.Net;
using System.IO;

namespace MobilityDojo.CinnamonExch
{
   public class SMSRoutingAgentFactory : RoutingAgentFactory
   {
      public override RoutingAgent CreateAgent(SmtpServer server)
      {
         RoutingAgent myAgent = new SMSAgent();
         return myAgent;
      }
   }
}  

public class SMSAgent : RoutingAgent
{
   public SMSAgent()
   {
      //Trigger whenever a message is submitted
      base.OnSubmittedMessage += 

      new SubmittedMessageEventHandler(SMSAgent_OnSubmittedMessage);
   }

   void SMSAgent_OnSubmittedMessage

   (SubmittedMessageEventSource source, QueuedMessageEventArgs e)
   {
      string kannelServer = "http://kannel";
      string kannelPort = "13000";
      string smsPath = "/cgi-bin/sendsms";
      string username = "";
      string passWord = "";
      string fromAddress = "Exchange";
      string toAddress = "";
      string msgContent = "Hello Exchange";

      string smsPost = kannelServer + ":" + kannelPort + smsPath
         + "?user=" + username + "&pass=" + passWord + "&from="
         + fromAddress + "&to=%2B" + toAddress + "&text=" + msgContent;

      string kannelRes = sendSMS(smsPost);
   }

   string sendSMS(string uri)
   {
      WebRequest kannelRequest = WebRequest.Create(uri);
      kannelRequest.ContentType = "x-www-form-urlencoded";
      kannelRequest.Method = "GET";

      try
      {
         WebResponse kannelResponse = kannelRequest.GetResponse();
         if (kannelResponse == null)
         {
            return null;
         }

         StreamReader sr = 

            new StreamReader(kannelResponse.GetResponseStream());
         return sr.ReadToEnd().Trim();
      }
      catch (WebException ex)
      {
         return ex.ToString();
      }
   }
}

You’ve now got a dll file that can be copied to your Exchange server. You choose the destination folder.

Open up the Exchange Management Shell. There’s a bug in the Exchange 2010 Beta build so you need to open the “Local Powershell” version of the shell. (Does not apply to Exchange 2007.)

Run the following cmdlet:

Install-TransportAgent -Name “CinnamonExch”

-TransportAgentFactory “MobilityDojo.CinnamonExch.SMSRoutingAgentFactory”

-AssemblyPath “C:\myAgent\CinnamonExch.dll”

Install_Agent

Exit the shell, re-enter the shell and enable the agent:

Enable-TransportAgent -Identity “CinnamonExch”

Enable_Agent

Restart the “Microsoft Exchange Transport” service.

Restart_Service

Test it. In my simple agent a mail sent to yourself through OWA should do the trick. (Contents doesn’t matter as I’ve already defined that in the HTTP GET in the code.)

Trigger_Mail

I don’t make any modifications to the original message so the mail should come through as usual with no visible trace client side that an SMS was sent.

Were still doing basic stuff, but you can do some neat stuff nonetheless if you use some imagination. Yes, there are a lot of software out there already that will plug-in to Exchange, custom SMSC integration, and whatnot. Some times it’s cheaper buying off-the-shelf software, but it doesn’t beat the satisfaction it gives to implement it yourself :)

There are no responses yet

Leave a Reply

RSS for Posts RSS for Comments