Thursday, December 15, 2011

C# Text Messages by Email Queues


Summary
This tutorial shows how to simply send a text message (SMS) by Email and .

Description
There are two goals  The first is simple and described in the beginning, send a text message by email.  The second is to send text messages of unlimited length via email as text messages have a character length limit.  As an addition, we are using a queue data structure to get the job done.  The format of this article explains the concept of a code chunk then shows the entire code.

Before we begin
For the tutorial, take a look at the following:

Send Email C# - Example Only - Find the clsSmtpClient class in this post.

Send Text Messages
     Want to send a text message by email? It's easy, and free.  Compose a new email and send it to "your 10 digit number@smsgateway.com".  For example, my pretend Verizon phone number is (555)123-0987.  If someone wanted to send a text message to me, they would send an email to "5551230987@vtext.com".  This is free.  
     "number@vtext.com" will get the message to Verizon customers.  In order for this to work you will need to use the correct SMS gateway.  Thankfully, you can find a list of them here.
     Lastly, all text messages have a character limit of 160 characters.  I can only send 140 characters per email sent to "@vtext.com".  This means that if I write a 1000 character email and want to send it as a text message to someone, only the first 140 will be sent as a text message.  This could be different for each SMS gateway as I have only worked with the Verizon SMS gateway.


Queue the Queue
     Data structures class was one of my favorite classes.  To me, data structures bring organization to the processing of data in a way that just makes sense.   I like to use them whenever relevant/needed not only for what they do but also to practice using them.  In short, the queue is a collection of objects that processes objects in a first-in/first-out manner.
     As an example (analogy), the queue is like standing in line at the grocery store.  In this example, the people waiting in line are our objects in the queue.  The idea of getting into line is called, Enqueue.  The idea of calling the next person in the line to check-out is called, Dequeue.   People (objects) get into the single-file line (Enqueue) and are processed at the check-out (Dequeue) in the order which they got into the line (the queue).
     As a programming example, we have three strings we want to put into a queue:  Customer1, Customer2, and Customer3.  Let's pretend we already have a queue called "checkOutLine" for our string objects.  We get them into the queue (our grocery store check-out line) by saying:

checkOutLine.Enqueue(Customer1);
checkOutLine.Enqueue(Customer2);
checkOutLine.Enqueue(Customer3);

     You, the programmer, are at the counter waiting to check these Customers (and their strings) out.  We  call the next Customer in line up to the counter. While the Customer is at the counter, we take a look at what they have and then the Customer leaves the queue (Dequeue).

// For example

// This string represents the string of the customer we call to the counter to check-out...
string nextCustomer = "";

// Call the next customer in line to the counter
nextCustomer = checkOutLine.Dequeue();

// Do something with the nextCustomer string

     We can also iterate through all of the customers in line using a foreach loop:

foreach (string str in checkOutLine)
{
     // Do something with each customer until there are none in the queue
}

Send Text Messages, No Length Limit
     Well, technically this isn't true.  Due to the limitations of the Short Message Service (again SMS), we are limited to 160 characters.  For those interested in why, an SMS message can only contain 1120 bits  (Reference here).  The commonly used GSM 7-bit alphabet gives us 160 characters.  While it's possible to send a long SMS using a  User Data Header (reference here), we aren't going to cover it.
      Instead we are going to take the original message (of any length), chop the whole message into 140 character or less separate messages, place each message in a queue, and send each message as a separate email.

The clsMessageQueue Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SmsDemo
{
    public class clsMessageQueue
    {
        Queue<string> _messageQueue = new Queue<string>();
        string _wholeMessage;
        int _max_length;
        int _totalMessages;
        int _messageLength;

        public clsMessageQueue(String SmsMessage, int length)
        {
            // Pass the entire message in
            WholeMessage = SmsMessage;
         
            // Pass the desired max length of the SMS message
            Max_Length = length;
         
            // Set the message length based on the entire message
            MessageLength = WholeMessage.Length;

            // Start processing the message and ready it in the queue
            Setup();
        }


        public Queue<string> MessageQueue
        {
            get { return _messageQueue; }
        }

        public string getMessage()
        {
            return _messageQueue.Dequeue();
        }

        public void setMessage(string str)
        {
            _messageQueue.Enqueue(str);
        }

        public string WholeMessage
        { get { return _wholeMessage; } set { _wholeMessage = value; } }

        public int Max_Length
        { get { return _max_length; } set { _max_length = value; } }

        public int TotalMessages
        { get { return _totalMessages; } set { _totalMessages = value; } }

        public int MessageLength
        { get { return _messageLength; } set { _messageLength = value; } }


        private void Setup()
        {

            // Find the amount of messages we need to make
            // based on the length of the total message


            // If there is any remaining characters (remainder)
            // there will be an extra message with less than
            // 140 characters
            if (MessageLength % Max_Length > 0)
            {
                // divide the messageLength by the Max_Length
                // in order to get the amount of messages and
                // add one for the extra message
                TotalMessages = (MessageLength / Max_Length) + 1;
            }
            // Otherwise - there is no remainder
            else
                TotalMessages = (MessageLength / Max_Length);

            // The total times we loop is equal to the amount of message
            // we need to make (see the above if statement)
            for (int i = 0; i <= (TotalMessages - 1); i++)
            {

                // if the length of the message is less than the Max_length
                if (MessageLength <= Max_Length)
                {
                    // all we need to do is put the message in the queue
                    setMessage(WholeMessage);
                }

                // if the length of the message is more than the Max_length
                else if (MessageLength > Max_Length)
                {
                    // take the first 140 chars (Max_Length)
                    // and put this into the queue
                    setMessage(WholeMessage.Substring(0, Max_Length));
                 
                    // cut the first 140 chars (Max_length) out
                    WholeMessage = WholeMessage.Substring(Max_Length, (WholeMessage.Length - Max_Length));
                 
                    // reset the length of the message
                    MessageLength = WholeMessage.Length;
                }
            }
        }

    }
}



How do we use it?
     Now that we have a queue full of 140 character or less messages, we need to send them in the order that we put them in (first in, first out).  For this demo we simple text boxes to get user input, a button named "btnSend", the clsMessageQueue (above) to process the messages, and the clsSmtpClient class to send each message.



namespace SmsDemo
{
    public partial class SendSMS : System.Web.UI.Page
    {
        int MAX_LENGTH = 140;

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnSend_Click(object sender, EventArgs e)
        {

             // Get the email of who this text is from
            string fromEmail = Server.HtmlEncode(txtSmsFrom.Text);
         
            // I'm assuming the phone number is for a Verizon subscriber
            string toEmail = Server.HtmlEncode(txtSmsTo.Text) + "@vtext.com";
            // Get the message we want to send from the user
            string messageBody = Server.HtmlEncode(txtMessageBody.Text);


            clsMessageQueue messageQueue = new clsMessageQueue(messageBody, MAX_LENGTH);

            /*
             * Logic tier - clsSmtpClient
             *      Mail logic is put in another class
             *      and implemented here concisely.
            */

            // Smtp Client - other settings in web.config for safeness.
            clsSmtpClient mySmtpClient = new clsSmtpClient(fromEmail,
                                                           "Sean");
            // set the to email address
            mySmtpClient.setToAddress(toEmail);


            // This is where we send all the messages.
            // For every 140 char or less message, we send an email
            // and because we're using a queue, they are being sent int
            // the order that we cut them up.
            foreach (string str in messageQueue.MessageQueue)
            {
                // set the message content
                mySmtpClient.setMessageBody(str);

                // Send the email!! - Hiz-zah's are in order.
                mySmtpClient.SendEmail();

                // Need to wait a couple seconds
                // Otherwise the messages may get out of
                // order when they hit the SMS gateway.
                System.Threading.Thread.Sleep(2000);

            }

            if (mySmtpClient.Complete)
            {
                // When sending the messages, everything went fine
            }

            else if (!mySmtpClient.Complete)
            {
                // Something happened when sending the messages

            }
        }


Done!!!

Tuesday, December 13, 2011

Multiplatform Project

Project Summary
The current project is an ongoing, multiplatform project.  The purpose is to collect and analyze data from agricultural areas (farms) using simple, inexpensive technology.  It is a project that connects together a website, a mobile device, a database, and some hardware lead by an Arduino.  The Arduino-led hardware is a quadcopter (Figure 1.1), the mobile device is my Android device, the site is an ASP.NET site (C#), and MS SQL 2008 for the database.  

Figure 1.1
I like to keep things as simple as possible. The quadcopter goes to predetermined lat/long coordinates without direction, but can accept commands in-flight.  The Android device is on-board the quadcopter.  It has two purposes.  The first is to pass commands to the quadcopter via SMS and data.   The second is to get sensor data and images back to the ASP.NET website.  The ASP.NET site has three purposes.  It will process data, analyze it (if needed), and send it to the database.  The website is also the place where information is presented.  Lastly, it's the only place to control the quadcopter.  The idea can visually be summed up in Figure 2.1.



Progress

  • The quadcopter is put together (Figure 1.1).   Creating an image library for the site is rough around the edges but done.  Image library information (mapping) is stored in a database.  Broadcast Receiver for SMS on Android is kinda stock-ish code but works.
  • The quadcopter was built in a weekend and broke in the next.  The longest time with the quadcopter has been spent getting board, props, motors, speed control stuff set correctly.  Other than the RC Car project, I don't have any prior experience with RC stuff..  not a big deal though.  Best flight was about five feet for a few seconds at a little over 1.5Kg under 50% throttle.  Very sturdy but a prop broke (Figure 3.1). 

Monday, December 12, 2011

Send Email C# - Example Only


Summary
This example is a simple class that can be used to send email, written in C#

Description
This example shows everything needed to send an email except for the SMTP settings.  These settings will vary depending on who you are sending your email through.  While these settings can be hard coded, always place them in the web.config file or the app.config file.

Before We Begin
You'll need the SMTP settings in your web.config or app.config file.  Do a search for your email provider's SMTP settings.  Here is a skeleton to use:


<system.net>
    <mailSettings>
      <smtp>
        <network host="You email provider will tell you what to use (example. smtp.gmail.com)"
                 password="The password you use to log into your email account"
                 port="Your email provider will tell you what port to use"
           userName="youremailaddress@something.com"/>
      </smtp>
    </mailSettings>
  </system.net>

The clsSmtpClient Class




using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Mail;

namespace EmailDemo
{
    public class clsSmtpClient
    {
        private string _fromEmailAddress;
        private string _fromEmailName;
        private string _toEmailAddress;
        private string _messageSubject;
        private string _messageBody;
        private bool _complete = false;
        private string _error;
        SmtpClient mailClient = new SmtpClient();
        MailMessage message = new MailMessage();

        public string FromEmailAddress
        {
            get { return _fromEmailAddress; }
            set { _fromEmailAddress = value; }
        }

        public string FromEmailName
        {
            get { return _fromEmailName; }
            set { _fromEmailName = value; }
        }

        public string ToEmailAddress
        {
            get { return _toEmailAddress; }
            set { _toEmailAddress = value; }
        }

        public string MessageSubject
        {
            get { return _messageSubject; }
            set { _messageSubject = value; }
        }

        public string MessageBody
        {
            get { return _messageBody; }
            set { _messageBody = value; }
        }

        public string Error
        {
            get { return _error; }
            set { _error = value; }
        }

        public bool Complete
        {
            get { return _complete; }
            set { _complete = value; }
        }


        /*
         * Constructor
         */
        public clsSmtpClient(string fromEmailAddress,
                             string fromEmailName,
                             string toEmailAddress,
                             string messageSubject,
                             string messageBody)
        {
            FromEmailAddress = fromEmailAddress;
            FromEmailName = fromEmailName;
            ToEmailAddress = toEmailAddress;
            MessageSubject = messageSubject;
            MessageBody = messageBody;

            setupClient();
        }

        /*
         * Default Constructor
         */
        public clsSmtpClient(string fromEmailAddress, string fromEmailName)
        {
            mailClient.EnableSsl = true;
            FromEmailAddress = fromEmailAddress;

            FromEmailName = fromEmailName;

            MailAddress fromAddress = new MailAddress(FromEmailAddress, FromEmailName);
        }


        private void setupClient()
        {
            // Smtp Client - other settings in web.config for safeness
            mailClient.EnableSsl = true;

            // To and From address objects
            MailAddress fromAddress = new MailAddress(FromEmailAddress, FromEmailName);
            MailAddress toAddress = new MailAddress(ToEmailAddress);

            // Build the message
            message.From = fromAddress;
            message.To.Add(toAddress);
            message.Subject = MessageSubject;
            message.Body = MessageBody;
        }


        public void setToAddress(string str)
        {
            MailAddress toAddress = new MailAddress(str);
            message.To.Clear();
            message.To.Add(toAddress);
        }

        public void setMessageBody(string str)
        {
            message.Body = str;
        }

        public void SendEmail()
        {
            try
            {
                mailClient.Send(message);
                Complete = true;
                Error = "Complete!";
            }
            catch (Exception mailException)
            {
                Complete = false;
                Error = mailException.Message.ToString();
            }
        }

    }
}

How do we use it?
Below is an example of how to use this class to make emailing simple.

             // In a winform project, remove "Server.HtmlEncode"
           
             // This is the email address you want to send to, taken from a textbox control.

            string toEmail = Server.HtmlEncode(txtMessageTo.Text);
             // This is the email subject taken from a textbox control
            string messageSubject = Server.HtmlEncode(txtMessageSubject.Text);
             // This is the actual message of the email taken from a textbox control
            string messageBody = Server.HtmlEncode(txtMessageBody.Text);
         
            /*
             * Logic tier - clsSmtpClient
             *      Mail logic is put in another class
             *      and implemented here concisely.
            */

            // Smtp Client - other settings in web.config for safeness.
            clsSmtpClient mySmtpClient = new clsSmtpClient("the email address you are sending from",
                                                           "the from email name you want to use",
                                                           toEmail,
                                                           messageSubject,
                                                           messageBody);

                // Send the email.
                mySmtpClient.SendEmail();
             
                // After sending an email, we have two outcomes... it either sent or failed.
                // Below, we check for both.
                // check to see if the email got sent.
                if (mySmtpClient.Complete)
                {

                    // If the email was sent without problems,
                    // do the following..  yours will be different
                    // Everything below is just a summary of what was sent.

                    pnlInput.Visible = false;
                    pnlResult.Visible = true;

                    lblEmailToReturn.Text = toEmail;
                    lblMessageSubjectReturn.Text = messageSubject;
                    lblMessageBodyReturn.Text = messageBody;
                }
             
                // If the email failed to send for some reason, no internet connection, etc.
                else if (!mySmtpClient.Complete)
                {
                    // This code gets the error message and sets a label with it.
                    lblError.Text = mySmtpClient.Error;
                    pnlInput.Visible = false;
                    pnlResult.Visible = false;
                    pnlError.Visible = true;
             
                }
        }