I'm trying to send emails based on Gmail API. I have created a project in Google Develover Console.
I referred to GmailService instance: https://developers.google.com/gmail/api/quickstart/dotnet
And here’s the code that sent an email:
var msg = new AE.Net.Mail.MailMessage { Subject = "Your Subject", Body = "Hello, World, from Gmail API!", From = new MailAddress("[you]#qq.com") }; msg.To.Add(new MailAddress("yourbuddy#qq.com"));
msg.ReplyTo.Add(msg.From); // Bounces without this!!
var msgStr = new StringWriter();
msg.Save(msgStr);
string[] Scopes = { GmailService.Scope.GmailSend };
string ApplicationName = "Gmail API .NET Quickstart";
UserCredential credential
using (var stream = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath( System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/gmail-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
var gmail = new GmailService(new Google.Apis.Services.BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = ApplicationName, });
var result = gmail.Users.Messages.Send(new Google.Apis.Gmail.v1.Data.Message { Raw = Base64UrlEncode(msgStr.ToString()) }, "user").Execute();
But I'm only getting this:
An unhandled exception of type 'Google.GoogleApiException' occurred in
Google.Apis.dll Additional information:
Google.Apis.Requests.RequestError Bad Request [400]
Errors [
Message[Bad Request] Location[ - ] Reason[failedPrecondition]
Domain[global]
]
Any idea what is wrong? Thanks!
Related
Currently i am trying to send message from C# to Google chat Room ,tried Authentication using following code
UserCredential credential;
var jsonPath = "";
jsonPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "client_secrets.json");
//using (var stream = new FileStream(jsonPath, FileMode.Open, FileAccess.Read))
using (var stream = new FileStream(jsonPath, FileMode.Open, FileAccess.Read))
{
string[] scopes = new[] { "https://www.googleapis.com/auth/chat"};
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
scopes,
"admin#XXXX.XX", CancellationToken.None, new FileDataStore("C:\\AlexaHangout\\Google.Hangout.Auth.Store")).Result;
}
// Create the service.
var service = new HangoutsChatService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "VSAHangout",
})
Message msg = new Message();
msg.Text = "Hi USER";
msg.Sender = new User() { DisplayName = "Test", Name = "admin#XXXXX.XX", ETag = "12345", Type = "BOT" };
msg.Space = new Space() { Name = "spaces/XXXXXXXX", DisplayName = "ViSev" }
SpacesResource.MessagesResource.CreateRequest req = new SpacesResource.MessagesResource(service).Create(msg, "spaces/XXXXXXX");
var result = req.Execute();
Authenication is working fine but when i trying to send message getting following error.
{"ClassName":"Google.GoogleApiException","Message":"Google.Apis.Requests.RequestError\r\nRequest had insufficient authentication scopes. [403]\r\nErrors [\r\n\tMessage[Request had insufficient authentication scopes.] Location[ - ] Reason[forbidden] Domain[global]\r\n]\r\n","Data":null,"InnerException":null,"HelpURL":null,"StackTraceString":" at Google.Apis.Requests.ClientServiceRequest`1.d__31.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Google.Apis.Requests.ClientServiceRequest`1.Execute()\r\n at HangoutSample.WebForm1.CheckService() in E:\\mahesh Works\\HangoutSample\\HangoutSample\\WebForm1.aspx.cs:line 70","RemoteStackTraceString":null,"RemoteStackIndex":0,"ExceptionMethod":"8\nMoveNext\nGoogle.Apis, Version=1.43.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab\nGoogle.Apis.Requests.ClientServiceRequest`1+d__31\nVoid MoveNext()","HResult":-2146233088,"Source":"Google.Apis","WatsonBuckets":null}
Judging by this maybe your scope should be set to:
string[] scopes = new[] { "https://www.googleapis.com/auth/chat.bot"};
Don't forget to delete the previously generated token.json with the old scope.
Trying to write to google sheets from .NET .
Got exception:
An unhandled exception of type 'Google.GoogleApiException' occurred in mscorlib.dll
Additional information: Google.Apis.Requests.RequestError
Request had insufficient authentication scopes. [403]
Errors [
Message[Request had insufficient authentication scopes.] Location[ - ] Reason[forbidden] Domain[global]
]
Analog function with read works fine. Credentials are created and google sheets API is enabled. I don't see any settings while create credentials regarding read/write. Spreadsheet is shared for everyone read/write. How to solve this problem?
static void UpdateEntry()
{
string spreadsheetId = "1IAD2okAWZD7anbt5L4ybgD2dxHBGmsY6IkNIWHBQkBM";
string ApplicationName = "myapp";
UserCredential credential;
using (var stream = new FileStream("credentials_1.json", FileMode.Open, FileAccess.Read))
{
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 Google Sheets API service.
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
String range = "new first sheet!A1";
//var range = "{sheet}!D543";
var valueRange = new ValueRange();
var oblist = new List<object>() { "updated" };
valueRange.Values = new List<IList<object>> { oblist };
var updateRequest = service.Spreadsheets.Values.Update(valueRange, spreadsheetId, range);
updateRequest.ValueInputOption = SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.USERENTERED;
var appendReponse = updateRequest.Execute();
}
Below is the code I use to obtain the data from my spreadsheet. This works if I am logged into google+, but that isn't the intention, as I want users to access the data through this application.
When I build and provide the files to a user on another PC, it doesn't even start the application, on my own, it can at least start
String myUrl =
"http://nofile.io/g/[REDACTED]/client_secret.json";
WebClient client = new WebClient(); {
client.DownloadFile(myUrl, "\\client_secret.json");
}
UserCredential credential;
using (var stream =
new FileStream("\\client_secret.json", FileMode.Open, FileAccess.Read)) {
string credPath = Environment.GetFolderPath(
Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.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 Google Sheets API service.
var service = new SheetsService(new BaseClientService.Initializer {
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
// Define request parameters.
String spreadsheetId = "1uLxm0jvmL1_FJNYUJp6YqIezzqrZdjPf2xQGOWYd6ao";
String range = "TestSheet!A1:F";
SpreadsheetsResource.ValuesResource.GetRequest request =
service.Spreadsheets.Values.Get(spreadsheetId, range);
File.Delete("\\client_secret.json");
I am trying to create new folder MY_FOLDER in Google Drive using Drive API, using the quick starter example and adding more to it as I read through the https://developers.google.com/drive/v3/web/quickstart/dotnet.
My scope is set as:
static string[] Scopes = { DriveService.Scope.DriveFile };
And I create service like this
private static void CreateService()
{
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.ReadWrite))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart.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 Drive API service.
service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
}
As per example on this page [https://developers.google.com/drive/v3/web/folder], 2, I am creating new folder
var fileMetadata = new File()
{
Name = "MY_FOLDER",
MimeType = "application/vnd.google-apps.folder"
};
var request = driveService.Files.Create(fileMetadata);
request.Fields = "id";
var file = request.Execute();
Console.WriteLine("Folder ID: " + file.Id);
The error I get reads "Insufficient Permissions [403]"
UPDATE
I created credentials as described in same Google tutorial at https://developers.google.com/drive/v3/web/quickstart/dotnet
i was trying to create and run the sample project given in this link.
here is the code:
namespace GmailQuickstart
{
class Program
{
static string[] Scopes = { GmailService.Scope.GmailReadonly };
static string ApplicationName = "Gmail API Quickstart";
static void Main(string[] args)
{
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials");
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.");
}
Console.Read();
}
}
}
after i have done everything stated in google's documentation, including issuing a secrets.json file for my application/product, i ran it.
It fails with an exception, containing a "An invalid argument was supplied" inner exception.
I have retried everything with a new acocunt given new api credentials, etc., and still same error occurs. what am i doing wrong?
Try this
ClientSecrets secrets = new ClientSecrets()
{
ClientId = CLIENT_ID,
ClientSecret = CLIENT_SECRET
};
var token = new TokenResponse { RefreshToken = REFRESH_TOKEN };
var credentials = new UserCredential(new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets
}),
"user",
token);
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credentials,
ApplicationName = "ApplicationName"
});