PHPでLINEのMessaging APIと連携し、LINEBotを作成してみた。

## はじめに
PHPを使ってLINE Messaging APIと連携し、LINE Botを作成する方法について説明します。
自分の為の備忘録も含むw

APIも定期的にバージョンアップする事もあるのでAPIの部分は公式ページもよく確認しましょう。
もし、下記のサンプルコードでエラーになった場合は仕様が変わっている可能性もあります。

公式ページ：https://developers.line.biz/ja/services/messaging-api/

## 必要なもの
- LINEの公式アカウント
- LINE Messaging APIと連携するPHPファイルを実行させるサーバー
- LINEの公式アカウントに紐づくチャネルIDとチャネルシークレットキー
- PHPのスキル

### LINEの公式アカウントの作成方法～チャネルIDの取得まで
LINEの公式アカウントの作成方法は、@yuki0716 さんの<a href="https://qiita.com/yuki0716/items/92a78795ccdcf6c9926f">LineDevelopers 公式アカウントの作り方</a>が参考になります。

チャネルIDとチャネルシークレットキーの取得は下記が参考になります。
参考サイト：https://help.ex-pa.jp/tri-manual/login-channel01/

## LINE Botを作った経緯
普段からLINEをよく使っていて携帯キャリアなどの公式アカウントでBotが使われており、仕組みに興味があった為。
下記のサンプルコードは単純に応答だけですが、LINE IDやLINEの表示名を取得する事も可能です。

## 手順
1. LINEの公式アカウント作成
1. LINE Messaging APIを使えるように設定
1. LINEの公式アカウントに紐づくチャネルIDとチャネルシークレットキーを取得してメモする
1. サンプルコードを基にPHPファイルを作成
1. サーバー上に作成したPHPファイルを置く
1. LINEの公式アカウントの管理画面上でWebフックURLにPHPファイルを置いたサーバーのURLを指定

## サンプルコード
``` index.php
    LINEの公式アカウントのチャネルID
    $client_id = "XXXXXXXXX";

    LINEの公式アカウントのチャンネルシークレットキー
    $client_secret = "XXXXXXXXX";

    アクセストークンの取得処理 開始

        LINEのリクエスト先URL
        const API_URL = "https://api.line.me/v2/oauth/accessToken";

        LINEのAPIに渡す値
        $data = array(
            'grant_type' => 'client_credentials',
            'client_id' => $client_id,
            'client_secret' => $client_secret,
        );

        LINEのAPIに渡すヘッダーを設定
        $header = array(
            "Content-Type: application/x-www-form-urlencoded",
         );

        LINEのAPIに渡すオプションを設定
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header'  => implode("\r\n", $header),
                'content' => http_build_query($data)
            )
        );

        LINEののAPIへリクエスト結果を取得
        $response = file_get_contents(
            API_URL,
            false,
            stream_context_create($options)
        );

        LINEのレスポンスのjsonからtokenを取得
        $access_token = json_decode($response)->access_token;

    アクセストークンの取得処理 終了

    メッセージ取得処理からメッセージ返信処理 開始

        LINEのAPIから送信されてきたイベントオブジェクトを取得
        $json_string = file_get_contents('php://input');
    
        LINEのAPIから受け取ったJSON文字列をデコードする
        $json_obj = json_decode($json_string);
    
        LINEのAPIから受け取ったイベントオブジェクトへの応答に使用するトークンを取得
        $reply_token = $json_obj->{'events'}[0]->{'replyToken'};

        LINEのAPIから受けとったイベントオブジェクトの種別を取得
        messageならメッセージが送信されると発生
        postbackならポストバックオプションに返信されると発生
        $type = $json_obj->{'events'}[0]->{'type'};

        LINEのAPIから受けとったメッセージオブジェクトを取得
        textならテキストメッセージ、stickerならスタンプ、imageなら画像、locationなら位置情報
        $msg_obj = $json_obj->{'events'}[0]->{'message'}->{'type'};

        LINEでメッセージを受け取った場合
        if($type === 'message') {
            LINEで受け取ったメッセージがテキストだった場合
            if($msg_obj === 'text') {
                LINEで受け取ったメッセージ内容を取得
                $msg_text = $json_obj->{'events'}[0]->{'message'}->{'text'};

                受け取ったメッセージ内容によって返信する内容を指定する
                if($msg_text == 'こんにちは') {
                    返信するメッセージを指定
                    $text = 'こんにちは';
                    
                    返信するメッセージの種別を指定
                    $messageType = "text";
                } else if($msg_text == 'おはようございます') {
                    返信するメッセージを指定
                    $text = 'おはようございます';
                    
                    返信するメッセージの種別を指定
                    $messageType = "text";
                }

                LINEで送信するメッセージを生成する
                ※ 色々な場所で呼び出す場合は関数化すると楽です。
                $post_data = LinePostAPI($messageType, $text, $reply_token);

                CURLでメッセージを返信する
                $ch = curl_init('https://api.line.me/v2/bot/message/reply');
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
                curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    'Content-Type: application/json; charser=UTF-8',
                    'Authorization: Bearer ' . $access_token
                ));

                $result = curl_exec($ch);
                curl_close($ch);

    メッセージ取得処理からメッセージ返信処理 終了

    LINEで送信するメッセージを生成する関数 開始

        function LinePostAPI($messageType, $text, $reply_token) {
            LINE上で送るメッセージの作成
            $message = array(
                'type' => $messageType,
                'text' => $text
            );
    
            $post_data = array(
                'replyToken' => $reply_token,
                'messages' => array($message)
            );
    
            return $post_data;
        }

    LINEで送信するメッセージを生成する関数 終了
    
```

## APIで追加して欲しい機能
- 流入経路分析用にユニークなQRコードまたは友達登録URLの発番
- タグの自動付け

## 感想
公式ドキュメントである程度は分かりますが、公式ドキュメントの情報だけでは難易度としては高いなと個人的には思いました。
色々な言語に対応しているので他の言語でも作ってみたいです。
アフィリエイト、コンテンツ販売、独自のコミュニティを作る時などLINEの公式アカウントは良いと思うので、
その際にAPIと連携して独自のカスタマイズできると良さそうです。

実運用としてはLINEの公式アカウントの管理画面での色々出来るのでそこで出来ない所をAPI使って補う形になると思います。
有料ツールでしかできない事もあるので要注意です！
参考になれば幸いです。

間違いがあればご指摘ください。