Email Automatisch verarbeiten

Hallo,

ich bekomme von einem Lieferant täglich eine Statusdatei an eine bestimmte Emailadresse.
Nun sollte ich diese mithilfe von php abrufen und den anhang weiterverarbeiten. Dabei handelt es sich um eine csv-Datei. Mit soetwas kann ich umgehen, dass hab ich schon öfters gemacht.
Aber kann ich mit PHP ein Mailkonto abrufen und von den Emails die Anhänge weiterverarbeiten??

Nachtrag:
ich hab grad die imap_ Funktionen gefunden. Allerdings finde ich da nix mit anhängen…

öh ich würd das mit fsocketopen lösen
du connectest auf den pop3 server des emailaccounts und lässt dir die entsprechende Email ausgeben.

aber wie soll ich mir mit fsocket eine email holen??
ich kenne das ganze nur um HTTP-Kommandos abzusetzen (GET,…)

hab grad noch was gefunden.
Wenn ich die Mail auslese, dann müsste wohl ein Teil des Bodys mein CSV anhang sein.
Kann mir jemand sagen wie ich aus dem ganzen den CSV-Teil rausbekomme?

hier ma nen kleines beispiel:
[PHP]
$socket = fsockopen(„pop.gmx.de“,110,$e1,$e2,5);
if(!$socket)
die(„Fehler beim Verbindungsaufbau (“.$e1." „.$e2.“)");
echo fgets($socket,4096);
fwrite($socket,„USER email@gmx.de\r\n“);
echo fgets($socket,4096);
fwrite($socket,„PASS passwort\r\n“);
echo fgets($socket,4096);
fwrite($socket,„LIST\r\n“);
do {
echo fgets($socket,4096);
} while(!feof($socket)!==false);

[/PHP]

Und so weiter.
Hier sind die Befehle die du übergeben kannst

[CODE]POP commands:

USER uid Log in as „uid“

PASS password Substitue „password“ for your actual password

STAT List number of messages, total mailbox size

LIST List messages and sizes

RETR n Show message n

DELE n Mark message n for deletion

RSET Undo any changes

QUIT Logout (expunges messages if no RSET)

TOP msg n Show first n lines of message number msg[/CODE]

danke für das Beispiel, das bringt mich mal einiges weiter.
allerdings hab ich jetzt ja immer noch das Problem, dass ich den Anhang vom „normalen“ Text trennen muss.

Also eine Email mit Anhang ist eine Multipart Mime-Typ email.

In dieser Email gibt es verschiedene Bereiche, die Headers, dann kommt ein Boundary, dann kommt der Inhalt der Email, wieder die gleiche boundary, und dann die Dateiinformationen.

Sieht dann so aus (z.B.):

[CODE]Return-Path:
X-Flags: 1001
Delivered-To: GMX delivery to praetorian@gmx.net
Received: (qmail invoked by alias); 09 Oct 2007 15:04:49 -0000
Received: from fmmailgate05.web.de (EHLO fmmailgate05.web.de) [217.72.192.243]
by mx0.gmx.net (mx070) with SMTP; 09 Oct 2007 17:04:49 +0200
Received: from web.de
by fmmailgate05.web.de (Postfix) with SMTP id CB0672F705AA
for ; Tue, 9 Oct 2007 17:04:49 +0200 (CEST)
Received: from [90.128.81.251] by freemailng0102.web.de with HTTP;
Tue, 09 Oct 2007 17:04:49 +0200
Date: Tue, 09 Oct 2007 17:04:49 +0200
Message-Id: 1680744406@web.de
MIME-Version: 1.0
From: sybex_ts@web.de
To: praetorian@gmx.net
Subject: FW: test
Content-Type: multipart/mixed;
boundary=„=-------------11919422898411948184“

This is a multi-part message in MIME format.

–=-------------11919422898411948184
Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable

DIE NACHRICHT

–=-------------11919422898411948184

Content-Type: image/jpeg;
name=„scr1.jpg“
Content-Disposition: attachment;
filename=„scr1.jpg“
Content-Transfer-Encoding: base64

/9j/4AAQSkZJRgABAgEASABIAAD/4SPuRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEa
AAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAcAAAAcgEyAAIAAAAU
AAAAjodpAAQAAAABAAAApAAAANAACvyAAAAnEAAK/IAAACcQQWRvYmUgUGhvdG9zaG9wIENT
MiBXaW5kb3dzADIwMDc6MTA6MDcgMjE6NDA6MTMAAAAAA6ABAAMAAAABAAEAAKACAAQAAAAB
AAABQKADAAQAAAABAAAA8AAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAA
AAEAAAEmASgAAwAAAAEAAgAA
–=-------------11919422898411948184
[/CODE]

Hier ist die Boundary

=-------------11919422898411948184

Du musst die Email also auslesen, den letzten Teil filtern und ihn in eine Datei schreiben mit der endung. Vorher musst du den Teil noch mit base64_decode() bearbeiten.

Ich habe mich da mal ran gesetzt und ne Klasse geschrieben, aber allem Anschein nach bin ich zu doof das teil an den boundaries zu teilen (habs mit split,preg_split,explode und strpos versucht).

Da fällt mir grad ein, es gibt eine Klasse im OpenSource bereich die das alles kann. Mir fällt aber grad iwie der Name nicht ein… :s

Hier sind meine Anfänge, es geht soweit, dass er sich die boundary hohlt, das Trennen wie gesagt da bin ich gescheitert.

[PHP]<?php
error_reporting(E_ALL);
class MyMail {
var $socket;
var $errno;
var $error;
var $LastLine;
var $LastLineMultiple;
var $list;
var $email;
var $boundary;
function MyMail($host=„“,$port=110,$timeout=5) {
$this->socket = @fsockopen($host,$port,$this->errno,$this->error,$timeout);
if($this->socket)
$this->_LastLine();
}
function isConnected() {
if($this->socket)
return true;
return false;
}
function getLastError() {
return array($this->errno,$this->error);
}
function getLastErrorFormated() {
die(‚Error #‘.$this->errno.‚
‘.$this->error);
}
function _LastLine() {
$this->LastLine = fgets($this->socket);
}
function _LastLineMultiple() {
$lines = array();
while (substr($line = fgets($this->socket), 0, 1) != „.“) {
$lines = substr($line,0,strlen($line)-2);
}
$this->LastLineMultiple = $lines;
}
function getLastLine() {
return $this->LastLine;
}
function getLastLineMultiple() {
return $this->LastLineMultiple;
}
function login($email,$password) {
if($this->_eval($this->_exec("USER „.$email)) && $this->_eval($this->_exec(„PASS „.$password)))
return true;
return false;
}
function listmails() {
if($this->_eval($this->_exec(„LIST“,2))) {
$list = $this->getLastLineMultiple();
unset($list[0]);
$this->list = $list;
return true;
}
return false;
}
function getEmail($id=1) {
if($this->_eval($this->_exec(„RETR „.$id,2))) {
$email = $this->getLastLineMultiple();
unset($email[0]);
$this->email = $email;
return true;
}
return false;
}
function getBoundary() {
foreach($this->email as $seekline) {
if(preg_match('%boundary=“(.)„%iU’,$seekline)) {
$this->boundary = preg_replace('%boundary=“(.
)“%isU’,‚\1‘,$seekline);
return true;
}
}
return false;
}
function _exec($cmd,$read=1) {
fputs($this->socket,$cmd.“\r\n“);
if($read==1) {
$this->_LastLine();
return $this->getLastLine();
}
if($read==2) {
$this->_LastLineMultiple();
return $this->getLastLineMultiple();
}
}
function _eval($string = „-ERR“) {
if(gettype($string) == „array“)
$string = $string[0];
if(substr($string,0,3) === „+OK“)
return true;
else {
$this->errno = " ?“;
$this->error = substr($string,4);
return false;
}
}
}

// Verbindung zum Mail Server
$mail = new MyMail(„pop.gmx.de“);
if(!$mail->isConnected()) {
$mail->getLastErrorFormated();
}
// Login mit benutzername und Passwort
$login = $mail->login(„praetorian@gmx.net“,„*****“);
if(!$login) {
$mail->getLastErrorFormated();
}
// Liste der vorhandenen Emails hohlen
$list = $mail->listmails();
if(!$list) {
$mail->getLastErrorFormated();
}
// LISTE AUSGEBEN
$liste = $mail->getLastLineMultiple();
unset($liste[0]);
echo implode(„
“,$liste);
echo „


“;
// EMAIL auswählen ID der Email als Parameter
$select = $mail->getEmail(1);
if(!$select) {
$mail->getLastErrorFormated();
}
// EMAIL AUSGEBEN

$email = $mail->getLastLineMultiple();
unset($email[0]);
echo implode(„
“,$email);
echo „


“;

// boundary bekommen
$boundary = $mail->getBoundary();
?>[/PHP]

ich hab das ganze jetzt soweit hinbekommen:
[PHP]

<? $mbox = imap_open("{pop.1und1.com:110/pop3/notls}INBOX","",""); //$folders = imap_listmailbox($mbox, "{pop.1und1.de:110}", "*"); $headers = imap_headers($mbox); $i = 1; foreach ($headers as $value) { mail_func($mbox,$i); echo $value."
"; $i++; } imap_expunge($mbox); imap_close($mbox); //alles löschen was älter als 60Tag ist $abfrage = "DELETE FROM dpd_daten WHERE (to_days(current_date) - to_days(datum)) > 60"; $ergebnis = mysql_query($abfrage) or die ("Fehler"); function mail_func($mbox_i, $nr_i) { $body = imap_body($mbox_i,$nr_i); $teile = explode("\n", $body); $str = ""; if ($body == false) { echo "Abruf fehlgeschlagen
\n"; } else { $y=1; /*foreach($teile as $teil) { if($y>14 && $y<83) { $str = $str."\r\n".$teil; } $y++; }*/ $z = 1; foreach($teile as $teil) { echo $z.". ".$teil."
"; $z++; } } $str = base64_decode($str); $verbindung = mysql_connect("localhost", "","") or die ("Keine Verbindung moeglich"); mysql_select_db("") or die ("Die Datenbank existiert nicht"); $zeilen = explode("\n", $str); for($x = 1; $x < count($zeilen); $x++) { $data = explode(";",$zeilen[$x]); $daten = explode(".",$data[14]); $datum = $daten[2]."-".$daten[1]."-".$daten[0]; $abfrage = "INSERT INTO dpd_daten". "(`paketscheinnr`, `scanart`, `depot`, `route`, `tour`, `service`, `plz`, `zusatzcode1`, `zusatzcode2`, `zusatzcode3`, `gewicht`, `ausrolllistennr`, `ort`, `info`, `datum`, `uhrzeit`, `land`, `block`)". " VALUES('".$data[0]."', '".$data[1]."', '".$data[2]."', '".$data[3]."', '".$data[4]."', '".$data[5]."', '".$data[6]."', '".$data[7]."', '".$data[8]."', '".$data[9]."', '".$data[10]."', '".$data[11]."', '".$data[12]."', '".$data[13]."', '".$datum."', '".$data[15]."', '".$data[16]."', '".$data[17]."')"; $ergebnis = mysql_query($abfrage) or die ("Fehler"); } /* if(imap_delete($mbox_i,$nr_i)) { echo "Mail Nr. ".$nr_i." wurde gelöscht
"; } else { echo "Mail Nr. ".$nr_i." konnte nicht gelöscht werden
"; }*/ } ?>

[/PHP]
Abrufen kann ich die mails auch und mir anzeigen lassen.

Aber kann mir jemand sagen wie ich den anhang jetzt ausfindig machen kann und extrahieren kann.
Ich blick in dem obigen beispiel leider nicht durch…

also du bekommst in den Headern deiner Email mitgeteilt

boundary="XYCVBXNXY"

dann sieht die EMAIL so aus:

headers

XYCVBXNXY

emailtext

XYCVBXNXY

datei (base64 encoded)

XYCVBXNXY

dann musst du anhand der boundary (XYCVBXNXY) die email auseinanderschneiden, der letzte teil ist dann die datei

ist denn der header des anhangs immer die ersten 6. Zeilen des anhangs??

das weiß ich nicht xD

schick doch mal nen paar emails mit anhang an dich und guck nach :wink:

Irgendwo gibts auch son RFC dafür soweit ich weiß - ich schau mal