2015-01-24 9 views
7

Verwendung von GMail API in .Net. Erstellen von Nachrichten mit Net.Mail.MailMessage Verwenden Sie dann MimeKit, um MimeMessage zu erstellen (mit diesem Befehl senden Sie Anhang + HTML-Nachricht). Übergabe von MimeMessage.ToString an Base64-Encoder. Kein API-Fehler Code läuft durch ok. Ich kann die Nachricht auf der gesendeten Seite in Google Mail sehen. Mail sieht perfekt aus (und die Nachricht sendet tatsächlich die Nachrichten-ID zurück). Aber dann gibt es die folgende angehängte Nachricht an diese Mail in Gmail.GMail API E-Mails Bouncing

Bounce <[email protected]> 

An error occurred. Your message was not sent. 

Wie üblich, keine weiteren Informationen von Google. Wie behebe ich das?

 Dim msg = New Net.Mail.MailMessage 
     msg.Subject = subject 
     msg.To.Add(New MailAddress(ToEmail)) 
     msg.From = New MailAddress(FromEmail, SenderName) 
     msg.ReplyTo = New MailAddress(FromEmail, SenderName) 
     msg.Body = bodyText 
     msg.IsBodyHtml = True 

     If Not String.IsNullOrWhiteSpace(fileAttachment) Then 
      If System.IO.File.Exists(fileAttachment) Then 
       Dim Attachment As New Net.Mail.Attachment(fileAttachment, "application/pdf") 
       msg.Attachments.Add(Attachment) 
      End If 
     End If 
     Dim message As MimeMessage = MimeMessage.CreateFromMailMessage(msg) 
     Dim newMsg = New Google.Apis.Gmail.v1.Data.Message() 
     newMsg.Raw = Base64UrlEncode(message.ToString) 
     GmailService.Users.Messages.Send(newMsg, "me").Execute() 



Private Function Base64UrlEncode(ByVal input As String) As String 
      Dim inputBytes = System.Text.Encoding.UTF8.GetBytes(input) 
      'Special "url-safe" base64 encode. 
      Return Convert.ToBase64String(inputBytes).Replace("+", "-").Replace("/", "_").Replace("=", "") 
     End Function 

Dies ist die Rückmeldung. Wie Sie sehen können, sieht alles gut aus. Die Arbeit mit Google APIs ist am frustrierendsten.

200 OK 

- Hide headers - 

cache-control: no-cache, no-store, max-age=0, must-revalidate 
content-encoding: gzip 
content-length: 85 
content-type: application/json; charset=UTF-8 
date: Sat, 24 Jan 2015 05:57:21 GMT 
etag: "96Z6JVARoyR8skov3RseF4DCFpA/mFWFskkdSFxyjIhRJHJuhDCBvfY" 
expires: Fri, 01 Jan 1990 00:00:00 GMT 
pragma: no-cache 
server: GSE 
vary: Origin, X-Origin 

{ 
"id": "14b1a841e4fff910", 
"threadId": "14b1a841e4fff910", 
"labelIds": [ 
    "SENT" 
] 
} 
+0

versuchen es in der [API Explorer] Laufen zu bekommen (https://developers.google.com/gmail/api/v1/reference/users/messages/send#try-it) zuerst finden http://StackOverflow.com/A/24461102/1545993 – Taifun

+0

Gleiche Ergebnisse in API Explorer. Die Nachricht wird übermittelt, aber nicht zugestellt. Ja, ich habe diese Seite gelesen. Ich mache genau das. Mein Problem ist, dass die GMail-API eine Ausnahme ausgelöst haben sollte, wenn im Format etwas nicht stimmt. Außerdem sieht die Mail perfekt aus, wenn ich den gesendeten Gmail-Ordner einchecke. Das heißt, die Datenstruktur und Formatierung war in Ordnung. Gibt es eine Möglichkeit, mit diesen brillanten Google-Entwicklern in Kontakt zu treten? –

+0

Verwenden Sie die Beispielnachricht, base64 kodieren Sie es und überprüfen Sie, ob Sie das gleiche Ergebnis erhalten, starten Sie es zuerst mit dem API-Explorer ... – Taifun

Antwort

4

Das ist verrückt. Das war das Problem.

Diese Linie

msg.ReplyTo = New MailAddress(FromEmail, SenderName) 

für welchen Gründen auch immer (ich denke, wenn FROMEMAIL und ReplyTo gleichen E-Mails) verlässt den Parameter leer RFC2822 Reply-To. Der Parameter bleibt leer, auch wenn msg.ReplyTo kommentiert ist. Unnötig zu erwähnen, dass die GMail-API offenbar Probleme mit der Möglichkeit hat, dass "Antworten" leer bleibt. Definitiv ein Programmierfehler.

Also musste ich diesen Hack in der letzten RFC2882 Nachricht tun.

inputTxt = Replace(inputTxt, "Reply-To:", "Reply-To: " & FromEmail) 

Es funktioniert jetzt.

********* wie im Kommentar unten angegeben, können Sie stattdessen MailMessage.ReplyToList.Add() verwenden, um dieses Problem zu lösen. Das Problem ist also, dass die Adresse ReplyTo in der Google Mail-API erforderlich ist (auch wenn man annehmen könnte, dass ReplyTo standardmäßig auf From E-Mail festgelegt werden sollte). **********

+1

Ja, 'Reply-To' leer gelassen ist ein Problem. Aber der Grund, warum es nicht zu URL-codierten base64 macht, ist die Verwendung von veraltetem 'MailMessage.ReplyTo'. Wenn Sie 'MailMessage.ReplyToList.Add()' stattdessen verwenden, funktioniert alles einwandfrei. – jansokoly

+0

@jansokoly ja du hast Recht –

2

Nur für den Fall jemand stolpert über diese und will eine C# Antwort, hier ist, was ich in der Lage war zu arbeiten mit der vorherigen Antwort als Leitfaden, mit MimeKit. auch

public void SendEmail(MyInternalSystemEmailMessage email) 
{ 
    var mailMessage = new System.Net.Mail.MailMessage(); 
    mailMessage.From = new System.Net.Mail.MailAddress(email.FromAddress); 
    mailMessage.To.Add(email.ToRecipients); 
    mailMessage.ReplyToList.Add(email.FromAddress); 
    mailMessage.Subject = email.Subject; 
    mailMessage.Body = email.Body; 
    mailMessage.IsBodyHtml = email.IsHtml; 

    foreach (System.Net.Mail.Attachment attachment in email.Attachments) 
    { 
     mailMessage.Attachments.Add(attachment); 
    } 

    var mimeMessage = MimeKit.MimeMessage.CreateFromMailMessage(mailMessage); 

    var gmailMessage = new Google.Apis.Gmail.v1.Data.Message { 
     Raw = Encode(mimeMessage.ToString()) 
    }; 

    Google.Apis.Gmail.v1.UsersResource.MessagesResource.SendRequest request = service.Users.Messages.Send(gmailMessage, ServiceEmail); 

    request.Execute(); 
} 

public static string Encode(string text) 
{ 
    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text); 

    return System.Convert.ToBase64String(bytes) 
     .Replace('+', '-') 
     .Replace('/', '_') 
     .Replace("=", ""); 
}