雑談に応答するLINE Botを爆速で作成する方法(Google Apps Script + Chaplus雑談対話API)


# 追記
本記事で紹介する「Chaplus雑談対話API」の後継となるAPIを公開しました。下記の記事で紹介をしているので、合わせてこちらもご覧ください。
https://qiita.com/maKunugi/items/14f1b82a2c0b6fa5c202
本記事で紹介するAPIよりも精度が向上している他、文脈を考慮した会話ができるようになっています。また、実装不要でLINE Botでの利用もできるようになりました。

# 対象読者
・手軽にLINE Botを作って見たい方
・LINE Botに会話(雑談)をさせてみたい方

# 概要
Google Apps ScriptとChaplus 雑談対話APIを利用してLINE Botを爆速で作成する方法について紹介します。(作業所用時間は10分程度です)

関連の記事として、Google Apps ScriptとChaplus 雑談対話APIを利用したSlack Botの作り方に関しましては以下の記事で紹介しているので、ぜひ併せてお読みください。

[たった10分で雑談ができる脱力系Slack Botを作成する方法(セリフや口調のカスタマイズも簡単)](https://qiita.com/maKunugi/items/6a6abf83ca27716541df)

# どんな雑談LINE Botを作るのか
<img width="400" alt="S__25419855.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66341/9c3bf8d8-fe13-f8e4-3af3-8bb4b859d105.jpeg">

- 暇なときにたわいもない雑談ができる
- 愚痴や悩みを聞いてくれる
- 手軽にセリフのカスタマイズができる
- 飽きてきたら口調を変えられる

# 作り方
## 利用する技術

- Google Apps Script (GAS)
GASでユーザからLINE Botへの発話を受け取り、Botの応答を送信します。

- Chaplus - 雑談対話API
Chaplus APIというユーザの発話に対しての応答を取得できるAPIを利用します。
様々な雑談が可能なことに加え、ボットのセリフのカスタマイズや口調の変更等ができます。
Chaplus APIは下記の記事で詳しく紹介をしています。
https://qiita.com/maKunugi/items/b1afb6441571119729a7

- LINE Messaging API
LINEが提供するサービスとLINEユーザーの双方向コミュニケーションを可能にするAPIです。
[Messaging API](https://developers.line.biz/ja/services/messaging-api/)

## Messaging API 利用の準備

Messaging APIを利用するための準備をしていきます。
Messaging APIの利用にはLINE Developersに登録が済んでいる必要があります。

https://developers.line.me/ja/
上記のページからLINE Developersに登録をしてください。(個人のLINEアカウントを利用して登録が可能です)画面に沿いながら直感的に登録ができるので、詳細については省略します。

LINE Developersに登録が完了したら、下記を開き「プロバイダー」を作成していきます。
https://developers.line.biz/console/

![](https://i.imgur.com/17fnZ3S.png)

プロバイダーが作成できたら次に「チャネル」を作成します。

![](https://i.imgur.com/PqCJVvK.png)

チャネルの種類を聞かれるので「Messaging API」を選択します。
![](https://i.imgur.com/6Rutuo5.png)

入力が必要な項目を埋めましょう。
![](https://i.imgur.com/uQUp4oE.png)

利用規約に同意しチャネル作成が完了するとLINE Botが作られ、友達登録をしてLINEでトークをすることが可能になります。

チャネルは様々な設定が可能ですが、今回特に関わってくる項目を先に紹介しておきます。
![](https://i.imgur.com/f0ZSZ32.png)

- Webhook設定

Messaging APIタブにある「Webhook設定」には後ほど作成するGASで作ったアプリケーションのURLが入ります。
![](https://i.imgur.com/kFO4PKb.png)

- チャンネルアクセストークン

後ほどGASで利用します。

- 応答設定

応答モードや挨拶メッセージ等を設定できます。
今回はBotの自動応答を行うので、「応答モード」は「Bot」にしておきます。
Botは動的に生成した文章を返したいので、「詳細設定」の「応答メッセージ」については「オフ」を選択します。

![](https://i.imgur.com/k5fVwXF.png)


以上でLine Developers側での設定は終了です。
（最後にWebhook URLを設定しに戻ってきます。）

## Google Apps Scriptの用意
Google Apps ScriptからMessaging APIを利用してLINE BOTの応答を実装していきます。

### Google Apps Scriptの準備
![](https://i.imgur.com/zFG8qaw.png)

LINE Botへのコメントを管理するスプレッドシートを用意します。
用意ができたら、「スクリプトエディタ」を開きましょう

![](https://i.imgur.com/XyU8MnB.png)

### LINE Botへのメッセージを受け取る

Google Apps ScriptでLINE Botへのメッセージを受け取りましょう。

```javascript
var CHANNEL_ACCESS_TOKEN = '<チャネルのアクセストークン>';

function doPost(e) {
  var event = JSON.parse(e.postData.contents).events[0];
  var replyToken= event.replyToken;

  if (typeof replyToken === 'undefined') {
    return;
  }
  
  var userId = event.source.userId;
  var username = getUserName(userId);

  if(event.type == 'message') {
    var userMessage = event.message.text;
    // TODO: メッセージの返信処理
    return ContentService.createTextOutput(
      JSON.stringify({'content': 'ok'})
    ).setMimeType(ContentService.MimeType.JSON);
  }
}

function getUserName(userId){ 
  var url = 'https://api.line.me/v2/bot/profile/' + userId;
  var userProfile = UrlFetchApp.fetch(url,{
    'headers': {
      'Authorization' :  'Bearer ' + CHANNEL_ACCESS_TOKEN,
    },
  })
  return JSON.parse(userProfile).displayName;
}

```

LINE BotにユーザからメッセージがあるとMessaging APIがPostでevent情報を送ってくれます。event情報からユーザ情報やメッセージの内容を取得します。


### メッセージに対するBotの応答を取得する

LINE Botが行うユーザへのリプライ用のメッセージを取得します。ユーザのメッセージに対する応答文を取得するには、先述したChaplus APIという雑談対話APIを利用します。

![](https://i.imgur.com/Pjwj6QB.png)

[公式サイト](https://www.chaplus.jp/)にて利用規約の確認とメールアドレスの登録を行い、メールに送られてくるAPI KEYを入手します。

※ 送られてくるメールが迷惑メールに振り分けられることがあるので注意

API KEYが取得できたらChaplus APIを利用して応答文を取得しましょう。
応答文を取得し、一番精度の高い返答を返すメソッドは以下のような実装になります。

```javascript
function getChaplusMessage(mes, username) {
  var dialogue_options = {
    'utterance': mes,
    'username' : username,
    'agentState' : {
      'agentName' : 'sample_bot',
      'age' : '0歳',
      'tone' : 'kansai'
    }
  }
  var options = {
    'method': 'POST',
    'contentType': 'text/json',
    'payload': JSON.stringify(dialogue_options)
  };

  var chaplusUrl = "https://www.chaplus.jp/v1/chat?apikey=<APIキー>";
  var response = UrlFetchApp.fetch(chaplusUrl, options);
  var content = JSON.parse(response.getContentText());
  
  var answer = content.bestResponse.utterance;
  return answer;
}
```

API KEYは任意の値に変更してください。
上記では下記の項目を指定しています。

- utterance: ユーザの発話
- username: ユーザの名前
- agentState
    - agentName: LINE Botの名前
    - age: LINE Botの年齢(設定)
    - tone:LINE Botの口調

LINE Botの口調は、normal(default)、kansai(関西弁風)、koshu(甲州弁風)、dechu(赤ちゃん言葉風)を指定できます。
APIの仕様については詳しく触れませんが、他にもセリフをカスタマイズできたり、NGワードを指定するなど様々な利用方法ができます。詳しくは下記の記事をご参照ください。

https://qiita.com/maKunugi/items/b1afb6441571119729a7


### LINE Botのリプライを送信する

応答が取得できたらLINE Botでリプライを送信します。
下記のようにメッセージを送信します。

```javascript
function sendMessage(replyToken, replyMessage) {
  var url = 'https://api.line.me/v2/bot/message/reply';
  UrlFetchApp.fetch(url, {
     'headers': {
       'Content-Type': 'application/json; charset=UTF-8',
       'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
     },
     'method': 'post',
     'payload': JSON.stringify({
       'replyToken': replyToken,
       'messages': [{
         'type': 'text',
         'text': replyMessage,
       }],
     }),
   });
}

```

### スプレッドシートにログを残す

必要であればスプレッドシートにログを残しましょう。

```javascript
function appendRow(text) {
  var spreadsheetId = "<スプレッドシートのID>";
  var sheetName = "<スプレッドシートの名前>";
  var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
  var sheet = spreadsheet.getSheetByName(sheetName);
  sheet.appendRow([new Date(),text]);
  return text;  
}
```

スプレッドシートのIDはスプレッドシートファイルのURLに記載があります。
```例: https://docs.google.com/spreadsheets/d/<スプレッドシートのID>/edit#gid=0```

### Google Apps Script 全文

上記で紹介したスクリプトの全文になります。

```javascript
var CHANNEL_ACCESS_TOKEN = '<アクセストークン';

function doPost(e) {
  var event = JSON.parse(e.postData.contents).events[0];
  var replyToken= event.replyToken;

  if (typeof replyToken === 'undefined') {
    return;
  }
  
  var userId = event.source.userId;
  var username = getUserName(userId);

  if(event.type == 'message') {
    var userMessage = event.message.text;
    var replyMessage = getChaplusMessage(userMessage, username);
    appendRow(userMessage);
    sendMessage(replyToken, replyMessage);
    return ContentService.createTextOutput(
      JSON.stringify({'content': 'ok'})
    ).setMimeType(ContentService.MimeType.JSON);
  }
}

function sendMessage(replyToken, replyMessage) {
  var url = 'https://api.line.me/v2/bot/message/reply';
  UrlFetchApp.fetch(url, {
     'headers': {
       'Content-Type': 'application/json; charset=UTF-8',
       'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
     },
     'method': 'post',
     'payload': JSON.stringify({
       'replyToken': replyToken,
       'messages': [{
         'type': 'text',
         'text': replyMessage,
       }],
     }),
   });
}

function getUserName(userId){ 
  var url = 'https://api.line.me/v2/bot/profile/' + userId;
  var userProfile = UrlFetchApp.fetch(url,{
    'headers': {
      'Authorization' :  'Bearer ' + CHANNEL_ACCESS_TOKEN,
    },
  })
  return JSON.parse(userProfile).displayName;
}

function getChaplusMessage(mes, username) {
  var dialogue_options = {
    'utterance': mes,
    'username' : username,
    'agentState' : {
      'agentName' : 'sample_bot',
      'age' : '0歳',
      'tone' : 'kansai'
    }
  }
  var options = {
    'method': 'POST',
    'contentType': 'text/json',
    'payload': JSON.stringify(dialogue_options)
  };

  var chaplusUrl = "https://www.chaplus.jp/v1/chat?apikey=<APIキー>";
  var response = UrlFetchApp.fetch(chaplusUrl, options);
  var content = JSON.parse(response.getContentText());
  
  var answer = content.bestResponse.utterance;
  return answer;
}
        
function appendRow(text) {
  var spreadsheetId = "<スプレッドシートのID>";
  var sheetName = "log";
  var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
  var sheet = spreadsheet.getSheetByName(sheetName);
  sheet.appendRow([new Date(),text]);
  return text;  
}
```

チャネルのアクセストークンやChaplus APIのAPIキー、スプレッドシートのID等は適宜リプレイスしてください。

### デプロイ

ここまで記述したら、スクリプトをデプロイします。
![](https://i.imgur.com/dzm4sMM.png)

「公開」-> 「ウェブアプリケーションとして導入」を選択します。
![](https://i.imgur.com/z85EA9P.png)

![](https://i.imgur.com/7GCbsZl.png)

公開をするとアプリケーションのURL(Current web app URL)が取得できます。
このURLをLINE DevelopersでMessaging APIのWebhook URLに設定すれば作業は完了です！


<img width="400" alt="S__25419855.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66341/9c3bf8d8-fe13-f8e4-3af3-8bb4b859d105.jpeg">


LINEで話しかけてみましょう！

## まとめ
GAS + Chaplus API を利用して雑談LINE Botを作成する方法について紹介しました。LINE Botの開発に興味のある方の参考になれば幸いです！