文档菜单
A PRACTICAL GUIDE
Bulk Alimtalk sending and per-recipient variables
Send one template to many recipients with different values each, in batches. Batch sizing, partial failures, queue patterns and the data hygiene that prevents most incidents.
이 문서의 목차
POST /api/v2/notices/send이 가이드는 아직 번역되지 않아 English 문서를 표시합니다.
Bulk sending is one template, many values. Each entry in contacts carries its own variables, so the same wording can deliver a different order number, amount or date to each person.
The basic shape
await sendgo.alimtalk.send({
templateCode: 'ORDER_CONFIRM_001',
contacts: [
{ contact: '01011111111', name: 'Hong Gildong', var1: 'ORD-001', var2: '29,000원' },
{ contact: '01022222222', name: 'Kim Chulsoo', var1: 'ORD-002', var2: '15,000원' },
{ contact: '01033333333', name: 'Lee Younghee', var1: 'ORD-003', var2: '52,000원' },
],
});
client.alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[
{"contact": "01011111111", "name": "Hong Gildong", "var1": "ORD-001"},
{"contact": "01022222222", "name": "Kim Chulsoo", "var1": "ORD-002"},
],
)
<?php
$sendgo->alimtalk->send([
'templateCode' => 'ORDER_CONFIRM_001',
'contacts' => [
['contact' => '01011111111', 'name' => 'Hong Gildong', 'var1' => 'ORD-001'],
['contact' => '01022222222', 'name' => 'Kim Chulsoo', 'var1' => 'ORD-002'],
],
]);
Batching
Ten thousand recipients in one request means a timeout tells you nothing about how far it got, and retrying is expensive. Split into a few hundred at a time.
Node.js
const BATCH = 500;
async function sendInBatches(recipients: Recipient[]) {
const failures: Recipient[] = [];
for (let i = 0; i < recipients.length; i += BATCH) {
const chunk = recipients.slice(i, i + BATCH);
try {
await sendgo.alimtalk.send({
templateCode: 'ORDER_CONFIRM_001',
contacts: chunk.map((r) => ({
contact: r.phone,
name: r.name,
var1: r.orderNo,
var2: r.amount,
})),
});
} catch (error) {
// One bad batch must not stop the rest.
console.error(`batch ${i / BATCH} failed`, error);
failures.push(...chunk);
}
}
return failures;
}
PHP · Laravel
<?php
use Illuminate\Support\Collection;
collect($recipients)->chunk(500)->each(function (Collection $chunk) use ($sendgo) {
try {
$sendgo->alimtalk->send([
'templateCode' => 'ORDER_CONFIRM_001',
'contacts' => $chunk->map(fn ($r) => [
'contact' => $r->phone,
'name' => $r->name,
'var1' => $r->order_no,
'var2' => number_format($r->amount).'원',
])->values()->all(),
]);
} catch (\Sendgo\Php\Exception\SendgoException $e) {
Log::error('batch send failed', ['message' => $e->getMessage()]);
}
});
Python
BATCH = 500
for i in range(0, len(recipients), BATCH):
chunk = recipients[i:i + BATCH]
try:
client.alimtalk.send(
template_code="ORDER_CONFIRM_001",
contacts=[{"contact": r.phone, "name": r.name, "var1": r.order_no} for r in chunk],
)
except SendgoError as e:
logger.error("batch send failed: %s", e)
Do it in a queue
Never run a bulk send inside a web request. The user waits, and a timeout leaves no way to resume from the middle.
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Sendgo\Php\Sendgo;
use Sendgo\Php\Exception\SendgoException;
class SendOrderAlimtalk implements ShouldQueue
{
use Queueable;
// Most send failures fail identically on retry. Do not loop forever.
public int $tries = 3;
public int $backoff = 30;
public function __construct(private array $contacts) {}
public function handle(Sendgo $sendgo): void
{
$sendgo->alimtalk->send([
'templateCode' => 'ORDER_CONFIRM_001',
'contacts' => $this->contacts,
]);
}
public function failed(SendgoException $e): void
{
// Recording the failed batch is what lets you resend just the failures.
FailedDispatch::create(['contacts' => $this->contacts, 'reason' => $e->getMessage()]);
}
}
Partial failures
A 200 response does not mean every recipient received it. Numbers can be dead, recipients blocked, people not on KakaoTalk.
- Do not resend the whole batch — everyone who succeeded gets it twice.
- Resend only the failures, or enable SMS fallback so they roll over to text automatically.
- Per-recipient outcomes are in the console's send history.
Easy to get wrong
- Normalise numbers first. Real databases contain
010-1234-5678,+821012345678and01012345678side by side. Strip hyphens and country codes down to digits. - Deduplicate. A repeated number sends twice and bills twice.
- Check the credit balance up front. Running out midway through 10,000 messages returns
PAYMENT_REQUIREDand the remainder fails wholesale. - Advertising content is subject to the night ban. Make sure a batch cannot run past 21:00 KST → Advertising message rules
Next
자주 묻는 질문
- How many recipients can one request take?
- The contacts array can hold many recipients in a single request. Very large requests are risky though — a timeout leaves you unsure how much was delivered — so batches of a few hundred are more stable.
- Can each recipient get different values?
- Yes. Every entry in contacts carries its own var1 to var8. Sending the same template with a different order number and amount per person is the normal use.
- What if only some recipients fail?
- A request can succeed while individual recipients fail — invalid numbers, blocked recipients. Check per-recipient results in the console and resend only the failures; resending the whole batch double-sends to everyone who succeeded.
- Can I run a bulk send inside a web request?
- Not advisable. The external call lands in your response time, and on timeout you cannot tell how far it got. Move it to a queue job.
이 문서에서 쓰는 패키지
관련 문서
이메일 · SMTP 연동 — 발신 인증, 뉴스레터와 자동화 수신함 →
일반 발송 승인이 완료된 이메일 서비스입니다. 발신 인증과 앱의 발송 가능 상태를 확인하고 SMTP, HTTP API와 자동화 수신함을 연동하세요.
Send a Kakao Alimtalk — PHP, Node.js, Python, Java, Go examples →
Send Kakao Alimtalk with an approved template code. Runnable code for Laravel, Node.js, Python, PHP, Java, Go, Ruby and .NET, plus every required field and why sends fail.
Send SMS, LMS and MMS in South Korea — code examples →
Send Korean SMS (90 bytes), LMS (long text) and MMS (with images) through Sendgo. Type selection, byte counting, verification-code patterns and advertising rules.
Send a Kakao Brand Message — the successor to Friendtalk →
Send Brand Messages to channel friends, non-friends, or every consenting friend at once. How targeting splits the request path, and when to keep using the Friendtalk endpoint.
SMS fallback when a Kakao Alimtalk fails →
Use replaceSms so a text message goes out when the Alimtalk cannot be delivered. Required fields, cost implications, and the mistake that silently sends nothing.
Scheduling an Alimtalk or SMS — scheduleType and at →
Send at a specific time with scheduleType SCHEDULED. Timestamp format, the KST timezone trap, and how scheduling interacts with the advertising night ban.