query('token') ?: $request->header('X-RelaisSMS-Callback-Token', ''))); abort_if($configuredToken === '' || ! hash_equals($configuredToken, $receivedToken), 403); $sender = $this->sender($request); if ($sender === '') { return response()->json([ 'status' => 'ignored', 'reason' => 'missing_sender', ], 422); } $result = $normalizer->normalize( $sender, (string) config('relais_sms.default_settings.default_country'), ); if (! $result->isValid || $result->normalizedNumber === null) { return response()->json([ 'status' => 'ignored', 'reason' => 'invalid_sender', ], 422); } $contacts = ContactPhoneNumber::query() ->with('contact') ->where('normalized_number', $result->normalizedNumber) ->get() ->pluck('contact') ->filter() ->unique('id') ->values(); $updatedContacts = 0; $alreadyOptedOutContacts = 0; foreach ($contacts as $contact) { if ($contact->sms_opt_out) { $alreadyOptedOutContacts++; continue; } $contact->update(['sms_opt_out' => true]); $updatedContacts++; } return response()->json([ 'status' => $contacts->isEmpty() ? 'unmatched' : 'ok', 'sender' => $result->normalizedNumber, 'updated_contacts' => $updatedContacts, 'already_opted_out_contacts' => $alreadyOptedOutContacts, ]); } private function sender(Request $request): string { foreach (['sender', 'from', 'number', 'phone', 'msisdn'] as $key) { $value = $request->input($key); if (is_string($value) && trim($value) !== '') { return trim($value); } } return ''; } }