LINE Messaging API でできることまとめ【送信編】

この記事は[エイチームブライズアドベントカレンダー](https://qiita.com/advent-calendar/2017/a-t-brides)10日目の記事です。

# はじめに
今回はLINE Messaging APIで出来ることをまとめてみようと思います。
技術的な部分は公式ドキュメント見ればほぼ載ってるんですが、受信した側がどういう風に表示されるのかイメージ図が載っていないので、その一覧として役に立てばいいなと思いまとめます。

# メッセージオブジェクト
送信するメッセージの内容を表すJSONオブジェクトです。
どれも送信部分のコードはこんな感じ。

```php:
// 受信したメッセージ情報
$raw = file_get_contents('php://input');
$receive = json_decode($raw, true);

$event = $receive['events'][0];
$reply_token  = $event['replyToken'];

$headers = array('Content-Type: application/json',
                 'Authorization: Bearer ' . $accessToken);

$message = 【ここが送信するオブジェクトにより異なります】

$body = json_encode(array('replyToken' => $reply_token,
                          'messages'   => array($message)));
$options = array(CURLOPT_URL            => 'https://api.line.me/v2/bot/message/reply',
                 CURLOPT_CUSTOMREQUEST  => 'POST',
                 CURLOPT_RETURNTRANSFER => true,
                 CURLOPT_HTTPHEADER     => $headers,
                 CURLOPT_POSTFIELDS     => $body);

$curl = curl_init();
curl_setopt_array($curl, $options);
curl_exec($curl);
curl_close($curl);
```

それぞれ順番にみていってみましょう。

## テキスト

![IMG_0059.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/937e92a0-cc09-7e21-c05e-e1605e7659c6.png)

```php:
$message = array('type' => 'text',
                 'text' => 'こんにちは。テキスト応答ですよ。');
```

何の説明も不要なくらい簡単。テキストを返すオブジェクトです。最大文字数は2,000文字。

## スタンプ

![IMG_0060.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/ad7fd677-8bae-10f0-b885-83bd54ec16a8.png)

```php:
$message = array('type'      => 'sticker',
                 'packageId' => 1,
                 'stickerId' => 1);
```

公式で用意されているスタンプを送信することが出来ます。
送信できるスタンプの一覧は[こちら](https://developers.line.me/media/messaging-api/sticker_list.pdf)。

## 画像

![IMG_0061.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/5bdc19cf-2037-76cc-e014-e7cb7a7d612a.png)

```php:
$message = array('type'               => 'image',
                 'originalContentUrl' => '画像のURL',
                 'previewImageUrl'    => 'プレビュー画像のURL');
```

画像URLはどちらもHTTPSじゃなくてはいけません。そしてJPEGのみ。

|      |      メイン画像 |    プレビュー画像    |
|:-----------------|------------------:|:------------------:|
| 最大画像サイズ             |              1024×1024|        240×240|
| 最大ファイルサイズ          |            1MB |       1MB       |
と記載がありますがプレビューに240x240以上の画像を入れて送ってみても送信ができました。でもプレビューは小さい画像のほうが表示速度は早そうですね。

## 動画

![IMG_0062.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/612277cf-0c92-4d60-bbf6-1a90f121b041.png)

```php:
$message = array('type'               => 'video',
                 'originalContentUrl' => '動画ファイルのURL',
                 'previewImageUrl'    => 'プレビュー画像のURL');
```

動画として送れるのは1分未満で10MB以下のものに限ります。
プレビュー用の画像URLとして送ったものが吹き出しに表示されるようです。（今回の場合だと猫がうさぎの頭に手を置いている画像がプレビュー画像）

## 音声
![IMG_0063.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/c4fcfc06-3537-2ebd-020b-5a5475dc0271.png)

```php:
$message = array('type'               => 'audio',
                 'originalContentUrl' => '音源のURL',
                 'duration'           =>  音声ファイルの長さ（ミリ秒）);
```
音声として送れるのは1分未満で10MB以下のものに限ります。

## 位置情報
![IMG_0065.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/e2aa8bb4-ac8c-5646-6566-9eddd5152a6d.png)

![IMG_0064.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/2c3378d1-44f2-d175-5f04-4174c125b544.png)


```php:
$message = array('type'      => 'location',
                 'title'     => 'ここにタイトル',
                 'address'   => '住所だよ',
                 'latitude'  => 緯度,
                 'longitude' => 経度);
```
位置情報を送るときは address も latitude longitude も両方共必須項目です。
どちらかわかれば地図表示できるじゃんと思っていたのですが、address に入れた値は表示用に使われており、地図表示には latitude longitude が使われているようです。つまり address にいれるのは実は住所じゃなくてもいいんですね。

## テンプレートメッセージ
テンプレートメッセージは、LINE側で用意された４種類のレイアウトをカスタマイズして構築するメッセージです。
それぞれに actions と呼ばれるものが設定できますがこの actions については後述します。

### ボタンテンプレート
![IMG_0068.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/731d3e4c-b0e2-ed4b-da0d-febda40da9f2.png)

```php:
$template = array('type'    => 'buttons',
                  'thumbnailImageUrl' => 'https://d1f5hsy4d47upe.cloudfront.net/79/79e452da8d3a9ccaf899814db5de9b76_t.jpeg',
                  'title'   => 'タイトル最大40文字' ,
                  'text'    => 'テキストメッセージ。タイトルがないときは最大160文字、タイトルがあるときは最大60文字',
                  'actions' => array(
                                 array('type'=>'message', 'label'=>'ラベルです', 'text'=>'アクションを実行した時に送信されるメッセージ' )
                                )
                );

$message = array('type'     => 'template',
                 'altText'  => '代替テキスト',
                 'template' => $template
                );
```
画像、タイトル、テキスト、最大４つのアクションボタンが含まれたテンプレートメッセージです。またテンプレートはこれ以降に紹介するものも含めすべて、高さに制限があり、テキストの最大文字数以内であっても制限を超えていたらテキストを自動でカットされちゃうので注意が必要です。
今回の例だと「ラベルです」をクリックすると「アクションを実行した時に送信されるメッセージ」が送信されます。

### 確認テンプレート
![IMG_0069.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/becb39b6-57bb-d597-1fdf-b2032de1dd1e.png)

```php:
$template = array('type'    => 'confirm',
                  'text'    => 'テキストメッセージ。最大240文字',
                  'actions' => array(
                                 array('type'=>'message', 'label'=>'yes', 'text'=>'yesを押しました' ),
                                 array('type'=>'message', 'label'=>'no',  'text'=>'noを押しました' )
                                )
                );

$message = array('type'     => 'template',
                 'altText'  => '代替テキスト',
                 'template' => $template
                );
```
２つのアクションを設定できるメッセージテンプレートです。

### カルーセルテンプレート
![IMG_0071.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/519fedb5-0d61-543d-03a8-690357b4578a.png)

```php:
$columns = array(
                 array('thumbnailImageUrl' => '画像のURL',
                       'title'   => 'タイトル最大４０文字',
                       'text'    => 'タイトルか画像がある場合は最大60文字、どちらもない場合は最大120文字',
                       'actions' => array(array('type' => 'message', 'label' => 'ラベルです', 'text' => 'メッセージ')) 
                 ),
                 array('thumbnailImageUrl' => '画像のURL',
                       'title'   => 'タイトル最大４０文字',
                       'text'    => 'タイトルか画像がある場合は最大60文字、どちらもない場合は最大120文字',
                       'actions' => array(array('type' => 'message', 'label' => 'ラベルです', 'text' => 'メッセージ')) 
                 )            
            );

$template = array('type'    => 'carousel',
                  'columns' => $columns,
                );

$message = array('type'     => 'template',
                 'altText'  => '代替テキスト',
                 'template' => $template
                );
```
カルーセルは最大10個まで登録できます。画像は任意項目なので画像なしでテキストだけのカルーセルも実装できます。ただし各カラムのアクションの数や画像またはタイトルの有無も、各カラムで統一する必要があります。

### 画像カルーセルテンプレート
上記カルーセルの画像だけ版なので画像は割愛。

```php:
$columns = array(
                 array('imageUrl' => '画像のURL',
                       'actions' => array(array('type' => 'message', 'label' => 'ラベルです', 'text' => 'メッセージ')) 
                 ),
                 array('imageUrl' => '画像のURL',
                       'actions' => array(array('type' => 'message', 'label' => 'ラベルです', 'text' => 'メッセージ')) 
                 )            
                );

$template = array('type'    => 'image_carousel',
                  'columns' => $columns,
                );

$message = array('type'     => 'template',
                 'altText'  => '代替テキスト',
                 'template' => $template
                );
```

# アクションオブジェクト
上記で紹介してきたテンプレートをクリックした時にアクションを設定できましたが、そのアクションは全部で4種類あります。それぞれ見ていってみましょう。

## メッセージアクション
ボタンテンプレートのところで使ったのがメッセージアクションです。クリックするとtextに登録されている文字列が送信されます。最大300文字まで送信可能です。

## uriアクション

```php:
$actions = array('type'  => 'uri',
                 'uri'   => 'https://example.com',
                 'label' => 'ラベル文字列');
```

クリックするとuriに登録されているURIが開きます。

## 日時選択アクション
![IMG_0072.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/c9d188b5-c146-eb0c-cff3-70258233cbfc.png)

```php:
$actions = array('type'  => 'datetimepicker',
                 'label' => 'ラベル文字列',
                 'data'  => 'ポストバックイベントのpostback.dataプロパティで返される文字列',
                 'mode'  => 'datetime');
```

クリックすると日時選択のダイアログが立ち上がり、ユーザーが選択した日時を含むポストバックイベントが、webhookを通じて返されます。mode は datetime date time の３種類があります。日付のデフォルト値や最大最小値は設定できますが、任意の日にちだけ選択肢として出すといったことは現時点ではできないようです。

## ポストバックアクション

```php:
$actions = array('type'  => 'postback',
                 'label' => 'ラベル文字列',
                 'data'  => 'ポストバックイベントのpostback.dataプロパティで返される文字列',
                 'text'  => 'アクションの実行時に送信されるテキスト');
```

クリックするとdataフィールドに指定された文字列を含むポストバックイベントが、webhookを通じてサーバーに返されます。textの項目は任意項目です。

# まとめ
これが現在のMessagingAPIを使って送信できるメッセージの全てになります。Messaging API はどんどん機能追加されてきているのでこれから新しいことができるようになるのが楽しみですね。

# 追記
今年のアドベントカレンダーは [猫好きエンジニアのIoT obnizを使った「遠隔ご飯あげマシーン」](https://qiita.com/kakakaori830/items/099493aae7d7b1e71765)ということで初めてのIoTにチャレンジしてみました！興味がある方はぜひご覧ください。
  
# お知らせ
エイチームブライズでは一緒に活躍してくれる優秀な人材を募集中です。
興味のある方はぜひとも[エイチームグループ採用ページ](http://www.a-tm.co.jp/recruit/)（[Webエンジニア詳細ページ](http://www.a-tm.co.jp/recruit/requirements/career/lifestylesupport-webengineer/)）よりお問い合わせ下さい。

# 明日
[エイチームブライズアドベントカレンダー](https://qiita.com/advent-calendar/2017/a-t-brides)10日目の記事は、いかがでしたでしょうか。
明日は @GakuYasui が何かについて書いてくれるようです。一体何について書くつもりなのでしょうか。お楽しみに！