diff --git a/app/Http/Controllers/Api/Admin/Barobill/BarobillKakaotalkController.php b/app/Http/Controllers/Api/Admin/Barobill/BarobillKakaotalkController.php index 6b2216ec..dae9a3cf 100644 --- a/app/Http/Controllers/Api/Admin/Barobill/BarobillKakaotalkController.php +++ b/app/Http/Controllers/Api/Admin/Barobill/BarobillKakaotalkController.php @@ -7,7 +7,6 @@ use App\Services\Barobill\BarobillService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Log; class BarobillKakaotalkController extends Controller { @@ -23,7 +22,7 @@ private function resolveMember(): BarobillMember|JsonResponse $tenantId = session('selected_tenant_id', 1); $member = BarobillMember::where('tenant_id', $tenantId)->first(); - if (!$member) { + if (! $member) { return response()->json([ 'success' => false, 'message' => '바로빌 회원사가 등록되어 있지 않습니다.', @@ -45,11 +44,13 @@ private function resolveMember(): BarobillMember|JsonResponse public function getChannels(): JsonResponse { $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->getKakaotalkChannels($member->biz_no); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -62,14 +63,16 @@ public function getChannels(): JsonResponse public function getChannelManagementUrl(): JsonResponse { $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->getKakaotalkChannelManagementUrl( $member->biz_no, $member->barobill_id ); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -90,14 +93,16 @@ public function getTemplates(Request $request): JsonResponse ]); $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->getKakaotalkTemplates( $member->biz_no, $request->input('channel_id') ); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -110,14 +115,16 @@ public function getTemplates(Request $request): JsonResponse public function getTemplateManagementUrl(): JsonResponse { $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->getKakaotalkTemplateManagementUrl( $member->biz_no, $member->barobill_id ); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -151,41 +158,48 @@ public function sendAlimtalk(Request $request): JsonResponse ]); $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $buttons = $validated['buttons'] ?? []; + // sender_id 폼 필드는 채널 ID (예: @codebridge-x) + // SenderID는 바로빌 계정 ID, YellowId는 카카오톡 채널 ID + $yellowId = $validated['sender_id']; // 버튼이 있으면 Ex 버전 사용 - if (!empty($buttons)) { + if (! empty($buttons)) { $result = $this->barobillService->sendATKakaotalkEx( - $member->biz_no, - $validated['sender_id'], - $validated['template_name'], - $validated['receiver_name'], - $validated['receiver_num'], - $validated['title'] ?? '', - $validated['message'], - $buttons, - $validated['sms_message'] ?? '', - $validated['sms_subject'] ?? '', - $validated['reserve_dt'] ?? '' + corpNum: $member->biz_no, + senderId: $member->barobill_id, + yellowId: $yellowId, + templateName: $validated['template_name'], + receiverName: $validated['receiver_name'], + receiverNum: $validated['receiver_num'], + title: $validated['title'] ?? '', + message: $validated['message'], + buttons: $buttons, + smsMessage: $validated['sms_message'] ?? '', + smsSubject: $validated['sms_subject'] ?? '', + reserveDT: $validated['reserve_dt'] ?? '' ); } else { $result = $this->barobillService->sendATKakaotalk( - $member->biz_no, - $validated['sender_id'], - $validated['template_name'], - $validated['receiver_name'], - $validated['receiver_num'], - $validated['title'] ?? '', - $validated['message'], - $validated['sms_message'] ?? '', - $validated['sms_subject'] ?? '', - $validated['reserve_dt'] ?? '' + corpNum: $member->biz_no, + senderId: $member->barobill_id, + yellowId: $yellowId, + templateName: $validated['template_name'], + receiverName: $validated['receiver_name'], + receiverNum: $validated['receiver_num'], + title: $validated['title'] ?? '', + message: $validated['message'], + smsMessage: $validated['sms_message'] ?? '', + smsSubject: $validated['sms_subject'] ?? '', + reserveDT: $validated['reserve_dt'] ?? '' ); } - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -211,17 +225,20 @@ public function sendAlimtalkBulk(Request $request): JsonResponse ]); $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->sendATKakaotalks( - $member->biz_no, - $validated['sender_id'], - $validated['template_name'], - $validated['messages'], - $validated['reserve_dt'] ?? '' + corpNum: $member->biz_no, + senderId: $member->barobill_id, + yellowId: $validated['sender_id'], + templateName: $validated['template_name'], + messages: $validated['messages'], + reserveDT: $validated['reserve_dt'] ?? '' ); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -255,7 +272,9 @@ public function sendFriendtalk(Request $request): JsonResponse ]); $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->sendFTKakaotalk( $member->biz_no, @@ -271,7 +290,7 @@ public function sendFriendtalk(Request $request): JsonResponse $validated['reserve_dt'] ?? '' ); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -298,7 +317,9 @@ public function sendFriendtalkImage(Request $request): JsonResponse ]); $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->sendFIKakaotalk( $member->biz_no, @@ -315,7 +336,7 @@ public function sendFriendtalkImage(Request $request): JsonResponse $validated['reserve_dt'] ?? '' ); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -342,7 +363,9 @@ public function sendFriendtalkWide(Request $request): JsonResponse ]); $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->sendFWKakaotalk( $member->biz_no, @@ -359,7 +382,7 @@ public function sendFriendtalkWide(Request $request): JsonResponse $validated['reserve_dt'] ?? '' ); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -376,11 +399,13 @@ public function sendFriendtalkWide(Request $request): JsonResponse public function getSendResult(string $sendKey): JsonResponse { $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->getSendKakaotalk($member->biz_no, $sendKey); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -398,14 +423,16 @@ public function getSendResults(Request $request): JsonResponse ]); $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->getSendKakaotalks( $member->biz_no, $validated['send_keys'] ); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } @@ -422,11 +449,13 @@ public function getSendResults(Request $request): JsonResponse public function cancelReserved(string $sendKey): JsonResponse { $member = $this->resolveMember(); - if ($member instanceof JsonResponse) return $member; + if ($member instanceof JsonResponse) { + return $member; + } $result = $this->barobillService->cancelReservedKakaotalk($member->biz_no, $sendKey); - if (!$result['success']) { + if (! $result['success']) { return response()->json($result, 422); } diff --git a/app/Http/Controllers/ESign/EsignApiController.php b/app/Http/Controllers/ESign/EsignApiController.php index fc334a8e..0c84814e 100644 --- a/app/Http/Controllers/ESign/EsignApiController.php +++ b/app/Http/Controllers/ESign/EsignApiController.php @@ -970,9 +970,9 @@ private function sendAlimtalk( $barobill = app(BarobillService::class); $barobill->setServerMode($member->server_mode ?? 'production'); - // 카카오톡 채널 목록에서 발신프로필 키(SenderID) 조회 - $senderId = $this->getKakaotalkSenderId($barobill, $member->biz_no); - if (! $senderId) { + // 카카오톡 채널 ID 조회 (YellowId로 사용) + $channelId = $this->getKakaotalkChannelId($barobill, $member->biz_no); + if (! $channelId) { return ['success' => false, 'channel' => 'alimtalk', 'error' => '등록된 카카오톡 채널이 없습니다']; } @@ -981,10 +981,21 @@ private function sendAlimtalk( $templateName = $isReminder ? '전자계약_리마인드' : '전자계약_서명요청'; - // 등록된 템플릿 본문과 정확히 일치해야 함 (변수만 치환) - $message = $isReminder - ? "안녕하세요, {$signer->name}님.\n아직 서명이 완료되지 않은 전자계약이 있습니다.\n\n ■ 계약명: {$contract->title}\n ■ 서명 기한: {$expires}\n\n 기한 내에 서명을 완료해 주세요." - : " 안녕하세요, {$signer->name}님. \n 전자계약 서명 요청이 도착했습니다.\n\n ■ 계약명: {$contract->title}\n ■ 서명 기한: {$expires}\n\n 아래 버튼을 눌러 계약서를 확인하고 서명해 주세요."; + // 등록된 템플릿 본문을 가져와서 변수 치환 (정확한 포맷 유지) + $templateContent = $this->getTemplateContent($barobill, $member->biz_no, $channelId, $templateName); + + if ($templateContent) { + $message = str_replace( + ['#{이름}', '#{계약명}', '#{기한}'], + [$signer->name, $contract->title, $expires], + $templateContent + ); + } else { + // 템플릿 조회 실패 시 하드코딩 폴백 + $message = $isReminder + ? "안녕하세요, {$signer->name}님.\n아직 서명이 완료되지 않은 전자계약이 있습니다.\n\n ■ 계약명: {$contract->title}\n ■ 서명 기한: {$expires}\n\n 기한 내에 서명을 완료해 주세요." + : " 안녕하세요, {$signer->name}님. \n 전자계약 서명 요청이 도착했습니다.\n\n ■ 계약명: {$contract->title}\n ■ 서명 기한: {$expires}\n\n 아래 버튼을 눌러 계약서를 확인하고 서명해 주세요."; + } $smsMessage = $smsFallback ? "[SAM] {$signer->name}님, 전자계약 서명 요청이 도착했습니다. {$signUrl}" @@ -992,15 +1003,16 @@ private function sendAlimtalk( $result = $barobill->sendATKakaotalkEx( corpNum: $member->biz_no, - senderId: $senderId, + senderId: $member->barobill_id, + yellowId: $channelId, templateName: $templateName, receiverName: $signer->name, receiverNum: preg_replace('/[^0-9]/', '', $signer->phone), - title: $isReminder ? '전자계약 리마인드' : '전자계약 서명 요청', + title: '', message: $message, buttons: [ [ - 'Name' => $isReminder ? '서명하기' : '계약서 확인하기', + 'Name' => '계약서 확인하기', 'ButtonType' => 'WL', 'Url1' => $signUrl, 'Url2' => $signUrl, @@ -1032,9 +1044,9 @@ private function sendAlimtalk( } /** - * 바로빌 카카오톡 채널 목록에서 발신프로필 키(ChannelId) 조회 + * 바로빌 카카오톡 채널 ID 조회 (YellowId로 사용) */ - private function getKakaotalkSenderId(BarobillService $barobill, string $bizNo): ?string + private function getKakaotalkChannelId(BarobillService $barobill, string $bizNo): ?string { $result = $barobill->getKakaotalkChannels($bizNo); @@ -1044,10 +1056,7 @@ private function getKakaotalkSenderId(BarobillService $barobill, string $bizNo): $data = $result['data']; - // 바로빌 응답 형식에 따라 채널 목록 파싱 - if (is_array($data) && isset($data[0])) { - $channels = $data; - } elseif (is_object($data) && isset($data->KakaotalkChannel)) { + if (is_object($data) && isset($data->KakaotalkChannel)) { $channels = is_array($data->KakaotalkChannel) ? $data->KakaotalkChannel : [$data->KakaotalkChannel]; @@ -1056,7 +1065,7 @@ private function getKakaotalkSenderId(BarobillService $barobill, string $bizNo): ? $data['KakaotalkChannel'] : [$data['KakaotalkChannel']]; } else { - $channels = [$data]; + $channels = is_array($data) ? $data : [$data]; } $channel = $channels[0] ?? null; @@ -1070,6 +1079,35 @@ private function getKakaotalkSenderId(BarobillService $barobill, string $bizNo): : ($channel->ChannelId ?? null); } + /** + * 바로빌 등록 템플릿의 본문 내용 조회 + */ + private function getTemplateContent(BarobillService $barobill, string $bizNo, string $channelId, string $templateName): ?string + { + $result = $barobill->getKakaotalkTemplates($bizNo, $channelId); + + if (! ($result['success'] ?? false) || empty($result['data'])) { + return null; + } + + $data = $result['data']; + $items = []; + + if (is_object($data) && isset($data->KakaotalkTemplate)) { + $items = is_array($data->KakaotalkTemplate) + ? $data->KakaotalkTemplate + : [$data->KakaotalkTemplate]; + } + + foreach ($items as $tpl) { + if (($tpl->TemplateName ?? '') === $templateName) { + return $tpl->TemplateContent ?? null; + } + } + + return null; + } + /** * PDF 다운로드 */ diff --git a/app/Http/Controllers/ESign/EsignPublicController.php b/app/Http/Controllers/ESign/EsignPublicController.php index e874f2f7..eb5a35a4 100644 --- a/app/Http/Controllers/ESign/EsignPublicController.php +++ b/app/Http/Controllers/ESign/EsignPublicController.php @@ -387,17 +387,51 @@ public function submitSignature(Request $request, string $token): JsonResponse $member = BarobillMember::where('tenant_id', $contract->tenant_id)->first(); if ($member) { $barobill = app(BarobillService::class); - $barobill->setServerMode($member->is_test_mode ? 'test' : 'production'); + $barobill->setServerMode($member->server_mode ?? 'production'); $nextSignUrl = config('app.url').'/esign/sign/'.$nextSigner->access_token; $nextExpires = $contract->expires_at?->format('Y-m-d H:i') ?? '없음'; + + // 채널 ID 조회 + $channelResult = $barobill->getKakaotalkChannels($member->biz_no); + $yellowId = ''; + if ($channelResult['success'] ?? false) { + $chData = $channelResult['data']; + if (is_object($chData) && isset($chData->KakaotalkChannel)) { + $ch = is_array($chData->KakaotalkChannel) ? $chData->KakaotalkChannel[0] : $chData->KakaotalkChannel; + $yellowId = $ch->ChannelId ?? ''; + } + } + + // 템플릿 본문 조회하여 변수 치환 + $tplResult = $barobill->getKakaotalkTemplates($member->biz_no, $yellowId); + $tplMessage = null; + if ($tplResult['success'] ?? false) { + $tplData = $tplResult['data']; + $tplItems = []; + if (is_object($tplData) && isset($tplData->KakaotalkTemplate)) { + $tplItems = is_array($tplData->KakaotalkTemplate) ? $tplData->KakaotalkTemplate : [$tplData->KakaotalkTemplate]; + } + foreach ($tplItems as $t) { + if (($t->TemplateName ?? '') === '전자계약_서명요청') { + $tplMessage = str_replace( + ['#{이름}', '#{계약명}', '#{기한}'], + [$nextSigner->name, $contract->title, $nextExpires], + $t->TemplateContent + ); + break; + } + } + } + $atResult = $barobill->sendATKakaotalkEx( - corpNum: $member->corp_num, - senderId: $member->kakaotalk_sender_id ?? '', + corpNum: $member->biz_no, + senderId: $member->barobill_id, + yellowId: $yellowId, templateName: '전자계약_서명요청', receiverName: $nextSigner->name, receiverNum: preg_replace('/[^0-9]/', '', $nextSigner->phone), - title: '전자계약 서명 요청', - message: "안녕하세요, {$nextSigner->name}님.\n전자계약 서명 요청이 도착했습니다.\n\n■ 계약명: {$contract->title}\n■ 서명 기한: {$nextExpires}\n\n아래 버튼을 눌러 계약서를 확인하고 서명해 주세요.", + title: '', + message: $tplMessage ?? "안녕하세요, {$nextSigner->name}님.\n전자계약 서명 요청이 도착했습니다.\n\n■ 계약명: {$contract->title}\n■ 서명 기한: {$nextExpires}\n\n아래 버튼을 눌러 계약서를 확인하고 서명해 주세요.", buttons: [['Name' => '계약서 확인하기', 'ButtonType' => 'WL', 'Url1' => $nextSignUrl, 'Url2' => $nextSignUrl]], smsMessage: $nextSmsFallback ? "[SAM] {$nextSigner->name}님, 전자계약 서명 요청이 도착했습니다. {$nextSignUrl}" : '', ); @@ -536,18 +570,30 @@ private function sendCompletionAlimtalk(EsignContract $contract, EsignSigner $si } $barobill = app(BarobillService::class); - $barobill->setServerMode($member->is_test_mode ? 'test' : 'production'); + $barobill->setServerMode($member->server_mode ?? 'production'); + + // 채널 ID 조회 + $channelResult = $barobill->getKakaotalkChannels($member->biz_no); + $yellowId = ''; + if ($channelResult['success'] ?? false) { + $chData = $channelResult['data']; + if (is_object($chData) && isset($chData->KakaotalkChannel)) { + $ch = is_array($chData->KakaotalkChannel) ? $chData->KakaotalkChannel[0] : $chData->KakaotalkChannel; + $yellowId = $ch->ChannelId ?? ''; + } + } $signUrl = config('app.url').'/esign/sign/'.$signer->access_token; $completedAt = $contract->completed_at?->format('Y-m-d H:i') ?? now()->format('Y-m-d H:i'); $result = $barobill->sendATKakaotalkEx( - corpNum: $member->corp_num, - senderId: $member->kakaotalk_sender_id ?? '', + corpNum: $member->biz_no, + senderId: $member->barobill_id, + yellowId: $yellowId, templateName: '전자계약_완료', receiverName: $signer->name, receiverNum: preg_replace('/[^0-9]/', '', $signer->phone), - title: '전자계약 완료', + title: '', message: "안녕하세요, {$signer->name}님.\n전자계약이 모든 서명자의 서명 완료로 확정되었습니다.\n\n■ 계약명: {$contract->title}\n■ 완료일: {$completedAt}\n\n아래 버튼에서 서명 완료된 계약서를 확인할 수 있습니다.", buttons: [ [ diff --git a/app/Services/Barobill/BarobillService.php b/app/Services/Barobill/BarobillService.php index a1f5b171..dabfc9cf 100644 --- a/app/Services/Barobill/BarobillService.php +++ b/app/Services/Barobill/BarobillService.php @@ -1277,7 +1277,8 @@ public function getKakaotalkTemplateManagementUrl(string $corpNum, string $id): * 알림톡 단건 발송 * * @param string $corpNum 회원사 사업자번호 - * @param string $senderId 발신프로필 키 (채널 ID) + * @param string $senderId 바로빌 계정 ID + * @param string $yellowId 카카오톡 채널 ID (예: @codebridge-x) * @param string $templateName 템플릿 이름 * @param string $receiverName 수신자 이름 * @param string $receiverNum 수신자 전화번호 @@ -1285,11 +1286,13 @@ public function getKakaotalkTemplateManagementUrl(string $corpNum, string $id): * @param string $message 알림톡 본문 * @param string $smsMessage SMS 대체발송 메시지 (빈 값이면 대체발송 안 함) * @param string $smsSubject SMS 대체발송 제목 + * @param string $smsSenderNum SMS 발신번호 * @param string $reserveDT 예약일시 (YYYYMMDDHHmmss, 빈 값이면 즉시발송) */ public function sendATKakaotalk( string $corpNum, string $senderId, + string $yellowId, string $templateName, string $receiverName, string $receiverNum, @@ -1297,15 +1300,17 @@ public function sendATKakaotalk( string $message, string $smsMessage = '', string $smsSubject = '', + string $smsSenderNum = '', string $reserveDT = '' ): array { $params = [ 'CorpNum' => $this->formatBizNo($corpNum), 'SenderID' => $senderId, + 'YellowId' => $yellowId, 'TemplateName' => $templateName, 'SendDT' => $reserveDT, - 'SmsReply' => '', - 'SmsSenderNum' => '', + 'SmsReply' => empty($smsMessage) ? 'N' : 'S', + 'SmsSenderNum' => $smsSenderNum, 'KakaotalkMessage' => [ 'ReceiverName' => $receiverName, 'ReceiverNum' => $receiverNum, @@ -1323,7 +1328,8 @@ public function sendATKakaotalk( * 알림톡 단건 발송 (버튼 포함) * * @param string $corpNum 회원사 사업자번호 - * @param string $senderId 발신프로필 키 + * @param string $senderId 바로빌 계정 ID + * @param string $yellowId 카카오톡 채널 ID (예: @codebridge-x) * @param string $templateName 템플릿 이름 * @param string $receiverName 수신자 이름 * @param string $receiverNum 수신자 전화번호 @@ -1332,11 +1338,13 @@ public function sendATKakaotalk( * @param array $buttons 버튼 배열 [{Name, ButtonType, Url1, Url2}] * @param string $smsMessage SMS 대체발송 메시지 * @param string $smsSubject SMS 대체발송 제목 + * @param string $smsSenderNum SMS 발신번호 * @param string $reserveDT 예약일시 */ public function sendATKakaotalkEx( string $corpNum, string $senderId, + string $yellowId, string $templateName, string $receiverName, string $receiverNum, @@ -1345,6 +1353,7 @@ public function sendATKakaotalkEx( array $buttons = [], string $smsMessage = '', string $smsSubject = '', + string $smsSenderNum = '', string $reserveDT = '' ): array { $kakaotalkMessage = [ @@ -1363,11 +1372,11 @@ public function sendATKakaotalkEx( $params = [ 'CorpNum' => $this->formatBizNo($corpNum), 'SenderID' => $senderId, - 'YellowId' => '', + 'YellowId' => $yellowId, 'TemplateName' => $templateName, 'SendDT' => $reserveDT, - 'SmsReply' => '', - 'SmsSenderNum' => '', + 'SmsReply' => empty($smsMessage) ? 'N' : 'S', + 'SmsSenderNum' => $smsSenderNum, 'KakaotalkMessage' => $kakaotalkMessage, ]; @@ -1378,7 +1387,8 @@ public function sendATKakaotalkEx( * 알림톡 대량 발송 * * @param string $corpNum 회원사 사업자번호 - * @param string $senderId 발신프로필 키 + * @param string $senderId 바로빌 계정 ID + * @param string $yellowId 카카오톡 채널 ID (예: @codebridge-x) * @param string $templateName 템플릿 이름 * @param array $messages 메시지 배열 [{ReceiverName, ReceiverNum, Title, Message, SmsMessage, SmsSubject}] * @param string $reserveDT 예약일시 @@ -1386,6 +1396,7 @@ public function sendATKakaotalkEx( public function sendATKakaotalks( string $corpNum, string $senderId, + string $yellowId, string $templateName, array $messages, string $reserveDT = '' @@ -1393,9 +1404,10 @@ public function sendATKakaotalks( $params = [ 'CorpNum' => $this->formatBizNo($corpNum), 'SenderID' => $senderId, + 'YellowId' => $yellowId, 'TemplateName' => $templateName, 'SendDT' => $reserveDT, - 'SmsReply' => '', + 'SmsReply' => 'N', 'SmsSenderNum' => '', 'KakaotalkMessages' => ['KakaotalkATMessage' => $messages], ];