Files
sam-manage/app/Http/Controllers/Api/Admin/Barobill/BarobillKakaotalkController.php
김보곤 d69f4ef5d3 feat:바로빌 카카오톡(알림톡/친구톡) 서비스 구현
- BarobillService에 KAKAOTALK SOAP 클라이언트 추가
  - 채널/템플릿 관리, 알림톡/친구톡 발송, 전송조회/예약취소 API
- BarobillKakaotalkController (API) 생성: 15개 엔드포인트
- KakaotalkController (페이지) 생성: 5개 페이지
- 라우트 등록 (web.php, api.php)
- Blade 뷰 5개 생성: 대시보드, 채널관리, 템플릿관리, 발송, 전송내역

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 14:11:15 +09:00

436 lines
13 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Admin\Barobill;
use App\Http\Controllers\Controller;
use App\Models\Barobill\BarobillMember;
use App\Services\Barobill\BarobillService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class BarobillKakaotalkController extends Controller
{
public function __construct(
protected BarobillService $barobillService
) {}
/**
* 회원사 조회 및 서버 모드 전환 헬퍼
*/
private function resolveMember(): BarobillMember|JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$member = BarobillMember::where('tenant_id', $tenantId)->first();
if (!$member) {
return response()->json([
'success' => false,
'message' => '바로빌 회원사가 등록되어 있지 않습니다.',
], 404);
}
$this->barobillService->setServerMode($member->server_mode ?? 'test');
return $member;
}
// ==========================================
// 채널 관리
// ==========================================
/**
* 카카오톡 채널 목록 조회
*/
public function getChannels(): JsonResponse
{
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->getKakaotalkChannels($member->biz_no);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
/**
* 카카오톡 채널 관리 URL 조회
*/
public function getChannelManagementUrl(): JsonResponse
{
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->getKakaotalkChannelManagementUrl(
$member->biz_no,
$member->barobill_id
);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
// ==========================================
// 템플릿 관리
// ==========================================
/**
* 카카오톡 템플릿 목록 조회
*/
public function getTemplates(Request $request): JsonResponse
{
$request->validate([
'channel_id' => 'required|string',
]);
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->getKakaotalkTemplates(
$member->biz_no,
$request->input('channel_id')
);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
/**
* 카카오톡 템플릿 관리 URL 조회
*/
public function getTemplateManagementUrl(): JsonResponse
{
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->getKakaotalkTemplateManagementUrl(
$member->biz_no,
$member->barobill_id
);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
// ==========================================
// 알림톡 발송
// ==========================================
/**
* 알림톡 단건 발송
*/
public function sendAlimtalk(Request $request): JsonResponse
{
$validated = $request->validate([
'sender_id' => 'required|string',
'template_name' => 'required|string',
'receiver_name' => 'required|string',
'receiver_num' => 'required|string',
'title' => 'nullable|string',
'message' => 'required|string',
'buttons' => 'nullable|array',
'buttons.*.Name' => 'required_with:buttons|string',
'buttons.*.ButtonType' => 'required_with:buttons|string',
'buttons.*.Url1' => 'nullable|string',
'buttons.*.Url2' => 'nullable|string',
'sms_message' => 'nullable|string',
'sms_subject' => 'nullable|string',
'reserve_dt' => 'nullable|string',
]);
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$buttons = $validated['buttons'] ?? [];
// 버튼이 있으면 Ex 버전 사용
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'] ?? ''
);
} 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'] ?? ''
);
}
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
/**
* 알림톡 대량 발송
*/
public function sendAlimtalkBulk(Request $request): JsonResponse
{
$validated = $request->validate([
'sender_id' => 'required|string',
'template_name' => 'required|string',
'messages' => 'required|array|min:1',
'messages.*.ReceiverName' => 'required|string',
'messages.*.ReceiverNum' => 'required|string',
'messages.*.Title' => 'nullable|string',
'messages.*.Message' => 'required|string',
'messages.*.SmsMessage' => 'nullable|string',
'messages.*.SmsSubject' => 'nullable|string',
'reserve_dt' => 'nullable|string',
]);
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->sendATKakaotalks(
$member->biz_no,
$validated['sender_id'],
$validated['template_name'],
$validated['messages'],
$validated['reserve_dt'] ?? ''
);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
// ==========================================
// 친구톡 발송
// ==========================================
/**
* 친구톡 텍스트 발송
*/
public function sendFriendtalk(Request $request): JsonResponse
{
$validated = $request->validate([
'sender_id' => 'required|string',
'channel_id' => 'required|string',
'receiver_name' => 'required|string',
'receiver_num' => 'required|string',
'message' => 'required|string',
'buttons' => 'nullable|array',
'buttons.*.Name' => 'required_with:buttons|string',
'buttons.*.ButtonType' => 'required_with:buttons|string',
'buttons.*.Url1' => 'nullable|string',
'buttons.*.Url2' => 'nullable|string',
'sms_message' => 'nullable|string',
'sms_subject' => 'nullable|string',
'ad_yn' => 'nullable|boolean',
'reserve_dt' => 'nullable|string',
]);
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->sendFTKakaotalk(
$member->biz_no,
$validated['sender_id'],
$validated['channel_id'],
$validated['receiver_name'],
$validated['receiver_num'],
$validated['message'],
$validated['buttons'] ?? [],
$validated['sms_message'] ?? '',
$validated['sms_subject'] ?? '',
$validated['ad_yn'] ?? false,
$validated['reserve_dt'] ?? ''
);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
/**
* 친구톡 이미지 발송
*/
public function sendFriendtalkImage(Request $request): JsonResponse
{
$validated = $request->validate([
'sender_id' => 'required|string',
'channel_id' => 'required|string',
'receiver_name' => 'required|string',
'receiver_num' => 'required|string',
'message' => 'required|string',
'image_url' => 'required|string|url',
'buttons' => 'nullable|array',
'sms_message' => 'nullable|string',
'sms_subject' => 'nullable|string',
'ad_yn' => 'nullable|boolean',
'reserve_dt' => 'nullable|string',
]);
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->sendFIKakaotalk(
$member->biz_no,
$validated['sender_id'],
$validated['channel_id'],
$validated['receiver_name'],
$validated['receiver_num'],
$validated['message'],
$validated['image_url'],
$validated['buttons'] ?? [],
$validated['sms_message'] ?? '',
$validated['sms_subject'] ?? '',
$validated['ad_yn'] ?? false,
$validated['reserve_dt'] ?? ''
);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
/**
* 친구톡 와이드 이미지 발송
*/
public function sendFriendtalkWide(Request $request): JsonResponse
{
$validated = $request->validate([
'sender_id' => 'required|string',
'channel_id' => 'required|string',
'receiver_name' => 'required|string',
'receiver_num' => 'required|string',
'message' => 'required|string',
'image_url' => 'required|string|url',
'buttons' => 'nullable|array',
'sms_message' => 'nullable|string',
'sms_subject' => 'nullable|string',
'ad_yn' => 'nullable|boolean',
'reserve_dt' => 'nullable|string',
]);
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->sendFWKakaotalk(
$member->biz_no,
$validated['sender_id'],
$validated['channel_id'],
$validated['receiver_name'],
$validated['receiver_num'],
$validated['message'],
$validated['image_url'],
$validated['buttons'] ?? [],
$validated['sms_message'] ?? '',
$validated['sms_subject'] ?? '',
$validated['ad_yn'] ?? false,
$validated['reserve_dt'] ?? ''
);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
// ==========================================
// 전송 결과 조회
// ==========================================
/**
* 전송 결과 조회 (단건)
*/
public function getSendResult(string $sendKey): JsonResponse
{
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->getSendKakaotalk($member->biz_no, $sendKey);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
/**
* 전송 결과 조회 (다건)
*/
public function getSendResults(Request $request): JsonResponse
{
$validated = $request->validate([
'send_keys' => 'required|array|min:1',
'send_keys.*' => 'required|string',
]);
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->getSendKakaotalks(
$member->biz_no,
$validated['send_keys']
);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
// ==========================================
// 예약 취소
// ==========================================
/**
* 예약 전송 취소
*/
public function cancelReserved(string $sendKey): JsonResponse
{
$member = $this->resolveMember();
if ($member instanceof JsonResponse) return $member;
$result = $this->barobillService->cancelReservedKakaotalk($member->biz_no, $sendKey);
if (!$result['success']) {
return response()->json($result, 422);
}
return response()->json($result);
}
}