BLOG ブログ

「寂しいkintone」を救いたい

こんにちは。球蹴り大好きなkitoです。

来シーズンの注目選手は、マケレレの上位互換こと、エンゴロ・カンテです。
運動量とボール奪取力、、、、昨シーズンのレスターでの活躍は本当にすごかったですね。。。
ビッグクラブへ行くのでしょうか、気になります。

さて、今回ですが kintone Café 名古屋 vol3. で発表した
「寂しくないkintone」を補足していきたいと思います。

※発表の詳細は、 kintone Café 名古屋 Vol.3 開催報告 からどうぞ。

何故、今さら補足を・・・・

今さら補足する大きな理由として、2つあります。

実は私の発表、元々LT(5分)の予定でした(汗
そのため、実現しているコードの紹介が一切ありません・・・。補足しなければーーー、と悶々としてました。

そして、もう一つ。

最近、BotAIのニュースが増えてきていると思いませんか?

春頃に MicrosoftLineFacebook が立て続けにBotのAPIを発表しました。
これから今まで以上に、BotやAIを活用したニュースや事例がドンドン出てくると思います。

この流れに乗って、お手軽雑談Botを紹介し、
寂しくkintoneを利用されているそんなアナタを救いたい!と思った次第です。

(チームワークを謳っているkintoneで、そもそも寂しく感じる事なんて無いよー
という突っ込みが聞こえてきますが、張り切ってスルーします。)

雑談Botに利用したAPI

雑談Botには、Docomo社提供の雑談APIを利用しています。
※APIを利用するためには、申込が必要です。

このAPIを利用する事で、独自に返答する機能を作りこみせずとも、
お手軽に実現できます。

完成形は、こんな感じで書き込んだコメントに対し、雑に反応してくれます。

それでは、大まかですが作成手順をみていきましょう!

チャット画面用のライブラリを導入する

本当は、kintoneのコメント欄で実現したかったのですが、実装時はコメント系のAPIがなく、自前で用意する必要がありました。。。
2016/05/08のメンテナンスでコメント系APIが追加されています!)

チャット画面、簡単に作れないかなぁ~と検索してみたところ、以下のライブラリに遭遇。
サクッと導入します。

関連ファイルをダウンロードして、「アプリの設定変更 > JavaScript / CSSでカスタマイズ」 から、読み込み設定します。
併せて、ライブラリが依存しているjQueryとjQueryUIを、Cybozu-CDNを利用して読み込みます。

※kintoneのフラットなスタイルに合わせたい場合は、こちらもどうぞ。

独自のチャット画面を表示する

導入したライブラリを利用して、
kintoneアプリのレコード一覧を表示したタイミングでチャット画面が表示されるようにします。

以下に記載したコードを記述したJavaScriptファイルを作成し、
先で紹介した手順同様に「アプリの設定変更 > JavaScript / CSSでカスタマイズ」で読み込み設定します。
JSEdit for kintoneプラグインを利用すると超絶簡単に作成できます。

これで、チャット画面が表示され、メッセージの追加ができるようになります!

(function () {
    "use strict";

    /**
     * レコード一覧画面表示
     */
    kintone.events.on("app.record.index.show", function(e) {

        var chat = $('#chat_div');
        if ( chat.length === 0 ) {
            // チャットボックス用の要素追加
            var chat_div = document.createElement('div');
            chat_div.id = 'chat_div';
            kintone.app.getHeaderMenuSpaceElement().appendChild(chat_div);
            chat = $('#chat_div');
        }

        // チャットボックス生成
        chat.chatbox({
            id: 'chat_div', offset: 0, width: 600,
            title : 'チャットボックスのタイトル',
            messageSent : function(id, user, msg) {
                // チャットメッセージを追加
                chat.chatbox('option', 'boxManager')
                    .addMsg(kintone.getLoginUser().name, msg);
            }
        });
    });
})();

Botに応答させて、ついでにブラウザにも喋らせて、完成!!

次に追加されたメッセージに対して、雑談Botが応答するようにしていきます。
テキストだけでは寂しい…。そんなアナタのためについでに喋らせます。
※喋るのは、Web Speech API対応のブラウザのみ。Chormeでお楽しみください。

先のカスタマイズコードを以下のように変更して完成!?

(function() {
    "use strict";

    /**
     * レコード一覧画面表示
     */
    kintone.events.on("app.record.index.show", function(e) {

        var chat = $('#chat_div');
        if ( chat.length === 0 ) {
            // チャットボックス用の要素追加
            var chat_div = document.createElement('div');
            chat_div.id = 'chat_div';
            kintone.app.getHeaderMenuSpaceElement().appendChild(chat_div);
            chat = $('#chat_div');
        }

        // チャットボックス生成
        chat.chatbox({
            id: 'chat_div', offset: 0, width: 600,
            title : 'チャットボックスのタイトル',
            messageSent : function(id, user, msg) {
                // チャットメッセージを追加
                chat.chatbox('option', 'boxManager')
                    .addMsg(kintone.getLoginUser().name, msg);
                // Botから返答する
                addBotResponse(msg, this.boxManager);
            }
        });
    });

    /**
     * 応答内容を追加
     */
    function addBotResponse(message, boxManager) {

        var chatApiUrl = 'ここに雑談APIのURLを指定';
        var header = {'Content-Type': 'application/json'};
        var chatPayload = createPayload(message);

        kintone.proxy(chatApiUrl, 'POST', header, chatPayload)
            .then(function(args) {
                    var botMessage = parseBotResponse(args);
                    boxManager.addMsg('Botより愛をこめて', botMessage);
                    speakMessage(botMessage);
            });
    }

    /**
     * チャット応答の解析
     */
    function parseBotResponse(response) {

        var body =  response[0];
        var status = response[1];
        var headers = response[2];

        if (status != 200) {
            console.log(body);
            return status + 'エラー出てしまったぁ。直してーーーー';
        }
        var parsedResponse = JSON.parse(body);
        CHAT_MODE_ID = parsedResponse.mode;
        CHAT_CONTEXT_ID = parsedResponse.context;    // 会話コンテキストID退避
        return parsedResponse.utt;
    }

    var CHAT_MODE_ID = '';    // 会話モードID格納用
    var CHAT_CONTEXT_ID = ''; // 会話コンテキストID格納用

    /**
     * 問合せ内容を作成
     */
    function createPayload(message) {
        var payload = {
                'nickname' : kintone.getLoginUser().name,
                'utt': message,
                'place' : '名古屋',
                't' : 20,    // なし:標準、20:関西弁、30:赤ちゃん
                'mode' : CHAT_MODE_ID,
                'context' : CHAT_CONTEXT_ID
        };
        return JSON.stringify(payload);
    }

    /**
     * 指定されたメッセージを発話する
     */
    function speakMessage(message) {

        if (!('SpeechSynthesisUtterance' in window)) {
            return;
        }
        var msg = new SpeechSynthesisUtterance();
        msg.voiceURI = 'Google 日本人';
        msg.rate = 1;   // 速度
        msg.pitch = 2.0; // 音程
        msg.text = message;
        msg.lang = 'ja-JP';
        // message.volume = 1; // 音量

        speechSynthesis.speak(msg);
    }
})();

まとめ

いかがでしたでしょうか。
寂しくkintone利用していたアナタも寂しくなくなれば幸いです。

発表スライド内の野望等、さらに発展させて
当ブログ、もしくは kintone Café 名古屋 (そろそろ次回開催がありそう?!)で伝えられたらと思います~。