Created
August 30, 2019 16:59
-
-
Save arthurtsang/82d91a3f770df45842b310ec75f2318b to your computer and use it in GitHub Desktop.
authorize and get token from gmail api using protractor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import gmailCred from '../resources/gmail.credentials.json'; | |
import { gmail_v1, google } from 'googleapis'; | |
import * as fs from 'fs'; | |
import { OAuth2Client } from 'google-auth-library'; | |
import { browser, by, ElementFinder } from 'protractor'; | |
// If modifying these scopes, delete token.json. | |
const SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']; | |
// 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. | |
const TOKEN_PATH = 'token.json'; | |
const gmailAccount = '[email protected]'; | |
const gmailPassword = 'somepassword'; | |
export class GmailUtils { | |
/** | |
* Create an OAuth2 client with the given credentials | |
*/ | |
async authorize() { | |
const { client_secret, client_id, redirect_uris } = gmailCred.installed; | |
const oAuth2Client = new google.auth.OAuth2( | |
client_id, | |
client_secret, | |
redirect_uris[0] | |
); | |
// Check if we have previously stored a token. | |
const token = !fs.existsSync(TOKEN_PATH) | |
? await this.getNewToken(oAuth2Client) | |
: JSON.parse(fs.readFileSync(TOKEN_PATH).toString()); | |
oAuth2Client.setCredentials(token); | |
return oAuth2Client; | |
} | |
/** | |
* Get and store new token after prompting for user authorization, and then | |
* execute the given callback with the authorized OAuth2 client. | |
* @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for. | |
*/ | |
private async getNewToken(oAuth2Client: OAuth2Client) { | |
const authUrl = oAuth2Client.generateAuthUrl({ | |
access_type: 'offline', | |
scope: SCOPES | |
}); | |
const code = await this.getOAuth2Code(authUrl); | |
const tokenResponse = await oAuth2Client.getToken(code); | |
fs.writeFileSync(TOKEN_PATH, JSON.stringify(tokenResponse.tokens)); | |
return tokenResponse.tokens; | |
} | |
/** | |
* the function is only use when token.json does not exists | |
* it will open a new window, grant permission to the app and return the code | |
* @param authUrl | |
*/ | |
async getOAuth2Code(authUrl: string) { | |
const googleBrowser = await browser.forkNewDriverInstance().ready; | |
await googleBrowser.waitForAngularEnabled(false); | |
await googleBrowser.manage().window().maximize(); | |
await googleBrowser.driver.get(authUrl); | |
const appPo = new AppPo(googleBrowser); | |
const email = googleBrowser.element(by.id('identifierId')); | |
await appPo.sendKeys(email, gmailAccount, false); | |
const emailNext = googleBrowser.element(by.id('identifierNext')); | |
await appPo.click(emailNext); | |
const password = googleBrowser.element(by.id('password')).element(by.tagName('input')); | |
await appPo.sendKeys(password, gmailPassword); | |
const passwordNext = googleBrowser.element(by.id('passwordNext')); | |
await appPo.click(passwordNext); | |
await googleBrowser.wait( | |
async () => { | |
try { | |
const links: ElementFinder[] = await googleBrowser.element.all( | |
by.tagName('a') | |
); | |
for (const link of links) { | |
if ((await link.getText()) === 'Advanced') { | |
await appPo.click(link); | |
return true; | |
} | |
} | |
} catch (e) {} | |
return false; | |
}, | |
defaultTimeout, | |
'Timeout waiting for Advanced link' | |
); | |
await googleBrowser.wait( | |
async () => { | |
try { | |
const links: ElementFinder[] = await googleBrowser.element.all( | |
by.tagName('a') | |
); | |
for (const link of links) { | |
if ((await link.getText()) === 'Go to Quickstart (unsafe)') { | |
await appPo.click(link); | |
return true; | |
} | |
} | |
} catch (e) {} | |
return false; | |
}, | |
defaultTimeout, | |
'Timeout waiting for Go to Quickstart link' | |
); | |
await googleBrowser.wait( | |
async () => { | |
try { | |
const divs: ElementFinder[] = await googleBrowser.element.all( | |
by.tagName('div') | |
); | |
for (const div of divs) { | |
if ((await div.getAttribute('role')) === 'button') { | |
if ((await div.getText()) === 'Allow') { | |
await appPo.click(div); | |
return true; | |
} | |
} | |
} | |
} catch (e) {} | |
return false; | |
}, | |
defaultTimeout, | |
'Timeout waiting for the Allow button' | |
); | |
const approveAccess = googleBrowser.element(by.id('submit_approve_access')); | |
await appPo.click(approveAccess); | |
const textarea = googleBrowser.element(by.tagName('textarea')); | |
await appPo.waitForElementToBePresent(textarea); | |
await appPo.waitForElementToBeVisible(textarea); | |
const code = await textarea.getAttribute('value'); | |
googleBrowser.close(); | |
return code; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment