Send Google Mail in C# failed because of 403 Insufficient permissions - c#

I created a console application which sends an email to an address, it shows like:
private static string[] Scopes = { GmailService.Scope.GmailCompose, GmailService.Scope.GmailSend };
private static string ApplicationName = "Gmail API Quickstart";
private const string SUBJECT = "Some simple subject";
private static string[] emails = new string[] { "teodorescumihail2008#live.com" };
static void Main(string[] args)
{
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/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);
}
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
var msg = new AE.Net.Mail.MailMessage
{
Subject = SUBJECT,
Body = "Test body",
From = new MailAddress("teodorescumihail2008#gmail.com")
};
msg.To.Add(new MailAddress("teodorescumihail2008#live.com"));
StringWriter sw = new StringWriter();
msg.Save(sw);
var result = service.Users.Messages.Send(new Message
{
Raw = Base64UrlEncode(sw.ToString())
}, "me").Execute();
Console.Read();
}
private static string Base64UrlEncode(string input)
{
var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
// Special "url-safe" base64 encode.
return Convert.ToBase64String(inputBytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
}
When execute sending email, I received:
Where is my mistake ?

I assumed you changed your scope in the code without reauthorize/getting a new credential file from Gmail. The problem is GmailAPI does not know that your scope is updated. You have to reauthorize your app in GmailAPI by deleting your app permission and regenerate your credentials.json so that your scope is updated on GmailAPI.
To delete your app permission: click here

Related

I can't read my inbox emails with Google Api

I tried read my emails content. I need the complete text email. I read a lot of Stack Overflow questions but no working. My message.Payload.Body.Data is a lot of times null. I need a think like message.Snippet but with the complete message.
My code is :
//Login
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,
"admin",
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");
var inboxlistRequest = service.Users.Messages.List("me");
inboxlistRequest.LabelIds = "INBOX";
inboxlistRequest.IncludeSpamTrash = false;
var emailListResponse = inboxlistRequest.Execute();
foreach (var mail in emailListResponse.Messages)
{
var mailId = mail.Id;
var threadId = mail.ThreadId;
Message message = service.Users.Messages.Get("me", mailId).Execute();
Console.WriteLine(message.Payload.Body.Data);
}
I try too thinks like :
foreach (var part in message.Payload.Parts)
{
byte[] data = Convert.FromBase64String(part.Body.Data);
string decodedString = Encoding.UTF8.GetString(data);
Console.WriteLine(decodedString);
}
But no work because i don't find content in Payload.

C# forward a gmail message to another email address

My goal is to retrieve all emails that exist under one label within my gmail account and forward those emails to another email address. Here's what i have so far:
string[] Scopes = { GmailService.Scope.GmailReadonly, GmailService.Scope.GmailSend, };
string ApplicationName = "APP NAME";
UserCredential credential;
using (var stream = new FileStream("credentials.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);
}
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
var labelList = service.Users.Messages.List("me#gmail.com");
labelList.LabelIds = "LABEL_NAME";
var emailListResponse = labelList.Execute();
if (emailListResponse != null && emailListResponse.Messages != null)
{
foreach (var email in emailListResponse.Messages)
{
//THIS IS WHERE I WOULD LIKE TO FORWARD this email TO ANOTHER EMAIL ADDRESS?
//How to set TO?
//service.Users.Messages.Send(email, "me#gmail.com").Execute();
}
}
I am able to retrieve the emails but i'm not sure how to forward. Thank you for your help
To forward a message you have to get it and add the recipient's email to the "To:" field.
Alternatively, you could set up a filter to forward all emails with the Label you have to another address.

How to access client secret file of google calendar

I want to access client_secret file of google calendar and to use it to add an event in my calendar.
I'm creating a chatbot in c# and in the moment that I use the path of my computer ( when I try to access client_secret file of my project in my pc ) works goods.
When I publish the project on the web and try to access the file I can't.
My code is :
string path = #"C:\Project\Test\Bot\V3\client_secret.json";
string pathi = #"{
'installed': {
'client_id': '1111111-
21432423.apps.googleusercontent.com',
'project_id': '111',
'auth_uri': 'https://accounts.google.com/o/oauth2/auth',
'token_uri': 'https://www.googleapis.com/oauth2/v3/token',
'auth_provider_x509_cert_url': 'https://www.googleapis.com/oauth2/v1/certs',
'client_secret': '22222222222222',
'redirect_uris': [ 'urn:ietf:wg:oauth:2.0:oob', 'http:dev.ai.com/BotTest/' ]
}
}";
UserCredential credential;
string[] Scopes = { CalendarService.Scope.Calendar };
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
using (var stream =
new FileStream(pathi, FileMode.Open, FileAccess.Read))
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
string ApplicationName = "Google Calendar API .NET Quickstart";
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
Event newEvent = new Event()
{
Summary = "Event",
Location = "",
Description = "Event is scheduled for: " +
eventi.Date.ToString("dd-MM-yyyy") + " " +
eventi.Time.ToShortTimeString(),
Start = new EventDateTime()
{
// DateTime = eventi.Date,
DateTime = new DateTime(eventi.Date.Year,
eventi.Date.Month, eventi.Date.Day, eventi.Time.Hour,
eventi.Time.Minute, 0),
TimeZone = "Europe/Brussels",
},
End = new EventDateTime()
{
DateTime = eventi.Date.AddMinutes(60),
// DateTime = new DateTime(eventi.Date.Year,
eventi.Date.Month, eventi.Date.Day, eventi.Time.Hour,
eventi.Time.Hour +1 ,0),
TimeZone = "Europe/Brussels",
},
Recurrence = new String[] { "RRULE:FREQ=DAILY;COUNT=1" },
Attendees = new EventAttendee[] {
new EventAttendee() { Email = "eeee#gmail.com" },
},
///////////////////////////////////////////
///////////////////////////////////////////
Reminders = new Event.RemindersData()
{
UseDefault = false,
Overrides = new EventReminder[] {
new EventReminder() { Method = "email", Minutes = 1 * 60 },
new EventReminder() { Method = "sms", Minutes = 10 },
}
}
};
String calendarId = "primary";
EventsResource.InsertRequest request1 =
service.Events.Insert(newEvent, calendarId);
Event createdEvent = request1.Execute();
Console.WriteLine("Event created: {0}", createdEvent.HtmlLink);
// Define parameters of request.
EventsResource.ListRequest request = service.Events.List("primary");
request.TimeMin = eventi.Time;
request.ShowDeleted = false;
request.SingleEvents = true;
request.MaxResults = 10;
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
// List events.
Events events = request.Execute();
Console.WriteLine("Upcoming events:");
if (events.Items != null && events.Items.Count > 0)
{
foreach (var eventItem in events.Items)
{
string when = eventItem.Start.Date;
if (String.IsNullOrEmpty(when))
{
when = eventItem.Start.Date;
}
Console.WriteLine("{0} ({1})", eventItem.Summary, when);
}
}
else
{
Console.WriteLine("No upcoming events found.");
}
//Console.Read();
// context.Wait(this.MessageReceived);
}
context.Wait(this.MessageReceived);
}
When i use path and in this part of code i put path work :
using (var stream =
new FileStream(path, FileMode.Open, FileAccess.Read))
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
When I put the root of the file in the web doesn't work, the same when i put all the script of the file in a string path :
string path = #"http://dev.aaaa.com/bot/client_secret.json"
I try to put just the name file but still don't work:
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Can you help me please how to access this file?
Copy credentials.json to bin\debug and bin\release folders and follow this way if your client is console application ,
UserCredential credential;
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { CalendarService.Scope.CalendarReadonly },
"user", CancellationToken.None, new FileDataStore(credPath));
}
For web App the client_secret.json would look like this and contains redirect uri's etc.
{"web":{"client_id":" ","project_id":" ","auth_uri":" ","token_uri":" ","auth_provider_x509_cert_url":" ","client_secret":" ","redirect_uris":[]}}
Also don't disclose any of your id's and secrets.

