diff --git a/samples/Add-on/Code.gs b/samples/Add-on/Code.gs index 7b2e3efd..4a2e297f 100644 --- a/samples/Add-on/Code.gs +++ b/samples/Add-on/Code.gs @@ -160,8 +160,7 @@ function authCallback(request) { * Logs the redict URI to register in the Google Developers Console. */ function logRedirectUri() { - var service = getGitHubService(); - Logger.log(service.getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } /** diff --git a/samples/AdobeSign.gs b/samples/AdobeSign.gs index 4d446c9c..d2ff57e3 100644 --- a/samples/AdobeSign.gs +++ b/samples/AdobeSign.gs @@ -97,5 +97,5 @@ function authCallback(request) { * Logs the redict URI to register in the Dropbox application settings. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Basecamp.gs b/samples/Basecamp.gs index b995310d..96fa8617 100644 --- a/samples/Basecamp.gs +++ b/samples/Basecamp.gs @@ -69,5 +69,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/ChatWork.gs b/samples/ChatWork.gs index d8eecf8d..c2cc0ea4 100644 --- a/samples/ChatWork.gs +++ b/samples/ChatWork.gs @@ -81,5 +81,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/CloudIdentityAwareProxy.gs b/samples/CloudIdentityAwareProxy.gs index 8aba606b..2185041b 100644 --- a/samples/CloudIdentityAwareProxy.gs +++ b/samples/CloudIdentityAwareProxy.gs @@ -98,5 +98,5 @@ function authCallback(request) { * Logs the redict URI to register in the Google Developers Console. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Dropbox.gs b/samples/Dropbox.gs index 3e6c4c4e..b6fa7509 100644 --- a/samples/Dropbox.gs +++ b/samples/Dropbox.gs @@ -74,5 +74,5 @@ function authCallback(request) { * Logs the redict URI to register in the Dropbox application settings. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Facebook.gs b/samples/Facebook.gs index 11b1c7b2..01c9efb8 100644 --- a/samples/Facebook.gs +++ b/samples/Facebook.gs @@ -73,5 +73,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/FitBit.gs b/samples/FitBit.gs index 748aa2b9..1275c31b 100644 --- a/samples/FitBit.gs +++ b/samples/FitBit.gs @@ -74,5 +74,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/GitHub.gs b/samples/GitHub.gs index bb795880..3f017fd5 100644 --- a/samples/GitHub.gs +++ b/samples/GitHub.gs @@ -67,5 +67,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/GooglePlus.gs b/samples/GooglePlus.gs index de6e1dba..6b0ec0fc 100644 --- a/samples/GooglePlus.gs +++ b/samples/GooglePlus.gs @@ -73,6 +73,6 @@ function authCallback(request) { * Logs the redict URI to register in the Google Developers Console. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Harvest.gs b/samples/Harvest.gs index d126a3e2..7abab4c5 100644 --- a/samples/Harvest.gs +++ b/samples/Harvest.gs @@ -79,5 +79,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Jira.gs b/samples/Jira.gs index 9fe436dc..10d38699 100644 --- a/samples/Jira.gs +++ b/samples/Jira.gs @@ -109,5 +109,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/LinkedIn.gs b/samples/LinkedIn.gs index c96aaa10..29c629a3 100644 --- a/samples/LinkedIn.gs +++ b/samples/LinkedIn.gs @@ -68,5 +68,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Medium.gs b/samples/Medium.gs index b074bf7a..c9cf43a6 100644 --- a/samples/Medium.gs +++ b/samples/Medium.gs @@ -75,5 +75,5 @@ function authCallback_(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Meetup.gs b/samples/Meetup.gs index 20183667..652a814f 100644 --- a/samples/Meetup.gs +++ b/samples/Meetup.gs @@ -73,5 +73,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/RingCentral.gs b/samples/RingCentral.gs index 4d5cb6c4..23eec69e 100644 --- a/samples/RingCentral.gs +++ b/samples/RingCentral.gs @@ -82,5 +82,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Salesforce.gs b/samples/Salesforce.gs index fc2edf33..e6dfed4c 100644 --- a/samples/Salesforce.gs +++ b/samples/Salesforce.gs @@ -105,5 +105,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Smartsheet.gs b/samples/Smartsheet.gs index c177f2c8..2a9134cb 100644 --- a/samples/Smartsheet.gs +++ b/samples/Smartsheet.gs @@ -105,5 +105,5 @@ function smartsheetTokenHandler(payload) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Strava.gs b/samples/Strava.gs index 08879f66..4cad09b7 100644 --- a/samples/Strava.gs +++ b/samples/Strava.gs @@ -72,5 +72,5 @@ function authCallback_(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/UltraCart.gs b/samples/UltraCart.gs index 71425b8f..b7a47cf9 100644 --- a/samples/UltraCart.gs +++ b/samples/UltraCart.gs @@ -73,5 +73,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/VK.gs b/samples/VK.gs index 4febfe28..79b5a82e 100644 --- a/samples/VK.gs +++ b/samples/VK.gs @@ -73,5 +73,5 @@ function authCallback(request) { * Logs the redict URI to register in the VK Aps Page https://vk.com/apps?act=manage. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/WebApp/Code.gs b/samples/WebApp/Code.gs index 422894b7..0677fbc6 100644 --- a/samples/WebApp/Code.gs +++ b/samples/WebApp/Code.gs @@ -133,8 +133,7 @@ function authCallback(request) { * Logs the redict URI to register in the Google Developers Console. */ function logRedirectUri() { - var service = getGitHubService(); - Logger.log(service.getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } /** diff --git a/samples/Wordpress.gs b/samples/Wordpress.gs index d8143712..309039e6 100644 --- a/samples/Wordpress.gs +++ b/samples/Wordpress.gs @@ -68,5 +68,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Yahoo.gs b/samples/Yahoo.gs index 746a06a8..6bea7ab4 100644 --- a/samples/Yahoo.gs +++ b/samples/Yahoo.gs @@ -73,5 +73,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Yandex.gs b/samples/Yandex.gs index 1502e681..6c2a3823 100644 --- a/samples/Yandex.gs +++ b/samples/Yandex.gs @@ -72,5 +72,5 @@ function authCallback(request) { * Logs the redict URI to register in the Yandex oAuth Page https://oauth.yandex.ru/client/new. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Zendesk.gs b/samples/Zendesk.gs index b1a0fd26..ec9a3b8a 100644 --- a/samples/Zendesk.gs +++ b/samples/Zendesk.gs @@ -78,5 +78,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/Zoom.gs b/samples/Zoom.gs index 473a9189..3d0ee067 100644 --- a/samples/Zoom.gs +++ b/samples/Zoom.gs @@ -85,5 +85,5 @@ function authCallback(request) { * Logs the redict URI to register. */ function logRedirectUri() { - Logger.log(getService().getRedirectUri()); + Logger.log(OAuth2.getRedirectUri()); } diff --git a/samples/eBay.gs b/samples/eBay.gs new file mode 100644 index 00000000..01cd9cde --- /dev/null +++ b/samples/eBay.gs @@ -0,0 +1,92 @@ +/* + * This sample demonstrates how to configure the library for the eBay API, + * using the authorization code flow to get a user access token. + * Instructions on how to generate OAuth credentuals is available here: + * https://developer.ebay.com/api-docs/static/oauth-qref-auth-code-grant.html + */ + +var CLIENT_ID = '...'; // App ID +var CLIENT_SECRET = '...'; // Cert ID +var RU_NAME = '...'; // eBay Redirect URL name. + +/** + * Authorizes and makes a request to the Ebay API. + */ +function run() { + var service = getService(); + if (service.hasAccess()) { + // Sandbox environment. + var url = 'https://api.sandbox.ebay.com/sell/inventory/v1/inventory_item'; + var response = UrlFetchApp.fetch(url, { + headers: { + Authorization: 'Bearer ' + service.getAccessToken() + } + }); + var result = JSON.parse(response.getContentText()); + Logger.log(JSON.stringify(result, null, 2)); + } else { + var authorizationUrl = service.getAuthorizationUrl(); + Logger.log('Open the following URL and re-run the script: %s', + authorizationUrl); + } +} + +/** + * Reset the authorization state, so that it can be re-tested. + */ +function reset() { + getService().reset(); +} + +/** + * Configures the service. + */ +function getService() { + return OAuth2.createService('eBay') + // Set the endpoint URLs (sandbox environment). + .setTokenUrl('https://api.sandbox.ebay.com/identity/v1/oauth2/token') + .setAuthorizationBaseUrl('https://signin.sandbox.ebay.com/authorize') + + // Set the client ID and secret. + .setClientId(CLIENT_ID) + .setClientSecret(CLIENT_SECRET) + + // Set the name of the callback function in the script referenced + // above that should be invoked to complete the OAuth flow. + .setCallbackFunction('authCallback') + + // Set the property store where authorized tokens should be persisted. + .setPropertyStore(PropertiesService.getUserProperties()) + + // Set the redirect URI to the RuName (eBay Redirect URL name). + .setRedirectUri(RU_NAME) + + // Set the require scopes. + .setScope('https://api.ebay.com/oauth/api_scope/sell.inventory.readonly') + + // Add a Basic Authorization header to token requests. + .setTokenHeaders({ + Authorization: 'Basic ' + + Utilities.base64Encode(CLIENT_ID + ':' + CLIENT_SECRET) + }); +} + +/** + * Handles the OAuth2 callback. + */ +function authCallback(request) { + var service = getService(); + var authorized = service.handleCallback(request); + if (authorized) { + return HtmlService.createHtmlOutput('Success!'); + } else { + return HtmlService.createHtmlOutput('Denied.'); + } +} + +/** + * Logs the redict URI to register. + */ +function logRedirectUri() { + Logger.log(OAuth2.getRedirectUri()); +} diff --git a/src/OAuth2.js b/src/OAuth2.js index b121b19d..6dd5ddb1 100644 --- a/src/OAuth2.js +++ b/src/OAuth2.js @@ -59,11 +59,13 @@ function createService(serviceName) { /** * Returns the redirect URI that will be used for a given script. Often this URI * needs to be entered into a configuration screen of your OAuth provider. - * @param {string} scriptId The script ID of your script, which can be found in - * the Script Editor UI under "File > Project properties". + * @param {string} [optScriptId] The script ID of your script, which can be + * found in the Script Editor UI under "File > Project properties". Defaults + * to the script ID of the script being executed. * @return {string} The redirect URI. */ -function getRedirectUri(scriptId) { +function getRedirectUri(optScriptId) { + var scriptId = optScriptId || ScriptApp.getScriptId(); return 'https://script.google.com/macros/d/' + encodeURIComponent(scriptId) + '/usercallback'; } diff --git a/src/Service.js b/src/Service.js index 045bdb3e..90be5b80 100644 --- a/src/Service.js +++ b/src/Service.js @@ -33,7 +33,6 @@ var Service_ = function(serviceName) { this.params_ = {}; this.tokenFormat_ = TOKEN_FORMAT.JSON; this.tokenHeaders_ = null; - this.scriptId_ = eval('Script' + 'App').getScriptId(); this.expirationMinutes_ = 60; }; @@ -301,6 +300,27 @@ Service_.prototype.setGrantType = function(grantType) { return this; }; +/** + * Sets the URI to redirect to when the OAuth flow has completed. By default the + * library will provide this value automatically, but in some rare cases you may + * need to override it. + * @param {string} redirectUri The redirect URI. + * @return {Service_} This service, for chaining. + */ +Service_.prototype.setRedirectUri = function(redirectUri) { + this.redirectUri_ = redirectUri; + return this; +}; + +/** + * Returns the redirect URI that will be used for this service. Often this URI + * needs to be entered into a configuration screen of your OAuth provider. + * @return {string} The redirect URI. + */ +Service_.prototype.getRedirectUri = function() { + return this.redirectUri_ || getRedirectUri(); +}; + /** * Gets the authorization URL. The first step in getting an OAuth2 token is to * have the user visit this URL and approve the authorization request. The @@ -313,12 +333,10 @@ Service_.prototype.setGrantType = function(grantType) { Service_.prototype.getAuthorizationUrl = function(optAdditionalParameters) { validate_({ 'Client ID': this.clientId_, - 'Script ID': this.scriptId_, 'Callback function name': this.callbackFunctionName_, 'Authorization base URL': this.authorizationBaseUrl_ }); - var redirectUri = getRedirectUri(this.scriptId_); var stateTokenBuilder = eval('Script' + 'App').newStateToken() .withMethod(this.callbackFunctionName_) .withArgument('serviceName', this.serviceName_) @@ -331,7 +349,7 @@ Service_.prototype.getAuthorizationUrl = function(optAdditionalParameters) { var params = { client_id: this.clientId_, response_type: 'code', - redirect_uri: redirectUri, + redirect_uri: this.getRedirectUri(), state: stateTokenBuilder.createToken() }; params = extend_(params, this.params_); @@ -358,15 +376,13 @@ Service_.prototype.handleCallback = function(callbackRequest) { validate_({ 'Client ID': this.clientId_, 'Client Secret': this.clientSecret_, - 'Script ID': this.scriptId_, 'Token URL': this.tokenUrl_ }); - var redirectUri = getRedirectUri(this.scriptId_); var payload = { code: code, client_id: this.clientId_, client_secret: this.clientSecret_, - redirect_uri: redirectUri, + redirect_uri: this.getRedirectUri(), grant_type: 'authorization_code' }; var token = this.fetchToken_(payload); @@ -447,16 +463,6 @@ Service_.prototype.getLastError = function() { return this.lastError_; }; -/** - * Returns the redirect URI that will be used for this service. Often this URI - * needs to be entered into a configuration screen of your OAuth provider. - * @return {string} The redirect URI. - */ -Service_.prototype.getRedirectUri = function() { - return getRedirectUri(this.scriptId_); -}; - - /** * Fetches a new token from the OAuth server. * @param {Object} payload The token request payload.