2016-10-06 2 views
7

Ich habe eine Anwendung, die E-Mail mit Bild-Anhängen durch einen SMTP-Server (sendgrid)SMTP-Mail-Server (sendgrid) Fehler bei Vorlage

sendet Wenn die Anwendung startet es eine Socket-Verbindung intitilaizes und authentifiziert den Benutzer (Anwendung. I siehe die folgende Meldung zurückgegeben von Sendgrid

SG ESMTP service ready at<foo..sendgrid.net 

und ich bekomme auch eine erfolgreiche Authentifizierung zurückgegeben.

jedoch auf das Senden einer E-Mail erhalte ich die folgenden drei Fehler

error 1 550 Unauthenticated senders not allowed 
error 2 503 Must have sender before recipient 
error 3 503 Must have valid receiver and originator 

Das bedeutet also, dass ich die Reihenfolge von Absender und Empfänger in meinem SMTP-Modul ändern muss. Intern nehme ich ein ankommendes ByteArray und konvertiere zu base64 string, um E-Mails mit angehängten Dateien zu senden.

Also, wie würde ich den folgenden Code-Auszug ändern?

 writeUTFBytes ("MAIL FROM: <"+pFrom+">\r\n"); 
     writeUTFBytes ("RCPT TO: <"+pDest+">\r\n"); 
     writeUTFBytes ("DATA\r\n"); 
     writeUTFBytes ("From: "+pFrom+"\r\n"); 
     writeUTFBytes ("To: "+pDest+"\r\n"); 

Dies ist die gesamte Klasse, die ich verwende. Ich rufe die Authentifizierung nur einmal nach der Initialisierung der Klasse und dann sendAttachedMail beim Senden von E-Mails mit Bildanhängen an. Und beim Testen eines lokalen SMTP-Server ohne Authentifizierung verwenden, funktioniert alles einwandfrei (E-Mails und Bildanhänge gesendet)

package org.bytearray.smtp.mailer 
{ 
    import flash.events.ProgressEvent; 
    import flash.net.Socket; 
    import flash.utils.ByteArray; 
    import flash.utils.getTimer; 

    import org.bytearray.smtp.crypto.MD5; 
    import org.bytearray.smtp.encoding.Base64; 
    import org.bytearray.smtp.events.SMTPEvent; 
    import org.bytearray.smtp.infos.SMTPInfos; 

    public class SMTPMailer extends Socket 
    { 
     private var sHost:String; 
     private var buffer:Array = new Array(); 

     // regexp pattern 
     private var reg:RegExp = /^\d{3}/img; 

     // PNG, JPEG header values 
     private static const PNG:Number = 0x89504E47; 
     private static const JPEG:Number = 0xFFD8; 

     // common SMTP server response codes 
     // other codes could be added to add fonctionalities and more events 
     private static const ACTION_OK:Number = 0xFA; 
     private static const AUTHENTICATED:Number = 0xEB; 
     private static const DISCONNECTED:Number = 0xDD; 
     private static const READY:Number = 0xDC; 
     private static const DATA:Number = 0x162; 
     private static const BAD_SEQUENCE:Number = 0x1F7; 

     public function SMTPMailer (pHost:String, pPort:int) 
     { 
      super (pHost, pPort);   
      sHost = pHost; 
      addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler,false,0,true); 
     } 

     public function reset():void{ 
      removeEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler); 
     } 

     /* 
     * This method lets you authenticate, just pass a login and password 
     */ 
     public function authenticate (pLogin:String, pPass:String):void 
     { 
      writeUTFBytes ("EHLO "+sHost+"\r\n"); 
      writeUTFBytes ("AUTH LOGIN\r\n"); 
      writeUTFBytes (Base64.encode64String (pLogin)+"\r\n"); 
      writeUTFBytes (Base64.encode64String (pPass)+"\r\n"); 
      flush(); 
     } 

     /* 
     * This method is used to send emails with attached files and HTML 
     * takes an incoming Bytearray and convert it to base64 string 
     * for instance pass a JPEG ByteArray stream to get a picture attached in the mail ;) 
     */ 
     public function sendAttachedMail (pFrom:String, pDest:String, pSubject:String, pMess:String, pByteArray:ByteArray, pFileName:String) :void 
     { 
      try { 

       writeUTFBytes ("HELO "+sHost+"\r\n"); 
       writeUTFBytes ("MAIL FROM: <"+pFrom+">\r\n"); 
       writeUTFBytes ("RCPT TO: <"+pDest+">\r\n"); 
       writeUTFBytes ("DATA\r\n"); 
       writeUTFBytes ("From: "+pFrom+"\r\n"); 
       writeUTFBytes ("To: "+pDest+"\r\n"); 
       writeUTFBytes ("Date : "+new Date().toString()+"\r\n"); 
       writeUTFBytes ("Subject: "+pSubject+"\r\n"); 
       writeUTFBytes ("Mime-Version: 1.0\r\n"); 

       var md5Boundary:String = MD5.hash (String (getTimer())); 

       writeUTFBytes ("Content-Type: multipart/mixed; boundary=------------"+md5Boundary+"\r\n"); 
       writeUTFBytes("\r\n"); 
       writeUTFBytes ("This is a multi-part message in MIME format.\r\n"); 
       writeUTFBytes ("--------------"+md5Boundary+"\r\n"); 
       writeUTFBytes ("Content-Type: text/html; charset=UTF-8; format=flowed\r\n"); 
       writeUTFBytes("\r\n"); 
       writeUTFBytes (pMess+"\r\n"); 
       writeUTFBytes ("--------------"+md5Boundary+"\r\n"); 
       writeUTFBytes (readHeader (pByteArray, pFileName)); 
       writeUTFBytes ("Content-Transfer-Encoding: base64\r\n"); 
       writeUTFBytes ("\r\n"); 

       var base64String:String = Base64.encode64 (pByteArray, true); 

       writeUTFBytes (base64String+"\r\n"); 
       writeUTFBytes ("--------------"+md5Boundary+"-\r\n"); 
       writeUTFBytes (".\r\n"); 
       flush(); 

      } catch (pError:Error) 
      { 
       trace("Error : Socket error, please check the sendAttachedMail() method parameters"); 
       trace("Arguments : " + arguments);  
      } 
     } 

     /* 
     * This method is used to send HTML emails 
     * just pass the HTML string to pMess 
     */ 
     public function sendHTMLMail (pFrom:String, pDest:String, pSubject:String, pMess:String):void 
     { 
      try 
      {   
       writeUTFBytes ("HELO "+sHost+"\r\n"); 
       writeUTFBytes ("MAIL FROM: <"+pFrom+">\r\n"); 
       writeUTFBytes ("RCPT TO: <"+pDest+">\r\n"); 
       writeUTFBytes ("DATA\r\n"); 
       writeUTFBytes ("From: "+pFrom+"\r\n"); 
       writeUTFBytes ("To: "+pDest+"\r\n"); 
       writeUTFBytes ("Subject: "+pSubject+"\r\n"); 
       writeUTFBytes ("Mime-Version: 1.0\r\n"); 
       writeUTFBytes ("Content-Type: text/html; charset=UTF-8; format=flowed\r\n"); 
       writeUTFBytes("\r\n"); 
       writeUTFBytes (pMess+"\r\n"); 
       writeUTFBytes (".\r\n"); 
       flush(); 

      } catch (pError:Error) 
      { 
       trace("Error : Socket error, please check the sendHTMLMail() method parameters"); 
       trace("Arguments : " + arguments); 
      } 
     } 

     /* 
     * This method automatically detects the header of the binary stream and returns appropriate headers (jpg, png) 
     * classic application/octet-stream content type is added for different kind of files 
     */ 
     private function readHeader (pByteArray:ByteArray, pFileName:String):String 
     { 
      pByteArray.position = 0; 

      var sOutput:String = null; 

      if (pByteArray.readUnsignedInt() == SMTPMailer.PNG) 
      { 
       sOutput = "Content-Type: image/png; name="+pFileName+"\r\n"; 
       sOutput += "Content-Disposition: attachment filename="+pFileName+"\r\n"; 
       return sOutput; 
      } 

      pByteArray.position = 0; 

      if (pByteArray.readUnsignedShort() == SMTPMailer.JPEG) 
      { 
       sOutput = "Content-Type: image/jpeg; name="+pFileName+"\r\n"; 
       sOutput += "Content-Disposition: attachment filename="+pFileName+"\r\n"; 
       return sOutput; 
      } 

      sOutput = "Content-Type: application/octet-stream; name="+pFileName+"\r\n"; 
      sOutput += "Content-Disposition: attachment filename="+pFileName+"\r\n"; 

      return sOutput; 
     } 

     // check SMTP response and dispatch proper events 
     // Keep in mind SMTP servers can have different result messages the detection can be modified to match some specific SMTP servers 
     private function socketDataHandler (pEvt:ProgressEvent):void 
     { 
      var response:String = pEvt.target.readUTFBytes (pEvt.target.bytesAvailable); 
      buffer.length = 0; 
      var result:Array = reg.exec(response); 

      while (result != null) 
      { 
       buffer.push (result[0]); 
       result = reg.exec(response); 
      } 

      var smtpReturn:Number = buffer[buffer.length-1]; 
      var smtpInfos:SMTPInfos = new SMTPInfos (smtpReturn, response); 

      if (smtpReturn == SMTPMailer.READY) 
       dispatchEvent (new SMTPEvent (SMTPEvent.CONNECTED, smtpInfos)); 

      else if (smtpReturn == SMTPMailer.ACTION_OK && (response.toLowerCase().indexOf ("queued") != -1 || response.toLowerCase().indexOf ("accepted") != -1 || 
        response.toLowerCase().indexOf ("qp") != -1)) dispatchEvent (new SMTPEvent (SMTPEvent.MAIL_SENT, smtpInfos)); 
      else if (smtpReturn == SMTPMailer.AUTHENTICATED) 
       dispatchEvent (new SMTPEvent (SMTPEvent.AUTHENTICATED, smtpInfos)); 
      else if (smtpReturn == SMTPMailer.DISCONNECTED) 
       dispatchEvent (new SMTPEvent (SMTPEvent.DISCONNECTED, smtpInfos)); 
      else if (smtpReturn == SMTPMailer.BAD_SEQUENCE) 
       dispatchEvent (new SMTPEvent (SMTPEvent.BAD_SEQUENCE, smtpInfos)); 
      else if (smtpReturn != SMTPMailer.DATA) 
       dispatchEvent (new SMTPEvent (SMTPEvent.MAIL_ERROR, smtpInfos));  
     } 
    } 
} 
+0

