SolutionsTools & SDKSupport  



Quick Links
 
Jack's Hack: "Send and Receive" with MMS
 
 
Using the Openwave MMS library, you can build compelling applications to send and receive enriched MMS. The library comes with a variety of sample code for sending messages and for receiving delivery and read reports. For developers, the ability to receive a request for content and respond with an MMS message is the lifeblood fueling the power of "A2P" messaging.

This technical note describes how to implement a servlet application to receive and parse an incoming MMS message from a handset and send an appropriate MMS response back to the phone.

The application allows users to register for a "Sport Quiz" from a front-end html page that can be viewed either on the desktop or from the browser on a mobile device. The user will then receive an MMS message that contains two slides, one with a welcome message and another with the first question in the quiz. The user submits their answer to the question by simply replying to the MMS message with the option they think is correct.

The application will parse the MMS message, retrieve the answer from it, check the answer and send the user the feed back on their answer on one slide, and the next question in a second slide. The Sport Quiz sample application has three questions, and once the user finishes it, the last MMS message will display the score.

The application is made up of two Java classes: mmsSender.java and mmsReceiver.java, and an HTML page for registration: send.html, as well as a table to keep user's information.

The logic flow for of the application is as follows:
  1. Users register for Sport Quiz by entering their phone numbers on the html registration page (a user name can also be caught further use and promotion but the sample application doesn't catch the user name at this point). The form in send.html calls mmsSender.java and passes phone number to it.
  2. mmsSender.java catches the phone number and sends an MMS to the VASP account so the application referred by VASP account can process the request and send appropriate MMS contents to the user. In this application, the VASP account on the MMSC is configured to send messages to mmsReceiver.java (this configuration is done at the time the VASP account is provisioned on the MMSC).
  3. mmsReceiver.java catches the phone number or ID from MMS subject line, parses the contents of the MMS message to get the answer, checks the answer, builds the appropriate MMS contents and sends an MMS back to the user. mmsReciver.java also manipulates database by inserting an entry for a new user, and updating information for existed users.
Let's take a close look at each class.

mmsSender.java
Step 1
Catch the phone number from Querystring.
String num = request.getParameter("num");

Step 2
Add the number associated with VASP account in recipient array.
recipients.add(new Recipient(Recipient.Type.TO, AddressType.NUMBER, userName));

Step 3
Create a text file as MMS content.
String fileName ="/usr/local/java/tomcat/webapps/mmsDemo2/data.txt"; mmFiles.add(fileName);

Step 4
Create a connection to a relay and call method sendMM() to compose a MMS and send it out.
RelayConnection conn = RelayConnection.createSender(mmscUrl, userName, password);
sendMM(conn, userName, mmFiles, recipients, num);

Step 5
Create a SubmitRequest object in which we set the user phone number in MMS subject line so it is easily retrieved by mmsReceiver.java.

SubmitRequest request = new SubmitRequest();
request.setVaspID("my id");
request.addRecipients(recipients);
request.setMessageClass(SubmitRequest.MessageClass.PERSONAL);
request.setPriority(SubmitRequest.Priority.LOW);
request.setDeliveryReport(false);
request.setReadReply(false);
request.setSubject("num"+num);

Step 6
Compose MMS content.

String fileName = (String) mmFiles.get(0);
MimeBodyPart part = new MimeBodyPart();
DataSource source = new FileDataSource(fileName);
part.setDataHandler(new DataHandler(source));
File file = new File(fileName);
part.setFileName(file.getName());
part.setHeader("Content-ID", "<" + file.getName() + ">");
request.setContent(part);

Step 7
Use the connection object created earlier to send the request to the relay. Catch the response from MMSC and print it out via method printResponse().

response = conn.sendRequest(request);
SubmitResponse submitResponse = (SubmitResponse) response;
printResponse(submitResponse);

mmsReceiver.java
(Where the bulk of the work of our application takes place.) There are really five basic steps that we will explore:
  1. Basic processing of the delivery request
  2. Identifying the user, extracting their response, and updating their status in the quiz database
  3. Building the appropriate MMS response based on what the user submitted
  4. Sending off the MMS message to the user
  5. Cleaning up at the end of the quiz
Step 1
Dispatch an incoming request from MMSC and call processDeliverRequest() to process deliver request. This is pretty straight forward, and comes right out of our existing sample code for receiving an MMS message.
try {
        RelayConnection.dispatch(request, response, this);
    } catch(APIException e) {
        e.printStackTrace();
        System.out.println("APIException dispatching message: " +
        e.getMessage() + "(" +
        e.getErrorCode() + ")");
    }

Step 2
Retrieve phone number or ID from MMS subject line and manipulate database. We use this approach because on the developer MMSC we are not in a real mobile operator network, so we cannot reliably identify the user simply from the sender address.

We're going to do a lot of work in this step, so we're going to break the process down into six sub steps:
  1. Capture the phone number of the user from the subject line of the message
  2. Capture the contents of the incoming MMS message
  3. Look up the user to see if they are a known user and if so, what question they are currently on in the quiz
  4. Validate the answer they have submitted (captured in step 2)
  5. Update the user's score and identify if they've reached the end of the quiz
  6. If the user is starting the at the beginning of the quiz, re-initialize if they are a returning user, or insert them into the quiz data base if they are a new player
Substep 1
Check the MMS subject line. If the subject line has "<", the MMS is from a phone. The user has received a question and replied it back. Parse the ID within <>. The ID is a unique number for each user so it is a key for each entry in the table.
    if (subject.indexOf("<")>=0||subject.indexOf("<")>=0){
 
    if(subject.indexOf("<")>=0){ 
        flag = subject.indexOf("<");
        flag1 = subject.indexOf(">"); 
        subject = subject.substring((flag+4), flag1);
    }else{
        flag = subject.indexOf("<");
        flag1 = subject.indexOf(">");
        subject = subject.substring(++flag, flag1);
    }

    id = Integer.parseInt(subject);

Substep 2
Write the MMS content in a unique file (recv_id.txt).
try {
    writer = new PrintStream(new
        FileOutputStream(
        "/usr/local/java/tomcat/webapps/mmsDemo2/recv"+
        id+".txt"));
} catch(FileNotFoundException fnfe) {
    System.out.println("Cannot create file: temp.txt. Error: " +
        fnfe.getMessage());
    return null;
}

try {
    Object content = deliverRequest.getContent();
    if(content instanceof MultimediaContent) {
        ((MultimediaContent) content).writeTo(writer);
    } else if(content instanceof MimeBodyPart) {
        ((MimeBodyPart) content).writeTo(writer);
    }
} catch(APIException e) {
    writer.println("APIException processing request: " +
    e.getLocalizedMessage() + "(" +
        e.getErrorCode() + ")");
} catch(java.io.IOException ie) {
    writer.println("IOException: " + ie.getMessage());
} catch(ContentException ce) {
    writer.println("ContentException: " + ce.getMessage());
} catch(MessagingException me) {
    writer.println("MessagingException: " + me.getMessage());
}
writer.flush();
writer.close();

Substep 3
Look up the table to search for the question number, phone number and score based on ID. These parameters will be used later.
try{
    //connect to mySQL database
    Class.forName("org.gjt.mm.mysql.Driver");
    String url = "jdbc:mysql://localhost:3306/mmsDemo";
    Connection con = DriverManager.getConnection (url, "", ""); 

    // execute the query
    Statement stmt = con.createStatement (); 
    ResultSet res = stmt.executeQuery("Select question, score, 
                num from user  where id ="+id);
    while(res.next()){
        question = res.getInt(1);
        score = res.getInt(2);
        number = res.getString(3);
        }
     stmt.close (); 
     con.close (); 
     }
     catch (Exception e) { 
              System.out.println (e.getMessage ()); 
              e.printStackTrace (); 
    } 

Substep 4
Open the file (recv_id.txt), parse the answer and check whether the answer is correct.

try {
    reader = new BufferedReader(new 
        FileReader
        ("/usr/local/java/tomcat/webapps/mmsDemo2/recv"+
        id+ ".txt"));
    } catch(FileNotFoundException fnfe) {
    System.out.println("Cannot access file: recv.txt. Error: " +
        fnfe.getMessage());
    }

String line = null;

try {   
    //Check the answer 
    while((line = reader.readLine()) != null) {
        if(line.indexOf("---=")>=0) {
            if(flag1==1) flag2=1;
        }  
        if (flag1==1&&flag2==0&&(line.indexOf("Content")<0)){
            if(line.indexOf(answer1[question-1])>=0){
                //if the answer is correct
                match = 1;
                score++;
            }
        }
        if(line.indexOf("text/plain")>=0){ 
            flag1 = 1;
            counter = 1;
            client = 1;
         }
    }
}   catch(IOException e){
        System.out.println (e.getMessage ());
}

Substep 5
Make another file (data_id.txt) to write down a line indicating if the answer is correct or not. If the user finishes the quiz, create a file (final_id.txt) that contains the score and welcome back message. data_id.txt and final_id.txt are a part of an MMS that will send back to the user.

try {
    writer = new PrintStream(new FileOutputStream
            ("/usr/local/java/tomcat/webapps/mmsDemo2/data"+
            id+".txt"));
    } catch(FileNotFoundException fnfe) {
    System.out.println("Cannot create file: 
            data1.txt. Error: " + fnfe.getMessage());
    }

    if (match == 1) writer.println("Correct");
    else writer.println("Sorry, correct answer is"
            +answer2[question-1]);
    writer.flush();
    writer.close();

if (question==3){//if question=3, the user has finished the quiz
    try {
        writer = new PrintStream(new FileOutputStream
                ("/usr/local/java/tomcat/webapps/mmsDemo2/final"+
                id+".txt"));
    } catch(FileNotFoundException fnfe) {
        System.out.println("Cannot create file: final.txt. Error: " +
                fnfe.getMessage());
    }
  
    writer.println("Your score: "+score+"/3");
    writer.println("Thanks for playing, 
                check back soon for new quizzes");
    writer.flush();
    writer.close();
}

Substep 6
If the subject line has "num", the MMS is from mmsSender.java, indicating that the user wanted to start the quiz. Retrieve the sender's phone number and look it up the table. If there is entry having the same phone number, retrieve the ID that will be used to send the MMS message, and update the entry to the initial position by setting the question number to 1 and score to 0. Otherwise, insert new entry and set ID in sequence.
else if (subject.indexOf("num")>=0){

/*  Set score to 0 and question to 1.
    These variables are used to update database.
    Set flag and counter to 1.
    These variables determine to send what kind of MMS to users */

  flag = 1;
  counter = 1;
  score = 0;
  question = 1;
  //Retrieve number from subject line
  number = subject.substring(3);
     flag2 = 0;
     //Check if the user is in database.
     //If yes, retrieve ID to send MMS.
  try{
        //connect to mySQL database 
        Class.forName("org.gjt.mm.mysql.Driver");
        String url = "jdbc:mysql://localhost:3306/mmsDemo";
        Connection con = DriverManager.getConnection (url, "", ""); 

        // execute the query
        Statement stmt = con.createStatement (); 
        ResultSet res = stmt.executeQuery("Select id from 
                user where num ='"+number+"'");
         while(res.next()){
            flag2 = 1;
            id = res.getInt(1);

        }
         stmt.close (); 
         con.close (); 
         }
         catch (Exception e) { 
                  System.out.println (e.getMessage ()); 
                  e.printStackTrace (); 
        } 
        // The user is in database.
        //Update the entry to set question to 1 and score to 0.
        if (flag2==1){
        try{
        //connect to mySQL database 
        Class.forName("org.gjt.mm.mysql.Driver");
        String url = "jdbc:mysql://localhost:3306/mmsDemo";
        Connection con = DriverManager.getConnection (url, "", ""); 

        // execute the query
        Statement stmt = con.createStatement (); 
        command = "update user set question = 1, 
                score = 0 where num = '"+number+"'"; 
        stmt.executeUpdate(command);
        stmt.close (); 
        con.close (); 
   }
    catch (Exception e) { 
        System.out.println (e.getMessage ()); 
        e.printStackTrace (); 
    } 
}   else    {
    /* If the user is not in database, count how many rows 
    are in the table.  The row number is the ID for each entry.
    Make the ID for the new entry as current total row number 
    plus one.*/

     try{
        //connect to mySQL database 
        Class.forName("org.gjt.mm.mysql.Driver");
         String url = "jdbc:mysql://localhost:3306/mmsDemo";
         Connection con = DriverManager.getConnection (url, "", ""); 

        // execute the query
         Statement stmt = con.createStatement (); 
             ResultSet res = stmt.executeQuery("Select * from user");
  
        while(res.next()){
            k ++;
        }
         stmt.close (); 
         con.close (); 
         }
         catch (Exception e) { 
                  System.out.println (e.getMessage ()); 
                  e.printStackTrace (); 
        } 


    //Insert a new row in the table
       try{
        //connect to mySQL database 
        Class.forName("org.gjt.mm.mysql.Driver");
        String url = "jdbc:mysql://localhost:3306/mmsDemo";
        Connection con = DriverManager.getConnection (url, "", ""); 

        // execute the query
         Statement stmt = con.createStatement (); 
            if(k==0){
            command = "insert into user values(1"+", "+
                    question+", "+score+", '"+number+"', 'N/A')";
            id = 1;

        }
            else{
            command = "insert into user values("+(k+1)+", "+
                    question+", "+score+", '"+number+"', 'N/A')";
            id = k + 1;
 
        }
        stmt.executeUpdate(command);
        stmt.close (); 
        con.close (); 
        }   
        catch (Exception e) { 
            System.out.println (e.getMessage ()); 
            e.printStackTrace (); 
        }
 
      }

}

Step 3
Add the user's phone number in recipient array and make slides based on different situations. If the user is not on the last question, send two slides, one telling whether the answer is correct, another showing the next question. Update the score and question number in database. Otherwise, send two slides, one telling whether the answer is correct, another displaying the score and welcome back message. The slide contains sound file (.amr), image (.gif) and/or text file (.txt).
try{
    recipients.add(new Recipient(Recipient.Type.TO,
    AddressType.NUMBER,
    number));
} catch(APIException e) {
    System.out.println("exception adding recipient: " +
            e.getMessage());
    System.exit(1);
} 
    // If flag = 1, send the first MMS that contains 
    //  welcome message and the first question.
try{
    if (flag == 1){
    slides.add(makeSlide(0, question, match, "start.txt"));
    slides.add(makeSlide(2, question, match, "q1.txt"));
    }
    else if (client == 1){
        //If client = 1, send the next question to the user
        if (question < 3){
            /*If question<3, the user hasn't finished 
            the quiz. 
            Sent two slides, one telling whether the 
            answer is correct, another showing the next
            question. 
            Update the score and question number in database. */

            slides.add(makeSlide(1, question, match, 
                    "data"+id+".txt"));
            question ++;
            slides.add(makeSlide(2, question, 
                    match, ("q"+question+".txt")));
            try{

                //connect to mySQL database acmedatabase
                Class.forName("org.gjt.mm.mysql.Driver");
                String url = "jdbc:mysql://localhost:3306/mmsDemo";
                Connection con = 
                        DriverManager.getConnection (url, "", ""); 

                // execute the query
                Statement stmt = con.createStatement ();
                command = "update user set question ="+
                        question+", score ="+score+" where id = "+id; 
                stmt.executeUpdate(command);
                stmt.close (); 
                con.close (); 
            }catch (Exception e) { 
                System.out.println (e.getMessage ()); 
            }
        }else {
  
        /* If question=3, the user finishes the quiz.
        Send two slides, one telling whether the answer 
        is correct, another displaying the score and 
        welcome back message.  */

            slides.add(makeSlide(1, question, match,
                    ("data"+id+".txt")));
            slides.add(makeSlide(0, question, match,
                    ("final"+id+".txt")));
            question ++;
        }
    }
} catch(ContentException ce) {
    System.out.println("exception making slide: " + ce.getMessage());
    System.exit(1);
} catch(FileNotFoundException fnfe) {
    System.out.println("exception making slide: " + fnfe.getMessage());
    System.exit(1);
} catch(IOException ioe) {
    System.out.println("exception making slide: " + ioe.getMessage());
    System.exit(1);
}

Step 4
Compose MMS and send it to the user. This is another multipart process because what we send is going to depend on exactly where in the quiz a user is, so we've got four sub steps here:
  1. Create a connection to the MMSC, and begin the message setup
  2. Within the sendMM method, build the SubmitRequest
  3. Assemble the slides that are going to be sent to the user
  4. Send the message out
Substep 1
Create a connection to a relay and call method sendMM() to compose a MMS and send it out.
   RelayConnection conn = 
            RelayConnection.createSender(mmscUrl, 
            userName, password);
   sendMM(conn, userName, slides, recipients, question, id);

Substep 2
Create a SubmitRequest object in which we set different subject line for each question and include ID in it. The ID is the hint to search for database to get user phone number, which question has been sent to the user and score.
SubmitRequest request = new SubmitRequest();
request.setVaspID("my id");
request.addRecipients(recipients);
request.setMessageClass(SubmitRequest.MessageClass.PERSONAL);
request.setPriority(SubmitRequest.Priority.LOW);
request.setDeliveryReport(false);
request.setReadReply(false);
if (question == 1)
request.setSubject("Welcome to Sports Trivia <"+id+">");
else if (question == 2)
request.setSubject("Sports Trivia Question 2 of 3 <"+
        id+">");
else if (question == 3)
request.setSubject("Sports Trivia Question 3 of 3 <"+
        id+">");
else if (question == 4)
request.setSubject("Your Sports Trivia Score <"+id+">");
Calendar twoDaysFromNow = Calendar.getInstance();
twoDaysFromNow.add(Calendar.DATE, 2);
request.setExpiry(twoDaysFromNow);

Substep 3
Compose MMS content.
private void setContent(SubmitRequest request,
        List slides) throws 
                ContentException,
                MessagingException,
                IOException {
                    if(slides.size() > 0) 
                        request.setContent(slides);
                }

Substep 4
Use the connection object created earlier to send the request to the relay. Catch the response from MMSC and print it out via method printResponse().
response = conn.sendRequest(request);
SubmitResponse submitResponse = (SubmitResponse) response;
printResponse(submitResponse);

Step 5
Once the user finishes the quiz, clean up temporary files that are used to store MMS contents such as recv_id, data_id and final_id.
if (question == 4){//clean up files
    String path = "/usr/local/java/tomcat/webapps/mmsDemo2/";
    File dummy; 
    dummy = new File (path+"recv"+id+".txt");
    dummy.delete();
    dummy = new File (path+"data"+id+".txt");
    dummy.delete();
    dummy = new File (path+"final"+id+".txt");
    dummy.delete();
}

To deploy this application yourself it, you need a VASP account that refers to the URL where the application is located. You also need a database to keep information such as ID, phone number, user name, question number that indicates which question has been sent to the user, and score.



 
Copyright © 2000-2008 Openwave Systems Inc.    Openwave  |  Terms & Conditions  |  Privacy Policy