How to insert user into group with Google api

I am using Google.Apis.Admin.Directory.directory_v1.Data to manage google users and groups. I can create user and group, but how to insert my new user in new group?
Here is my code
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/admin-directory_v1-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new string[] { DirectoryService.Scope.AdminDirectoryGroup, DirectoryService.Scope.AdminDirectoryUser },
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
var service = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Directory API .NET Quickstart",
});
User user = new User();
UserName username = new UserName();
user.PrimaryEmail = "mail#gmail.com";
username.GivenName = "GivenName";
username.FamilyName = "FamilyName";
user.Name = username;
user.Password = "Password";
service.Users.Insert(user);
var group = new Group();
group.Email = "group#gmail.com";
group.Name = "GroupName";
service.Groups.Insert(group);
}
Use https://developers.google.com/admin-sdk/directory/v1/reference/members/insert
Like role, add email as a parameter. Check the Members resource for more details.
Add Execute() and that worked for me
service.Users.Insert(user).Execute()

How To create an instance of Google BaseClientService.Initializer

I want to know how to create an instance of Google BaseClientService.Initializer. I need to use the BaseClientService.Initializer to create the GmailService instance, and then use this GmailService instance to create an UsersResource instance.
Google.Apis.Services.BaseClientService.Initializer initializer = new BaseClientService.Initializer();
initializer.ApiKey = "MyApiKey";
initializer.ApplicationName = "MyProject";
initializer.DefaultExponentialBackOffPolicy = Google.Apis.Http.ExponentialBackOffPolicy.None;
Google.Apis.Gmail.v1.GmailService gmailService = new GmailService(initializer);
Google.Apis.Gmail.v1.UsersResource usersResource = new UsersResource(gmailService);
UsersResource.MessagesResource messagesResource = usersResource.Messages;
First go to the link bellow and open an application in your google account.
once you run the code you'll get exception for the first time, given you an address to go and enable the API in your google account.
https://console.developers.google.com/apis/dashboard?project=super-pharm-log-notifications
static string[] Scopes = { GmailService.Scope.GmailCompose, GmailService.Scope.GmailSend, GmailService.Scope.GmailInsert };
static private BaseClientService.Initializer initializeGmailAccountServices()
{
string appRoot = null;
if (System.Web.HttpContext.Current == null)
{
appRoot = Environment.CurrentDirectory;
}
else
{
appRoot = System.Web.HttpContext.Current.Server.MapPath(#"~\");
}
string path = Path.Combine(appRoot, DBConstants.GMAIL_CREDENTIALS_PATH);
UserCredential credential;
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
ClientSecrets secrets = GoogleClientSecrets.Load(stream).Secrets;
var t = GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, Scopes, "user", CancellationToken.None);
t.Wait();
credential = t.Result;
}
return= new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "your application name",
};
}
private static string Base64UrlEncode(string input)
{
var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
// Special "url-safe" base64 encode.
return Convert.ToBase64String(inputBytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
}

Categories