7

I am using the Google API Client to read emails from Gmail. Now I want to add a Cronjob so it reads every 5 minutes the mails.

The problem using the Google API Client is that it needs to allow the user to first click on the authorization link and allow the user to use the Google API Client.

I have a class Inbox with a function initialize that initliazes the Google API Client. But the cronjob doesn't work because I have to get an access_token.

public function initialize() {
    $configuration = Configuration::getConfiguration('class_Inbox');

    // Creates the Google Client
    $this->client = new Google_Client();
    $this->client->setApplicationName('Tiptsernetwork');
    $this->client->setClientId($configuration['clientId']);
    $this->client->setClientSecret($configuration['clientSecret']);
    $this->client->setRedirectUri('http://www.tipsternetwork.nl/cronjob/authenticate');
    $this->client->addScope('https://mail.google.com/');
    $this->client->setApprovalPrompt('force');
    $this->client->setAccessType('offline');

    // Creates the Google Gmail Service
    $this->service = new Google_Service_Gmail($this->client);

    // Authenticates the user.
    if (isset($_GET['code'])) {
        $this->authenticate($_GET['code']);
    }

    // Check if we have an access token in the session
    if (isset($_SESSION['access_token'])) {
        $this->client->setAccessToken($_SESSION['access_token']);
    } else {
        $loginUrl = $this->client->createAuthUrl();
        echo '<a href="'.$loginUrl.'">Click Here</a>';
    }

    // If the token is expired it used the refresh token to generate a new Access Token
    if($this->client->isAccessTokenExpired()) {
        $this->client->refreshToken($configuration['refreshToken']);
    }
}

public function authenticate($code) {
    // Creates and sets the Google Authorization Code
    $this->client->authenticate($code);
    $_SESSION['access_token'] = $this->client->getAccessToken();

    $this->client->refreshToken($configuration['refreshToken']);

    // Redirect the user back after authorizaton
    $url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
    header('Location: ' . filter_var($url, FILTER_VALIDATE_URL));
}

Do you guys know how to fix it using the refresh token or whatever? I can't get it working and I am out of ideas.

If I am accessing the URL and click on "Click Here" and allow it it works succesfully but not with a Cronjob because I can't click on the "Click Here" URL...

I hope you people understand it and can help me :).

Kind regards,
Yanick

1 Answers1

5

This answer is more a general approach on how to use the O-Auth2 Flow, since I faced with a similar problem a while ago. I hope it'll help a bit.

One possible problem (in understanding the correct use of OAuth) is that you use force as approval prompt. Why do you force the user to give permission when he already did?

When a user autheticates against your backend, he's asked if he wants to give your application permission to the actions defined in scope. The first time your application get this permissions (by the user clicking the "Agree"-Button) your Script will get an access_token and refresh_token from google.

The access_token is used to access the Google-APIs with the account of that authenticated user. You should store that somewhere on your server if you want to access the google APIs without having the user to be present (so called offline-access). With this token you can do anything in the name of the user (limited to defined scopes). It will went invalid after 1 hour or so. In the whole time (of 1 hour) you can use this token without having the user to be present!

The refresh_token is needed when the access_token wents invalid after this period of time. And only then. You only get the refresh_token ONCE and it will never change. This is very important data and should be stored safely!

So if you want to access google APIs without the user's presence you have to make API calls with the stored access_token. If the response is something like token expired (I think there was a errorcode for that - have to do research), then you call $client->refreshToken($refreshToken) with the refresh token you stored somewhere safe. You'll get a new access_token from that. With this access_token you can do further work, without having the user to click somewhere (again).

Next time that new access_token wents invalid, you have to use the same refresh_token as before and that's the reason why this refresh_token is so important.

I hope I could help you a little bit. If not, please comment on this.

Happy coding

Resources

Community
  • 1
  • 1
Hecke29
  • 761
  • 6
  • 18