c# - 尝试使用 Google.Apis.Gmail 从 asp.net core web api 应用程序从谷歌工作区发送电子邮件时出错
问题描述
我正在尝试使用以下代码从我的 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
我究竟做错了什么?是否有直接的指南来做到这一点?
解决方案
您遇到的问题是您正在使用带有服务帐户的 Gmail,并且您没有正确配置域范围内的委派给您工作区帐户上的用户。按照本指南使用服务帐户配置您的工作区帐户。执行 Google Workspace 域范围的授权
以下代码应向您展示如何授权它。请注意 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 核心应用程序
来自评论
客户端未授权使用此方法检索访问令牌,或者客户端未授权任何请求的范围
此错误消息意味着您的 servcie 帐户未获得适当范围的授权。gmail 发送方法需要一个允许访问发送电子邮件的范围,GmailService.Scope.GmailSend
例如,因为我已经使用了我的代码,所以记得将它添加到工作区中。
带有 google 工作区和 .net 的完整教程Gmail api
推荐阅读
- android - 迁移到 androidX 后,Retrofit 界面中的 Kapt NonExistentClass 异常
- javascript - fancybox 两个图像显示在同一个窗口
- python - 带有“+”选项的 argparse
- javascript - 用另一个 HTML 标记将 HTML 标记包装在纯字符串中
- javascript - React Native 未处理的异常未在 ErrorUtils 中捕获 & 发布 APK 显示空白屏幕而不是在 JS 异常上崩溃
- android - 在 Android Kotlin 中,assertNotNull 导致单元测试无法运行
- javascript - 使用不同的数据属性使多个计数器计数
- javascript - 如何在类方法中处理 redux 道具
- android - 无法在 Android Studio 模拟器中加载应用程序
- javascript - 如何在ngrx/effect(redux-observable)中调度多个动作?