카카오 알림톡 보내기 — PHP · Node.js · Python · Java · Go 예제
승인된 템플릿 코드로 카카오 알림톡을 발송하는 코드. Laravel, Node.js, Python, PHP, Java, Go, Ruby, .NET 예제와 필수 파라미터, 실패 원인을 정리했습니다.
POST /api/v2/notices/send알림톡은 승인된 템플릿에 변수를 채워 보내는 방식입니다. 본문을 코드에서 만드는 게 아니라, 이미 심사를 통과한 문안의 빈칸만 채웁니다.
[#{var2}] 주문이 확인되었습니다.
주문번호: #{var1}
결제금액: #{var3}
이 템플릿이 ORDER_CONFIRM_001 로 승인돼 있다면, 코드는 var1, var2, var3 만 넘기면 됩니다.
준비물
- 승인 완료된 템플릿 코드 → 알림톡 템플릿 등록과 심사 통과
- 카카오 발신프로필 키(
kakaoSenderKey) → 발신번호 사전등록 - 액세스 키 / 시크릿 키
필수 파라미터
POST /api/v2/notices/send
| 파라미터 | 필수 | 설명 |
|---|---|---|
templateCode |
✅ | 승인된 템플릿 코드 |
contacts |
✅ | 수신자 배열. 비어 있으면 EMPTY_CONTACTS |
contacts[].contact |
✅ | 수신 번호. 하이픈 없이 숫자만 (01012345678) |
contacts[].name |
수신자 이름 | |
contacts[].var1~var8 |
템플릿 변수 | |
kakaoSenderKey |
✅ | 카카오 발신프로필 키 (클라이언트에 넣어두면 생략 가능) |
senderKey |
문자 발신번호 키. SMS 대체 발송을 켤 때 필요 | |
scheduleType |
DIRECTLY(기본) 또는 SCHEDULED |
|
at |
예약 시각 Y-m-d H:i:s. scheduleType: SCHEDULED 일 때 |
|
replaceSms |
Y 면 실패 시 SMS 대체 발송 |
|
smsSubject / smsContent |
대체 발송 본문. replaceSms: Y 면 필수 |
언어별 예제
Node.js / TypeScript
import Sendgo from '@sendgo/node';
const sendgo = new Sendgo({
accessKey: process.env.SENDGO_ACCESS_KEY!,
secretKey: process.env.SENDGO_SECRET_KEY!,
kakaoSenderKey: process.env.SENDGO_KAKAO_SENDER_KEY,
smsSenderKey: process.env.SENDGO_SMS_SENDER_KEY,
apiVersion: 'v2',
});
await sendgo.alimtalk.send({
templateCode: 'ORDER_CONFIRM_001',
contacts: [{
contact: '01012345678',
name: '홍길동',
var1: 'ORD-001',
var2: '맥북 프로',
var3: '3,490,000원',
}],
});
Python
from sendgo import Sendgo
client = Sendgo(
access_key=os.environ["SENDGO_ACCESS_KEY"],
secret_key=os.environ["SENDGO_SECRET_KEY"],
kakao_sender_key=os.environ.get("SENDGO_KAKAO_SENDER_KEY"),
sms_sender_key=os.environ.get("SENDGO_SMS_SENDER_KEY"),
api_version="v2",
)
client.alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[
{"contact": "01012345678", "name": "홍길동", "var1": "ORD-001", "var2": "맥북 프로"}
],
)
Django 라면 sendgo-django, FastAPI 라면 sendgo-fastapi 를 쓰면 설정과 주입이 붙어 있습니다.
PHP
<?php
use Sendgo\Php\Sendgo;
$sendgo = new Sendgo([
'access_key' => $_ENV['SENDGO_ACCESS_KEY'],
'secret_key' => $_ENV['SENDGO_SECRET_KEY'],
'kakao_sender_key' => $_ENV['SENDGO_KAKAO_SENDER_KEY'],
'sms_sender_key' => $_ENV['SENDGO_SMS_SENDER_KEY'],
'api_version' => 'v2',
]);
$sendgo->alimtalk->send([
'templateCode' => 'ORDER_CONFIRM_001',
'contacts' => [
['contact' => '01012345678', 'name' => '홍길동', 'var1' => 'ORD-001', 'var2' => '29,000원'],
],
]);
Laravel
<?php
namespace App\Services;
use Sendgo\Php\Sendgo;
use Sendgo\Php\Exception\SendgoException;
use Illuminate\Support\Facades\Log;
class OrderNotifier
{
public function __construct(private Sendgo $sendgo) {}
public function confirmed(Order $order): void
{
try {
$this->sendgo->alimtalk->send([
'templateCode' => 'ORDER_CONFIRM_001',
'contacts' => [[
'contact' => $order->user->phone,
'name' => $order->user->name,
'var1' => $order->number,
'var2' => $order->items->first()->name,
'var3' => number_format($order->total).'원',
]],
]);
} catch (SendgoException $e) {
// 발송 실패가 주문 처리를 막지 않도록 로깅만 하고 넘어간다.
Log::error('알림톡 발송 실패', ['order' => $order->id, 'message' => $e->getMessage()]);
}
}
}
발송은 큐에 넣는 편이 낫습니다. 외부 API 호출이 HTTP 응답 시간에 들어가면 카카오 쪽이 느릴 때 사용자 요청까지 함께 느려집니다.
Java / Spring Boot
import io.sendgo.*;
import io.sendgo.model.*;
import java.util.List;
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("ORDER_CONFIRM_001")
.contacts(List.of(
Contact.builder()
.contact("01012345678")
.name("홍길동")
.var1("ORD-001")
.var2("29,000원")
.build()
))
.build());
Go
result, err := client.Alimtalk.Send(sendgo.AlimtalkRequest{
TemplateCode: "ORDER_CONFIRM_001",
Contacts: []sendgo.Contact{
{Contact: "01012345678", Name: "홍길동", Var1: "ORD-001", Var2: "29,000원"},
},
})
if err != nil {
log.Printf("알림톡 발송 실패: %v", err)
}
Ruby
client.alimtalk.send(
template_code: 'ORDER_CONFIRM_001',
contacts: [
{ contact: '01012345678', name: '홍길동', var1: 'ORD-001', var2: '29,000원' }
]
)
C# / .NET
await client.SendAlimtalkAsync(new AlimtalkRequest
{
TemplateCode = "ORDER_CONFIRM_001",
Contacts =
[
new Contact { PhoneNumber = "01012345678", Name = "홍길동", Var1 = "ORD-001" }
],
});
REST 직접 호출
curl -X POST https://sendgo.io/api/v2/notices/send \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"templateCode": "ORDER_CONFIRM_001",
"scheduleType": "DIRECTLY",
"replaceSms": "N",
"kakaoSenderKey": "your_kakao_sender_key",
"senderKey": "your_sms_sender_key",
"contacts": [
{ "contact": "01012345678", "name": "홍길동", "var1": "ORD-001" }
]
}'
발송이 실패하는 이유
| 오류 코드 | 원인 | 재시도로 해결되나 |
|---|---|---|
INVALID_TEMPLATE_CODE |
없는 코드이거나 아직 승인되지 않음 | ❌ |
INVALID_KAKAO_SENDER_KEY |
발신프로필 키가 틀림 | ❌ |
EMPTY_CONTACTS |
수신자 배열이 비어 있음 | ❌ |
PAYMENT_REQUIRED |
크레딧 부족 | ❌ (충전 필요) |
ACCESS_KEY_NOT_APPROVED |
앱 미승인 | ❌ |
IP_NOT_ALLOWED |
허용 IP 밖 | ❌ |
| 네트워크 타임아웃 | 일시적 | ✅ |
거의 모든 실패는 재시도해도 똑같이 실패합니다. 무한 재시도 대신 로깅하고 넘어가세요. 자세한 전략은 오류 코드와 재시도 전략에 있습니다.
놓치기 쉬운 것
- 전화번호에 하이픈을 넣지 마세요.
010-1234-5678이 아니라01012345678입니다. - 템플릿 변수를 빠뜨리면 치환되지 않은 채 발송됩니다. 템플릿에
#{var4}가 있는데var4를 안 넘기면 수신자가 그 문자열을 그대로 봅니다. - 광고 문구는 알림톡으로 나가지 않습니다. 정보성만 승인됩니다. 홍보는 브랜드메시지입니다.
- 클라이언트를 요청마다 새로 만들지 마세요. 캐시된 토큰이 버려집니다.
다음 단계
자주 묻는 질문
- 알림톡 본문을 코드에서 직접 작성할 수 있나요?
- 없습니다. 알림톡은 카카오 심사를 통과한 템플릿에만 발송됩니다. 코드가 하는 일은 templateCode 를 지정하고 그 템플릿의 변수(var1~var8)를 채우는 것뿐입니다. 자유 본문이 필요하면 LMS 나 브랜드메시지를 쓰세요.
- 템플릿 변수는 몇 개까지 쓸 수 있나요?
- var1 부터 var8 까지 여덟 개입니다. 템플릿에 정의된 변수보다 적게 채우면 치환되지 않은 자리가 그대로 노출되므로, 모든 변수를 채우세요.
- 한 번에 몇 명까지 보낼 수 있나요?
- contacts 배열에 여러 수신자를 넣어 한 요청으로 보냅니다. 수신자마다 다른 변수 값을 넣을 수 있습니다. 대량 발송 시 배열을 적당한 크기로 나눠 보내는 방법은 대량 발송 문서를 참고하세요.
- 수신자가 카카오톡을 쓰지 않으면 어떻게 되나요?
- 알림톡이 실패합니다. replaceSms 를 Y 로 설정하고 smsSubject/smsContent 를 함께 넘기면 자동으로 문자로 대체 발송됩니다.