Laravel で「ダイレクト・レスポンス・マーケティング」基礎システムをつくる

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

さてさて、まだまだ「市場価値の高いエンジニア」になりたいので、マーケティング知識を詰め込んでいる今日この頃です。

そして、マーケティングを勉強するにあたって、ある重要な単語を知ることになりました。

それは・・・・・・

ダイレクト・レスポンス・マーケティング(DRM)

です。

とても簡単に言うと、「何かに登録してくれた人だけにセールスしていく」という手法で、メルマガとかだと「これは買うしかないっしょ!」となるように、お客さんを「教育」をしたりするようです。

そして、そのDRMをする上で今回は注目したのは、「前は買ってくれなかったよね。もう一回考えてみない??😄」と2回目のセールスをする「リターゲティング」です。

例えば「割引するから買わない??」とかメール送信できるわけですね。

そこで❗

今回はこの「割引クーポンコードつきのメール機能」をLaravelで作ってみることにしました。

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

「迫佑樹社長の
人生攻略ロードマップ
具体的でマジで良い本でした 😄✨」

開発環境: Laravel 10.x

やりたいこと

今回は特定のユーザーがメルマガ登録したという想定にしています。

そして、そのユーザーが「何をしたか」を1つずつ保存し、その後「特定の行動」をしたときにメールでアプローチするところまで実装してみます。

つまり、具体的な動きは次のとおりです。

  1. メルマガに登録(登録部分は今回省略します)
  2. 「SNS集客」に興味が出て、商品ページを見に来た(しかし、購入はしなかった)
  3. 1ヶ月後「SNS集客」の商品ページをまた見に来た
  4. 期間限定の割引クーポンつきメールを送信

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

行動タイプの Enum をつくる

まずは「ユーザーがどんな行動をしたか」が分かる「行動タイプ」のリストをつくっていつでも取り出せるようにしておきましょう。

app/Enums/NewsletterUserActionType.php

<?php

namespace App\Enums;

enum NewsletterUserActionType: string
{
    case Sns_Sales_Viewed = 'sns_sales_viewed'; // SNS集客の商品ページを見た

    // その行動も追加できます
}

DB まわりをつくる

次に、データベースまわりです。
以下のコマンドを実行してください。

php artisan make:model NewsletterUser -ms
php artisan make:model NewsletterUserAction -m

すると、5ファイルが作成されるのでそれぞれ中身を以下のようにします。

モデル

app/Models/NewsletterUser.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class NewsletterUser extends Model
{
    use HasFactory;

    protected $fillable = ['uuid', 'name', 'email'];
}

app/Models/NewsletterUserAction.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class NewsletterUserAction extends Model
{
    use HasFactory;

    protected $fillable = ['newsletter_user_id', 'action_type'];
}

マイグレーション

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

// 省略

public function up(): void
{
    Schema::create('newsletter_users', function (Blueprint $table) {
        $table->id();
        $table->uuid()->comment('ユニークID');
        $table->string('name')->comment('名前');
        $table->string('email')->unique()->comment('メールアドレス');
        $table->timestamps();
    });
}

// 省略

