代码之家  ›  专栏  ›  技术社区  ›  daugaard47

在Laravel电子邮件中创建取消订阅链接

  •  0
  • daugaard47  · 技术社区  · 3 年前

    我正在尝试允许用户通过服务器端的电子邮件链接取消订阅。

    只需让他们点击链接,在我的表中添加一列,并向他们显示一个页面,告诉他们已经取消订阅。

    链接如下所示:

    https://mysite.test/unsubscribe-confirm/eyJpdiI6Ims3Y3RJdHhvWTgyNGVLais1UXlzdlE9PSIsInZhbHVlIjoiUUF0NFZUUkNqTklmTTExTVRmZEdyaEUvN1kzcXpLNmNhRit3enpPNDE0ak5xalRaa1JQQS91elBCazIzTWFxayIsIm1hYyI6IjMzZDM4MDUwNTYzZjY1ZjQ4OTEyNDI3ZjJhY2M4NzgxNzgwMDFiMGQ2NjQ0ZjFiMGFjNGJlNjg3YzY0Zjc5NTkiLCJ0YWciOiIifQ==/1
    

    在我的工作中 JobToSendEmails 我正在创建 $unsubscribeLink 像这样:

    // Generate token
    $unsubscribeToken = encrypt($sponsor->email);
    // Generate unsubscribe link
    $unsubscribeLink = route('unsubscribe.confirm', ['token' => $unsubscribeToken, 'campaign_id' => $emailCampaign->id]);
    

    然后像这样传递到我的电子邮件:

    Mail::to($sponsor->email)->send(new EmailToUsers(
    ...
    $unsubscribeLink
    ));
    

    然后在 EmailToUsers 视图我有这样一行:

    If you no longer wish to receive these emails, you can [unsubscribe]({{ $unsubscribeLink }}) at any time.
    

    链接指向以下路线:

    Route::post('/unsubscribe-confirm/{token}/{campaign_id}', [EmailPreferenceController::class, 'confirmUnsubscribe'])->name('unsubscribe.confirm');
    

    然后在EmailPreferenceController中 confirmUnsubscribe 方法如下所示:

        public function confirmUnsubscribe()
        {
            $token = Request::get('token');
            $user  = User::findByToken($token);
            if ($user) {
                $emailCampaignId         = Request::get('email_campaign_id');
                $emailCampaignPreference = EmailCampaignPreference::updateOrCreate(
                    [
                        'user_id'           => $user->id,
                        'email_campaign_id' => $emailCampaignId,
                    ],
                    [
                        'opt_out' => true,
                        'email'   => $user->email,
                    ]
                );
    
                return redirect()->route('unsubscribe');
            }
            Log::error('User not found by token: ' . $token);
    
            return response()->view('errors.404', [], 404);
        }
    

    findByToken 看起来是这样的:

    public static function findByToken($token): User
      {
        $email = decrypt($token);
        return static::where('email', $email)->first();
      }
    

    当我点击电子邮件中的取消订阅链接时,我会收到错误:

    Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException “路由不支持GET方法 取消订阅确认/eyJpdiI6Ims3Y3RJdHhvWTgyNGVLais1UXlzdlE9PSIsInZhbHVlIjoiUUF0NFZUkNqTklmTTExTVRmZEdyaEUvN1kzcXpLNmNhRit3enpPNDE0ak5xalRaa1JQQS91elBCazIzTWFxaysIm1hYy6IjMzZDM4MDUwNTYzZjY1ZjQ4OTEyNDI3ZjJY2M4NzgxNzgwMDFiMGQ2NjQ0ZjFiMGFjNGJlNjg3YzY0Zjc5NTkiLCJ0YWciOiifQ==/1。 支持的方法:POST。“

    我能做些什么来解决这个问题?我在路线上使用Post方法。我想在电子邮件中保留这种格式, [unsubscribe]({{ $unsubscribeLink }})

    如有任何帮助,我们将不胜感激。

    0 回复  |  直到 3 年前
        1
  •  0
  •   daugaard47    3 年前

    主要问题是将路线从post改为get。

    Changed:
    Route::post('/unsubscribe-confirm/{token}/{campaign_id}', [EmailPreferenceController::class, 'confirmUnsubscribe'])->name('unsubscribe.confirm');
    
    To:
    Route::get('/unsubscribe-confirm/{token}/{campaign_id}', [EmailPreferenceController::class, 'confirmUnsubscribe'])->name('unsubscribe.confirm');
    

    然后在EmailPreferenceController中,confirmUnsubscribe方法现在如下所示:

        public function confirmUnsubscribe($token, $campaign_id)
        {
            $user = User::findByToken($token);
    
            if ($user) {
                $emailCampaignPreference = EmailCampaignPreference::updateOrCreate(
                    [
                        'user_id'           => $user->id,
                        'email_campaign_id' => $campaign_id,
                        'opt_out'           => true,
                        'email'             => $user->email,
                    ]
                );
    
                return redirect()->route('unsubscribe');
            }
            Log::error('User not found by token: ' . $token);
    
            return response()->view('errors.404', [], 404);
        }
    

    用户模型 findByToken 看起来是这样的:

        public static function findByToken($token): User
        {
            $email = decrypt($token);
            return static::where('email', $email)->first();
        }
    

    用户将立即取消订阅,数据将存储在表中。

    推荐文章