카카오 알림톡 보내기 — PHP · Node.js · Python · Java · Go 예제

카카오 알림톡 보내기 — 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 만 넘기면 됩니다.

준비물

필수 파라미터

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 를 함께 넘기면 자동으로 문자로 대체 발송됩니다.

이 문서에서 쓰는 패키지

관련 문서