1+ var CLIENT_ID = '...' ;
2+ var CLIENT_SECRET = '...' ;
3+
4+ /**
5+ * Authorizes and makes a request to the GitHub API.
6+ */
7+ function run ( ) {
8+ var service = getService ( ) ;
9+ if ( service . hasAccess ( ) ) {
10+ var url = 'https://api.smartsheet.com/2.0/users/me' ;
11+ var response = UrlFetchApp . fetch ( url , {
12+ headers : {
13+ Authorization : 'Bearer ' + service . getAccessToken ( )
14+ }
15+ } ) ;
16+ var result = JSON . parse ( response . getContentText ( ) ) ;
17+ Logger . log ( JSON . stringify ( result , null , 2 ) ) ;
18+ } else {
19+ var authorizationUrl = service . getAuthorizationUrl ( ) ;
20+ Logger . log ( 'Open the following URL and re-run the script: %s' ,
21+ authorizationUrl ) ;
22+ }
23+ }
24+
25+ /**
26+ * Reset the authorization state, so that it can be re-tested.
27+ */
28+ function reset ( ) {
29+ var service = getService ( ) ;
30+ service . reset ( ) ;
31+ }
32+
33+ /**
34+ * Configures the service.
35+ */
36+ function getService ( ) {
37+ return OAuth2 . createService ( 'Smartsheet' )
38+ // Set the endpoint URLs.
39+ . setAuthorizationBaseUrl ( 'https://app.smartsheet.com/b/authorize' )
40+ . setTokenUrl ( 'https://api.smartsheet.com/2.0/token' )
41+
42+ // Set the client ID and secret.
43+ . setClientId ( CLIENT_ID )
44+ . setClientSecret ( CLIENT_SECRET )
45+
46+ // Set the name of the callback function that should be invoked to complete
47+ // the OAuth flow.
48+ . setCallbackFunction ( 'authCallback' )
49+
50+ // Set the property store where authorized tokens should be persisted.
51+ . setPropertyStore ( PropertiesService . getUserProperties ( ) )
52+
53+ // Scopes to request
54+ . setScope ( 'READ_SHEETS' )
55+
56+ // Set the handler for adding Smartsheet's required SHA hash parameter to the payload:
57+ . setTokenPayloadHandler ( smartsheetTokenHandler )
58+ }
59+
60+ /**
61+ * Handles the OAuth callback.
62+ */
63+ function authCallback ( request ) {
64+ var service = getService ( ) ;
65+ var authorized = service . handleCallback ( request ) ;
66+ if ( authorized ) {
67+ return HtmlService . createHtmlOutput ( 'Success!' ) ;
68+ } else {
69+ return HtmlService . createHtmlOutput ( 'Denied' ) ;
70+ }
71+ }
72+
73+ /**
74+ * Adds the Smartsheet API's required SHA256 hash parameter to the access token request payload.
75+ */
76+ function smartsheetTokenHandler ( payload ) {
77+ var codeOrRefreshToken = payload . code ? payload . code : payload . refresh_token ;
78+ var input = CLIENT_SECRET + "|" + codeOrRefreshToken ;
79+ var hash = Utilities . computeDigest ( Utilities . DigestAlgorithm . SHA_256 ,
80+ input ,
81+ Utilities . Charset . UTF_8 ) ;
82+ hash = hash . map ( function ( val ) {
83+ // Google appears to treat these as signed bytes, but we need them unsigned...
84+ if ( val < 0 )
85+ val += 256 ;
86+ var str = val . toString ( 16 ) ;
87+ // pad to two hex digits:
88+ if ( str . length == 1 )
89+ str = '0' + str ;
90+ return str ;
91+ } ) ;
92+ payload . hash = hash . join ( "" ) ;
93+ // The Smartsheet API doesn't need the client secret sent (secret is verified by the hash)
94+ if ( payload . client_secret ) {
95+ delete payload . client_secret ;
96+ }
97+ return payload ;
98+ }
0 commit comments