開発情報・ナレッジ

投稿者: SPIRERS ナレッジ向上チーム 2022年8月12日 (金)

完了ページでLINEのリッチメニューを切り替えるサンプルプログラム

ユーザの情報登録状況に応じて、リッチメニューを出し分けるサンプルプログラムを作成いたしました。
SPIRAL ver.2とLINEを連携して認証エリアにログインさせるような会員サイトを作成しようと思っている方は、ぜひ参考にしてみてください。

関連記事はこちら

変更・改定履歴

  • 変更

    退会(削除フォーム)を使ってリッチメニューを変更するパターンを追加

仕様

登録・更新・削除のブロックで会員登録完了や退会時の完了時にリッチメニューの変更を行うサンプルプログラムとなります。
リッチメニュー切り替えを行う際に、リッチメニューの作成・リッチメニューのIDが必要となります。
リッチメニューの作成・リッチメニューのID取得については、こちらを参考にして、事前に準備をお願いします。
また、LINEアカウントで認証エリアにログインさせるサンプルプログラムを使用している場合は、
LINEログイン時に事前にデータが登録されるため、会員情報登録が更新フォームになるので、ご注意ください。

LINEアカウント

LINE のリッチメニュー切り替えのAPIを実装するために、LINE Developersアカウントが作成が必要となります。
Messaging APIを始めようを参考にアカウントおよびMessaging APIのチャネルを作成してください。

サンプルプログラム

このサンプルプログラムは、登録・更新・削除フォームブロックを設置しているページに追加してください。
PHP
<?php
// SPIRAL ver.2 の情報
define("LINE_RECORD_ID", "1"); // LineIDのフィールドID
// Line の情報
define('LINE_MESSAGE_TOKEN', '');;// チャネルアクセストークン
define('RICH_MENU_ID', ''); // 変更したいリッチメニューID

// 登録ブロックの場合
// $formComplete = $SPIRAL->getRegistrationForm(""); // 登録ブロックの識別名を登録
// 更新ブロックの場合
// $formComplete = $SPIRAL->getUpdateForm(""); // 更新ブロックの識別名を登録
// 削除ブロックの場合
// $formComplete = $SPIRAL->getDeleteForm(""); // 削除ブロックの識別名を登録

// 以下修正不要
if($formComplete->isCompletedStep()){
    $result = lineRichMenuChange($SPIRAL->getAuthRecordByFieldId(LINE_RECORD_ID));
    // debug
    // $SPIRAL->setTHValue("result", print_r($result,true));
}

function lineRichMenuChange($lineID){
    $ch = curl_init();   
    $header = array(
        'Content-Type: application/json',
        'Authorization: Bearer '.LINE_MESSAGE_TOKEN,
    );
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/user/'.$lineID.'/richmenu/'.RICH_MENU_ID);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);   
    
    $json = json_decode($response);
    $userInfo= json_decode(json_encode($json), true);
    return $userInfo;
}
設定値は3ヶ所となります。
チャネルアクセストークンは、LINEアカウントで発行したアカウントのLINE Developersより取得してください。
リッチメニューIDの取得方法に関しては、LINE Messaging APIでのリッチメニュー作成、リッチメニューID取得を参考にしてください。
LINE_RECORD_ID LINE IDを登録しているフィールドIDを設定
LINE_MESSAGE_TOKEN LINEのMessaging API チャネルアクセストークンを設定
RICH_MENU_ID LINE のリッチメニューIDを設定

次にどのフォームブロックかを判定する箇所を修正します。
9行目 - 14行目の箇所になります。
// 登録ブロックの場合
// $formComplete = $SPIRAL->getRegistrationForm(""); // 登録ブロックの識別名を登録
// 更新ブロックの場合
// $formComplete = $SPIRAL->getUpdateForm(""); // 更新ブロックの識別名を登録
// 削除ブロックの場合
// $formComplete = $SPIRAL->getDeleteForm(""); // 削除ブロックの識別名を登録
使用するブロックタイプのコメントアウト(*)をはずして識別を設定してください。
* 文字の先頭に「//」をつけることでコメントアウトできます。

実行失敗時の処理について

サンプルプログラムでは、リッチメニュー変更のAPIを実行していますが、実行失敗時のリトライ処理は入っておりません。
失敗時のアクションとしては、リッチメニュー切り替え前のページにステータス等が違うユーザからアクセスがあった場合は、リッチメニューのAPIを投げる等の処理を追加してください。
挙動イメージ図
挙動イメージのような処理を行う場合は、会員情報登録時に情報登録済みとなるステータスを入れておいてください。
また、リッチメニューの変更時に、遷移先のURLも変更されるようリッチメニューの作成が必要となります。

リッチメニュー変更前のページ(挙動イメージ図の場合、会員情報登録ページ)にアクセスに下記のサンプルプログラムを設定ください。
PHP
<?php
// SPIRAL ver.2 の情報
define("LINE_RECORD_ID", ""); // LineIDのフィールドID
define("USER_STATUS_ID", ""); // ステータスのフィールドID
define("REDIRECT_PASS",""); // 相対パスで設定
// Line の情報
define('LINE_MESSAGE_TOKEN', '');
define('RICH_MENU_ID', ''); // 変更したいリッチメニューID

$SPIRAL->setTHValue('REDIRECT',false);
if($SPIRAL->getAuthRecordByFieldId(USER_STATUS_ID)){
    $result = lineRichMenuChange($SPIRAL->getAuthRecordByFieldId(LINE_RECORD_ID));
    // debug
    // $SPIRAL->setTHValue("result", print_r($result,true));
    $redirect = true;
    $SPIRAL->setTHValue('REDIRECT',true);
    $SPIRAL->setTHValue('REDIRECT_PASS',LOGIN_TOP_PASS);
}

function lineRichMenuChange($lineID){
    $ch = curl_init();   
    $header = array(
        'Content-Type: application/json',
        'Authorization: Bearer '.LINE_MESSAGE_TOKEN,
    );
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/user/'.$lineID.'/richmenu/'.RICH_MENU_ID);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);   
    
    $json = json_decode($response);
    $userInfo= json_decode(json_encode($json), true);
    return $userInfo;
}
4行目 と 11行目がステータスのフィールドを選択している箇所と分岐処理になります。
分岐処理に関しては、データの持たせ方に合わせて、処理の変更をお願いします。

リッチメニュー変更前のページ(挙動イメージ図の場合、会員情報登録ページ)の HEAD および BODY は、以下を設定してください。

HEAD
<title th:text="${page.title}"></title>
<th:block th:if="${cp.result.value['REDIRECT']}">
    <meta http-equiv="refresh" th:content="|0;URL=${cp.result.value['redirectURL']}|">
</th:block>
BODY
<div th:if="${cp.result.isSuccess}">
    <th:block th:if="${!cp.result.value['REDIRECT']}'">
        <!-- リッチメニュー変更前にアクセスされた際に表示させたいブロックをこちらに設定 -->
    </th:block>
</div>
<div th:if="${!cp.result.isSuccess}">
    <p th:text="${cp.result.errorMessage}">error message</p>
</div>

ユーザ側のプログラムでリッチメニューを変更するのではなく、裏側からユーザ毎に送信する方法は下記を参照ください。
LINE Messaging APIでのリッチメニュー作成、リッチメニューID取得

退会(削除フォーム)を使ってリッチメニューを変更

削除フォームを使用して、退会フォームを実装する場合は、APIによるログアウト処理が必要となります。
APIでのログアウト処理をいれていないと、LINEブラウザを閉じ再度アクセスを行うと400エラーが表示されてしまいます。
LINEブラウザを閉じただけでは、セッションが切られないため、レコードがない状態で認証エリア内にアクセスされる状態となります。
この状態を防ぐために APIでログアウトする処理を入れてください。
* リッチメニューの変更及びログアウト処理を行う処理になります。
PHP
<?php
// SPIRAL ver.2 の情報
define("LINE_RECORD_ID", ""); // LineIDのフィールドID
// ログアウト処理用
define("API_URL", "https://api.spiral-platform.com/v1/");
define("API_KEY", $SPIRAL->getEnvValue(""));
define("API_ROLE", "");
define("SITE_ID", "");
define("AUTHENTICATION_ID", "");

// Line の情報
define('LINE_MESSAGE_TOKEN', '');// チャネルアクセストークン
define('RICH_MENU_ID', ''); // 変更したいリッチメニューID

// セッションスタート
session_start();

// 削除ブロックの場合
$formComplete = $SPIRAL->getDeleteForm(""); // 削除ブロックの識別名を登録

// 以下修正不要
if($formComplete->isCompletedStep()){
    $result = lineRichMenuChange($SPIRAL->getAuthRecordByFieldId(LINE_RECORD_ID));
    // debug
    // $SPIRAL->setTHValue("result", print_r($result,true));
    if(isset($_COOKIE['asid'])){
        $data = array(
            "token" => $_SESSION['token'],
        );
        $logout = apiCurlAction("POST","sites/".SITE_ID."/authentications/".AUTHENTICATION_ID."/logout",$data);
    }
}

function lineRichMenuChange($lineID){
    $ch = curl_init();   
    $header = array(
        'Content-Type: application/json',
        'Authorization: Bearer '.LINE_MESSAGE_TOKEN,
    );
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/bot/user/'.$lineID.'/richmenu/'.RICH_MENU_ID);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);   
    
    $json = json_decode($response);
    $userInfo= json_decode(json_encode($json), true);
    return $userInfo;
}

/**
 * V2用 API送信ロジック
 * @return Result
 */
function apiCurlAction($method, $addUrlPass, $data = null){    
    $header = array(
        "Authorization:Bearer " . API_KEY,
        "Content-Type:application/json",
        "X-Spiral-Api-Version: 1.1",
    );
    if(API_ROLE){
        $header = array_merge($header,array("X-Spiral-App-Role: ".API_ROLE));
    }

    // curl
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_URL, API_URL . $addUrlPass);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    if ($method == "POST") {
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
    }
    if ($method == "PATCH") {
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
    }
    if ($method == "DELETE") {
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
    }
    if ($method == "GET") {
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
    }
    $response = curl_exec($curl);
    if (curl_errno($curl)) echo curl_error($curl);
    curl_close($curl);
    return json_decode($response, true);
}

ログアウト処理用の設定値は、下記が必要となります。

LINE_RECORD_ID LINE IDを登録しているフィールドIDを設定
API_KEY APIキーを設定
API_ROLE アプリロールの識別名をセットしたPHP環境変数の変数名を設定
アプリロールによる権限設定をしない場合は未入力
SITE_ID サイトIDをセットしたPHP環境変数の変数名を設定
AUTHENTICATION_ID LINEログインを行う、認証エリアIDを設定
LINE_MESSAGE_TOKEN LINEのMessaging API チャネルアクセストークンを設定
RICH_MENU_ID LINE のリッチメニューIDを設定

下記は、PHP環境変数を使った書き方になります。
PHP環境変数については、サポートサイトを参照ください。
PHP環境変数を使用しない場合は、下記を使用せずに直接識別名もしくは IDを設定してください。
$SPIRAL->getEnvValue("")
ログアウト処理には、APIでログイン処理を行った際に発行される token が必要となります。
こちらに関しては、2022/08/25 に ログイン処理側 にも修正を行っていますので、修正版にてご確認ください。

最後に

設定後は動作確認を必ず行い、動作に問題がないか確認をしてください。
不具合やほかのやり方が知りたい等あれば、下記の「コンテンツに関しての要望はこちら」からご連絡ください。
解決しない場合はこちら コンテンツに関しての
要望はこちら