Solved

Reading MMS emails

Posted on 2004-08-05
7
1,198 Views
Last Modified: 2008-01-09
hi,
I'm in a mist of a project where by I've to recieve images through the email, which are sent by MMS from mobile phones, so they can be displayed or saved in a database.

Now I've two questions, and I will definately grant more points for answering both questions altogether.

1) I know how to open emails etc.. the thing is... How to parse the email header to know it's a MMS email.. and then extract the image?

2) How do I extract the image.. and save in the server after that?

Hope I'm not too messy with my question..
0
Comment
Question by:Daveyz83
  • 4
  • 3
7 Comments
 
LVL 25

Expert Comment

by:Squinky
Comment Utility
I just sent a couple of tests from my Nokia 6600, and the messages (whether routed via email or MMS) are all bog-standard MIME with totally normal looking attachments (base-64 encoded), so PEAR::Mail_MIME will handle it all with ease: http://pear.php.net/manual/en/package.mail.mail-mimedecode.example.php.

To install this module for PHP, enter 'pear install mail_mime' on a command line.

The basic pattern is, parse the message headers and bodies, extract the decoded attachments and write them to local files as necessary. Mail_MIME will do all this in just a few lines except save, and to do that just look up fopen() in PHP docs.

This may of course just be a feature of my particular service provider, who has transcoded from native MMS to MIME via their gateway, but I'd imagine most service providers work this way.

To distinguish MMS-sourced email from "normal" email, look for extra headers like 'X-Mms-MMS-Version', though you really don't need to worry about MMS formats.
0
 

Author Comment

by:Daveyz83
Comment Utility
I can't yet give you the points because I'm still not too sure about the solution.
I've installed that pear module but it seems that the example provided is not clear enough of how I can use it to actually decode a mime email.

Do you have a short example of how attachments can be opened. What if the mms is a video, how do I do extract the attachment also?

I add every 50 points to some answers that will lead to my final solution
0
 
LVL 25

Expert Comment

by:Squinky
Comment Utility
Here's a working example using the test message I sent earlier (waring - it's long!):

<?php
require_once 'Mail/mimeDecode.php'; //PEAR MIME decoder
$message = <<<EOD
Return-Path: <441234567890@orangemms.net>
Delivered-To: squinky@example.com
Received: (qmail 19300 invoked from network); 6 Aug 2004 09:00:51 -0000
Received: from unknown (HELO blue.orangemms.net) (193.36.78.36)
  by mail.example.com with SMTP; 6 Aug 2004 09:00:51 -0000
Received: from blue.orangemms.net (blue.orangemms.net [193.36.78.36])
      by blue.orangemms.net (Switch-2.2.8/Switch-2.2.8) with ESMTP id i7690jZ09590
      for <squinky@example.com>; Fri, 6 Aug 2004 10:00:45 +0100 (BST)
From: 441234567890@orangemms.net
Received: from conversion-daemon.blue.orangemms.net by blue.orangemms.net
 (iPlanet Messaging Server 5.2 (built Feb 21 2002))
 id <0I2000501OIECO@blue.orangemms.net> for squinky@example.com; Fri,
 06 Aug 2004 10:00:45 +0100 (BST)
Received: from agw1 (agw1.orangemms.net [192.168.224.188])
 by blue.orangemms.net (iPlanet Messaging Server 5.2 (built Feb 21 2002))
 with ESMTP id <0I2000KVZP19VK@blue.orangemms.net> for squinky@example.com; Fri,
 06 Aug 2004 10:00:45 +0100 (BST)
Date: Fri, 06 Aug 2004 10:00:44 +0100 (BST)
Subject: Multimedia message
To: squinky@example.com
Message-id: <2499981.1091782845412.JavaMail.wluser@agw1>
MIME-version: 1.0
Content-Type: multipart/mixed;
 boundary="----<2499981.1091782845412.JavaMail.wluser@agw1>"
X-Mms-MMS-Version: 16
X-Mms-Priority: 1
X-Mms-Delivery-Report: 1
X-Nokia-Ag-Version: 2.0
X-Mms-Message-Class: 0
X-Mms-Message-Type: 0
X-Mms-Transaction-ID: E0BEAB8EFC3639
X-Mms-Read-Reply: 1

This is a multi-part message in MIME format.
------<2499981.1091782845412.JavaMail.wluser@agw1>
Content-type: multipart/mixed; boundary="Boundary_(ID_aJq4F2fj6B2KyUl7m0DRrw)"


