全国のbotファンの皆様こんにちは 大橋です。
Nulab社のディスカッションツールTypetalkは使っていますでしょうか?
なかなかシンプルな作りなのと、しっかりとしたAPIがあるので、素敵な限りです。
そして実はGoogle Apps Scriptは「Googleの情報を使って定期的にAPIを叩く基盤」としては最強に近くて、
今回のようなBot開発にはとても向いています。
今回はこのTypetalkのAPIを楽に扱うためのTypetalkAppというライブラリと、
その参考実装となるTypetalk Google Calendar Botを作ったのでその話を書きたいと思います。
なお、結構ボリュームがあるので何回かに分けてかけたらなーと思ってます。
今回は一回目なのでLibraryの話をします。
なおGASSER向けに書くと、今回のLibraryとBotのアプリケーションは、
2014年2月に追加となったScriptApp.getOAuthToken()
とStateTokenBuilder
を使ったOAuth2フローを体現しているアプリケーションなのでコードのサンプルになるかもしれません。
Libraryをとりあえず使いたい( ー`дー´)キリッ
Libraryを取り込む
以下のライブラリをGASで取り込みます。
Library Key : MQvyTczLCUS1XlKfdLRSaGgV62A3znfOO
Libraryの取り込み方はこちらの記事を参考にして下さい。
そうすると以下のようにTypetalkApp
というサービスが利用できるようになります。
なおこのTypetalkAppは補完が効くように作成していますが、最初にcreate
メソッドを呼び出し、インスタンスを取得して下さい。
Typetalk APIの認可をする
TypetalkにApplication登録する
まずAPIを利用するにはTypetalkにApplication登録をして、
ClientIdとClientSecretを取得する必要があります。
GrantTypeはClient Credentials
とAuthorizatoin Code
の二つがありますが
- Typetalk上の自分のアカウントの情報を取得したり、自分のアカウントでポストしたい
- Client Credentialsを選択
- 自分以外のアカウントの情報を取得したり、自分以外のアカウントでポストしたい
- Authorization Codeを選択
という考えになります。
GrantTypeでClient Credentialsを選択した場合
特に設定は必要ありません。
アプリケーション名や、icon画像などは自由に設定して問題無いと思います。
GrantTypeでAuthorization Codeを選択した場合
「リダイレクト URI」以外の項目は認可済みアプリケーション画面や、認可画面に表示される項目となります。
という感じで設定していた場合は、
という感じで表示されます。
超重要「リダイレクト URI」の設定
これにミスると全くうまく行きません。
ここにはGoogle Apps Scriptのコールバック専用URLを設定する必要があります。
コールバックURLを作るにはいくつか手順が必要です。
- まず2013年度版 5分で始めるWebアプリケーション(Google Apps Script)を参考にLibraryを使う予定のGASプロジェクトでWebアプリケーションとして動作するように設定します。
- 以下のテストコードを1.で作成したプロジェクトに作成し、このテストコードを走らせます。
funciton showCallbackURL() {
Logger.log(TypetalkApp.create("dummy","dummy",[]).getCallbackURL("dummy"));
}
-
ログコンソールを表示(Ctrl + Enter)して、
https://script.google.com/.../usercallback?state=...
を取得し?state=
までをコピーします。 -
コピーしたURLを「リダイレクト URI」に設定します。
これで設定は完了です。
Libraryを使ってGASからTypetalkの認可を行い、APIのAccessTokenを取得する。
TypetalkAppを利用して、Typetalk APIを呼び出すにはAccessTokenを取得する必要があります。
上記でGruntTypeに何を選んだかによって少しコードが異なります。
Client Credentialsを利用した場合
GruntTypeでClient Credentials
を設定している場合は、
特にWeb画面を作らなくてもコードだけでAccessTokenを取得できます。
それを行うには以下のようにします。
function authorize() {
var clientId = "上記で取得したClientID";
var clientSecret = "上記で取得したClientSecret";
var scopes = [
TypetalkApp.SCOPE_MY, //自身のプロフィールを取得する場合のSCOPE
TypetalkApp.SCOPE_TOPIC_POST,//投稿する場合のSCOPE
TypetalkApp.SCOPE_TOPIC_READ //投稿を取得する場合のSCOPE
]; //scopeは配列で指定します。TypetalkApp.SCOPE_で補完可能です。
var typetalkApp = TypetalkApp.create(clientId, clientSecret, scopes);
if(!typetalkApp.isAuthorized()) {
//typetalkApp.isAuthorized()はtypetalkAppにて認可済み(AccessTokenを取得済み)かを判定します。
//typetalkAppは内部でaccessTokenなどの情報をUserPropertiesに保存するため、一度呼び出していれば、以降は特に呼び出す必要はないです。
//これらの認証情報を削除したい場合はtypetalkApp.deleteCredential()メソッドを呼び出して下さい。
typetalkApp.authorize();
}
}
Authorization Codeを利用した場合
Webアプリケーションとして、認可フローが必要になります。
色々コードは必要なのですが、ざっくり言うと
- Typetalkの認可用URLを取得して画面に表示する関数
- Typetalkにて認可後、GASのWebアプリケーションに戻ってきた際に処理する関数
の二つが必要になります。
以下がそのサンプルです。
//Typetalkの認可用URLを取得して画面に表示する関数
function doGet(e) {
//TypetalkApp.create()を呼び出す処理をラップしています。
var typetalkApp = getTypetalkApp();
// var typetalkApp = TypetalkApp
if(typetalkApp.isAuthorized()) {
return showLoggedin(); //AccessToken取得済みの場合はログイン後の画面を表示
}
//"callback"は下に書くcallback関数のことを指しています。
var authorizeUrl = typetalkApp.getAuthorizeUrl("callback");
//画面にリンクを表示する
return HtmlService.createHtmlOutput('<a href="' + authorizeUrl + '" target="_blank">Typetalkで認可する</a>');
}
//Typetalkにて認可後、GASのWebアプリケーションに戻ってきた際に処理する関数
//Typetalkで認可が完了すると、この関数が呼ばれます。
function callback(e) {
var typetalkApp = getTypetalkApp();
// var typetalkApp = TypetalkApp
//typetalkAppのsaveAccessTokenに以下のようにcodeパラメータを渡すとLibrary側でAccessTokenを取得し、保存してくれます。
typetalkApp.saveAccessToken(e.parameter.code);
//完了後画面を表示する(HtmlService)とその画面がユーザに表示されます。
return showLoggedin();
}
これで上記GASの画面を表示すると認可を行うためのリンクが表示され、Typetalkへ遷移し、戻ってきてAccessTokenを取得できます。
Libraryを使ってTypetalkにポストしてみる
上記で認可が完了していれば準備は完了です。
まずは投稿してみましょう。
function postMessage() {
var typetalkApp = getTypetalkApp();
// var typetalkApp = TypetalkApp
if(!typetalkApp.isAuthorized()) {
typetalkApp.authorize();
}
//topicを取得
var result = typetalkApp.getTopics();
//topicIdを取得 topicIdはtypetalkの画面に行って、トピックを表示した際にURLに表示されているものでもOK
var topicId = result.topics[0].topic.id;
//対象トピックにポスト
typetalkApp.postMessage(topicId, "ほげほげ");
}
まとめ
上記の認証周り以外の処理はだいたい補完できるので、
補完を見て頂いて叩いていただければ分かるかなーと思います。
次回ぐらいにもっと細かいApps Scriptとの組み合わせとかのことを書く予定です。
なおそういうのが待てない方はサンプルとしてGoogle Calendar Botを作ったので見てみて下さい。
Calendar Botのコード
追記
次の話を書きました。
http://qiita.com/soundTricker/items/6b633314e04331fcf3ed