LINE messaging APIを使ってみた話(環境構築からメッセージの返信まで)

どうもすわんです。先日、PHPでLINE messaging APIを利用して、botを作成してみたので備忘録もの兼ねて記事に残していきたいと思います。様々な記事を参考に実装してみました。実装した機能は、メッセージの返信と誕生日の登録、お祝いメッセージとスタンプの送信です。今回は、環境構築をするところから、メッセージの返信までを書いていこうと思います。


*line-botsdk を利用せずに作成しています

事前準備

必要なもの

・LINEアカウント・自分のサーバー

(Herokuなどでもできるようです。今回は、エックスサーバーでの説明になります。)

Developer Trialアカウントの作成

まず初めにLINE messaging APIを利用するためにアカウントを作成(https://business.line.me/ja/services/bot)しましょう。無料でAPIを使えるアカウントはフリーとDeveloper Trial の2種類があります。今回は、返信(Reply)機能とbot自ら送信(Push)機能が必要なので、Developer Trialでアカウントを作成します。ここで、ログイン画面が表示されるので、LINEアカウントのメールアドレスとパスワードを入力してください。ぼくは、新規でLINEアカウントを作るのが面倒だったので、プライベートで使っているアカウントを使用しました。

LINE@の設定

アカウントの作成が完了したら、次にLINE@での設定を行います。まず、LINE BUSINESS CENTER からアカウントリストのタブを選択し、LINE@MANAGERを開きます。そしてアカウント設定 > Bot設定の順にクリックし、APIを利用するを選択します。その後、Bot設定画面に切り替わります。ここで詳しく設定を行っていきます。Bot設定の利用可能なAPIに REPLY_MESSAGE,PUSH_MESSAGEとなっていることを確認します。次にリクエスト設定では、・Webhook送信を「利用する」に変更してください。詳細設定では、・自動応答メッセージを「利用しない」に変更してください。

     

  • ここで「利用しない」が選択されていないと、何に対しても自動応答のテンプレメッセージが返ってきてしまいます。以上で設定を保存し、ここでのbot設定での準備は完了です。

LINE Developersでの設定

次に、LINE Developersでの設定をしていきます。まず、設定画面はLINE BUSINESS CENTERのアカウントリストタブをクリックしてください。そして、設定したいBotのアカウントの中のLINE DevelopersというボタンをクリックするとLINE Developersの管理画面に入れるはずです。

ここで行うことは、下記の2点です。・Webhook URLの設定・Channel Access Tokenの取得

それでは、設定を行っていこうと思います。

webhookURLの設定

webhookURLとは、今後実装するコードのURLです。今回は、エックスサーバーを自分で用意して、そこに配置したファイルを指定します。また、https://のsslを利用しているURLでないと使えないので、エックスサーバーにてhttpsのURLを取得しなければなりません。エックスサーバーでのSSL設定方法については、ここでの説明は割愛しますが、かなり簡単にできます。

webhookURLには、https://自分エックスサーバーのドメイン/コードを置いたファイルへのパス.phpの形で指定します。

Channel Access Tokenの取得

次に、APIを利用するためのアクセストークン(Channel Access Token)を取得します。これは、自身のAPIに接続する際に必要な鍵のようなものという理解で良いと思います。

以降の実装フェーズにて使用するのでアクセストークンを控えておいてください。

これで、LINE messaging APIを使うための準備が整いました。

実装

今回実装する機能

今回実装する機能をおさらいすると、・メッセージの返信・メッセージのプッシュ・誕生日の登録・登録された誕生日にお祝いメッセージをプッシュ

になります。それでは、メッセージの返信から順を追って実装をしていきたいと思います。

実装コード

解説はさておき、以下のcallback.phpというファイルを作成します。

callback.php

require_once dirname(__FILE__) . '/config.php';
require_once dirname(__FILE__) . '/response_format_text.php';
require_once dirname(__FILE__) . '/curl.php';
require_once dirname(__FILE__) . '/register.php';


//APIから送信されてきたイベントオブジェクトを取得
$json_string = file_get_contents('php://input');
$json_obj = json_decode($json_string);

//イベントオブジェクトから必要な情報を抽出
$source = $json_obj->{"events"}[0]->{"source"};
$message = $json_obj->{"events"}[0]->{"message"};
$reply_token = $json_obj->{"events"}[0]->{"replyToken"};

// group_idの取得
$group_id =  $source->{"groupId"};

$space_ignored = str_replace(" ", "", $message->{"text"} );
$exploded = explode(",", $space_ignored);

// 誕生日のフレーズと登録情報が4つテキストに含まれていれば、登録する
if($exploded[0] == "誕生日" && count($exploded) == 4) {
    // 誕生日の登録関数呼び出し
    register_birthday($exploded[1], $group_id, $exploded[2], $exploded[3]);
} else {
    // 通常の返信
    $response_format_text = response_format_text($message);
}

$post_data = [
    "replyToken" => $reply_token,
    "messages" => [$response_format_text]
    ];

curl($post_data, $access_token);

まず、require_onceでconfig.phpを呼び出しています。
config.php

$access_token = 'ACCESS TOKEN';

このACCESS TOKENには、上記で説明したChannel Access Tokenの取得の部分で取得したアクセストークンを記述します。
AccessTokenは他の人に知られてはいけないので、僕の環境では別ファイルに切り出して.gitignoreをしています。

このAccessTokenは、返信テキストを送信するときに権限の認証するのに使います。
具体的にcallback.phpでは、一番下の行でcurlで返信情報を送信するときに使っています。

それでは、具体的にcurl.phpを見てみましょう。
curl.php

function curl($post_data, $access_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);
}

