尝试使用 Google.Apis.Gmail 从 asp.net core web api 应用程序从谷歌工作区发送电子邮件时出错

Posted

技术标签:

【中文标题】尝试使用 Google.Apis.Gmail 从 asp.net core web api 应用程序从谷歌工作区发送电子邮件时出错【英文标题】:Error while trying to send email from google workspace from asp.net core web api app using Google.Apis.Gmail 【发布时间】:2021-12-11 19:06:31 【问题描述】:

我正在尝试使用此代码从我的 google 工作区帐户发送电子邮件:

using (var stream =
          new FileStream("credentials.json", FileMode.Open, FileAccess.Read))

    var credential = ServiceAccountCredential.FromServiceAccountData(stream);
    service = new GmailService(new BaseClientService.Initializer()
    
        HttpClientInitializer = credential,
        ApplicationName = ApplicationName,
    );

    var email = MimeMessage.CreateFromMailMessage(new System.Net.Mail.MailMessage("EMAILADDRESS", destinationEmailAddress, "Verification code", $"Your verification code is messageBody"));

    Message message = new Message();

    byte[] blob;

    using (var memory = new MemoryStream())
    
        email.WriteTo(memory);
        blob = memory.ToArray();
    

    message.Raw = await credential.SignBlobAsync(blob);
    await service.Users.Messages.Send(message, "me").ExecuteAsync();

但我得到以下异常:

Google.Apis.Requests.RequestError\n前置条件检查失败。 [400]\n错误 [\n\tMessage[前置条件检查失败。]位置[-]原因[failedPrecondition]域[全局]\n]\n

我做错了什么?是否有正确的指南?

【问题讨论】:

【参考方案1】:

您遇到的问题是您通过服务帐户使用 Gmail,并且您没有正确配置域范围内的委派给您工作区帐户上的用户。按照本指南使用服务帐户配置您的工作区帐户。 Perform Google Workspace Domain-Wide Delegation of Authority

以下代码应向您展示如何对其进行授权。请注意 CreateWithUser 方法,该方法设置您希望将服务帐户委派为的用户。

class Program
    
        private static readonly string[] Scopes = GmailService.Scope.GmailSend;

        private static readonly string PathToServiceAccountKeyFile =
            @"C:\YouTube\workspaceserviceaccount-e4823a933ae3.json";

        private static readonly string workspaceAdmin = "xxxx@daimto.com";
        private static readonly string sendEmailTo = "xxxx@gmail.com";

        static async Task Main(string[] args)
        
            Console.WriteLine("Hello World!");

            var credential = LoadGoogleCredentials();
            var service = CreateDirectoryService(credential);

            var mailMessage = new System.Net.Mail.MailMessage
            
                From = new System.Net.Mail.MailAddress(workspaceAdmin),
                ReplyToList = workspaceAdmin,
                To = sendEmailTo,
                Subject = "Welcome",
                Body = "welcome new workspace user",
            ;


            var mimeMessage = MimeMessage.CreateFromMailMessage(mailMessage);

            var gmailMessage = new Message
            
                Raw = Encode(mimeMessage)
            ;

            var request = await service.Users.Messages.Send(gmailMessage, workspaceAdmin).ExecuteAsync();

            Console.ReadLine();
        

        public static string Encode(MimeMessage mimeMessage)
        
            using (MemoryStream ms = new MemoryStream())
            
                mimeMessage.WriteTo(ms);
                return Convert.ToBase64String(ms.GetBuffer())
                    .TrimEnd('=')
                    .Replace('+', '-')
                    .Replace('/', '_');
            
        

        private static GmailService CreateDirectoryService(GoogleCredential credential)
        
            return new(new BaseClientService.Initializer()
                
                    HttpClientInitializer = credential,
                    ApplicationName = "Daimto Testing Workspace with service account"
                
            );
        

        private static GoogleCredential LoadGoogleCredentials()
        
            return GoogleCredential.FromFile(PathToServiceAccountKeyFile)
                .CreateScoped(Scopes)
                .CreateWithUser(workspaceAdmin);
        
    

注意:此代码对于所有类型的应用程序都是相同的,即使我的测试代码是控制台应用程序,所使用的方法也适用于您的 asp .net 核心应用程序

来自 cmets

客户端未授权使用此方法检索访问令牌,或客户端未授权任何请求的范围

此错误消息表示您的 servcie 帐户未获得适当范围的授权。 gmail send 方法需要一个允许访问发送电子邮件GmailService.Scope.GmailSend 的范围,例如,因为我使用了 din 我的代码记得将其添加到工作区中。

完整教程Gmail api with google workspace and .net

【讨论】:

我使用这些范围授权它:googleapis.com/auth/admin.directory.user,googleapis.com/auth/admin.directory.group 现在我面临这个异常:错误:\“unauthorized_client\”,描述:\“客户端未经授权无法检索访问权限使用此方法的令牌,或者客户端未获得请求的任何范围的授权。发送电子邮件的适当范围是什么? GmailService.Scope.GmailSend

以上是关于尝试使用 Google.Apis.Gmail 从 asp.net core web api 应用程序从谷歌工作区发送电子邮件时出错的主要内容,如果未能解决你的问题,请参考以下文章

来自 Gmail API 流的 MimeMessage.Load

使用 GMAIL API 跟踪电子邮件发送状态

尝试使用环境变量从 HostingViewController 呈现 SwiftUI

我正在尝试从 pyspark 访问 mysql 表。我正在尝试使用:

尝试使用 PS 脚本从 SQL 中提取数据

尝试使用 youtube api 从 json 中提取视频 ID