2
votes

I have a project in Google Apps for which I've enabled Calendar API and Gmail API (generated a '.p12' key for server-to-server authentication). I've managed to read/write my Google Calendar account with the following:

 private CalendarService GetCalendarService()
 {
     var certificate = new X509Certificate2(_googleCredentialsFilePath, "notasecret", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
     var serviceEmail = "599172797645-dthli52ji7j0j53gacmqigvs694bu7vs@developer.gserviceaccount.com";
     var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceEmail)
        {
            Scopes = new[] { CalendarService.Scope.Calendar, CalendarService.Scope.CalendarReadonly }
        }.FromCertificate(certificate));

        var applicationName = ConfigurationManager.AppSettings["ApplicationName"];
        var service = new CalendarService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = applicationName,
        });

        return service;
    }

With the service object I can create events in my calendars like so:

var newEvent = new Event()
{
     Summary = calendarEvent.Summary,
     Description = calendarEvent.Description,
     Start = new EventDateTime()
     {
        DateTime = calendarEvent.StartDateTime,
        TimeZone = _ianaTimezone,
     },
     End = new EventDateTime()
     {
         DateTime = calendarEvent.EndDateTime,
         TimeZone = _ianaTimezone,
     }
};

var request = _calendarService.Events.Insert(newEvent, googleCalendarId);
var result = request.Execute(); // CREATE EVENT SUCCESSFULLY

Now, for the Gmail API client I'd like to send emails using the service account owner email (the same I use to login Google Dev Console -- "[email protected]"

private GmailService GetGmailService()
{
    var certificate = new X509Certificate2(_googleCredentialsFilePath, "notasecret", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
    var serviceEmail = "599172797645-dthli52ji7j0j53gacmqigvs694bu7vs@developer.gserviceaccount.com";
    var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceEmail)
    {
        Scopes = new[] { GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailCompose, GmailService.Scope.GmailModify, GmailService.Scope.GmailSend },
        User = "[email protected]"
    }.FromCertificate(certificate));

    var applicationName = ConfigurationManager.AppSettings["ApplicationName"];
    var service = new GmailService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = applicationName,
     });

     return service;
}

But when I try to test this client requesting the list of drafts:

ListDraftsResponse draftsResponse = _gmailService.Users.Drafts.List("[email protected]").Execute();

Then I get the error:

"Error:\"unauthorized_client\", Description:\"Unauthorized client or scope in request.\", Uri:\"\"" string

I've logged in to Google Developers Console with [email protected] and in

API Manager > Permissions > Add service account owner added "[email protected]" as the service email owner (probably redundantly)

Do I need a Google Apps for Work to send/read emails from my own gmail account via service account? My app is currently hosted in Azure as a web application.

1
The Google service account used for the migration has no permissions to access to the user. Make sure to add all the necessary scopes to set the permissions. Here is the link to set the permissions correctly.abielita
When it comes to the 'Set Permissions to the service account' I'm redirected to a 'Google for Work' login page -- I'm assuming having a 'for Work' account is mandatory...Rafael Companhoni

1 Answers

0
votes

Check This

And make sure that you access the google.Admin account for referencing the service account Client ID of the app you created and the time zone is in the following format "America/Phoenix".