詳しい説明は割愛しますが、上記のように認証をするためにAccess Tokenを利用します。

次に、返信テキストを設定しているファイルを見ていきたいと思います。
response_format_text.php

{"text"},$phrase);

    //ユーザーからのメッセージに対し、返信するテキスト
    if ($match) {
        $response_format_text = array();

        switch($match){
            case 0:
                $response_format_text = [
                    "type" => "text",
                    "text" => "おはよう♡"
                    ];
            break;
            case 1:
                $response_format_text = [
                    "type" => "text",
                    "text" => "おやすみ。明日も頑張ってね〜!"
                    ];
            break;
            case 2:
                $response_format_text = [
                    "type" => "text",
                    "text" => "おはよう!今日も1日頑張ってね〜!"
                    ];
            break;
        }
    }
    return $response_format_text;
}

$phraseに指定した、フレーズがユーザーから送信されてきたときに、switch文でそのフレーズに該当する返信キーワードを返すといった構成です。ここは、記述量が多いので改善の余地がありそうです。

次に誕生日を登録するファイルを見ていきましょう。
register.php

{"birthdays"})) {
        $new_id = 1;
    } else {
        $used_nums = [];
        foreach($birthdays->{"birthdays"} as $user) {
            array_push($used_nums, $user->{"birthdayId"});
        }

        $new_id = max($used_nums) + 1;
    }

    // 新規の誕生日データの挿入
    array_push(
        $birthdays->{"birthdays"},
        [
            "birthdayId" => $new_id,
            "name" => $name,
            "groupId" =>$group_id,
            "month" => $month,
            "day" =>$day
        ]
    );

    // 誕生日データをJSONに書き込む
    return file_put_contents($storage_file_path, json_encode($birthdays));
}

ここでは、DBなどは使わずにjsonファイルにユーザから入力された誕生日を書き出すことで登録しています。
そしてエックスサーバーのcron設定で、毎日0:00で日付が切り替わった瞬間にbirthday_push.phpを実行して、jsonファイルの登録情報と今日の日付が一致する誕生日のユーザーがいないか探しに行っています。
そして、今日誕生日の人がいた場合に、誕生日のメッセージとスタンプを送るように設定しています。
birthday_push.php

require_once dirname(__FILE__) . '/config.php';
require_once dirname(__FILE__) . '/register.php';

// 誕生日データのロード
$birthdays = get_birthday_data();

// 今日の日付を取得
$today = [
    "month" => date("n"),
    "day" => date("j")
];

// 今日誕生日の人にメッセージを送る
foreach ($birthdays->{"birthdays"} as $user) {
    if($user->{"month"} == $today["month"] && $user->{"day"} == $today["day"]) {
        push_message(
            [
                "to" => $user->{"groupId"},
                "messages" => [
                    [
                        "type" => "text",
                        "text" => $user->{"name"} . "くん、誕生日おめでとう!"
                    ],
                    [
                        "type" => "sticker",
                        "packageId" => "1",
                        "stickerId" => "410"
                    ],
                    [
                        "type" => "sticker",
                        "packageId" => "4",
                        "stickerId" => "307"
                    ]
                ]
            ]
        );
    }
}

// プッシュメッセージの送信
function push_message($post_data) {
    global $access_token;

    $ch = curl_init("https://api.line.me/v2/bot/message/push");
    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 Messaging API で LINE Botを作ってみてください!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です