Hinweis: Ich verwende diese SMTP-Bibliothek ... http: //www.bytearray.org/? P = 27 https://code.google.com/archive/p/smtpmailer/downloads If Du kannst es mit SendGrid arbeiten lassen und die Antwort liefern, die ich belohnen werde +500 –

Antwort

0

So this suggests to me that I must change the order of sender and recipient in my SMTP module.

Die Reihenfolge der Befehle korrekt ist. Stattdessen sollten Sie bei der ersten Fehlermeldung für die eigentliche Ursache des Problems aussehen:

error 1 550 Unauthenticated senders not allowed 

Dies sagen Ihnen, dass die server requires authentication vom Sender, das heißt die Verwendung der SMTP AUTH Befehle mit Benutzerdaten. Versuche, E-Mails von einem nicht authentifizierten Absender zu senden, werden zurückgewiesen. Wenn MAIL FROM fehlschlägt, schlägt RCPT TO fehl. Wenn RCPT TO fehlschlägt, schlägt DATA fehl. Und so weiter.

Verwenden des SMTP-Befehl, um den EHLOAUTH Schemen (und andere Fähigkeiten) zu entdecken, dass der Server unterstützt, und dann vor dem Senden MAIL FROM den entsprechenden AUTH Befehl senden.

+0

Ja, ich weiß, aber wenn meine Anwendung startet, kann ich eine erfolgreiche Authentifizierung sehen. Es ist eine XML-Socket-Verbindung. Da ein einziger Benutzer (eine Anwendung) authentifiziert werden muss, muss ich mich jedes Mal neu authentifizieren, wenn ich eine E-Mail sende. Meine Annahme ist, dass die erste Fehlermeldung direkt mit dem 2. und 3. Fehler verbunden war, dh wenn ich den Empfänger ändere, sollte die Senderreihenfolge korrekt error1 verschwinden. –

