2

I'm trying to create a application service to be ran in a cloud server (AppHarbor) I do not directly handle, as a C# Console Application. Basically, it is a Telegram Bot that needs to access Gmail and Google Calendar. When running it locally, it propts the user via browser to give access to the account the first time.

Unfortunately, in the server I cannot give that access, so I need a way to login (authentication) directly, without need for authorization.

I've seen the option to use a Service Account, but sadly it requires GSuite to configure the user permissions and that needs payment I need to avoid.

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",
        System.Threading.CancellationToken.None,
        new FileDataStore(credPath, true)).Result;
}

I have generated my json file with all the settings and secrets needed, but it still requires user interaction.

Is there any way to do so without user prompt?

SysDragon
  • 9,692
  • 15
  • 60
  • 89
  • Easy. See https://stackoverflow.com/questions/19766912/how-do-i-authorise-an-app-web-or-installed-without-user-intervention and provide the gmail and calendar scopes that your app needs. – pinoyyid Jan 25 '19 at 13:45
  • @pinoyyid Nope. I have the scopes already, of course. The answer you linked uses Service Account, and is not an option here, as stated on the question – SysDragon Jan 25 '19 at 13:47
  • the answer I linked does NOT use a service account, it uses a Refresh Token. Try reading it again. – pinoyyid Jan 25 '19 at 14:08

1 Answers1

3

USER

The term user denotes the owner of the data or the account you wish to access. In order to access data owned by a user account. You must have permission of the user in question.

Service Account

Service accounts are only indented for user when you the developer have access to the accounts in question. You are correct that you can only use them with gmail if the emails are controlled though a gsuite other wise there is no way to preauthorize them. service accounts

Oauth2 refresh token

I have done something like this in the past. What you are going to need is two applications. One which your users can run to authenticate your application and send the credentials to your server and the second is the console application you have now. Oauth

User Application

The user application should either be a web application or an installed application that the users can run. They run this application grant your application access (remember to add the offline scope) You will get a refresh token back. Take this refresh token and send it to the server that is running your console application.

Console application

your console application should then use these refresh tokens to request a new access token and gain access to the users data when ever it needs to.

To load this refresh token you will need to create your own implementation of IDataStore. The code you are using now usees FileDataStore which stores the crednetials in %appdata% you will need to over ride that so that it can read from where ever it is you had the user application store the data. I have a few examples here datastore.cs gist

Application verification

remember that you will need to have your application verified by google before you can release it GMAIL is one of the harder scopes to have approved you may want to start that process early.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • note there are no users using the application. It is basically a server (specifically a Telegram Bot server to listen to the requests) – SysDragon Jan 25 '19 at 12:17
  • User: Is the owner of the data you wish to access. Gmail and Google Calendar data is private user data. You must have the permission of the user who owns any account you wish to access. There is a user even if its a bot account its still a user. If these are single accounts you are trying to access ones you yourself created. You could use a service account for calendar and just authcate the gmail account once using Oauth2 and save the refresh token and use it as i explained with idatastore. – Linda Lawton - DaImTo Jan 25 '19 at 12:22
  • does the token expire? – SysDragon Jan 25 '19 at 13:21
  • refresh tokens should not expire but they can you will need to have it set to notify you if it has a problem. its pretty rare. – Linda Lawton - DaImTo Jan 25 '19 at 13:30
  • I'll try this option and let you know. Sounds like the good-to-go solution. I only wished there is an easier way – SysDragon Jan 25 '19 at 13:48
  • Then I need to configure my console application to be listening to requests so it can receive the tokens – SysDragon Jan 25 '19 at 13:51
  • 1
    if it's only one account you are accessing there will be no need just create the refresh token once and up load it with you settings in your application – Linda Lawton - DaImTo Jan 26 '19 at 07:53
  • My bot doesn't have a database configured. Is there any possibility to store the refresh token without using a database on AppHarbor? As per their FAQ, it seems that they allow to write on the AppData folder, so I guess that means I can keep the FileDataStore – SysDragon Feb 01 '19 at 07:55