gmail api 发送邮件不起作用 C# 控制台应用程序(身份验证范围不足)
Posted
技术标签:
【中文标题】gmail api 发送邮件不起作用 C# 控制台应用程序(身份验证范围不足)【英文标题】:gmail api Send Mail not working C# Console Application (Insufficient Authentication Scopes) 【发布时间】:2021-01-06 07:21:36 【问题描述】:我是谷歌云/gmail API 的新手。在 c# 中,我想使用他们的 gmail api 来:
-
登录到谷歌云 - 工作
阅读列表项 - 作品
发送电子邮件 - 不起作用
第 3 步中的 Api 返回 Insufficient Request Scopes (403) 我确信我已登录到我的云帐户:我最怀疑的代码行是这样的:
static string[] Scopes = GmailService.Scope.GmailAddonsCurrentActionCompose, GmailService.Scope.GmailAddonsCurrentMessageAction ;
我收到了这个错误
Request had insufficient authentication scopes. [403]
Errors [
Message[Insufficient Permission] Location[ - ] Reason[insufficientPermissions] Domain[global]
]
// 代码
class Program
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-dotnet-quickstart.json
static string[] Scopes = GmailService.Scope.GmailAddonsCurrentActionCompose, GmailService.Scope.GmailAddonsCurrentMessageAction ;
static string ApplicationName = "Gmail API .NET Quickstart";
static void Main(string[] args)
UserCredential credential;
using (var stream =
new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
);
// Define parameters of request.
UsersResource.LabelsResource.ListRequest request = service.Users.Labels.List("me");
// List labels.
IList<Label> labels = request.Execute().Labels;
Console.WriteLine("Labels:");
if (labels != null && labels.Count > 0)
foreach (var labelItem in labels)
Console.WriteLine("0", labelItem.Name);
else
Console.WriteLine("No labels found.");
string plainText = "Body Test";
var newMsg = new Google.Apis.Gmail.v1.Data.Message();
newMsg.Raw = Program.Base64UrlEncode(plainText.ToString());
try
service.Users.Messages.Send(newMsg, "me").Execute();
catch (Exception ex)
Console.WriteLine(ex.Message);
/*
"Google.Apis.Requests.RequestError\r\nRequest had insufficient authentication scopes.
[403]\r\nErrors [\r\n\tMessage[Insufficient Permission] Location[ - ] Reason[insufficientPermissions] Domain[global]\r\n]\r\n" Google.GoogleApiException
*/
Console.Read();
public static string Base64UrlEncode(string input)
var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
return Convert.ToBase64String(inputBytes).Replace("+", "-").Replace("/", "_").Replace("=", "");
//从上面输出
Credential file saved to: token.json
Labels:
CHAT
SENT
INBOX
IMPORTANT
TRASH
DRAFT
SPAM
CATEGORY_FORUMS
CATEGORY_UPDATES
CATEGORY_PERSONAL
CATEGORY_PROMOTIONS
CATEGORY_SOCIAL
STARRED
UNREAD
Sent Messages
Pa0
P
Insurance
Junk E-mail
Licenses
Notes
Personal
Receipts
Travel
Work
Tickets
**Google.Apis.Requests.RequestError
Request had insufficient authentication scopes. [403]
Errors [
Message[Insufficient Permission] Location[ - ] Reason[insufficientPermissions] Domain[global]
]**
【问题讨论】:
我正在取得一些进展。此代码基于 QuickStart。我需要使用云控制台修改云 ID 本身以允许发送邮件。现在我遇到了下一个错误......当我最终获胜时,我会用结果更新这个问题 【参考方案1】:好的: 我决定将 GMAIL.API 提供的凭证文件放入单行环境变量中,然后将 JSON 转换为 GoogleClientSecrets:
private static GoogleClientSecrets GetSecretsFromEnvironment()
var environmentConfiguration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var secretsEnv = environmentConfiguration["GoogleSecrets"];
var secrets = JsonConvert.DeserializeObject<GoogleClientSecrets>(secretsEnv);
return secrets;
appsettings.json
"MailSettings":
"account": "mark.d.wardell@gmail.com",
"subject": "Please Confirm Account",
"from": "mark.d.wardell@gmail.com",
"html": "<b>Hello 0</b>"
由谷歌云控制台提供的credentials.json。我做了一个单行字符串并添加到 EnvironmentVariable
以及调用代码:
using Google.Apis.Auth.OAuth2;
using Google.Apis.Gmail.v1;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Threading;
using System.Threading.Tasks;
namespace SendMail
class Program
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-dotnet-quickstart.json
static string[] Scopes = GmailService.Scope.GmailAddonsCurrentActionCompose, GmailService.Scope.GmailAddonsCurrentMessageAction, GmailService.Scope.GmailSend ;
static string ApplicationName = "Restful Resting Place";
static async Task Main(params string[] args)
try
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
Dictionary<string, string> MailSettings;
MailSettings = configuration.GetSection("MailSettings").GetChildren().ToDictionary(x => x.Key, x => x.Value);
MailSettings.Add("to", args[0]);
MailSettings.Add("link", args[1]);
GoogleClientSecrets gSecrets = GetSecretsFromEnvironment();
string credPath = "token.json";
UserCredential gcredential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
gSecrets.Secrets,
Scopes,
MailSettings["account"],
CancellationToken.None,
new FileDataStore(credPath, true));
var service = new GmailService(new BaseClientService.Initializer()
HttpClientInitializer = gcredential,
ApplicationName = ApplicationName,
);
SendItTwo(service, MailSettings);
Console.WriteLine()
catch (Exception ex)
Console.WriteLine(ex.Message);
private static GoogleClientSecrets GetSecretsFromEnvironment()
var environmentConfiguration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var secretsEnv = environmentConfiguration["GoogleSecrets"];
var secrets = JsonConvert.DeserializeObject<GoogleClientSecrets>(secretsEnv);
return secrets;
public static void SendItTwo(GmailService gmail, Dictionary<string,string> dict)
MailMessage mailmsg = new MailMessage();
mailmsg.Subject = dict["subject"];
mailmsg.Body = string.Format(dict["HTML"],dict["link"]);
mailmsg.From = new MailAddress(dict["from"]);
mailmsg.To.Add(new MailAddress(dict["to"]));
mailmsg.IsBodyHtml = true;
////add attachment if specified
if (dict.ContainsKey("attachement"))
if (File.Exists(dict["attachment"]))
Attachment data = new Attachment(dict["attachment"]);
mailmsg.Attachments.Add(data);
else
Console.WriteLine("Error: Invalid Attachemnt");
//Make mail message a Mime message
MimeKit.MimeMessage mimemessage = MimeKit.MimeMessage.CreateFromMailMessage(mailmsg);
Google.Apis.Gmail.v1.Data.Message finalmessage = new Google.Apis.Gmail.v1.Data.Message();
finalmessage.Raw = Base64UrlEncode(mimemessage.ToString());
var result = gmail.Users.Messages.Send(finalmessage, "me").Execute();
public static string Base64UrlEncode(string input)
var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
return Convert.ToBase64String(inputBytes).Replace("+", "-").Replace("/", "_").Replace("=", "");
【讨论】:
以上是关于gmail api 发送邮件不起作用 C# 控制台应用程序(身份验证范围不足)的主要内容,如果未能解决你的问题,请参考以下文章