- 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>
436 lines
13 KiB
PHP
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);
|
|
}
|
|
}
|