--Boundary_(ID_aJq4F2fj6B2KyUl7m0DRrw)
Content-type: image/jpeg; NAME=picture.jpg
Content-transfer-encoding: BASE64
Content-disposition: attachment; filename=picture.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoH
BwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQME
BAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
FBQUFBQUFBQUFBQUFBT/wAARCAB4AJ4DASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEA
AAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh
MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6
Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZ
mqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx
8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA
AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV
YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hp
anN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPE
xcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDx
BBvGD3qQQFSARwe9Q2cgmXPcdq1rZAwwwBB7V+4LU/L5txZXhgwOnWtC1gzjipRY
lQGX5l/lVyzgyRxxQ2jmnMtWMGOcVv2kWBVK0twMcVrxIFFc02cjdy7bDaoqe+ux
bWoQH55evstQ2xBPJAQDJJ7CsS+1M3dy8g+70UegrFR5mI0kus96nS596wVuziph
eH6VbgFjbFxnuacbkEdaxVvs96eLsmp5ANRrkDvTo7jnrWV5+RnNaul6VcX4D48u
HvI3T8PWlJJK7AuWztKwVcsx9K1oLcQgNJhmHYdBSQW8NmmyMZPdz1NMeUknmuVv
m2KSsTy3Jb+I4qlPcbRwfxpk82O9Z9xdEnAPPpVRiDZJNcbgADVaC6xeoAeOc+5w
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
rTlF/aP9z8f+AP/Z

--Boundary_(ID_aJq4F2fj6B2KyUl7m0DRrw)--
------<2499981.1091782845412.JavaMail.wluser@agw1>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit


--
This Orange Multi Media Message was sent wirefree from an Orange
MMS phone. If you would like to reply, please text or phone the
sender directly by using the phone number listed in the sender's
address. To learn more about Orange's Multi Media Messaging
Service, find us on the Web at www.orange.co.uk/mms

------<2499981.1091782845412.JavaMail.wluser@agw1>

------<2499981.1091782845412.JavaMail.wluser@agw1>--

EOD;

$decoderparams = array('include_bodies' => true, 'decode bodies' => true,
      'decode headers' => true, 'input' => $message, 'crlf' => "\r\n");
$mimeobj = Mail_mimeDecode::decode($decoderparams);
if (!is_a($mimeobj, 'PEAR_Error')) { //MIME decoding worked
//The message is now decoded and held in the $mimeobj object
//Let's have a look at it - it's quite fiddly to keep track what's an object and what's an array
//but this example extracts the image attachment
//var_dump($mimeobj);
$attachment = $mimeobj->parts[0]->parts[0];
//Dump it direct to the browser using the mime type provided
header("Content-type: {$attachment->ctype_primary}/{$attachment->ctype_secondary}");
$image = base64_decode($attachment->body);
echo $image;
}
?>

This displays a little image which should be familiar to MacOS X users.

You can see the full message structure if you just do a var_dump on $mimeobj - be warned that it's quite big even for a small message like this, but that's just how MIME is - and be thankful for all that the decoder is doing for you!.
It's probably best to write a recursive function (as it's a tree structure) that scans through the whole thing looking for attachments and extracting or saving each one.
If you have a video attachment it will probably have a ctype_primary of video and a ctype_secondary of x-3gpp, or mpeg4 or similar. All you then need to do is grab the body element, decode it and save it to a file (it's not as if you're about to play video within PHP), and you can apply his to any attachments, it makes no difference what type of media it is.

If you want to play video clips received from phones (locally or in web pages), go for QuickTime as it has full support for mpeg4, 3gpp and 3gpp2 video. You might like to pull the code from CVS (no files released yet) on my QuickTime PHP project at pearqt.sourceforge.net to help out with that.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:Daveyz83
Comment Utility
So to save the attachment all I hve to do is actually to actually do a fopen and write $attachment->body inside and save it as a .jpg or wadever file right?

How do I know if it's a gif, jpeg or whatever file extension?
0
 
LVL 25

Accepted Solution

by:
Squinky earned 310 total points
Comment Utility
Pretty much, yes.

It may not have a file extension, though it usually will (remember that reliance on file extensions is the result of MS persisting with such crap file system metadata!). You can tell what type it is using the ctype_primary and ctype_secondary fields - in my example they added up to the MIME type image/jpeg. Other types you might encounter are image/gif, image/png, video/quicktime, video/mpeg, audio/mpeg, text/plain, text/html, application/zip etc etc. You can send anything you like, it's up to your application to do whatever it likes with the attachments, which as you say, could include fopen() and fwrite() of a body part.

You can see that the original filename (if you want to ignore the mime type) is available as an additional parameter of the content-disposition field. In my example you would find it in:

$filename = $attachment->d_parameters['filename'];

In this case it's also available in $attachment->ctype_parameters['name'], but I think I'd expect the disposition to be the usual source of that information.

Don't forget that you may need to decode the body content before saving. There may be other encodings than base-64 (also known as MIME encoding, just to add confusion) used too, such as uuencode, 7-bit, quoted printable on HTML and others. You can see what kind of encoding is used for a part by looking at the transfer-encoding field for a part - in my example you can see that it used BASE64.

MIME is extremely flexible, and can present to some very complex structures, so you need to be careful about writing code to process the entire tree reliably.
0
 
LVL 25

Expert Comment

by:Squinky
Comment Utility
0
 

Author Comment

by:Daveyz83
Comment Utility
Thank you very much for your answer, it had been excellent and solved majority of my problems.

I've got many new questions coming up, I hope that you will provide more advices again!

Thank you :)
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Introduction Many web sites contain image galleries; a common design for these galleries includes a page with a collection of thumbnail images.  You can click on each of the thumbnail images to see the larger version of the image.  This is easily i…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now