文档菜单
Java / SDK REFERENCE
Java SDK 指南
用于发送 Kakao 通知消息、好友消息、品牌消息与 SMS 的官方 Java SDK —— 不依赖任何框架,构建器风格 API。
이 문서의 목차
- 패키지
- io.sendgo:sendgo-java
- 언어
- Java
- 레지스트리
- Maven Central
implementation "io.sendgo:sendgo-java:1.1.0"用于发送 Kakao 通知消息、品牌消息与短信的官方 Java SDK
io.sendgo:sendgo-java 是不依赖任何框架的核心客户端。Spring Boot Starter 构建在它之上。
要求 Java 17 及以上。
安装
Gradle
implementation "io.sendgo:sendgo-java:1.1.0"
Maven
<dependency>
<groupId>io.sendgo</groupId>
<artifactId>sendgo-java</artifactId>
<version>1.1.0</version>
</dependency>
快速上手
import io.sendgo.SendgoClient;
import io.sendgo.SendgoConfig;
import io.sendgo.model.AlimtalkRequest;
import io.sendgo.model.Contact;
SendgoClient sendgo = new SendgoClient(SendgoConfig.builder()
.accessKey(System.getenv("SENDGO_ACCESS_KEY"))
.secretKey(System.getenv("SENDGO_SECRET_KEY"))
.kakaoSenderKey(System.getenv("SENDGO_KAKAO_SENDER_KEY"))
.smsSenderKey(System.getenv("SENDGO_SMS_SENDER_KEY"))
.build());
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("ORDER_CONFIRM_001")
.contact(Contact.builder().contact("01012345678").var1("ORD-001").build())
.build());
各发送渠道都是客户端上的方法:
| 方法 | 渠道 |
|---|---|
sendgo.alimtalk() |
Kakao 通知消息 |
sendgo.friendtalk() |
Kakao 好友消息 |
sendgo.brandMessage() |
Kakao 品牌消息(仅 v2) |
sendgo.sms() |
SMS / LMS / MMS |
apiVersion 的默认值为 v2,因此无需显式设置;只有需要固定使用 v1 的旧对接才要指定。
请创建一次客户端并复用(作为单例或 DI Bean),令牌缓存才能生效。
通知消息
// 批量发送 —— `contact(...)` 每次调用都会追加一位接收者;
// 也可用 `contacts(List.of(...))` 一次性指定全部
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("ORDER_CONFIRM_001")
.contact(Contact.builder().contact("01011111111").var1("ORD-001").var2("29,000元").build())
.contact(Contact.builder().contact("01022222222").var1("ORD-002").var2("15,000元").build())
.build());
// 预约发送
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("PROMO_SUMMER_2026")
.scheduleType("SCHEDULED")
.at("2026-07-28 09:00:00")
.contact(Contact.builder().contact("01012345678").var1("夏季限定 5 折").build())
.build());
// 失败时自动回退为短信
sendgo.alimtalk().send(AlimtalkRequest.builder()
.templateCode("DELIVERY_START_001")
.replaceSms("Y")
.smsSubject("[发货通知]")
.smsContent("您购买的商品已出库。")
.contact(Contact.builder().contact("01012345678").var1("ORD-001").build())
.build());
任意命名的模板变量
除 var1 ~ var8 之外,也可使用任意名称的变量(对应模板中的 #{title}):
Contact.builder()
.contact("01012345678")
.variable("title", "订单确认")
.variable("amount", "29,000元")
.build();
好友消息
⚠️ 已停用 —— 按 Kakao 政策,好友消息已于 2025-12-31 停止服务。 自 2026-01-01 起,好友消息的发送请求由 Kakao 侧自动改以**品牌消息(自由形式)**发出。 调用仍会成功;而且自由文本类型(
FT/FI/FW)发往单个接收者的路径目前仍只有这一条, 因此现有代码无需立即改动。以下情形请改用品牌消息:
- 基于模板的富文本类型(
FL/FC/FM/FP/FA)- 非频道好友的接收者(
targeting=N/I)- 向已同意接收的全部频道好友群发(
targeting=F)消息类型一一对应,转换由服务端处理 ——
FT→BT、FI→BI、FW→BW、FL→BL、FC→BC、FM→BM、FP→BP、FA→BA。
import io.sendgo.model.FriendtalkRequest;
// 文本型
sendgo.friendtalk().send(FriendtalkRequest.builder()
.content("7 月限时特惠开始了,欢迎查看。")
.contact(Contact.builder().contact("01012345678").build())
.build());
// 图片型
sendgo.friendtalk().send(FriendtalkRequest.builder()
.messageType("FI")
.content("本周特价商品")
.imageUrl("https://cdn.example.com/banner.jpg")
.imageLink("https://example.com/event")
.contact(Contact.builder().contact("01012345678").build())
.build());
品牌消息
品牌消息是好友消息的后继渠道:可触达非频道好友的接收者(targeting("N")),也可向已同意接收的全部频道好友群发(targeting("F"))。消息类型与好友消息一一对应(FT→BT、FI→BI、FW→BW、FL→BL、FC→BC、FM→BM、FP→BP、FA→BA)—— 传入好友消息的代码,服务端会自动转换。
仅 v2 支持,也是本 SDK 的默认版本。
import io.sendgo.model.BrandMessageRequest;
import java.util.Map;
// 单条发送 —— targeting 为 M/N/I 时必须提供接收者
Map<String, Object> result = sendgo.brandMessage().send(BrandMessageRequest.builder()
.targeting("M")
.messageType("FL")
.friendTemplateUuid("9cd5460b-6458-4edc-9b11-c26d3013c340")
.contact(Contact.builder().contact("01012345678").var1("29,000元").build())
.build());
// 群发 —— 已同意接收的全部频道好友(不传接收者)
Map<String, Object> accepted = sendgo.brandMessage().broadcast(BrandMessageRequest.builder()
.messageType("FW")
.friendTemplateUuid("9cd5460b-6458-4edc-9b11-c26d3013c340")
.build());
// 群发在上游为异步处理,需轮询查看进度
Map<String, Object> detail = sendgo.brandMessage().campaign(campaignId);
targeting 的取值含义:
| 值 | 含义 |
|---|---|
M |
频道好友中的指定接收者 |
N |
非频道好友的接收者 |
I |
按标识符指定的接收者 |
F |
已同意接收的全部频道好友(群发) |
品牌消息的方法返回 Map<String, Object>(其余渠道返回 void),因为响应中包含发送件数与 campaignId 等需要读取的数据。
短信 / 长短信 / 多媒体短信
import io.sendgo.model.SmsRequest;
// SMS(90 字节以内)
sendgo.sms().sendSms(SmsRequest.sms()
.content("[Sendgo] 验证码:123456(请在 5 分钟内输入)")
.contact(Contact.builder().contact("01012345678").build()));
// LMS(长文,2,000 字节以内)
sendgo.sms().sendLms(SmsRequest.lms()
.subject("[重要] 服务维护通知")
.content("服务将于 2026-07-25 02:00 ~ 06:00 进行维护。")
.contact(Contact.builder().contact("01012345678").build()));
// MMS(含图片)
sendgo.sms().sendMms(SmsRequest.mms()
.subject("[活动] 7 月特惠")
.content("欢迎查看本月特价商品。")
.contact(Contact.builder().contact("01012345678").build()));
SmsRequest 不使用 builder()/build():它通过 sms() / lms() / mms() 静态工厂创建,
再用返回自身的链式 setter 配置。
sendSms / sendLms / sendMms 会强制设置消息类型,因此工厂方法与发送方法不会互相矛盾;
send(...) 则按请求自身携带的类型发送。
错误处理
import io.sendgo.exception.SendgoException;
try {
sendgo.alimtalk().send(request);
} catch (SendgoException e) {
log.error("Sendgo {} [{}] {}: {}",
e.getStatusCode(), e.getErrorCode(), e.getEndpoint(), e.getMessage());
switch (e.getErrorCode()) {
case "INVALID_ACCESS_KEY", "INVALID_SECRET_KEY" ->
// 是我们的配置有误,而非调用方的请求有误。
alertOps("请检查 Sendgo 密钥");
case "IP_NOT_ALLOWED" ->
alertOps("该 IP 未在白名单中");
case "PAYMENT_REQUIRED" ->
alertOps("Sendgo 余额不足");
default -> {
if (e.getStatusCode() >= 500) {
throw e; // 临时故障,交由重试机制处理
}
}
}
}
SendgoException 是运行时异常,因此不会强制 catch。这也意味着忘记捕获时会向上冒泡 —— 在不希望发送失败影响主流程的位置务必显式处理。
请根据 getErrorCode() 分支,而不要匹配错误消息文本 —— 消息文案可能变更,错误代码才是契约。
TOKEN_EXPIRED 与 TOKEN_MISMATCH 已在 SDK 内部处理:会重新签发令牌并自动重试该请求一次。
配置项
| 构建器方法 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
accessKey |
必填 | — | Sendgo 访问密钥 |
secretKey |
必填 | — | Sendgo 私密密钥 |
kakaoSenderKey |
选填 | null |
Kakao 发送者资料密钥 |
smsSenderKey |
选填 | null |
短信主叫号码密钥 |
apiVersion |
选填 | "v2" |
API 版本(v1 | v2) |
baseUrl |
选填 | "https://sendgo.io" |
API 基础地址 |
短链接
短链接会缩短消息正文中的链接,并统计该链接是否被真正点击。 短信按字节计费,因此链接更短就意味着正文可以写更多内容。
仅 v2 支持。
再次缩短同一个原始 URL 会直接返回已有的链接。若希望按活动分别统计反应,
请使用 forceNew 生成新的短码。
deactivate 不会删除链接,只停止重定向。当已发送消息中的链接必须失效时使用它;
累计统计会保留,访问已停止的链接会返回 410 Gone。
import io.sendgo.model.ShortUrlRequest;
Map<String, Object> created = sendgo.shortUrl().create(ShortUrlRequest.builder()
.targetUrl("https://example.com/promotions/summer-sale")
.title("夏季促销落地页")
.build());
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) created.get("data");
String code = (String) data.get("code");
// 反应统计 —— 按日趋势 + 设备/来源/国家分解
Map<String, Object> stats = sendgo.shortUrl().stats(code, "2026-08-01", null);
sendgo.shortUrl().list(null, null, 10);
sendgo.shortUrl().show(code);
sendgo.shortUrl().deactivate(code); // 仅停止重定向,统计保留
stats 返回按日趋势(daily)以及按设备(byDevice)、来源(byReferer)、国家(byCountry)的分解。按日趋势读取的是预聚合表,因此点击量再大响应时间也保持稳定。
包信息
- 包名:
io.sendgo:sendgo-java(Maven Central) - 仓库:send-go/java
- 注册表:https://central.sonatype.com/artifact/io.sendgo/sendgo-java
- 许可:MIT
如何获取 API 密钥
登录 Sendgo 后,在 API/SDK → API 对接 菜单中签发访问密钥与私密密钥。
使用通知消息/好友消息需在 Kakao 渠道 登记发送者资料以获取 kakaoSenderKey;使用短信需在 发送号码 菜单登记主叫号码。
이 패키지로 할 수 있는 것
Send your first Kakao Alimtalk in 5 minutes →
From issuing an access key to sending a Kakao Alimtalk, with working code in Node.js, Python, PHP, Laravel, Java and Go.
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.