Twilio Sending SMS from a SharePoint List

The following example can be worked into event receivers, workflow, etc – for simplicity and due to time constraints I used a console application.

For this simple PoC I wanted to send text messages from a SharePoint list, I signed up for a Twilio (https://www.twilio.com/) trial, Twilio offer a very good api for dealing with SMS and voice calls.

I’ve created a new console application and installed two nuget packages:

Install-Package Microsoft.SharePointOnline.CSOM

Install-Package Twilio

The following code assumes you have created a Client Context…

The code below is standard SharePoint code, this deals with getting the data from the list, and populating a dictionary containing the recipients number, and the message to be sent.  I also update the list item so I know it has been processed.

using (var context = new ClientContext(contextWebUrl))
            {
                context.Credentials = new SharePointOnlineCredentials(userName, password);
                Web web = context.Web;
                context.Load(context.Web, w => w.Title);
                context.ExecuteQuery();

                List sms = web.Lists.GetByTitle("SMS");
                context.Load(sms);
                context.ExecuteQuery();

                CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
                ListItemCollection items = sms.GetItems(query);
                context.Load(items);
                context.ExecuteQuery();

                Dictionary<string, string> messageToSend = new Dictionary<string, string>();
                context.Load(items);
                context.ExecuteQuery();

                foreach (ListItem item in items)
                {
                    if (string.Equals(item["Status"], "new"))
                    {
                        context.Load(item);
                        context.ExecuteQuery();
                        messageToSend.Add(item["Title"].ToString(), item["Body"].ToString());
                        item["Status"] = "Sent";
                        item.Update();
                        context.ExecuteQuery();
                    }
                }
          }

The next piece of code deals with sending the messages (this is rough and ready code – purely for a PoC)..

            string AccountSid = "xxxxxxxxxxxxxxxxxxxxxxxx";
            string AuthToken = "xxxxxxxxxxxxxxxxxxxxx";
            var twilio = new TwilioRestClient(AccountSid, AuthToken);

            foreach (var msg in messageToSend)
            {
                var newMsg = twilio.SendMessage("My Twilio Number", msg.Key, msg.Value);
                Console.WriteLine(newMsg.Sid + " " + newMsg.Status);
            }

Once you have a Twilio trial account, you’ll get a phone number, and credentials for interacting with the API.

The next article covers building a web API to receive text messages.

Advertisements

Manually creating ICS files and sending from SharePoint

In a previous post I created Outlook appointments using Microsoft.Office.Interop, a limitation of using this method means MS Outlook is required to be installed on the server.

To avoid this limitation it’s possible to create an Outlook appointment manually and send as an attachment, you still have full control over the content and behaviour of the appointment file, known as a .ICS file.

There are various examples on the web of how to do this, but I struggled to find one that met my exact requirements, my requirements were:

  • Dynamically populate the ICS file with content from a custom webpart within SharePoint.
  • Send the email with attachment using the configuration stored within SharePoint (Outgoing SMTP Server, sender address).
  • Ability for the recipient to accept the invitation, to enable the employee calendar to be updated, with no meeting organiser.

What the code does… Creates a new instance of MailMessage, specifics the SMTP Server, Sender Address, and a couple of other properties.
P.S. I’m not managing garbage collection within this area of code..Also the variable ‘appointment’ is a class that I created to store the variables from the SharePoint webpart.

MailMessage messageContent = new MailMessage();
SPSite site = SPContext.Current.Site;
SPWeb web = site.OpenWeb();
string senderAddress = web.Site.WebApplication.OutboundMailSenderAddress;
string smtpServer = web.Site.WebApplication.OutboundMailServiceInstance.Server.Address;
messageContent.From = new MailAddress(web.Site.WebApplication.OutboundMailSenderAddress);
messageContent.To.Add(new MailAddress("appointment.recipient");
messageContent.Subject = appointment.Subject;
messageContent.Body = appointment.Body;

The next part builds the ICS file as a string. I found these properties by sending meeting invitations to my Gmail account and opening the appointment file in Notepad to understand what parameters I required.

StringBuilder icsBuilder = new StringBuilder();
            icsBuilder.AppendLine("BEGIN:VCALENDAR");
            icsBuilder.AppendLine("VERSION:2.0");
            icsBuilder.AppendLine("PRODID:-//Schedule a Meeting");
            icsBuilder.AppendLine("METHOD:REQUEST");
            icsBuilder.AppendLine("BEGIN:VEVENT");
            icsBuilder.AppendLine(string.Format("DTSAMP:{0:yyyyMMddTHHmmssZ}", DateTime.Now));
            icsBuilder.AppendLine(string.Format("DTSTART:{0:yyyyMMddTHHmmssZ}", appointment.StartDateTime));
            icsBuilder.AppendLine(string.Format("DTEND:{0:yyyyMMddTHHmmssZ}", appointment.EndDateTime));
            icsBuilder.AppendLine("LOCATION:None");
            icsBuilder.AppendLine(string.Format("UID:{0}", Guid.NewGuid()));
            icsBuilder.AppendLine(string.Format("DESCRIPTION", messageContent.Bcc));
            icsBuilder.AppendLine(string.Format("SUMMARY:{0}", messageContent.Subject));
            icsBuilder.AppendLine(string.Format("ORANIZER:MAILTO:{0}", messageContent.From.Address));
if(!string.IsNullOrEmpty(appointment.Body))
icsBuilder.AppendLine(string.Format("X-ALT-DESC:FMTTYPE=text/html:{0}", messageContent.Body));

I couldn’t use the send mail functionality available in SPUtility as I was unable to add attachments, there may be better ways of sending the actually email with the attachments.

Below, I’m using the standard System.Net.Mail functionality:

System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient();
smtpClient.Host = smtpServer;
smtpClient.UseDefaultCredentials = true;
System.Net.Mime.ContentType contentType = new System.Net.Mime.ContentType("text/calendar");
contentType.Parameters.Add("method", "REQUEST");
contentType.Parameters.Add("name", "MeetingAppointment.isc");
AlternateView view = AlternateView.CreateAlternateViewFromString(icsBuilder.ToString(), contentType);
messageContent.AlternateViews.Add(view);
smtpClient.Send(messageContent);

Converting Times (UTC to Local) – SharePoint

Recently came across a scenario using SharePoint 2010, Duet, and SAP. The scenario being when submitting data to SAP from SharePoint any Date/Time fields would be stored in SAP using the local time of the user whom submitted the data. However when the data is sent back to SharePoint, the Netweaver layer converts any Date/Time fields to UTC time.

After a little research found some very useful information on MSDN that handles the conversion of UTC time to local time based on the regional settings of the SPWeb.

Two useful methods included in the SPTimeZone class:

Examples of how to implement the methods are available on MSDN

SPTimeZone Class: http://msdn.microsoft.com/en-us/library/ms464064

Programmatically creating Outlook appointments

Outlook Reference

Found myself needing to learn the basic of using the Microsoft Office API to programmatically creating appointments in Outlook.  The event will be initiated from SharePoint 2010, for various reasons I was unable to use the standard Outlook – SharePoint integration.

In this example I’ll demonstrate the basics of creating an Outlook Appointment…

First step is to add a reference into Visual Studio, Reference: Microsoft.Office.Interop.Outlook.

Once the reference is added you need to create a new Outlook Application, and then instantiate the object type you require, in this example…an Outlook appointment item.

Microsoft.Office.Interop.Outlook.Application outlookApp = new Microsoft.Office.Interop.Outlook.Application();

Microsoft.Office.Interop.Outlook.AppointmentItem appointmentItem =(Microsoft.Office.Interop.Outlook.AppointmentItem)outlookApp.
CreateItem(Microsoft.Office.Interop.
Outlook.OlItemType.olAppointmentItem);

As you’ve added the reference you get all the goodness of the intelliSense, obviously makes everything a lot easier.

Specify the Start and End date / time

appointmentItem.Start = DateTime.Now;
appointmentItem.End = DateTime.Now.AddHours(1);

Reminder settings

appointmentItem.ReminderSet = true;
appointmentItem.ReminderMinutesBeforeStart = 60;

Subject, location, and saving

appointmentItem.Subject = "Be Somewhere";
appointmentItem.Location = "Location 1";
appointmentItem.Body = "blah blah blah";
appointmentItem.Save();

Instead of calling ‘Save’ the appointment can be forwarded as a VCal attachment

protected void sendAsVcal(Microsoft.Office.Interop.Outlook.AppointmentItem appointmentItem)
{
Microsoft.Office.Interop.Outlook.MailItem mailItem = appointmentItem.ForwardAsVcal();
mailItem.SenderEmailAddress = "sysadmin@corp.net"
mailItem.To = "me@me.com";
mailItem.Send();
}

I initially built this as a console app to test the functionality, but can easily be moved to a standard web application project. Code above tested on Outlook 2007 / 2010.