こんにちは、長男は片付けしろと言えば、片付けるものの、次男が
さっぱり片づけをしません。しかも、長男が次男の分までおもちゃを片付けています。
そんな状況で手を焼いて、長男には自分の使いたいおもちゃだけ片付けさせ、
次男が片付けなかったおもちゃは翌日回収してしまってしまう作戦にでたところ、
若干次男片付けに参加するようになりました。@kjunichiです。
前提
すでにHerokuでdockerでbotkitを動かしている
OAuth関連のパラメータの取得
Google Calendar APIのページで、サンプルを動かす。
サンプルを動かすため必要なjsonファイルの取得
サンプルの説明に従い、OAuth認証に必要なjsonファイルを取得し、これを
- client_secret.json
として保存する。
サンプルを動かし、キーを設定する
サンプルを起動し、メッセージに従い、キーを取得し、サンプル入力して動かす。
この作業により
- ~/.credentials/calendar-nodejs-quickstart.json
にファイルが出来る。
herokuに環境変数としてOAuth関連のパラメータを登録する
DockerfileのENVにし記述してもHerokuの実行環境ではこれらの環境変数は無効化されているので、 以下の様にherokuコマンドで環境変数を設定する必要がある模様。
JSONファイルを環境変数として登録
json2envという便利なnpmパッケージがあり、今回はこれを利用して
npm install -g json2env
heroku config:set CALENDAR_TOKEN=`json2env ~/.credentials/calendar-nodejs-quickstart.json` --app アプリ名 heroku config:set CALENDAR_SECRET=`json2env ./client_secret.json` --app アプリ名
ファイル名 | 環境変数名 |
---|---|
client_secret.json | CALENDAR_SECRET |
calendar-nodejs-quickstart.json | CALENDAR_TOKEN |
コード
var google = require('googleapis'); var googleAuth = require('google-auth-library'); var buf = []; getOurEvents = (cb) => { buf = []; // Load client secrets from a local file. const content = process.env['CALENDAR_SECRET']; if (content) { console.log("CALENDAR_SECRET."); authorize(JSON.parse(content), cb, listAllEvents); } }; /** * Create an OAuth2 client with the given credentials, and then execute the * given callback function. * * @param {Object} credentials The authorization client credentials. * @param {function} callback The callback to call with getting calendar data. * @param {function} callback The callback to call with the authorized client. */ function authorize(credentials, cb, callback) { var clientSecret = credentials.installed.client_secret; var clientId = credentials.installed.client_id; var redirectUrl = credentials.installed.redirect_uris[0]; var auth = new googleAuth(); var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl); // Check if we have previously stored a token. const token = process.env['CALENDAR_TOKEN']; if (token) { console.log("calendar_token from ENV."); oauth2Client.credentials = JSON.parse(token); callback(oauth2Client,cb); } } function listAllEvents(auth,cb) { var calendar = google.calendar('v3'); calendar.calendarList.list({ auth: auth }, (err, res) => { if (err) { console.log('The API returned an error: ' + err); return; } //console.log(res.items); const numCals = res.items.length; var doneCals = 0; for (i = 0; i < res.items.length; i++) { var calId = res.items[i].id; var tday = new Date(); var targetSec = tday.getTime() + (2 * 86400000); tday.setTime(targetSec); //console.log("get "+calId); //console.log(tday.toISOString()); calendar.events.list({ auth: auth, calendarId: calId, timeMin: (new Date()).toISOString(), timeMax: tday.toISOString(), maxResults: 10, singleEvents: true, orderBy: 'startTime' }, (err2, res2) => { if (err2) { console.log('The API returned an error: ' + err2); return; } //console.log(res2); var events = res2.items; if (!events || events.length == 0) { //console.log('No upcoming events found. '); //console.log(res2); } else { //console.log('Upcoming events:'); for (var i = 0; i < events.length; i++) { var event = events[i]; var start = event.start.dateTime || event.start.date; buf.push(start + " " + event.summary); //console.log('%s - %s', start, event.summary); } } doneCals++; if (doneCals + 1 >= numCals) { return cb(buf); } }); } }); } exports.getOurEvents = getOurEvents;
これをlibcalendar.jsとして保存。
botkitに組み込む
以下を既存のbotkitでつくったボットのコードに追加。
const libcalendar = require('./libcalendar.js'); // snip controller.hears(['予定'],'ambient',function(bot,message) { libcalendar.getOurEvents((b)=>{ var a = ""; for(var i = 0; i < b.length; i++) { a = a + b[i]+"\n"; } bot.reply(message,a); }); });
これで、ボットがいるチャンネルで「予定」と言えば、Googleカレンダーに登録されている複数のカレンダーから二日後の予定まで教えてくれる。
ローカルで動かすための設定
herokuで動かすには前述の設定で良いが、ローカルで動かすためには、 以下のようにdocker-compose.ymlを編集して、環境変数を受け取れるようにする必要がある。
web: build: . command: 'bash -c ''node web.js''' working_dir: /app/user environment: TZ: 'Asia/Tokyo' PORT: 8080 CALENDAR_TOKEN: $CALENDAR_TOKEN CALENDAR_SECRET: $CALENDAR_SECRET SLACK_TOKEN: $SLACK_TOKEN ports: - '8080:8080'
ローカルのdockerで動かすには
SLACK_TOKEN=hogehoge CALENDAR_TOKEN=`json2env ~/.credentials/calendar-nodejs-quickstart.json` CALENDAR_SECRET=`json2env client_secret.json` docker-compose up web
関連記事
- アメッシュの画像を表示するslackのボットをbotkitを使ってDockerイメージにしてherokuで動かした
- IJuliaをHerokuの無料枠で動かした
- アメッシュでECONNRESETを食らっててslackbotが死んでた件
- JavaScriptでGoogle Calendar APIを使った