Interview Questions

Send long SMS message using JSMPP

We have already seen how to send a SMS using JSMPP in the article Send SMS Using JSMPP. Since the length of a text SMS is 140, in order to send a long message containing more than 140 characters, we need to split the message and send with some headers to identify each message which is split.

We have an API named OptionalParameters.newSarSegmentSeqnum(seqNum) to set the sequence number for each message which are split so that they can be arranged together in the destination (SMSC). Since we need to accommodate headers each split message will contain only 135 characters.

The following class used to send long text message using JSMPP.

SendLongSMSMessage.java

/**
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

import java.io.IOException;
import java.util.Date;
import java.util.Random;

import org.jsmpp.InvalidResponseException;
import org.jsmpp.PDUException;
import org.jsmpp.bean.Alphabet;
import org.jsmpp.bean.BindType;
import org.jsmpp.bean.ESMClass;
import org.jsmpp.bean.GeneralDataCoding;
import org.jsmpp.bean.MessageClass;
import org.jsmpp.bean.NumberingPlanIndicator;
import org.jsmpp.bean.OptionalParameter;
import org.jsmpp.bean.OptionalParameters;
import org.jsmpp.bean.RegisteredDelivery;
import org.jsmpp.bean.SMSCDeliveryReceipt;
import org.jsmpp.bean.TypeOfNumber;
import org.jsmpp.extra.NegativeResponseException;
import org.jsmpp.extra.ResponseTimeoutException;
import org.jsmpp.session.BindParameter;
import org.jsmpp.session.SMPPSession;
import org.jsmpp.util.AbsoluteTimeFormatter;
import org.jsmpp.util.TimeFormatter;

public class SendLongSMSMessage
{
        private static TimeFormatter    timeFormatter   = new AbsoluteTimeFormatter();

        public String[] submitLongSMS(String MSISDN, String senderAddr, String message) throws Exception
        {
                SMPPSession session = getSession();

                String[] msgId = null;
                int splitSize = 135;
                int totalSize = 140;
                int totalSegments = 0;

                RegisteredDelivery registeredDelivery = new RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT);

                GeneralDataCoding dataCoding = new GeneralDataCoding(false, false, MessageClass.CLASS1,
                Alphabet.ALPHA_8_BIT);
                ESMClass esmClass = new ESMClass();

                if (message != null && message.length() > totalSize)
                {
                        totalSegments = getTotalSegmentsForTextMessage(message);
                }

                Random random = new Random();
                OptionalParameter sarMsgRefNum = OptionalParameters.newSarMsgRefNum((short) random.nextInt());
                OptionalParameter sarTotalSegments = OptionalParameters.newSarTotalSegments(totalSegments);

                String[] segmentData = splitIntoStringArray(message, splitSize, totalSegments);

                msgId = new String[totalSegments];
                for (int i = 0, seqNum = 0; i < totalSegments; i++)
                {
                        seqNum = i + 1;
                        OptionalParameter sarSegmentSeqnum = OptionalParameters.newSarSegmentSeqnum(seqNum);
                        try
                        {
                                msgId[i] = session.submitShortMessage("CMT", TypeOfNumber.NATIONAL,
                                NumberingPlanIndicator.ISDN, "9999999999", TypeOfNumber.NATIONAL,
                                NumberingPlanIndicator.ISDN, MSISDN, esmClass, (byte) 0, (byte) 0, timeFormatter
                                .format(new Date()), null, registeredDelivery, (byte) 0, dataCoding, (byte) 0, segmentData[i]
                                .getBytes(), sarMsgRefNum, sarSegmentSeqnum, sarTotalSegments);

                                System.out.println("Message id  for segment " + seqNum + " out of totalsegment "
                                + totalSegments + "is" + msgId[i]);
                        }
                        catch (PDUException e)
                        {
                                System.out.println("PDUException has occured" + e.getMessage());
                        }
                        catch (ResponseTimeoutException e)
                        {
                                System.out.println("ResponseTimeoutException has occured" + e.getMessage());
                        }
                        catch (InvalidResponseException e)
                        {
                                System.out.println("InvalidResponseException has occured" + e.getMessage());
                        }
                        catch (NegativeResponseException e)
                        {
                                System.out.println("NegativeResponseException has occured" + e.getMessage());
                        }
                        catch (IOException e)
                        {
                                System.out.println("IOException has occured" + e.getMessage());
                        }
                }
                return msgId;
        }

        private SMPPSession getSession() throws Exception
        {
                return newSession();
        }

        private SMPPSession newSession() throws Exception
        {
                BindParameter bindParam = new BindParameter(BindType.BIND_TX, "<user_name>", "<pass_word>", "tdd",
                TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null);

                return new SMPPSession("17.1.1.1", 6666, bindParam);
        }

        public int getTotalSegmentsForTextMessage(String message)
        {
                int splitPos = 135;
                int totalsegments = 1;
                if (message.length() > splitPos)
                {
                        totalsegments = (message.length() / splitPos) + ((message.length() % splitPos > 0) ? 1 : 0);
                }
                return totalsegments;
        }

        public String[] splitIntoStringArray(String msg, int pos, int totalSegments)
        {
                String[] segmentData = new String[totalSegments];
                if (totalSegments > 1)
                {
                        int splitPos = pos;

                        int startIndex = 0;

                        segmentData[startIndex] = new String();
                        segmentData[startIndex] = msg.substring(startIndex, splitPos);

                        for (int i = 1; i < totalSegments; i++)
                        {
                                segmentData[i] = new String();
                                startIndex = splitPos;
                                if (msg.length() - startIndex <= pos)
                                {
                                        segmentData[i] = msg.substring(startIndex, msg.length());
                                }
                                else
                                {
                                        splitPos = startIndex + pos;
                                        segmentData[i] = msg.substring(startIndex, splitPos);
                                }
                        }
                }
                return segmentData;
        }

        public static void main(String[] args) throws Exception
        {
                SendLongSMSMessage slSMS = new SendLongSMSMessage();
               
                String message = "Tech Dive heralds the arrival of a community of Developers "
                + "who share, collaborate and exchange ideas, concepts, technical know-how. "
                + "This forum lets you take a deep dive in technical topics that are hot and happening as well as on legacy systems."
                + "The idea of the forum is to ensure collaboration amongst developers through exchange of ideas/concepts "
                + "so their technical skills are enhanced."
                + "We plan to bring in experienced professionals on board so content/blog written is authentic and precise."
                + "Come, join us and be a part of new way of collaboration!";

                String MSISDN = "9500000000";

                String senderAddr = "8500000000";
               
                slSMS.submitLongSMS(MSISDN, senderAddr, message);
        }
}