+0

@eco_bach: SMTP-Authentifizierung wird für jede SMTP-Verbindung (d. H. TCP-Verbindung) durchgeführt. Von dem Code, den Sie anzeigen, kann ich überhaupt keine Authentifizierung sehen. Und ich weiß auch nicht, was du mit "XML-Socket" meinst, SMTP benötigt einen TCP-Socket. Vielleicht sollten Sie mehr Code zeigen, insbesondere die erste Verbindung zum SMTP-Server und wie Sie sich erfolgreich gegen den SMTP-Server authentifizieren. –

+0

Verwenden dieser Bibliothek http://www.bytearray.org/?p=27 https://code.google.com/archive/p/smtpmailer/downloads Bearbeiten des ersten Posts –

0

UPDATE: Entschuldigung, ich hatte Ihre Klasse nicht sorgfältig untersucht. Sie haben bereits eine Authentifizierungsmethode und es tut, was es sollte. Also, während du denkst, dass du es nennst, wird es entweder nicht angerufen, oder es scheitert.

So sorgfältig prüfen, ob die Verbindung, die Sie in und die Verbindung sind Authentifizieren Sie E-Mails in sind tatsächlich die gleiche Verbindung, und Sie sind nicht vielleicht unwissentlich erneut die Schaffung einer neuen, nicht authentifizierte Verbindung sind zu senden .

Auch müssen Sie wirklich die Ergebnisse der Operationen überprüfen, die Sie durchführen - in diesem Fall die Authentifizierung. Ist es wirklich erfolgreich?

Alte Antwort

Von Ihrem Beispiel und welche wenig Dokumentation fand ich, was Sie brauchen - oder zumindest erscheinen müssen - zwei Authentifizierungen. Wahrscheinlich with the same username and password.

Die erste, die Sie richtig machen, ist die 'XML-Socket-Verbindung', die Sie auf die SMTP-Schicht bringt.

Jetzt benötigen Sie die zweite Authentifizierung. Sonst werden alle Befehle fehlschlagen und die Fehler werden ineinander übergehen, während der "echte" Fehler, wie Steffen Ulrich bemerkte, der erste ist.

writeUTFBytes ("HELO "+sHost+"\r\n"); 

// Inner authentication 
writeUTFBytes ("AUTH LOGIN\r\n"); 
writeUTFBytes (Base64.encode64 (username) + "\r\n"); 
writeUTFBytes (Base64.encode64 (password) + "\r\n"); 
// HERE you really should read the stream and ensure it says 
// "Authentication OK" -- or something to that effect. 

writeUTFBytes ("MAIL FROM: <"+pFrom+">\r\n"); 
Verwandte Themen