kubell Creator's Note

ビジネスチャット「Chatwork」のエンジニアのブログです。

ビジネスチャット「Chatwork」のエンジニアのブログです。

読者になる

ChatWorkのOAuthをGoogle Apps Scriptで使う

こんにちは。@kyo_agoです。

ChatWorkのOAuthが公開されました。

ここではChatWorkのOAuthをGoogle Apps Script(以降、GAS)から使う方法を紹介したいと思います。

これまでChatWorkではToken方式のAPI認証方式のみを提供していましたが、先日OAuth形式の認証方式の提供も開始しました。

blog-ja.chatwork.com

これによりToken形式では「常にToken発行者権限」だったAPIリクエストが、OAuth形式では「OAuthで認証を行った人の権限」でAPIリクエストを行うことができます。

それでは実際GASからOAuthを行う流れを紹介したいと思います。

ChatWorkにOAuthクライアントの登録を行う

まず、ChatWorkのAPI管理画面からOAuthクライアントの登録を行います。

https://www.chatwork.com/service/packages/chatwork/subpackages/oauth/client_list.php

  • 「クライアント名」にはわかりやすい名前を入力してください
  • 「クライアントタイプ」は「confidential」のチェックを入れたままにしてください
  • 「リダイレクト先URI」はGASを作成後書き換えるので一旦どこかのURL (例 : https://example.com/) を入力してください
  • 「スコープ」には作成したいアプリケーションに必要な権限を設定してください
    ここでは「自分のアカウントに紐づく情報の取得」をチェックしたものとして説明します。

f:id:cw-kyo-ago:20171207215830p:plain

画面下部の「作成」ボタンを押すとOAuthクライアントが作成されます。

f:id:cw-kyo-ago:20171207220032p:plain

「クライアントID」と「クライアントシークレット」はGAS作成時に使用するためメモしてください。

GASを作成する

SpreadSheetやGoogle Apps ScriptからScriptの作成を行ってください。

Apps Script – Google Apps Script

今回は簡単に作成するため「OAuth2 for Apps Script」を使用します。

ライブラリの追加

github.com

メニューの「Resources」から「Libraries...」を選択してください。

f:id:cw-kyo-ago:20171207220419p:plain

Librariesダイアログが開くので、以下の方法でライブラリを追加してください。

  1. 「Add a library」にOAuth2 for Apps ScriptのScript ID(1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF)を入力して「Add」を押す
  2. 「Version」から最新のバージョンを指定する(記事執筆時点ではVer 24)
  3. 「Save」を押してダイアログを閉じる

f:id:cw-kyo-ago:20171207221141p:plain

コードの記述

以下のコードを貼り付けます。

「クライアントID」と「クライアントシークレット」は先に保存した内容に置き換えてください。

var CLIENT_ID = 'クライアントID';
var CLIENT_SECRET = 'クライアントシークレット';
// スコープ をスペース区切りで指定
// http://developer.chatwork.com/ja/oauth.html#secAppendix
var scope = 'users.profile.me:read';

function doGet(env) {
    // URLに?logout=trueをつけてアクセスすることで認証をクリアする
    if (env.parameter.logout) {
        OAuth2.createService('ChatWork')
            .setPropertyStore(PropertiesService.getUserProperties())
            .reset()
        ;
        return HtmlService.createTemplate('Logout').evaluate();
    }

    var chatWorkService = getChatWorkService();
    if (chatWorkService.hasAccess()) {
        // 認証成功
        var response = UrlFetchApp.fetch('https://api.chatwork.com/v2/me', {
            headers: {
                Authorization: 'Bearer ' + chatWorkService.getAccessToken()
            }
        });
        var result = JSON.parse(response.getContentText());
        return HtmlService.createTemplate(JSON.stringify(result, null, 2)).evaluate();
    } else {
        var template = HtmlService.createTemplate(
            'RedirectUri:' + chatWorkService.getRedirectUri() + '<br>' +
            '<a href="<?= authorizationUrl ?>" target="_blank">Authorize</a>');
        template.authorizationUrl = chatWorkService.getAuthorizationUrl();
        return template.evaluate();
    }
}

function authCallback(request) {
    var chatWorkService = getChatWorkService();
    var isAuthorized = chatWorkService.handleCallback(request);
    if (isAuthorized) {
        return HtmlService.createHtmlOutput('Success! You can close this tab.');
    } else {
        return HtmlService.createHtmlOutput('Denied. You can close this tab');
    }
}

function getChatWorkService() {
    return OAuth2.createService('ChatWork')
        .setAuthorizationBaseUrl('https://www.chatwork.com/packages/oauth2/login.php')
        .setTokenUrl('https://oauth.chatwork.com/token')
        .setCallbackFunction('authCallback')
        .setPropertyStore(PropertiesService.getUserProperties())

        .setClientId(CLIENT_ID)
        .setClientSecret(CLIENT_SECRET)
        .setScope(scope)

        .setTokenHeaders({
            'Authorization': 'Basic ' + Utilities.base64Encode(CLIENT_ID + ':' + CLIENT_SECRET)
        })
        .setTokenPayloadHandler(function(tokenPayload) {
            delete tokenPayload.client_id;
            return tokenPayload;
        })
    ;
}

Webアプリとして公開

ブラウザからアクセスできるようにGASをWebアプリとして公開します。

メニューの「Publish」から「Deploy as web app...」を選択してください。
(GASの作成方法によってはここでProjectの保存を要求される場合があります。その場合任意の名前で保存してください)

f:id:cw-kyo-ago:20171207221923p:plain

以下のように指定してください。

  1. 「Project version」は「New」を指定
  2. 「Execute the app as」はこのGASを「作成者の権限」か「アクセスした人の権限」のどちらで実行するか指定
    (ここでは「アクセスした人の権限」(「User accessing the web app」)を選択)
  3. 「Who has access to the app」はこのGASにアクセスできる人を指定(ここでは「Anyone」を指定)
  4. Updateを押す

f:id:cw-kyo-ago:20171207222854p:plain

保存が完了すると「Current web app URL」が表示されるので、このURLをブラウザで開いてください。

f:id:cw-kyo-ago:20171207223114p:plain

URLにアクセスすると以下のようなURLと「Authorize」というリンクが表示されます。

f:id:cw-kyo-ago:20171207223323p:plain

「RedirectUri」と表示されているURLをコピーして、ChatWorkのOAuth管理画面から先に作成したOAuthクライアントを編集し、「リダイレクト先URI」へ貼り付けて保存してください。

https://www.chatwork.com/service/packages/chatwork/subpackages/oauth/client_list.php

保存後、GASの「Current web app URL」から「Authorize」のリンクをクリックしてください。

f:id:cw-kyo-ago:20171207224151p:plain

ChatWork側の認証を行うことで、この時アクセスした人の権限でAPIリクエストを行うことができるようになります。

認証後は表示されるタブを閉じてください。

GASの「Current web app URL」を再度開くと認証した人のプロフィール情報がJSON形式で表示されます。

もし、認証をクリアしたい場合、URLの末尾に「?logout=true」をつけてアクセスしてください。

まとめ

GAS + ライブラリを使うと比較的簡単にOAuth対応アプリが作れるのでぜひ試してみてください!