2018.04.19

LINEChatBotでナレッジを表示してみよう

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

はじめに

皆さんこんにちは
全てのナレッジを愛し、全てのナレッジに愛された男!になりたいと思ってから、さらに1年...
ナレッジをこよなく愛する仲です。

ナレッジの認知度向上のため、今回はLINEとナレッジを連携してみたいと思います。

事前準備

LINEとナレッジを連携するために必要なものは下記になります。
準備の詳細についてはリンク先を参考にして頂ければと思います。
・LINEの準備
・ナレッジの設定
・ナレッジのデータ
・PKBの設定(外部公開用)

Salesforce側の設定

LINEと繋がってみようのブログにあるLineWebHookCallbackをベースにナレッジを検索して結果を表示するようにしてみました。
@RestResource(urlMapping='/line_webhook_callback')
global with sharing class LineWebHookCallback {

    static String LINE_REPLY_URI = 'https://api.line.me/v2/bot/message/reply';
    static String CH_ACCESS_TOKEN = '**環境に合わせて設定**';
    static String MYSITESURL = 'https://**SitesのURL**.force.com/**カスタムURL**/articles/**記事タイプ**/';
 
    @HttpPost
    global static Map<String,String> doPost(){
 
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
          
        Map<String, Object> callbackParams = (Map<String, Object>)JSON.deserializeUntyped(req.requestBody.ToString());
        List<Object> resultParams = (List<Object>)callbackParams.get('events');

        String replyToken = '';
        String messageText = '';
                        
        for (Object obj : resultParams) {
            Map<String, Object> params = (Map<String, Object>)obj;           
            replyToken = (String)params.get('replyToken');
            Map<string, object> messageParams = (Map<String, Object>)params.get('message');
            messageText = (String)messageParams.get('text');            
        }
                
        //改行を置換
        messageText = messageText.replaceAll('[\n]+','');
        
        //ナレッジ検索
        List<List<KnowledgeArticleVersion>> resultList = [FIND :messageText RETURNING KnowledgeArticleVersion(Id,Title,Summary,UrlName WHERE PublishStatus='online' AND Language= 'ja')];
                                        
        HttpRequest hreq = new HttpRequest();
        hreq.setHeader('Content-Type', 'application/json');
        hreq.setHeader('Authorization', 'Bearer '+ CH_ACCESS_TOKEN);
        hreq.setEndpoint(LINE_REPLY_URI);
        hreq.setMethod('POST');
        
        if(resultList[0].isEmpty()){
            hreq.setBody('{"replyToken":"' +  replyToken  + '" ,"messages":[{"type":"text", "text":"' + messageText + ':該当のナレッジはありません"}]}');
        }else{
            hreq.setBody('{"replyToken":"' +  replyToken  + '" ,"messages":[' + getCarouselTemp(resultList) + ']}');
        }
        
        Http http = new Http();
        HTTPResponse hres; 
        
        try {
            hres = http.send(hreq);
            System.debug('●HTTP Response Code: ' + hres.getStatusCode());
            System.debug('●Response Body: ' + hres.getBody());
         
        } catch (Exception e) {
            System.debug('●Error:' + e.getMessage());            
        }
        
        Map<string, string> result= new Map<String, String>();
        result.put('result', 'success');         
          
        return result;
    }
    
    //カルーセルテンプレート
    private Static String getCarouselTemp(List<List<KnowledgeArticleVersion>> kavList){

        List<Object> colList = new List<Object>();      
        for(KnowledgeArticleVersion objKav : kavList[0]){
            Map<String, Object> cloumnActionMap = new Map<String, Object> {
                'title' => objKav.Title,
                'text' => objKav.Summary,
                'actions' => new Object[] {
                    new Map<String, Object> {
                        'type' => 'uri',
                        'label' => '見る',
                        'uri' => MYSITESURL + objKav.UrlName
                    }
                }
            };
            colList.add(cloumnActionMap);    
        }
        
        Map<String, Object> jMap = new Map<String, Object> {
                'type' => 'template',
                'altText' => 'this is a carousel template',
                'template' => new Map<String, Object>{
                    'type' => 'carousel',
                    'columns' => colList
                } 
            };
                
       return JSON.serialize(jMap); 

    }
     
}
LineWebHookCallback

ポイント

入力された質問でナレッジを検索して結果を返しますが、テキストで単純に結果を表示するのも味気なかったので、LINEの表現の1つであるカルーセルテンプレートで結果を表示するようにしています。見るボタンをタップするとPKBの外部公開サイトへ飛ぶように設定してあります。

動作確認

LINEの実行画面

実行すると検索件数に応じてカルーセルテンプレートで表示されます。

検索結果がない場合はメッセージ表示をするようにしています。

特定のキーワードだとそれっぽい回答になりますが、質問の書き方によっては回答がぶれてきますね

見るボタンをタップするとPKBの外部公開ページに遷移し、リッチテキスト等で表示した画面を表示できます。(PC版で表示を選択しています。)

まとめ

今回試した内容としてはLINEChatBotで入力された内容でナレッジを検索して表示するという単純なものになります。質問に対する検索結果はSalesforceのSOSLの検索結果に依存していますが、シンプルにLINEChatBotでナレッジを検索する仕組みとしては簡単に構築できると思います。

次回は下記にチャンレンジしてみたいと思っております。
・対話型によるナレッジの絞り込み
・Einstein Languageによる言語解析と組み合わせ
・LINEのみでクローズできるような回答の表現の工夫

ありがとうございました。

資料ダウンロード

24 件

関連する記事