使用Google OAuth 2和ASP.Net MVC发送/接收电子邮件

时间:2013-10-29 21:06:27

标签: c# asp.net-mvc google-api google-oauth

我在课堂上使用了以下内容:

public class AppFlowMetaData : FlowMetadata
{
    private static readonly IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
    {
        ClientSecrets = new ClientSecrets
        {
            ClientId = "nnnnnnnnnnnnn.apps.googleusercontent.com",
            ClientSecret = "nnnnnnn-nnnnnnnnnnnnnnn"
        },
        Scopes = new[] { CalendarService.Scope.Calendar },
        DataStore = new FileDataStore("Calendar.Api.Auth.Store")
    });

    public override string GetUserId(System.Web.Mvc.Controller controller)
    {
        var user = controller.Session["user"];
        if (user == null)
        {
            user = Guid.NewGuid();
            controller.Session["user"] = user;
        }
        return user.ToString();
    }

    public override IAuthorizationCodeFlow Flow
    {
        get { return flow; }
    }
}

以下是控制器:

public async Task<ActionResult> TestAsync(CancellationToken token)
    {
        var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetaData()).AuthorizeAsync(token);   
        if(result.Credential != null)
        {
            var service = new CalendarService(new BaseClientService.Initializer
            {
                HttpClientInitializer = result.Credential,
                ApplicationName = "Calendar Test"
            });
            IList<CalendarListEntry> results = service.CalendarList.List().Execute().Items;
            List<Event> model = new List<Event>();
            foreach (var calendar in results)
            {
                Google.Apis.Calendar.v3.EventsResource.ListRequest request = service.Events.List(calendar.Id);
                var events = request.Execute().Items;

                foreach (var e in events)
                {
                    model.Add(e);
                }
            }
            return View(model);
        }
        else
        {
            return new RedirectResult(result.RedirectUri);
        }
    }

这很好用,我希望能够使用相同的流程使用gmail发送邮件,但我无法在Google Api文档中找到范围或任何详细信息(这很坦率地说很糟糕)基于相同的过程执行此操作。我在其他地方看过使用Imap的第三方库,但这依赖于传递我不想做的用户名/密码。

有人可以帮我修改上面用于Gmail吗?

1 个答案:

答案 0 :(得分:1)

我意识到这个问题现在已经有一年了,但这是我发现提出这个问题的少数人之一。我已设法使用以下代码通过Gmail API发送电子邮件。当用户登录我的站点时,我正在保存AccessToken和RefreshToken,然后将它们插入到下面的方法中。感谢Jason Pettys指出我正确的方向(http://jason.pettys.name/2014/10/27/sending-email-with-the-gmail-api-in-net-c/)。

public string SendMail(string fromAddress, string toEmail, string subject, string body)
    {
        //Construct the message
        var mailMessage = new System.Net.Mail.MailMessage(fromAddress, toEmail, subject, body);
        mailMessage.ReplyToList.Add(new MailAddress(fromAddress));

        //Specify whether the body is HTML
        mailMessage.IsBodyHtml = true;

        //Convert to MimeMessage
        MimeMessage message = MimeMessage.CreateFromMailMessage(mailMessage);
        var rawMessage = message.ToString();

        var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = new ClientSecrets
            {
                ClientId = "GoogleClientId",
                ClientSecret = "GoogleClientSecret"
            },
            Scopes = new[] { GmailService.Scope.GmailCompose }
        });

        var token = new Google.Apis.Auth.OAuth2.Responses.TokenResponse()
            {
                AccessToken = MethodToRetrieveSavedAccessToken(),
                RefreshToken = MethodToRetrieveSavedRefreshToken()
            };

        //In my case the username is the same as the fromAddress
        var gmail = new GmailService(new Google.Apis.Services.BaseClientService.Initializer()
            {
                ApplicationName = "App Name",
                HttpClientInitializer = new UserCredential(flow, fromAddress, token)
            });

        var result = gmail.Users.Messages.Send(new Message
            {
                Raw = Base64UrlEncode(rawMessage)
            }, "me").Execute();
        return result.Id;
    }

    /// <summary>
    /// Converts input string into a URL safe Base64 encoded string. Method thanks to Jason Pettys.
    /// http://jason.pettys.name/2014/10/27/sending-email-with-the-gmail-api-in-net-c/
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    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("=", "");
    }