- FcmSender.sendToMany() 추가 (chunk/rate limit 지원) - FcmBatchResult 클래스 추가 (발송 결과 집계) - fcm:send 명령어 추가 (대량 발송, dry-run 지원) - fcm:prune-invalid 명령어 추가 (무효 토큰 정리) - PushDeviceToken에 last_error, last_error_at 컬럼 추가 - 실패 토큰 자동 비활성화 (UNREGISTERED, NOT_FOUND, INVALID_ARGUMENT)
87 lines
2.0 KiB
PHP
87 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Fcm;
|
|
|
|
class FcmResponse
|
|
{
|
|
public function __construct(
|
|
public readonly bool $success,
|
|
public readonly ?string $messageId,
|
|
public readonly ?string $error,
|
|
public readonly int $statusCode,
|
|
public readonly array $rawResponse
|
|
) {}
|
|
|
|
/**
|
|
* 성공 응답 생성
|
|
*/
|
|
public static function success(?string $messageId, int $statusCode, array $rawResponse): self
|
|
{
|
|
return new self(
|
|
success: true,
|
|
messageId: $messageId,
|
|
error: null,
|
|
statusCode: $statusCode,
|
|
rawResponse: $rawResponse
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 실패 응답 생성
|
|
*/
|
|
public static function failure(string $error, int $statusCode, array $rawResponse): self
|
|
{
|
|
return new self(
|
|
success: false,
|
|
messageId: null,
|
|
error: $error,
|
|
statusCode: $statusCode,
|
|
rawResponse: $rawResponse
|
|
);
|
|
}
|
|
|
|
/**
|
|
* FCM 에러 코드 추출
|
|
*/
|
|
public function getErrorCode(): ?string
|
|
{
|
|
if ($this->success) {
|
|
return null;
|
|
}
|
|
|
|
return $this->rawResponse['error']['details'][0]['errorCode'] ?? null;
|
|
}
|
|
|
|
/**
|
|
* 토큰이 유효하지 않은지 확인 (삭제 필요)
|
|
*/
|
|
public function isInvalidToken(): bool
|
|
{
|
|
if ($this->success) {
|
|
return false;
|
|
}
|
|
|
|
// FCM에서 반환하는 무효 토큰 에러 코드들
|
|
$invalidTokenErrors = [
|
|
'UNREGISTERED',
|
|
'INVALID_ARGUMENT',
|
|
'NOT_FOUND',
|
|
];
|
|
|
|
return in_array($this->getErrorCode(), $invalidTokenErrors, true);
|
|
}
|
|
|
|
/**
|
|
* 배열로 변환
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'success' => $this->success,
|
|
'message_id' => $this->messageId,
|
|
'error' => $this->error,
|
|
'status_code' => $this->statusCode,
|
|
];
|
|
}
|
|
}
|