database/migrations/****_**_**_******_create_newsletter_user_actions_table.php

// 省略

public function up(): void
{
    Schema::create('newsletter_user_actions', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('newsletter_user_id')->comment('メルマガユーザー ID'); // これは Cookie に保存されている ID を想定
        $table->string('action_type')->comment('ユーザーの行動タイプ'); // App\Enums\NewsletterUserActionType で定義
        $table->timestamps();

        $table->foreign('newsletter_user_id')->references('id')->on('newsletter_users');
    });
}

// 省略

Seeder

database/seeders/NewsletterUserSeeder.php

// 省略

public function run(): void
{
    $names = [
        'taro' => '太郎',
        'jiro' => '次郎',
        'saburo' => '三郎',
        'shiro' => '四郎',
        'goro' => '五郎',
        'rokuro' => '六郎',
        'shichiro' => '七郎',
        'hachiro' => '八郎',
        'kuro' => '九郎',
    ];

    foreach ($names as $name_en => $name_jp) {

        $uuid = ($name_en === 'taro')
            ? 'taro0000-0000-0000-0000-000000000000' // テストのため、太郎のため 固定 UUID
            : Str::uuid();

        NewsletterUser::create([
            'uuid' => $uuid,
            'name' => $name_jp,
            'email' => $name_en .'@example.com',
        ]);

    }
}

// 省略

Seederは作るだけでは反映されないのでDatabaseSeeder.phpへ登録して有効にしておきます。

database/seeders/DatabaseSeeder.php

    public function run(): void
    {
        // 省略

        $this->call([
            NewsletterUserSeeder::class,  // 👈 ここを追加しました
        ]);
    }

では、この状態でデータベースを初期化してみましょう。
以下のコマンドを実行してください。

php artisan migrate:fresh --seed

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

コントローラーをつくる

では、次に「ユーザーの行動履歴」を保存する部分です。

今回は「商品ページ」にアクセスしてきた場面を想定して「ProductController.php」をつくります。

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

php artisan make:controller ProductController

すると、ファイルが作成されるので中身を以下のようにします。

app/Http/Controllers/ProductController.php

<?php

namespace App\Http\Controllers;

use App\Enums\NewsletterUserActionType;
use App\Models\NewsletterUser;
use App\Models\NewsletterUserAction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class ProductController extends Controller
{
    public function show(Request $request, $id) // 本来はここに商品モデルをバインティングしますが、今回は省略します
    {
        $newsletter_uuid = $request->cookie('newsletter_uuid');
        $newsletter_user = NewsletterUser::where('uuid', $newsletter_uuid)->first();

        if(! is_null($newsletter_user)) {

            // 本来この部分はミドルウェアなどで共通化するべきですが、今回は省略します。
            // またこの部分は可変にするべきです

            if(intval($id) === 1) { // SNS集客に関するページを想定してます

                // 一番最初に商品ページを見たデータを取得する
                $oldest_action = NewsletterUserAction::query()
                    ->where('newsletter_user_id', $newsletter_user->id)
                    ->where('action_type', NewsletterUserActionType::Sns_Sales_Viewed)
                    ->oldest()
                    ->first();


                if(! is_null($oldest_action)) {

                    if($oldest_action->created_at->diffInDays() >= 7) { // 初めて商品ページを見てから7日以上経過しているか?

                        // 割引クーポンつきメールを送信(本来は Mailable を使うべきです)
                        $mail_body = 'ここに割引クーポンつきメールの本文を記述します。';
                        Mail::raw($mail_body, function ($message) use ($newsletter_user) {

                            $to = $newsletter_user->email;
                            $message
                                ->to($to)
                                ->subject('【Sukohi Web Service】期間限定クーポンのご案内 ●月●日まで!');

                        });

                    }

                }

                // ユーザーの行動は無条件で記録する(今後の分析のため)
                $newsletter_user_action = new NewsletterUserAction();
                $newsletter_user_action->newsletter_user_id = $newsletter_user->id;
                $newsletter_user_action->action_type = NewsletterUserActionType::Sns_Sales_Viewed;
                $newsletter_user_action->save();

                return '商品ページが表示されます(行動履歴が保存されました)';

            }

        }

        return '商品ページが表示されます(行動履歴は保存されていません)';
    }

    public function set_cookie()
    {
        // テスト用で Cookie をセットする
        // 本来はメルマガ登録時にセットするべき

        $uuid = 'taro0000-0000-0000-0000-000000000000';
        $minutes = 60 * 24 * 365 * 10; // 10年間有効

        return response('Cookie がセットされました', 200)
            ->cookie('newsletter_uuid', $uuid, $minutes);
    }
}

ちなみに、今回はテストなので、set_cookie(){ ... }は「Cookieをセットするためだけのテストページ」になってます。

本来は、メルマガを登録した時点でCookieをセットするようですね。

また、デバイスが変わっても本人を特定できるようにメールに「ウェブビーコン」と呼ばれる透明な画像をセットしておいて、そこからCookieをセットしたりもするようです。

ちなみに

ブログ記事のコードなので省略していますが、今回の機能を使用する際には以下の内容に気をつけないといけません。

  • Cookie の追加、取得はプライバシーポリシーなどに書いておく必要が出てくる(特に海外との関連がある場合に多いようです)
  • メルマガを送る際には、「送信してOKの同意」「いつでもストップOK」にしておかないといけない
  • 特定電子メール法に関わらず一度送信したメール文面を何度も送るべきではない(1年過ぎたりしたらOKかもですが…)ので、今回の条件だけではここは実装できていない

テストしてみる

では、実際にダイレクト・レスポンス・マーケティングの「リターゲティング」機能をテストしてみましょう❗

まず、ブラウザで「https://******/product/2」(👈 2です)にアクセスして行動履歴が保存「されない」かをチェックしてみましょう。

