gmail api发送邮件无法运行C#控制台应用程序(身份验证范围不足)
我是谷歌云/gmail API新手。在c#中,我想使用他们的gmail api:gmail api发送邮件无法运行C#控制台应用程序(身份验证范围不足),c#,.net,google-cloud-platform,gmail-api,C#,.net,Google Cloud Platform,Gmail Api,我是谷歌云/gmail API新手。在c#中,我想使用他们的gmail api: 登录谷歌云-works 阅读列表项目-作品 发送电子邮件-不起作用 步骤3中的Api返回请求范围不足(403)我有信心登录到我的云帐户:我最怀疑的代码是: static string[] Scopes = { GmailService.Scope.GmailAddonsCurrentActionCompose, GmailService.Scope.GmailAddonsCurrentMessageAction
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("=", "");
}
}
好:
我决定将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;
}
private static GoogleClientSecrets GetSecretsFromEnvironment()
{
var environmentConfiguration=new ConfigurationBuilder()
.AddenEnvironmentVariables()
.Build();
var secretsEnv=environmentConfiguration[“GoogleSecrets”];
var secrets=JsonConvert.DeserializeObject(secretsEnv);
归还机密;
}
appsettings.json
{
"MailSettings": {
"account": "mark.d.wardell@gmail.com",
"subject": "Please Confirm Account",
"from": "mark.d.wardell@gmail.com",
"HTML": "<b>Hello {0}</b>"
}
}
{
“邮件设置”:{
“账户”:“mark.d。wardell@gmail.com",
“主题”:“请确认账户”,
“from”:“mark.d。wardell@gmail.com",
HTML:“你好{0}”
}
}
由google云控制台提供的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("=", "");
}
}
}
使用Google.api.Auth.OAuth2;
使用Google.api.Gmail.v1;
使用Google.api.Services;
使用Google.api.Util.Store;
使用Microsoft.Extensions.Configuration;
使用Newtonsoft.Json;
使用制度;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用System.Net.Mail;
使用系统线程;
使用System.Threading.Tasks;
名称空间SendMail
{
班级计划
{
//如果修改这些作用域,请删除以前保存的凭据
//位于~/.credentials/gmail-dotnet-quickstart.json
静态字符串[]Scopes={GmailService.Scope.gmailddonscurrentactioncompose,GmailService.Scope.gmailddonscurrentMessageAction,GmailService.Scope.GmailSend};
静态字符串ApplicationName=“Restful rest-Place”;
静态异步任务主(参数字符串[]args)
{
尝试
{
var configuration=new ConfigurationBuilder()
.AddJsonFile(“appsettings.json”)
.Build();
字典设置;
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();
字符串credPath=“token.json”;
UserCredential gcredential=等待GoogleWebAuthorizationBroker.AuthorizationAsync(
秘密,秘密,
范围,
邮件设置[“帐户”],
取消令牌。无,
新文件数据存储(credPath,true));
var service=new-GmailService(new-BaseClientService.Initializer()
{
HttpClientInitializer=gcredential,
ApplicationName=ApplicationName,
});
SendItTwo(服务、邮件设置);
Console.WriteLine()
}捕获(例外情况除外)
{
控制台写入线(例如消息);
}
}
私有静态GoogleClientSecrets GetSecretsFromenEnvironment()
{
var environmentConfiguration=new ConfigurationBuilder()
.AddenEnvironmentVariables()
.Build();
var secretsEnv=environmentConfiguration[“GoogleSecrets”];
var secrets=JsonConvert.DeserializeObject(secretsEnv);
归还机密;
}
公共静态void SendItTwo(gmail服务gmail,字典dict)
{
MailMessage mailmsg=新邮件();
{
mailmsg.Subject=dict[“Subject”];
mailmsg.Body=string.Format(dict[“HTML”]、dict[“link”]);
mailmsg.From=新邮件地址(dict[“From”]);
mailmsg.To.Add(新邮件地址(dict[“To”]);
mailmsg.IsBodyHtml=true;
}
////如果指定,请添加附件
如果(附件)
{
如果(文件.Exists(dict[“附件”]))
{
附件数据=新附件(dict[“附件]);
mailmsg.Attachments.Add(数据);
}否则
{
Console.WriteLine(“错误:无效附件”);
}
}
//将邮件消息设置为Mime消息
MimeKit.MimeMessage MimeMessage=MimeKit.MimeMessage.CreateFromMailMessage(mailmsg);
Google.api.Gmail.v1.Data.Message finalmessage=new Google.api.Gmail.v1.Data.Message();
finalmessage.Raw=Base64UrlEncode(mimessage.ToString());
var result=gmail.Users.Messages.Send(finalmessage,“me”).Execute();
}
公共静态字符串Base64UrlEncode(字符串输入)
{
var inputBytes=System.Text.Encoding.UTF8.GetBytes(输入);
返回Convert.ToBase64String(inputBytes)。替换(“+”,“-”)。替换(“/”,“”)。替换(“=”,”);
}
}
}
好的:
我决定将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;
}
private static GoogleClientSecrets GetSecretsFromEnvironment()
{
var environmentConfiguration=new ConfigurationBuilder()
.AddenEnvironmentVariables()
.Build();