Etikettarkiv: mime decode

Så tar du emot och hanterar E-post i PHP

Bild CC flickr.com/photos/9009139@N08/2959912279När jag byggde Bloggy för några år sedan så byggde jag även in en funktion för att ta emot bilder och text från E-post samt MMS-meddelanden till PHP.

Det som sedan händer är att PHP-koden parsar meddelandet och hämtar ut olika delar såsom rubrik (subject), meddelande och eventuella bilder som är bifogade.

Men först lite beroenden, denna guide fungerar enbart om du har en VPS eller egen server med Sendmail, PHP och pear-paketet Mail_mimeDecode. Pear-paketet kan installeras på följande sätt:

# pear install Mail_mimeDecode

Först måste vi konfigurera Sendmail att ta emot brev för vissa adresser. Detta förfarande har jag automatiserat genom att generera en virtusertable-fil i /etc/mail-katalogen. Du kan behöva uppdatera din sendmail.mc med nedan och generera en ny sendmail.cf:

FEATURE(`virtusertable’,`hash -o /etc/mail/virtusertable’)dnl

Alternativt så kan du direkt via /etc/aliases sätta upp följande snutt som gör så att inkommande E-post hamnar hos PHP:

mms:  ”| /usr/bin/php /var/www/bloggy.se/docs/newmail.php”

Det som händer då är att allt som går till [email protected] alternativt det som routas via virtusertable till [email protected] på följande sätt:

[email protected] [email protected]

Hamnar i PHP hos newmail.php och kommer in som stdin. Obs, om du ändrar i aliases, virtusertable eller .mc-filen så måste du generera nya filer (med kommandot newaliases eller makemap hash exempelvis). Följande kod använder jag sedan för att parsa mailet:

  define("DOMAIN", "bloggy.se");

  include_once('Mail/mimeDecode.php');

  $input = file_get_contents("php://stdin");
  $from = "unknown";

  @file_put_contents("/tmp/maillog.txt", $input."\n--- new mail --\n", FILE_APPEND);

  $params['include_bodies'] = true;
  $params['decode_bodies'] = true;
  $params['decode_headers'] = true;
  $params['input'] = $input;

  $structure = Mail_mimeDecode::decode($params);

  $to = $structure->headers['to'];
  $from = $structure->headers['from'];

  #mailme('<pre>'.print_r($header, true).'</pre>'); // For debugging
  $header = imap_rfc822_parse_headers($input);

  foreach($header as $foo => $bar) {
    if($foo == 'to' || $foo == 'cc') {
        foreach($bar as $k) {
            if($k->host == DOMAIN) {
                $dste = $k->mailbox;
            }
        }
    }
  }

  foreach ($structure->parts as $part) {
    // Save text
    if (isset($part->ctype_primary) && $part->ctype_primary == "text") {
        if(strlen($part->body) > 2 && !preg_match("/iPhone$/", $part->body))
            $text = $part->body;
    }
  }
  if(!$text)
    $text = $header->headers['subject'];

  if(!$text)
    $text = $structure->headers['subject'];

Och slutligen så hamnar antingen innehållet i mailet eller rubriken i $text om vi har tur.