IBM Cloud Functionsを利用してチャットボットにWikipediaの情報を回答させる。(IBM Cloud Functionsの設定編)

IBM Cloud Functionsを使用してWikipediaを検索し、処理結果をWatson Assistant(チャットボット)に回答させる方法を紹介します。
このエントリーでは、IBM Cloud Functionsの設定についてのみ書いています。

# 実現したい世界
![ibmfunctions.png](https://qiita-image-store.s3.amazonaws.com/0/175902/6ae0fee5-ab0a-8806-b0ac-2ea86be5e1e5.png)
ユーザーが「xxxxって何？」のようにチャットボットに聞いた際に、Wikipediaに記載されているxxxxについての回答をします。
## **実現するためのアプローチ**
ユーザーが質問してきたら、
1.Watson Assistantで「xxxxって何？」のインテントを抽出。
2.Watson AssistantからIBM Cloud Functionsにユーザーの質問を連携。
3.IBM Cloud FunctionsでMeCabを使用して形態素解析し、固有名詞を1つ抽出。　←これを紹介
4.Wikipedia APIで抽出した固有名詞を検索しSummaryを返す。　←これを紹介

# やること1：IBM Cloud Functions上で動かすプログラムを用意
適当な名前のフォルダを用意し、以下の2つのファイルを保存します。
・index.js -> Watson Assistantから質問を受け取ったあと形態素解析してWikipedia検索するnode.js
・package.json -> index.jsを動かすために読み込む必要のあるnode module

```index.js
const mecab = require('mecabaas-client');
const async = require('async');
const wiki = require('wikijs').default({
    apiUrl : 'http://ja.wikipedia.org/w/api.php'
});

function getWiki(params) {
    return new Promise(function(resolve, reject) {
        let noun = [];
        const readAll = async() => {
            //文中の最初に現れた固有名詞をMeCabで抽出。
            let morphs = await mecab.parse(params.sentence);
            await morphs.map(function( morph ) {
                if (morph[2] === '固有名詞') noun.push(morph[0]);
            });
            if (noun.length == 0) {
                console.log('no noun');
                resolve({"noun":"null", "msg":"null"});
                return;
            }
            console.log(noun[0]);
            
            //Wikipediaで固有名詞を検索し、最初にヒットしたページから情報を抽出。
            let search_results = await wiki.search(noun[0]);
            if (search_results.length == 0) {
                console.log('no wikipedia content');
                resolve({"noun":"null", "msg":"null"});
                return;
            }
            //ページ全体の情報を取得。
            let page = await wiki.page(search_results.results[0]);
            //概要を取得。
            let summary = await page.summary();
            resolve({"noun":encodeURI(noun[0]), "msg":summary});
        }
        readAll();
    });
}
module.exports.main = getWiki;
```
```package.json
{
  "name": "YYYYYY",
  "main": "index.js",
  "dependencies" : {
    "request": "2.74.0",
    "mecabaas-client":"1.0.3",
    "wikijs":"4.7.0"
  }
}
```
保存したフォルダにコマンドラインで移動し、以下のコマンドを実行してnode_modulesを作成します。
`$ npm install`
そのあと、適当な名前をつけてzip化します。
`$ zip -r XXXXXX.zip *`

以下のファイル構成になるかと思います。

```
-親フォルダ
　|- XXXXXX.zip
　|- index.js
　|- package.json
　|- node_modules
　　|- mecabaas-client
　　|- request
　　|- wikijs
```

# やること2：IBM Cloud Functionsにプログラムをアップロード
コマンドライン上でIBM Cloudにログインします。
`$ bx login`
先ほど作ったzipファイルをIBM Cloud Functionsにアップロードします。
`$ bx wsk action create YYYYYY --kind nodejs:6 XXXXXX.zip`

動くか試してみます。
`$ bx wsk action invoke --result YYYYYY --param sentence "siriって何"`
以下の回答が返ってきたら成功です。

```
{
    "msg": "Siri（シリ）は、iOSやmacOS Sierra向け秘書機能アプリケーションソフトウェア。自然言語処理を用いて、質問に答える、推薦、Webサービスの利用などを行う。「Siri」とは、Speech Interpretation and Recognition Interface（発話解析・認識インターフェース）の略。",
    "noun": "siri"
}
```
これでIBM Cloud Functionsの設定は完成です。

# まとめ
IBM Cloud Functionsを使用してWikipediaを検索し、処理結果をWatson Assistant(チャットボット)に回答させるにあたり、このエントリーではIBM Cloud Functionsの設定について書きました。

チャットボットとIBM Cloud Functionsを連携することで、wikipediaの他にも天気や最新のニュースが答えられるようになります。
IBM Cloud Functionsはサーバーレスなんで、使ってない時は課金されないのは素晴らしいですね。