Last active
December 14, 2015 17:39
-
-
Save binux/5123568 to your computer and use it in GitHub Desktop.
Google App Script of reader2plus A script record user's Google reader starred items as activities.
This file contains hidden or 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
| // | |
| // 1. Depoly as web app (https://developers.google.com/apps-script/execution_web_apps#deploying) | |
| // 2. register as web app through the APIs Console (https://code.google.com/apis/console#access) | |
| // 3. add 'client_id', 'client_secret' to project properties. | |
| // 4. If published to anyone else, make sure they access to the code. (https://developers.google.com/apps-script/execution_time_triggers) | |
| // | |
| var script_url = ScriptApp.getService().getUrl(); | |
| var client_id = ScriptProperties.getProperty('client_id'); | |
| var client_secret = ScriptProperties.getProperty('client_secret'); | |
| var scope = "https://www.googleapis.com/auth/plus.login http://www.google.com/reader/api"; | |
| var activity_types = ["http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity", "http://schemas.google.com/CheckInActivity", | |
| "http://schemas.google.com/CommentActivity", "http://schemas.google.com/CreateActivity", "http://schemas.google.com/DiscoverActivity", | |
| "http://schemas.google.com/ListenActivity", "http://schemas.google.com/ReserveActivity", "http://schemas.google.com/ReviewActivity" ]; | |
| var request_visible_actions = "http://schemas.google.com/DiscoverActivity http://schemas.google.com/AddActivity"; | |
| function doGet(request) { | |
| if (request && request.parameter && request.parameter.logout) { | |
| logout(); | |
| return HtmlService.createHtmlOutput('done <a href="'+script_url+'">continue</a>'); | |
| } | |
| if (request && request.parameter && request.parameter.state == 'gplus' && request.parameter.code) { | |
| var result = get_token(request.parameter.code); | |
| welcome_moment(); | |
| do_update(); | |
| reset_tigger(); | |
| return result; | |
| } | |
| if (UserProperties.getProperty('gplus_access_token')) { | |
| return status(); | |
| } | |
| return HtmlService.createTemplateFromFile('index').evaluate(); | |
| } | |
| function get_auth_url() { | |
| return "https://accounts.google.com/o/oauth2/auth?" | |
| +"scope="+encodeURIComponent(scope) | |
| +"&state="+encodeURIComponent("gplus") | |
| +"&redirect_uri="+encodeURIComponent(script_url) | |
| +"&response_type=code&access_type=offline" | |
| +"&client_id="+encodeURIComponent(client_id) | |
| +'&request_visible_actions='+encodeURIComponent(request_visible_actions) | |
| } | |
| function get_token(code) { | |
| var payload = { | |
| "code" : code, | |
| "client_id" : client_id, | |
| "client_secret" : client_secret, | |
| "redirect_uri" : script_url, | |
| "grant_type" : "authorization_code" | |
| }; | |
| var options = { | |
| "method" : "post", | |
| "payload" : payload | |
| }; | |
| var response = UrlFetchApp.fetch('https://accounts.google.com/o/oauth2/token', options); | |
| var token = Utilities.jsonParse(response.getContentText()); | |
| for (var key in token) { | |
| UserProperties.setProperty('gplus_'+key, token[key]); | |
| } | |
| UserProperties.setProperty('gplus_token_expire', ((new Date()).getTime()+token.expires_in*1000).toString()); | |
| return HtmlService.createHtmlOutput('done <a href="'+script_url+'">continue</a>'); | |
| } | |
| function gplus_request(url, data) { | |
| if (!UserProperties.getProperty('gplus_access_token')) { | |
| return false; | |
| } | |
| if (UserProperties.getProperty('gplus_token_expire') <= (new Date()).getTime() && !refresh_token()) { | |
| return false; | |
| } | |
| var options = { | |
| "method": data ? "POST" : "GET", | |
| "payload": data ? Utilities.jsonStringify(data) : "", | |
| "contentType": "application/json", | |
| "headers" : { | |
| "Authorization" : "Bearer " + UserProperties.getProperty('gplus_access_token') | |
| }, | |
| "muteHttpExceptions": true, | |
| }; | |
| var response = UrlFetchApp.fetch(url, options); | |
| response = Utilities.jsonParse(response.getContentText()); | |
| return response; | |
| } | |
| function refresh_token() { | |
| if (!UserProperties.getProperty('gplus_refresh_token')) { | |
| logout(); | |
| return false; | |
| } | |
| var payload = { | |
| "refresh_token" : UserProperties.getProperty('gplus_refresh_token'), | |
| "client_id" : client_id, | |
| "client_secret" : client_secret, | |
| "grant_type" : "refresh_token" | |
| }; | |
| var options = { | |
| "method" : "post", | |
| "payload" : payload | |
| }; | |
| try { | |
| var response = UrlFetchApp.fetch('https://accounts.google.com/o/oauth2/token', options); | |
| Logger.log(response.getContentText()); | |
| var token = Utilities.jsonParse(response.getContentText()); | |
| for (var key in token) { | |
| UserProperties.setProperty('gplus_'+key, token[key]); | |
| } | |
| UserProperties.setProperty('gplus_token_expire', ((new Date()).getTime()+token.expires_in*1000).toString()); | |
| return true; | |
| } catch (e) { | |
| Logger.log(e.message); | |
| logout(); | |
| return false; | |
| } | |
| } | |
| function verify_token() { | |
| var options = { | |
| "muteHttpExceptions": true, | |
| }; | |
| var response = UrlFetchApp.fetch('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='+UserProperties.getProperty('gplus_access_token'), options); | |
| response = Utilities.jsonParse(response.getContentText()); | |
| if (response.error) { | |
| return false; | |
| } else { | |
| UserProperties.setProperty('gplus_token_expire', ((new Date()).getTime()+response.expires_in*1000).toString()); | |
| return true; | |
| } | |
| } | |
| function logout() { | |
| var triggers = ScriptApp.getScriptTriggers(); | |
| for (var i = 0; i < triggers.length; i++) { | |
| ScriptApp.deleteTrigger(triggers[i]); | |
| } | |
| var options = { | |
| "muteHttpExceptions": true, | |
| }; | |
| UrlFetchApp.fetch("https://accounts.google.com/o/oauth2/revoke?token="+UserProperties.getProperty('gplus_access_token'), options); | |
| UserProperties.deleteAllProperties(); | |
| } |
This file contains hidden or 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
| <html> | |
| <body> | |
| <a href="<?= get_auth_url() ?>"><img src="https://developers.google.com/+/images/branding/sign-in-buttons/Red-signin_Medium_base_44dp.png" /></a> | |
| </body> | |
| </html> |
This file contains hidden or 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
| function reset_tigger() { | |
| var triggers = ScriptApp.getScriptTriggers(); | |
| for (var i = 0; i < triggers.length; i++) { | |
| ScriptApp.deleteTrigger(triggers[i]); | |
| } | |
| ScriptApp.newTrigger("do_update") | |
| .timeBased() | |
| .everyMinutes(5) | |
| .create(); | |
| } | |
| function welcome_moment() { | |
| var moment = { | |
| "type": "http://schemas.google.com/AddActivity", | |
| "target": { | |
| "id": "welcome-moment", | |
| "type":"http://schemas.google.com/AddActivity", | |
| "name": "reader2plus is now working", | |
| "description": "A script record user's Google reader starred items as activities.", | |
| }, | |
| }; | |
| var response = gplus_request("https://www.googleapis.com/plus/v1/people/me/moments/vault", moment); | |
| } | |
| function status() { | |
| return HtmlService.createTemplateFromFile('status').evaluate(); | |
| } | |
| function do_update() { | |
| var reader; | |
| if (UserProperties.getProperty('last_update')) { | |
| reader = gplus_request("https://www.google.com/reader/api/0/stream/contents/user/-/state/com.google/starred?n=100&ot="+UserProperties.getProperty('last_update')); | |
| } else { | |
| reader = gplus_request("https://www.google.com/reader/api/0/stream/contents/user/-/state/com.google/starred?n=1"); | |
| } | |
| UserProperties.setProperty("last_update", parseInt((new Date()).getTime() / 1000).toString()); | |
| var sheet = get_sheet(); | |
| var scriptdb = ScriptDb.getMyDb(); | |
| reader.items.forEach(function(e) { | |
| if (e.alternate.length <= 0 || !e.alternate[0].href) return ; | |
| if (scriptdb.query({"id": e.id}).getSize() > 0) return; | |
| var moment = { | |
| "type": "http://schemas.google.com/DiscoverActivity", | |
| "target": { | |
| "url": e.alternate[0].href, | |
| }, | |
| }; | |
| var response = gplus_request("https://www.googleapis.com/plus/v1/people/me/moments/vault", moment); | |
| if (response.id) { | |
| scriptdb.save({'id': e.id}); | |
| } | |
| sheet.appendRow([e.origin.title, e.id, e.alternate[0].href, e.title, response.id]); | |
| }); | |
| } | |
| function get_sheet() { | |
| var sheet = SpreadsheetApp.getActiveSpreadsheet(); | |
| if (sheet) { | |
| return sheet; | |
| } else if (UserProperties.getProperty('sheet')) { | |
| sheet = SpreadsheetApp.openById(UserProperties.getProperty('sheet')); | |
| } else { | |
| sheet = SpreadsheetApp.create('reader2plus'); | |
| UserProperties.setProperty('sheet', sheet.getId()); | |
| } | |
| return sheet; | |
| } |
This file contains hidden or 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
| <html> | |
| <body> | |
| <? | |
| var reader_user = gplus_request('https://www.google.com/reader/api/0/user-info'); | |
| var me = gplus_request("https://www.googleapis.com/plus/v1/people/me"); | |
| ?> | |
| <?= reader_user.userEmail ?> => <a href="<?= me.url ?>" target=_blank>+<?= me.displayName ?></a> <a href="<?= script_url ?>?logout=1">logout</a> | |
| <hr /> | |
| last updatetime: <?= UserProperties.getProperty('last_update') ?> (<?= (new Date()).getTime() / 1000 - UserProperties.getProperty('last_update') ?>s ago) | |
| <a href="#" onclick="google.script.run.do_update();return false;">update now</a> | |
| <br /> | |
| <a href="<?= get_sheet().getUrl() ?>" target="_blank">log sheet</a><br /> | |
| <a href="#" onclick="document.getElementById('debug_area').setAttribute('style', '')">show debug</a> | |
| <div id="debug_area" style="display: none;"> | |
| <p> | |
| trigger: | |
| <a href="#" onclick="google.script.run.reset_tigger();return false;">reset tigger</a> <br /> | |
| <? for (var t = ScriptApp.getScriptTriggers(), i = 0; i < t.length; ++i) { ?> | |
| <?= t[i].getHandlerFunction() ?> <?= t[i].getEventType() ?> <?= t[i].getUniqueId() ?><br /> | |
| <? } ?> | |
| </p> | |
| <p> | |
| UserProperties:<br /> | |
| <a href="#" onclick="google.script.run.refresh_token();return false;">refresh_token</a> <br /> | |
| <? var p = UserProperties.getProperties(); for (var key in p) { ?> | |
| <?= key ?> = <?= p[key] ?> <br /> | |
| <? } ?> | |
| </p> | |
| </div> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment