Search code examples
laravelemailhyperlinkunsubscribe

Laravel - signed route with 404 error for an email unsubscribe link


I have an unsubscribe link for emails, but when I click on the link I get an error 404.

this is my code.

First, this is the generation for unsubscribe link with signed route (link is okay)

private function generateUnsubscribeLink($meoId, $email)
{
    return URL::signedRoute(
        'meo.confirm-unsubscribe', [
            'meo' => $meoId,
            'email' => $email
        ]
    );
}

next, this is my web.php routes

Route::get('/unsubscribe/{meo}/{email}', 'MeoMailController@confirmUnsubscribe')->name('meo.confirm-unsubscribe');
Route::post('/unsubscribe/confirmed/{meo}/{email}', 'MeoMailController@unsubscribe')->name('meo.unsubscribe');

and finally, this is my controller

public function confirmUnsubscribe(Request $request, Meo $meo, MailRecipient $email){
        if (!$request->hasValidSignature()) {
            abort(401);
        }

        return view('mail.confirm_unsubscribe', compact(['request', 'meo', 'email']));
    }

    public function unsubscribe(Meo $meo, MailRecipient $email)
    {
          $email->state = MailRecipientState::UNSUBSCRIBED;
          $email->save();

        return view('mail.unsubscribed');
    }

the final result of this is when I click on the unsubscribe link is an error 404

enter image description here

the link is unsubscribe/meoId/email@example.com?SIGNEDROUTE

what's wrong here?

In the past, I used the same method but without email (only using meoId), and was working correctly


Solution

  • change MailRecipient $email in method arg to $email then find that model manually like $email = MailRecipient::where('email',$email)->first(). should be like:

    public function confirmUnsubscribe(Request $request, Meo $meo, $email){
     if (!$request->hasValidSignature()) {
    abort(401);
    }
    
    $email = MailRecipient::where('email',$email)->first();
    return view('mail.confirm_unsubscribe', compact(['request', 'meo', 'email']));
    }
    
    public function unsubscribe(Meo $meo, $email)
    {
    $email = MailRecipient::where('email',$email)->first();
    
    $email->state = MailRecipientState::UNSUBSCRIBED;
    $email->save();
    
    return view('mail.unsubscribed');
    }