Thursday, 17 May 2007

SMS Alerts from Salesforce [3] - Send an SMS

I've realised two things writing this series of posts.

  1. I need a different template if I'm going to include code samples
  2. My blog host does not support uploading source code and projects for download

So, once I've complete this project, I'll collate it all and summarise it as a Code Project article. I'll post the link when I'm done.

So back to the matter at hand. We've completed the setup of the various elements, time to start tying them together. Today's post focuses on developing the code in the notifications method of the CaseAlert web service.

The first step is to retrieve the Case object passed through to the notification

CaseNotification caseNotification = (CaseNotification)notifications1.Notification[0];
Case caseItem = (Case)caseNotification.sObject;

I then setup the binding to the Salesforce API using a proxy I made earlier from the Salesforce WSDL. I passed in the Session ID contained with the notification. One gotcha, you have to specify the Url value which should be passed in by the calling service. This meant I had to add it in to the test harness application.

sforce.SforceService salesforceBinding = new sforce.SforceService();
salesforceBinding.SessionHeaderValue = new sforce.SessionHeader();
salesforceBinding.SessionHeaderValue.sessionId = notifications1.SessionId;
salesforceBinding.Url = notifications1.EnterpriseUrl;

Now I'm getting a lightweight Account object containing just the Name and OwnerID for the account. If you're new to the Salesforce API this retrieval of objects by specifying the fields and object type along with the ID can seem a bit arcane. It's actually really useful as by keeping the interface generic it allows you to request custom fields as well as those that are inbuilt.

sforce.sObject[] ret = salesforceBinding.retrieve("OwnerId,Name", "Account", new string[] { caseItem.AccountId });
sforce.Account caseAccount = (sforce.Account)ret[0];

Doing the same this time with the User object which corresponds to the Owner of the account.

ret = salesforceBinding.retrieve("MobilePhone", "User", new string[] { caseAccount.OwnerId });
sforce.User accountOwner = (sforce.User)ret[0];

The SMS message body is constructed using the data retrieved in the previous steps. If you want to include different parameters then just get more fields the Account and Owner objects.

string messageBody = string.Format("Your account {0} has opened a new Case ref:{1}. Call support on 0845 356 5759 for details", caseAccount.Name, caseItem.CaseNumber);

Now the really easy bit ;) sending an SMS. For this code snippet I've create a web reference called esendex to the SendService of the Esendex XML Web Service. You will need to have an account with us and enter the appropriate credentials to use this code as is. If you haven't got an account yet, then feel free to setup a trial.

esendex.MessengerHeader header = new esendex.MessengerHeader();
header.Account = "EX0000000";
header.Username = "user@company.com";
header.Password = "xxxxxxx";
esendex.SendService sendService = new esendex.SendService();
sendService.MessengerHeaderValue = header;
sendService.SendMessage(accountOwner.MobilePhone, messageBody, esendex.MessageType.Text);

Return a ACK response back to the calling service.

return new notificationsResponse();

Would you believe it, it worked first time! Well, after I'd set the EnterpriseURL property in the test client.

Next time I'm going to setup the workflow rule in Salesforce and see if the whole thing hangs together.

No comments: