Laravel: LINE の顧客リストを失わないリスクヘッジ

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、このところはLINEに関するマーケティング話をしてきましたが、今日も同じくLINEマーケティングの話です(笑)

LINEは「開封率が高い」「到達率も高い」という大きなメリットが
あるのでマーケターさんは好んで使ってます。

しかし、その反面大きなデメリットがあるのをご存知でしょうか。

それは・・・・・・

アカウント凍結されやすい

というものです。

人気であるがゆえにいろんな人が「やっちゃいけない事」をするんでしょうね。
LINEとしても凍結しやすくせざるを得ないようです。

しかし、アカウント凍結されるとどうなるでしょうか・・・・・・

そう❗

これまでゲットした全リストを失う

わけです。😨

例えば、これまで10,000見込み客とお友達になっていたとしても
アカウント凍結されたら、そのリストは全て失われます。ゼロ!

※ ウェブフックでユーザーデータを保存しておいても結局友達登録しないとメッセージが送れないのでLINE IDがあっても意味がないんです…。

これが大きなデメリットと言われているんですね。

そこで❗

今回はLaravelでこの「LINE アカウント凍結」の
リスクヘッジをする(保険をかけておく)機能をつくってみます。

ぜひ何かの参考になりましたら嬉しいです。😄✨

「たしかにX(旧Twitter)に
LINEへ誘導しようとする
日本語の怪しいアカウントあるね…」

開発環境: Laravel 11.x

リスクヘッジする方法

LINEへ登録してもらったら、一番はじめに
メルマガへ誘導するようにします。

そのために、「メルマガ限定のクーポンをお届けします😄」としておきましょう。(これで更に集客したお客さんを「育てる」こともできます!)

そして、DBの方ではLINEユーザーと、メルマガのユーザーが紐づくように(名寄せ)しておきましょう。

そうすることでリスクに対応することができます。

例えば、アカウント凍結後に別アカウントをつくり、そこに友達追加された場合、LINE IDからデータを紐付けて過去データを呼び出すことができるわけです。

また、シンプルにメールアドレスを取得しているのでメールでセールスすることもできるわけですね!

前提として

参考ページを見て、以下の作業を完了させておいてください。

  • LINE Messaging API を有効にする
  • ウェブフックを有効にする
  • パッケージ「linecorp/line-bot-sdk」をインストールする
  • CSRFトークンのチェックを解除

📝 参考ページ1: Line Messaging API で画像つき通報システムをつくる(神戸市に影響されて)

📝 参考ページ2: おまけ: ngrok について

📝 参考ページ3: CSRFトークンのチェックを解除する

※なお、Laravel 11.xからCSRFトークン解除の設定方法が変わっていますので注意してください。

では今回も楽しんでやっていきましょう❗

DBまわりをつくる

まずはデータベース周りです。
以下のコマンドを実行してください。

php artisan make:model LineUser -m
php artisan make:model NewsletterUser -m

そして、作成されたファイルを以下のように変更します。

