Now here’s the same thing for the GitHub API, which also uses Oauth2.
Since there’s a good chance you’ll be creating an app that will not be running as a webapp, you’ll need to be able to refresh tokens automatically and work offline. The EzyOauth library takes care of all that but it needs an initial set up and some local code you may want to customize.
This will take you through each step from a completely new project, including all the stuff you have to do in the cloud console.
Step 1
Include the library – you’ll get its details by clicking below (it uses the public library list.)
Step 2.
/* * patterns you can reuse for writing apps needing oAuth2 * just copy the whole thing to your project * for first time running seee oneTimeSet to load your credentials to your property store * you shouldn't need to modify any of this */ "use strict"; /** * gets the property key against which the authentication package will be stored * @param {string} optPackageName * @return {object} authentication package */ function getAuthenticationPackage_ (optPackageName) { var p = PropertiesService.getScriptProperties().getProperty(getPropertyKey_ (optPackageName)); if (p) { p.packageName = optPackageName || ''; } return p ? JSON.parse(p) : null; } /** * set your authentication package back to your property service * this will make the access token and refresh token available next time it runs * @param {object} authentication package to set * @return {void} */ function setAuthenticationPackage_ (package) { PropertiesService.getScriptProperties().setProperty(getPropertyKey_ (package.packageName), JSON.stringify(package)); } /** * this will be the first call back, you now need to get the access token * @param {object} e arguments as setup by the statetokenbuilder * @param {function} theWork that will be called with the access token as an argumment * @return {*} the result of the call to func() */ function getAccessTokenCallback(e) { // this will fetch the access token var authenticationPackage = getAuthenticationPackage_ (e.parameter.package_name); var eo = new cEzyOauth2.EzyOauth2 (authenticationPackage).fetchAccessToken(e); if (!eo.isOk()) { //throw ('failed to get access token:'+eo.getAccessTokenResult().getContentText()); return HtmlService.createHtmlOutput ( eo.getAccessTokenResult().getContentText() ); } else { // should save the updated properties for next time setAuthenticationPackage_ (authenticationPackage); return e.parameter.work ? evalWork(e.parameter.work) : null; } function evalWork (func) { return eval (func +'("' +eo.getAccessToken() +'")'); } } /** * gets called by doGet * @param {object} the doGet() parameters * @param {function} consentScreen - will be called with the consent Url as a an argument if required * @param {function} doSomething - the function that actually does your work * @param {function} optPackageName - optional package name to identify the oauth2 package to use * @return {*} whatever doSomething returns */ function doGetPattern(e, consentScreen, theWork,optPackageName, optArgs) { // set up authentication var packageName = optPackageName || ''; var authenticationPackage = getAuthenticationPackage_ (packageName); if (!authenticationPackage) { throw "You need to set up your credentials one time"; } var eo = new cEzyOauth2.EzyOauth2 ( authenticationPackage, "getAccessTokenCallback", undefined, {work:theWork.name,package_name:packageName} ); // eo will have checked for an unexpired access code, or got a new one with a refresh code if it was possible, and we'll already have it if (eo.isOk()) { // should save the updated properties for next time setAuthenticationPackage_ (authenticationPackage); // good to do whatever we're here to do return theWork (eo.getAccessToken(),optArgs); } else { // start off the oauth2 dance - you'll want to pretty this up probably return HtmlService.createHtmlOutput ( consentScreen(eo.getUserConsentUrl(),eo.getRedirectUrl()) ); } } /** * once you have done the one time doGet() process you can retrieve an access token like this * @return {string} an accessToken */ function getAccessToken(package) { return doGetPattern({} , constructConsentScreen, function (token) { return token; },package); }
Step 3
Step 4.
function oneTimeSetProperties () { setAuthenticationPackage_ ({ clientId : "5e1xxxxxxx306", clientSecret : "7b27xxxxxxxxxxxxxxxxx44", scopes : [ 'gist', 'repo' ], service: 'github', packageName: 'gasgit' }); }
Step 5.
"use strict"; /** * this is your web app * @param {object} webapp param object * return {HtmlOutput} */ function doGet (e) { // pattern for drive sdk return doGetPattern(e, constructConsentScreen, doSomething, 'gasgit') ; } /** * tailor your consent screen with an html template * @param {string} consentUrl the url to click to provide user consent * @param {string} redirectUrl the url that redirect will happen on * @return {string} the html for the consent screen */ function constructConsentScreen (consentUrl,redirectUrl) { return '<p>add Redirect URI to be added to cloud console then' + '</p><a href = "' + consentUrl + '">Click to authenticate to github access to script</a> ' + '<br>'; } /** * this is your main processing - will be called with your access token * @param {string} accessToken - the accessToken */ function doSomething (accessToken) { var options = { method: "GET", headers: { authorization: "Bearer " + accessToken } }; return HtmlService.createHtmlOutput (' it worked'); } /** * gets the property key against which you want the authentication package stored * @param {string} optPackageName * @return {string} */ function getPropertyKey_ (optPackageName) { return "EzyOauth2" + (optPackageName ? '_' + optPackageName : 'Auth'); }
Run doGet() to get permission for the things it will need to do as a webapp, then save a version, and publish as a web app and run. You’ll get the dialog from your construct screen function
Before clicking to authenticate, copy the published URI and head back to the github application console and replace the callback URI with the published URI (but replace /exec by /usercallback). I noticed that sometimes changing the redirect URI also changes the credentials. If it does, then repeat step 4 with updated credentials.
Now you can go ahead and complete the authentication dialog. You’ll get something that looks like this, which may be followed by a github password request.
Step 6