Създаване на съобщение за API на Gmail в C#

Гледам да използвам API на Gmail в приложение, върху което работя. Не съм сигурен обаче как да променя техните примери за Java или Python на C#. Как точно се променя съществуващата извадка?

Примерът е намерен тук.


person muttley91    schedule 14.07.2014    source източник
comment
Java е толкова близо до C#, сигурно сте се опитвали да го конвертирате и сте се провалили по някакъв начин? Може би публикуването на това, което сте се опитали да конвертирате, би било добро начало за хората, които да ви помогнат там, където грешите   -  person Prescott    schedule 14.07.2014
comment
Ами търся еквиваленти на MimeMessage, Properties и т.н. и бързото търсене в Гугъл не помогна с това.   -  person muttley91    schedule 14.07.2014
comment
Всички API на Google са REST API. Документите ви казват какви параметри трябва да влязат във вашите извиквания на REST API.   -  person Casey    schedule 15.07.2014


Отговори (3)


Ето какво успях да накарам да работи, използвайки MimeKit.

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("=", "");
}

Забележка: Ако получавате проблем с отхвърляне на имейл, това вероятно се дължи на това, че не сте задали полето ReplyToList. Вижте: Отхвърляне на имейли от API на GMail

Актуализация: Както е отбелязано в коментарите по-долу, има по-добър вариант от използването на mimeMessage.ToString(). Вижте: Изпращане на имейл с Gmail API, кодиране на гръцки знаци в тяло

person Xtros    schedule 03.10.2016
comment
Не мисля, че трябва да използвате mimeMessage.ToString(). Според забележки в namespace MimeKit: In general, the string returned from this method SHOULD NOT be used for serializing the message to disk. It is recommended that you use MimeKit.MimeMessage.WriteTo(System.IO.Stream,System.Threading.CancellationToken) instead. - person Doan Van Thang; 01.02.2021
comment
@DoanVanThang Да, това е възможно. Може да се е променило през последните пет години или може би винаги е трябвало да бъде така. Благодаря за бакшиша! - person Xtros; 02.02.2021
comment
Имах проблем с mimeMessage.ToString(). Героите ã ç ã á .. не биха дошли правилно. Намерих решение на: stackoverflow.com/questions/55402719/ - person ChrCury78; 16.06.2021

Това беше труден проблем за решаване, но в крайна сметка го получих. Използвах пакета NuGet AE.Net.Mail, за да получа RFC 2822 бита.

using System.IO;
using System.Net.Mail;
using Google.Apis.Gmail.v1;
using Google.Apis.Gmail.v1.Data;

public class TestEmail {

  public void SendIt() {
    var msg = new AE.Net.Mail.MailMessage {
      Subject = "Your Subject",
      Body = "Hello, World, from Gmail API!",
      From = new MailAddress("[you]@gmail.com")
    };
    msg.To.Add(new MailAddress("[email protected]"));
    msg.ReplyTo.Add(msg.From); // Bounces without this!!
    var msgStr = new StringWriter();
    msg.Save(msgStr);

    var gmail = new GmailService(MyOwnGoogleOAuthInitializer);
    var result = gmail.Users.Messages.Send(new Message {
      Raw = Base64UrlEncode(msgStr.ToString())
    }, "me").Execute();
    Console.WriteLine("Message ID {0} sent.", result.Id);
  }

  private static string Base64UrlEncode(string input) {
    var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
    // Special "url-safe" base64 encode.
    return Convert.ToBase64String(inputBytes)
      .Replace('+', '-')
      .Replace('/', '_')
      .Replace("=", "");
  }
}

Същият код с малко допълнителен анализ и причини са публикувани тук: http://jason.pettys.name/2014/10/27/sending-email-with-the-gmail-api-in-net-c/

person pettys    schedule 28.10.2014
comment
Опитах се да използвам вашия код, но получавам грешка за грешка CS0103: Името „Контекст“ не съществува в текущия контекст на Context.GoogleOAuthInitializer. Откъде получавате контекст? - person Rossini; 18.11.2014
comment
@Rossini Съжалявам за объркването там -- това е препратка към моя собствен код, който връща Google.Apis.Services.BaseClientService.Initializer, който е настроен да добавя токена на OAuth2 Bearer към всяка заявка. Може да сте в състояние просто да използвате конструктора по подразбиране GmailService() - зависи от това как вашата GmailService удостоверява. Ще актуализирам кода си, за да се опитам да направя това по-ясно. - person pettys; 18.11.2014
comment
Този код работи добре за имейл с обикновен текст. Но не работи с HTML имейл + прикачен файл. - person Allen King; 24.01.2015
comment
За всеки, който търси това в бъдеще, уверете се, че използвате пакета AE.Net.Mail Nuget (nuget.org/packages/AE.Net.Mail), а не System.Net.Mail (msdn.microsoft.com/en-us/library/system.net.mail(v=vs.110).aspx). Те са много подобни, но работят малко по-различно (напр. System.Net.Mail.MailMessage няма метода Save) - person derekantrican; 09.06.2017

Изглежда, че това всъщност не е проблем с API на Gmail. Това, което трябва да търсите, е "c# create email" (потенциално добавяне на "RFC 2822", тъй като това е RFC, който определя формата за тези имейли). След като имате такова валидно „имейл съобщение“ (истинското, цялото имейл съдържание, което можете да използвате с SMTP или IMAP и т.н.), тогава използването му с API на Gmail би трябвало да е доста тривиално.

person Eric D    schedule 14.07.2014
comment
Прав си. Публикувах под Gmail API, мислейки, че някой може да е попадал на това преди и да има отговор, но трябва да го насоча повече към C#. Благодаря. - person muttley91; 14.07.2014
comment
@rar Намерихте ли нещо? Опитвам се да реша същия проблем. - person pettys; 28.10.2014
comment
За съжаление не. Трябваше да изоставим API на Gmail, тъй като не работеше и нямахме много време за него, когато можехме просто да използваме по-опростен подател на имейл. Google наистина може да подобри документацията си по този... - person muttley91; 28.10.2014
comment
@rar Благодаря за отговора. Най-накрая успях да получа необработените байтове на съобщението RFC 2822, използвайки nuget пакет AE.Net.Mail - github.com/andyedinborough /aenetmail. Знам какво имате предвид за API на Gmail – отне ми цял ден, за да го накарам най-накрая да изпрати съобщение. - person pettys; 28.10.2014
comment
rar/pettys: какъв точно беше проблемът, който не можахте да разберете или как могат да се подобрят документите? Най-трудната част от IMO изглежда е създаването на имейл съобщение и това не е специфично за API, трябва да направите същото, независимо дали използвате SMTP или API или IMAP. След като имате низа на имейл съобщението, просто base64url го кодира и го ПУБЛИКУВА в правилния URL е доста тривиално и има добър Java код, който го показва. - person Eric D; 28.10.2014