[PHP] Messaging APIを使ったLINEbotで色々試してみる

#今回の題
API系の記事はこれで３つ目です！
前回→[[PHP] Zoom APIを利用してミーティングを作成する]
(https://qiita.com/kuzira_vimmer/items/d64f15447cb556eafd3b)
前々回→[[PHP] YouTube APIの利用（動画情報の取得）]
(https://qiita.com/kuzira_vimmer/items/dfd9f4febaec11851c06)

今回はタイトルの通り、LINEbotを作りましょう！
LINE Developersの[MessagingAPI](https://developers.line.biz/ja/docs/messaging-api/overview/)というものを利用すれば、自分好みのLINEbotが簡単に作れます。
この記事では、

- おうむ返し
- ボタン
- confirm
- カルーセル
- クイックリプライ
- 日付選択アクション

などを作ってみます。

#必要なもの
- サーバー

ssl化が必須です。
私はconohaで動かしてますが、ググるとherokuを使った記事を多く見かけました。

#チャネルシークレットとチャネルアクセストークンの取得
４つの段階に分けて説明していきます。
### 1. 開発者用のアカウントを作成
以下にアクセスし、LINEのアカウントを使ってログインしてください。
[LINE Developers](https://developers.line.biz/ja/)

### 2. プロバイダーの作成

以下のページの左サイドバーにプロバイダーという項目があると思うので選択し、画面中央辺りの「作成」を押してください。
[LINE Developers コンソール](https://developers.line.biz/console/)

![スクリーンショット 2020-07-08 5.00.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/702abf98-e064-20fb-9572-37c00793dec3.png)



作成するプロバイダー名を求められるので適当に入力し、「作成」を押したらプロバイダーの作成は完了です！
![スクリーンショット 2020-07-08 5.12.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/846d4acd-fcd4-7e60-a28a-6ef4f08bbbb9.png)


### 3. チャネルの作成
プロバイダーの作成後、以下のようなページに飛ばされます。
画像内の赤枠の**「Messaging API」**を選択してください。
![スクリーンショット 2020-07-08 5.13.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/9df5ffbc-7bc9-5264-2c52-aa538d59e667.png)

チャネルを作成する画面に飛ぶので、必須項目を全て入力し、「作成」を押したらチャネルの作成は完了です！
![スクリーンショット 2020-07-08 5.20.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/fd4ca0cf-6da3-eadb-c774-98599b91d6cd.png)


### 4. チャネルシークレットとチャネルアクセストークンの取得
チャネルの作成後、作成したチャネルの設定ページに飛ばされます。
チャネルシークレットとチャネルアクセストークンの取得はどちらもこのページを起点にします。
![スクリーンショット 2020-07-08 5.42.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/def3cc01-47bf-9dd3-24b1-4c3f31169229.png)

- **チャネルシークレット**
チャネル基本設定のタブの下の方に載っています。
あとで使うのでコピーしておいてください。
![スクリーンショット 2020-07-08 5.48.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/afa9a9dd-0864-0595-a572-c4d4dd64a41b.png)

- **チャネルアクセストークン**
Messaging API設定のタブの下の方に載っています。
初期状態だと何も表示されていませんが、右にある「発行」を押すと表示されます。
これもあとで使うのでコピーしておいてください。
![スクリーンショット 2020-07-08 5.53.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/e7f70007-08c5-007f-d53f-e223513c6507.png)

以上でチャネルシークレットとチャネルアクセストークンがGETできました。

#Webhook設定
Messaging API設定のタブの中央辺りに欄があるので、リクエストを受け取るURLを設定し、Webhookの利用を有効にします。
![スクリーンショット 2020-07-08 9.10.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/a06027f2-3526-5605-694d-c2c00355b461.png)

#botを友達に追加
Messaging API設定のタブの上の辺りにQRコードがあるので読み取って友達に追加しておきましょう。

そろそろコードを書いていきます。

#LINE Messaging API SDK for PHPのインストール
composerを使ってインストールします。

```terminal
$ composer require linecorp/line-bot-sdk
```
LINE Messaging API SDK for PHPのソースコードは以下です。
[LINE Messaging API SDK for PHP](https://github.com/line/line-bot-sdk-php)

#コードの例
実際に動かしたコードをそのまま載せておきます。
なので、チャネルシークレットとチャネルアクセストークンをセットすればコピペで動きます。

###1. おうむ返し。
ただテキストを返すだけ！

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/d012c686-5ae0-71fc-2b0e-560c1ae0faea.jpeg">

```php
<?php
require('vendor/autoload.php');

use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot;

//先ほど取得したチャネルシークレットとチャネルアクセストークンを以下の変数にセット
$channel_access_token = 'XXXXXXXXX';
$channel_secret = 'XXXXXXXXX';

$http_client = new CurlHTTPClient($channel_access_token);
$bot = new LINEBot($http_client, ['channelSecret' => $channel_secret]);
$signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE];
$http_request_body = file_get_contents('php://input');
$events = $bot->parseEventRequest($http_request_body, $signature);
$event = $events[0];

$reply_token = $event->getReplyToken();
$reply_text = $event->getText();
$bot->replyText($reply_token, $reply_text);

```

###2. ボタン

個人的に一番使います。便利。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/85a84aa7-f1c2-6006-f11c-df74add1ef01.jpeg">

```php
<?php
require('vendor/autoload.php');

use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot;
use LINE\LINEBot\TemplateActionBuilder\PostbackTemplateActionBuilder;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ButtonTemplateBuilder;

$channel_access_token = 'XXXXXXXXX';
$channel_secret = 'XXXXXXXXX';

$http_client = new CurlHTTPClient($channel_access_token);
$bot = new LINEBot($http_client, ['channelSecret' => $channel_secret]);
$signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE];
$http_request_body = file_get_contents('php://input');
$events = $bot->parseEventRequest($http_request_body, $signature);
$event = $events[0];
$reply_token = $event->getReplyToken();

$yes_button = new PostbackTemplateActionBuilder('はい', 'button=1');
$no_button = new PostbackTemplateActionBuilder('キャンセル', 'button=0');
$actions = [$yes_button, $no_button];
$button = new ButtonTemplateBuilder('タイトル', 'テキスト', '', $actions);
$button_message = new TemplateMessageBuilder('タイトル', $button);
$bot->replyMessage($reply_token, $button_message);
```

 ButtonTemplateBuilderの第3引数に画像のURLを渡せば少しおしゃれなボタンができるのでお試しあれ！

###3. confirm

ボタンをもっとシンプルにしたようなやつです。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/2eef9052-d3b7-f388-b0cb-50128614e664.jpeg">

```php
<?php
require('vendor/autoload.php');

use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot;
use LINE\LINEBot\TemplateActionBuilder\PostbackTemplateActionBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ConfirmTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;

$channel_access_token = 'XXXXXXXXX';
$channel_secret = 'XXXXXXXXX';

$http_client = new CurlHTTPClient($channel_access_token);
$bot = new LINEBot($http_client, ['channelSecret' => $channel_secret]);
$signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE];
$http_request_body = file_get_contents('php://input');
$events = $bot->parseEventRequest($http_request_body, $signature);
$event = $events[0];
$reply_token = $event->getReplyToken();

$yes_confirm = new PostbackTemplateActionBuilder('はい', 'confirm=1');
$no_confirm = new PostbackTemplateActionBuilder('いいえ', 'confirm=0');
$actions = [$yes_confirm, $no_confirm];
$confirm = new ConfirmTemplateBuilder('メッセージ', $actions);
$confirm_message = new TemplateMessageBuilder('confirm', $confirm);
$bot->replyMessage($reply_token, $confirm_message);
```


###4. カルーセルメッセージ

```php
<?php
require('vendor/autoload.php');

use LINE\LINEBot;
use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\TemplateActionBuilder\PostbackTemplateActionBuilder;
use LINE\LINEBot\Event\PostbackEvent;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselColumnTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselTemplateBuilder;

$channel_access_token = 'XXXXXXXXX';
$channel_secret = 'XXXXXXXXX';

$http_client = new CurlHTTPClient($channel_access_token);
$bot = new LINEBot($http_client, ['channelSecret' => $channel_secret]);
$signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE];
$http_request_body = file_get_contents('php://input');
$events = $bot->parseEventRequest($http_request_body, $signature);
$event = $events[0];
$reply_token = $event->getReplyToken();

$columns = [];
// カルーセルの各カラムを生成(5つまで)
for ($i = 1; $i < 5; $i++) {
    $yes = new PostbackTemplateActionBuilder('はい', 'button=yes');
    $cancel = new PostbackTemplateActionBuilder('キャンセル', 'button=no');
    $actions = [$yes, $cancel];
    $column = new CarouselColumnTemplateBuilder("タイトル", "本文", "画像のURL", $actions);
    $columns[] = $column;
}
// カラムをカルーセルに組み込む
$carousel = new CarouselTemplateBuilder($columns);
$builder = new TemplateMessageBuilder("テスト", $carousel);
$bot->replyMessage($this->reply_token, $builder);
```


###5. クイックリプライ

長いので別記事にまとめました
[[PHP] LINE ボットでクイックリプライを使う](https://qiita.com/kuzira_vimmer/items/177549c397a270db709a)

###日時選択アクション

ボタンやconfirmと合わせて使います。
LINE botは他のAPIと組み合わせて作成することが多いので、以下のコードで日付を送信できるということを覚えておけば何かと役立つと思い載せておきます。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/4110d110-8808-2bc8-8b47-3b01246a8cd6.jpeg">

```php
<?php
require('vendor/autoload.php');

use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot;
use LINE\LINEBot\TemplateActionBuilder\DatetimePickerTemplateActionBuilder;
use LINE\LINEBot\TemplateActionBuilder\PostbackTemplateActionBuilder;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\ButtonTemplateBuilder;

$channel_access_token = 'XXXXXXXXX';
$channel_secret = 'XXXXXXXXX';

$http_client = new CurlHTTPClient($channel_access_token);
$bot = new LINEBot($http_client, ['channelSecret' => $channel_secret]);
$signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE];
$http_request_body = file_get_contents('php://input');
$events = $bot->parseEventRequest($http_request_body, $signature);
$event = $events[0];
$reply_token = $event->getReplyToken();

$date_time = new DatetimePickerTemplateActionBuilder('日付を選択', 'storeId=12345', 'datetime');
$no_button = new PostbackTemplateActionBuilder('キャンセル', 'button=0');
$actions = [$date_time, $no_button];
$button = new ButtonTemplateBuilder('タイトル', 'テキスト', '', $actions);
$button_message = new TemplateMessageBuilder('タイトル', $button);
$bot->replyMessage($reply_token, $button_message);
```

###ボタンからのリクエストの取得

ユーザーがボタンを押した時のリクエストは以下のコードで配列の形にして取得できます。

```php
$postback_data = $event->getPostbackData();
parse_str($postback_data, $data);
```

まだあるけどキリがないので……とりあえず以上！


#最後に

LINE Messaging API SDK for PHPを使うには、記事中で挙げた[SDKのソース](https://github.com/line/line-bot-sdk-php)をしっかり追う必要があり初めは中々に手間です😩
今回の記事ではよく使うアクションをそのまま使えるコードを添えて書いたので、もしこれからソースを追おうとしている方などの参考になれば幸いです！

少しでも参考になりましたら**いいね（LGTM）やコメント**などいただけると嬉しいです！😬
良いLINEbotライフを！！

#参考
[LINE Developers APIリファレンス](https://developers.line.biz/ja/reference/)
[line-bot-sdk-php](https://github.com/line/line-bot-sdk-php)
他にもあったのですが、昔、Qiitaで参考にした記事が見つからず……。