database/migrations/****_**_**_******_create_line_users_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('line_users', function (Blueprint $table) {
            $table->id();
            $table->uuid()->unique()->comment('UUID');
            $table->string('line_id')->comment('LINEのID');
            $table->string('mode')->comment('チャネルの状態');
            $table->string('display_name')->comment('LINEの名前');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('line_users');
    }
};

database/migrations/****_**_**_******_create_newsletter_users_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('newsletter_users', function (Blueprint $table) {
            $table->id();
            $table->uuid()->unique()->comment('UUID');
            $table->string('email')->unique()->comment('メールアドレス');
            $table->boolean('is_agreed')->default(false)->comment('受け取り許可');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('newsletter_users');
    }
};

では、以下のコマンドでDBを初期化しておきましょう。

php artisan migrate:fresh --seed

すると、実際のテーブルはこうなりました。

ウェブフック用のコントローラーをつくる

次に、お友達登録されたときやメッセージが
送信されたときにデータ受信する「ウェブフック」をつくります。

以下のコマンドを実行してください。

php artisan make:controller LineMarketingWebhookController

そして、作成されたファイルを以下のように変更してください。

app/Http/Controllers/LineMarketingWebhookController.php

<?php

namespace App\Http\Controllers;

use App\Models\LineUser;
use GuzzleHttp\Client as GuzzleClient;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use LINE\Clients\MessagingApi\Configuration;
use LINE\Clients\MessagingApi\Api\MessagingApiApi;
use LINE\Clients\MessagingApi\Model\ReplyMessageRequest;
use LINE\Clients\MessagingApi\Model\TextMessage;
use LINE\Parser\EventRequestParser;
use LINE\Webhook\Model\FollowEvent;

class LineMarketingWebhookController extends Controller
{
    private $channel_secret, $access_token;

    public function __construct()
    {
        $this->channel_secret = env('LINE_CHANNEL_SECRET'); // 本来は config から取得すべきです
        $this->access_token = env('LINE_ACCESS_TOKEN'); // 本来は config から取得すべきです
    }

    public function receive(Request $request)
    {
        $request_body = $request->getContent();
        $hash = hash_hmac('sha256', $request_body, $this->channel_secret, true);
        $signature = base64_encode($hash);

        if($signature === $request->header('X-Line-Signature')) {

            $client = new GuzzleClient;
            $config = new Configuration();
            $config->setAccessToken($this->access_token);

            $this->api = new MessagingApiApi(
                client: $client,
                config: $config,
            );

            try {

                $event_parser = EventRequestParser::parseEventRequest($request_body, $this->channel_secret, $signature);

                foreach($event_parser->getEvents() as $event) {

                    if($event instanceof FollowEvent) { // お友達の登録したとき

                        $reply_token = $event->getReplyToken();
                        $line_id = $event->getSource()->getUserId();
                        $mode = $event->getMode();
                        $profile = $this->api->getProfile($line_id);
                        $display_name = $profile->getDisplayName();

                        if(is_null($line_id) || is_null($mode)) {

                            continue;

                        }

                        $line_user = LineUser::where('line_id', $line_id)->first();

                        if(is_null($line_user)) {

                            $line_user = new LineUser;
                            $line_user->uuid = Str::uuid();
                            $line_user->line_id = $line_id;

                        }

                        $line_user->mode = $mode; // チャネルの状態
                        $line_user->display_name = $display_name; // LINEの表示名
                        $line_user->save();

                        $text = view('line_webhook.thanks_text', [
                            'line_user' => $line_user,
                        ])->render();
                        $this->replyText($reply_token, $text);

                    }

                }

            } catch (\Exception $e) {}

        } else {

            abort(404);

        }
    }

    private function replyText(string $reply_token, string $text)
    {
        $message = new TextMessage([
            'type' => 'text',
            'text' => $text,
        ]);
        $request = new ReplyMessageRequest([
            'replyToken' => $reply_token,
            'messages' => [$message],
        ]);

        $this->api->replyMessage($request);
    }
}

メッセージ用のビューをつくる

続いて、先ほどのコントローラーの中でセットした
メッセージ用」のビューをつくります。

以下のコマンドを実行してください。

php artisan make:view line_webhook.thanks_text

そして、作成されたファイルは以下のようにします。

resources/views/line_webhook/thanks_text.blade.php

{{ $line_user->display_name }}さん、こんにちは! Console dot Log のすこひです。
お友達追加ありがとうございます。

これから、毎月 26日 にお得なクーポン情報をお届けします。
ぜひ、お楽しみに!

※ 通知が気になる方は、「トーク設定 → 通知」を OFF にしてください。

なお、メルマガに登録すると「メルマガ限定クーポン」もお届けします。
ぜひ、登録してくださいね!

{{ route('newsletter.create', $line_user->uuid) }}

メルマガ登録用コントローラーをつくる

そして、「メルマガ登録用」のコントローラーです。
以下のコマンドを実行してください。

php artisan make:controller NewsletterController

作成されたファイルを以下のようにします。

app/Http/Controllers/NewsletterController.php

<?php

namespace App\Http\Controllers;

use App\Models\LineUser;
use App\Models\NewsletterUser;
use Illuminate\Http\Request;

class NewsletterController extends Controller
{
    public function create(string $uuid)
    {
        $line_user = $this->getLineUserByUuid($uuid);

        return view('newsletter.create', [
            'line_user' => $line_user,
        ]);
    }

    public function store(Request $request)
    {
        // バリデーションは省略しています

        $line_user = $this->getLineUserByUuid($request->uuid);

        $newsletter_user = new NewsletterUser();
        $newsletter_user->uuid = $line_user->uuid;
        $newsletter_user->email = $request->email;
        $newsletter_user->is_agreed = $request->is_agreed;
        $newsletter_user->save();

        return 'メルマガの登録が完了しました。';
    }

    private function getLineUserByUuid(string $uuid)
    {
        $line_user = LineUser::where('uuid', $uuid)->first();

        if(is_null($line_user)) { // お友達登録していない場合

            abort(404);

        }

        return $line_user;
    }
}

メルマガ登録フォーム用のビューをつくる

続いて先ほどNewsletterController.php内でセットしたフォーム用のビューをつくります。

以下のコマンドを実行してください。

php artisan make:view newsletter.create

そして、中身を以下のようにします。

resources/views/newsletter/create.blade.php

<html>
    <head>
        <script src="https://cdn.tailwindcss.com/3.4.1"></script>
    </head>
    <body>
        <div class="p-5">
            <h1 class="text-2xl font-bold text-center">メルマガ登録フォーム</h1>
            <form method="POST" action="{{ route('newsletter.store') }}" class="flex flex-col space-y-2 w-full max-w-md mx-auto">
                @csrf
                <input type="hidden" name="uuid" value="{{ $line_user->uuid }}">
                <label>
                    メールアドレス
                    <input type="email" name="email" class="px-4 py-2 border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-transparent rounded-md shadow-sm w-full">
                </label>
                <label>
                    <div class="p-2">
                        <input type="checkbox" name="is_agreed" value="1" class="mr-2">
                        メルマガでお得な情報の配信を希望する
                    </div>
                </label>
                <button type="submit" class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 w-full">登録する</button>
            </form>
        </div>
    </body>
</html>

これで作業は完了です❗
お疲れ様でした😄✨

テストしてみる

では、実際にテストしてみましょう❗

まずはLINEで友達登録してみます。

すると・・・・・・

はい❗
登録完了のメッセージと
メルマガ登録フォームのURLが届きました。

※ ここにUUIDが入っているわけですね。

では、このURLをクリックしてみましょう。

どうなるでしょうか・・・・・・

フォームが表示されました。

ということで以下のようにして送信してみましょう。

うまくいくでしょうか・・・・・・

はい❗
登録完了メッセージが表示されました。

成功です😄

では、データベースの方がちゃんと名寄せできているか確認しておきましょう。

はい❗
UUIDが同じなので名寄せができていることがわかります。

今後はUUIDを使って相互のデータにアクセスすることができますね👍

すべて成功です。😄✨

企業様へのご提案

集客&セールスをするためには見込み客リストはとても重要な資産
といってもいいでしょう。

もしそれらが一瞬にして消えてしまったとしたら・・・・

しかし、今回のように「保険」をかけておけば安心です。

今ならLINE構築&メルマガによるリスクヘッジのご相談を承っています。

ぜひお気軽にお問い合わせからご相談ください。
お待ちしております。😄✨

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回は「LINEユーザーのアカウント凍結対策」をお届けしました。

とって集客は「マーケティングファネル」の
一番最初の部分になりますので、
ここの母数が多いほうがより成約数も多くなるわけです。

さらに、見込み客が多いということは
より質の高い顧客」と巡り合う可能性も高くなるので、
リストを守っておくに越したことはありません。

ぜひ皆さんも「リストマーケティング」を利用した
「稼ぐプログラム」を作ってみてくださいね。

ではでは〜❗

「半数は見終わりましたが、
YouTube の『後で見る』が
150本を超えてました。知恵熱出る…😂」

このエントリーをはてなブックマークに追加       follow us in feedly