Создание сообщения для Gmail API на C#

Я рассматриваю возможность использования Gmail API в приложении, над которым работаю. Однако я не уверен, как изменить их примеры Java или Python на С#. Как именно изменяется существующий образец?

Пример найден здесь.


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 к каждому запросу. Возможно, вы сможете просто использовать конструктор 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. То, что вы должны искать, это «с# создать электронную почту» (возможно, добавив «RFC 2822», поскольку это RFC, который определяет формат для этих электронных писем). Когда у вас есть такое действительное «сообщение электронной почты» (настоящее, полное содержимое электронной почты, которое вы можете использовать с SMTP или IMAP и т. д.), то его использование с API Gmail должно быть довольно тривиальным.

person Eric D    schedule 14.07.2014
comment
Ты прав. Я разместил сообщение в Gmail API, думая, что кто-то, возможно, сталкивался с этим раньше и получил ответ, но я должен направить его больше на С#. Спасибо. - person muttley91; 14.07.2014
comment
@rar Ты что-нибудь нашел? Пытаюсь решить ту же проблему. - person pettys; 28.10.2014
comment
К сожалению нет. Нам пришлось отказаться от Gmail API, так как он не работал, и у нас не было много времени, чтобы тратить на него, когда мы могли просто использовать более простой отправитель электронной почты. Google действительно мог бы улучшить свою документацию по этому вопросу... - person muttley91; 28.10.2014
comment
@rar Спасибо за ответ. Наконец-то мне удалось получить необработанные байты сообщения RFC 2822 с помощью пакета nuget AE.Net.Mail — github.com/andyedinborough /aenetmail. Я знаю, что вы имеете в виду по поводу Gmail API — мне потребовался целый день, чтобы, наконец, заставить его отправлять сообщения. - person pettys; 28.10.2014
comment
rar/pettys: в чем именно была проблема, которую вы не смогли понять, или как можно улучшить документацию? Самая сложная часть IMO, по-видимому, заключается в создании сообщения электронной почты, и это на самом деле не относится к API, вам нужно сделать то же самое, используете ли вы SMTP, API или IMAP. Когда у вас есть строка сообщения электронной почты, просто base64url, кодирующая ее и отправляющая ее по правильному URL-адресу, довольно тривиальна, и есть хороший код Java, показывающий это. - person Eric D; 28.10.2014