すると・・・・・・

はい❗

今回の機能には関係ない商品だったので「行動履歴は保存されていません」と表示されました。

まずは成功です。

では、次にテスト用のCookieをブラウザに付加してみましょう。

https://******/product/set_cookie」へアクセスします。

はい❗
Cookieがセットされました。

念のため、ブラウザでも確認しておきましょう。

きちんとセットされていますね。

※ちなみにLaravel側で値は暗号化されているので、毎回ここの値は変わります。安心ですね😄👍

では、この状態で「https://******/product/1」(これが目的の商品ページです)へアクセスします。

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

はい❗

今度は「行動履歴が保存されました」と表示されました。

では、データベースの方も確認しておきましょう。

うまく行動履歴が保存されています。

成功です😄

では、何度かリロードして行動履歴が溜まっていくかチェックしてみましょう。

はい❗
こちらもうまくいっています。

※ つまり、これらはマーケティング戦略によって「過去に5回も見に来たのに、買ってないんだから今度は似た商品でアプローチしよう」とかいろんな判断に使える訳です。

では、最後に割引クーポンが送信されるかチェックしてみましょう。

今回は「初めて商品ページを見てから 7日以上経過していたら」割引クーポン・メールを送るということになっているので、テストとして最初のデータのcreated_atを1ヶ月減らしておきます。

では、この状態でリロードします。

(つまり、初めて商品を見てから一ヶ月後が経過した状態ですね)

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

はい❗
うまくメールが送信されてきました。

実際には、ここにクーポンコードが書かれていて割引で買い物ができたりするわけです。

すべて成功です😄✨

企業様へのご提案

今回のようにリターゲティング手法をウェブシステムを融合させることによって、お客さんを「より購入をしやすい」状態にすることができます(つまり、CVRの改善につながります)

また、使い方によっては「ダウンセル(今回のような値引き)」や「クロスセル(別の商品の提案)」につなげることもできるでしょう。

もしこういった機能をご希望でしたら、お気軽にお問い合わせからご相談ください。

お待ちしております。😄✨

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

おわりに

ということで今回は、より実践的なマーケティング手法「ダイレクト・レスポンス・マーケティング」と「リターゲティング」を活用して機能をつくってみました。

しかし、マーケティングを知れば知るほど「あ❗じゃ、あのアプローチはそういうことだったのね!?」となる場合もあり、やっぱり頭のいい人ってすごいし、稼いでるんだろうなぁ、しみじみ感じてしまいました。

私もそろそろ少し大きなお金をかけて勉強するときが来たのかもしれません。

ぜひ皆さんもエンジニアの知識に何か別の知識を掛け合わせて、ご自身の市場価値を高めるようにしてみてくださいね。(私もがんばります👍)

ではでは〜❗

「でも、泊まるとなったら
ネカフェで節約が
デフォルトです 😂」

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