Skip to content

solapi/solapi-kotlin

Repository files navigation

SOLAPI Kotlin/Java SDK

Maven Central License: MIT

Kotlin๊ณผ Java์—์„œ SOLAPI ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต์‹ SDK์ž…๋‹ˆ๋‹ค.

AI์™€ ํ•จ๊ป˜ ์‹œ์ž‘ํ•˜๊ธฐ

์‚ฌ๋žŒ์ด ์ฝ์„ ๊ฐ€์ด๋“œ:

Claude Code, Cursor, Windsurf ๋“ฑ AI ์ฝ”๋”ฉ ๋„๊ตฌ์— ์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ถ™์—ฌ๋„ฃ๊ธฐํ•˜์„ธ์š”:

Implement messaging feature using SOLAPI SDK.
Guide: https://raw.githubusercontent.com/solapi/solapi-kotlin/main/LLM_GUIDE.md

LLM ์—์ด์ „ํŠธ๋ฅผ ์œ„ํ•œ ๊ฐ€์ด๋“œ:

SDK ๊ฐ€์ด๋“œ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ LLM ๊ฐ€์ด๋“œ๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

curl -s https://raw.githubusercontent.com/solapi/solapi-kotlin/main/LLM_GUIDE.md
์ƒํ™ฉ ํ”„๋กฌํ”„ํŠธ
SMS/MMS ๋ฐœ์†ก "SOLAPI SDK๋กœ SMS ๋ฐœ์†ก ์ฝ”๋“œ ์ž‘์„ฑํ•ด์ค˜"
์นด์นด์˜ค ์•Œ๋ฆผํ†ก "SOLAPI SDK๋กœ ์นด์นด์˜ค ์•Œ๋ฆผํ†ก ๋ฐœ์†ก ๊ตฌํ˜„ํ•ด์ค˜"
๋Œ€๋Ÿ‰ ๋ฐœ์†ก "SOLAPI SDK๋กœ ๋Œ€๋Ÿ‰ ๋ฌธ์ž ๋ฐœ์†ก ๊ธฐ๋Šฅ ์ถ”๊ฐ€ํ•ด์ค˜"
์˜ˆ์•ฝ ๋ฐœ์†ก "SOLAPI SDK๋กœ ์˜ˆ์•ฝ ๋ฐœ์†ก ๊ตฌํ˜„ํ•ด์ค˜"
๋ฐœ์†ก ์กฐํšŒ "SOLAPI SDK๋กœ ๋ฐœ์†ก ๊ฒฐ๊ณผ ์กฐํšŒ ์ฝ”๋“œ ์ž‘์„ฑํ•ด์ค˜"

์„ค์น˜

Gradle (Kotlin DSL)

dependencies {
    implementation("com.solapi:sdk:1.1.0")
}

Gradle (Groovy)

dependencies {
    implementation 'com.solapi:sdk:1.1.0'
}

Maven

<dependency>
    <groupId>com.solapi</groupId>
    <artifactId>sdk</artifactId>
    <version>1.1.0</version>
</dependency>

๋น ๋ฅธ ์‹œ์ž‘

Java

import com.solapi.sdk.SolapiClient;
import com.solapi.sdk.message.dto.response.MultipleDetailMessageSentResponse;
import com.solapi.sdk.message.model.Message;
import com.solapi.sdk.message.service.DefaultMessageService;

public class Main {
    public static void main(String[] args) {
        DefaultMessageService messageService = SolapiClient.INSTANCE.createInstance("API_KEY", "API_SECRET");

        Message message = new Message();
        message.setFrom("๋ฐœ์‹ ๋ฒˆํ˜ธ");
        message.setTo("์ˆ˜์‹ ๋ฒˆํ˜ธ");
        message.setText("์•ˆ๋…•ํ•˜์„ธ์š”. SOLAPI SDK ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.");

        MultipleDetailMessageSentResponse response = messageService.send(message, null);
        System.out.println("Group ID: " + response.getGroupInfo().getGroupId());
    }
}

Kotlin

import com.solapi.sdk.SolapiClient
import com.solapi.sdk.message.model.Message

fun main() {
    val messageService = SolapiClient.createInstance("API_KEY", "API_SECRET")

    val message = Message(
        from = "๋ฐœ์‹ ๋ฒˆํ˜ธ",
        to = "์ˆ˜์‹ ๋ฒˆํ˜ธ",
        text = "์•ˆ๋…•ํ•˜์„ธ์š”. SOLAPI SDK ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค."
    )

    val response = messageService.send(message)
    println("Group ID: ${response.groupInfo?.groupId}")
}

์˜ˆ์ œ ์‹คํ–‰

ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •

ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค๋ช… ํ•„์ˆ˜
SOLAPI_API_KEY SOLAPI API ํ‚ค O
SOLAPI_API_SECRET SOLAPI API ์‹œํฌ๋ฆฟ O
SOLAPI_SENDER ๋“ฑ๋ก๋œ ๋ฐœ์‹ ๋ฒˆํ˜ธ O
SOLAPI_RECIPIENT ์ˆ˜์‹ ๋ฒˆํ˜ธ O
SOLAPI_KAKAO_PF_ID ์นด์นด์˜ค ๋น„์ฆˆ๋‹ˆ์Šค ์ฑ„๋„ ID ์นด์นด์˜ค ๊ณ„์—ด ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ์‹œ
SOLAPI_KAKAO_TEMPLATE_ID ์นด์นด์˜ค ์•Œ๋ฆผํ†ก ํ…œํ”Œ๋ฆฟ ID ์•Œ๋ฆผํ†ก ๋ฐœ์†ก ์‹œ

์‹คํ–‰ ๋ช…๋ น์–ด

# Java ์˜ˆ์ œ ์‹คํ–‰
./gradlew :solapi-kotlin-example-java:run -Pexample=SendSms

# Kotlin ์˜ˆ์ œ ์‹คํ–‰
./gradlew :solapi-kotlin-example-kotlin:run -Pexample=SendSms

JDK 8 ์‚ฌ์šฉ์ž ์•ˆ๋‚ด

SDK ์‚ฌ์šฉ ์‹œ: ๋ณธ SDK๋Š” JDK 8 ์ด์ƒ์—์„œ ์ •์ƒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. Maven Central์—์„œ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋ฉด JDK 8 ํ™˜๊ฒฝ์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ ์‹คํ–‰ ์‹œ: ์ด ์ €์žฅ์†Œ์˜ ์˜ˆ์ œ๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•˜๋ ค๋ฉด Gradle 9.x๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ, ์ด๋Š” JDK 21 ์ด์ƒ์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

JDK 8๋งŒ ์„ค์น˜๋œ ํ™˜๊ฒฝ์—์„œ ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด:

๋ฐฉ๋ฒ• 1: ๋ณ„๋„์˜ JDK 21+ ์„ค์น˜ (๊ถŒ์žฅ)

Gradle Toolchain์ด ์ž๋™์œผ๋กœ JDK 8์„ ๋‹ค์šด๋กœ๋“œํ•˜์—ฌ ์˜ˆ์ œ๋ฅผ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. Gradle ์‹คํ–‰์šฉ์œผ๋กœ๋งŒ JDK 21 ์ด์ƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

# macOS (Homebrew)
brew install openjdk@21

# Ubuntu/Debian
sudo apt install openjdk-21-jdk

# SDKMAN (๊ถŒ์žฅ)
sdk install java 21.0.2-tem

๋ฐฉ๋ฒ• 2: ์ž์‹ ์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์ง์ ‘ ํ…Œ์ŠคํŠธ

JDK 8 ํ™˜๊ฒฝ์˜ ์ž์ฒด ํ”„๋กœ์ ํŠธ์—์„œ SDK๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

// build.gradle (Groovy)
plugins {
    id 'java'
}

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

dependencies {
    implementation 'com.solapi:sdk:1.1.0'
}
// src/main/java/MyTest.java
import com.solapi.sdk.SolapiClient;
import com.solapi.sdk.message.model.Message;
import com.solapi.sdk.message.service.DefaultMessageService;

public class MyTest {
    public static void main(String[] args) {
        DefaultMessageService messageService = SolapiClient.INSTANCE.createInstance(
            "YOUR_API_KEY",
            "YOUR_API_SECRET"
        );

        Message message = new Message();
        message.setFrom("๋ฐœ์‹ ๋ฒˆํ˜ธ");
        message.setTo("์ˆ˜์‹ ๋ฒˆํ˜ธ");
        message.setText("ํ…Œ์ŠคํŠธ ๋ฉ”์‹œ์ง€");

        messageService.send(message, null);
    }
}

์ฐธ๊ณ : Gradle 7.x (JDK 11+) ๋˜๋Š” Gradle 6.x (JDK 8+)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์œ„ ์„ค์ •์œผ๋กœ ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ ๋ชฉ๋ก

์˜ˆ์ œ ์„ค๋ช…
SendSms SMS ๋‹จ๊ฑด ๋ฐœ์†ก
SendMms MMS ์ด๋ฏธ์ง€ ์ฒจ๋ถ€ ๋ฐœ์†ก
SendBatch ๋Œ€๋Ÿ‰ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก
SendScheduled ์˜ˆ์•ฝ ๋ฐœ์†ก
SendVoice ์Œ์„ฑ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก
KakaoAlimtalk ์นด์นด์˜ค ์•Œ๋ฆผํ†ก ๋ฐœ์†ก
KakaoBrandMessage ์นด์นด์˜ค ๋ธŒ๋žœ๋“œ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก
GetBalance ์ž”์•ก ์กฐํšŒ
GetMessageList ๋ฐœ์†ก ๋‚ด์—ญ ์กฐํšŒ

์ง€์› ๋ฉ”์‹œ์ง€ ํƒ€์ž…

ํƒ€์ž… ์„ค๋ช…
SMS ๋‹จ๋ฌธ๋ฌธ์ž (80 byte ๋ฏธ๋งŒ)
LMS ์žฅ๋ฌธ๋ฌธ์ž (80 byte ์ด์ƒ, 2,000 byte ๋ฏธ๋งŒ)
MMS ์ด๋ฏธ์ง€ ํฌํ•จ ๋ฌธ์ž (200KB ์ด๋‚ด ์ด๋ฏธ์ง€ 1์žฅ)
ATA ์นด์นด์˜ค ์•Œ๋ฆผํ†ก
BMS_* ์นด์นด์˜ค ๋ธŒ๋žœ๋“œ ๋ฉ”์‹œ์ง€ (ํ…œํ”Œ๋ฆฟ, ์ž์œ ํ˜•)
RCS_* RCS ๋ฌธ์ž (SMS, LMS, MMS, TPL)
NSA ๋„ค์ด๋ฒ„ ์Šค๋งˆํŠธ ์•Œ๋ฆผ
FAX ํŒฉ์Šค
VOICE ์Œ์„ฑ ๋ฉ”์‹œ์ง€

์ฃผ์š” ๊ธฐ๋Šฅ

MMS ์ด๋ฏธ์ง€ ์ฒจ๋ถ€ ๋ฐœ์†ก

Java:

// ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
String imageId = messageService.uploadFile(imageFile, StorageType.MMS, null);

// MMS ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ ๋ฐ ๋ฐœ์†ก
Message message = new Message();
message.setType(MessageType.MMS);
message.setFrom("๋ฐœ์‹ ๋ฒˆํ˜ธ");
message.setTo("์ˆ˜์‹ ๋ฒˆํ˜ธ");
message.setText("MMS ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ");
message.setSubject("MMS ์ œ๋ชฉ");
message.setImageId(imageId);
messageService.send(message, null);

์ด๋ฏธ์ง€ ๊ทœ๊ฒฉ: JPG/JPEG, ์ตœ๋Œ€ 200KB, ๊ถŒ์žฅ ํ•ด์ƒ๋„ 1000x1000 ์ดํ•˜

๋Œ€๋Ÿ‰ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก

Java:

List<Message> messages = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
    Message msg = new Message();
    msg.setFrom(sender);
    msg.setTo("010XXXX000" + i);
    msg.setText("๋ฉ”์‹œ์ง€ " + i);
    messages.add(msg);
}

// ์ค‘๋ณต ์ˆ˜์‹ ๋ฒˆํ˜ธ ํ—ˆ์šฉ ์˜ต์…˜
SendRequestConfig config = new SendRequestConfig();
config.setAllowDuplicates(true);
messageService.send(messages, config);
  • ํ•œ ๋ฒˆ์— ์ตœ๋Œ€ 10,000๊ฑด ๋ฐœ์†ก ๊ฐ€๋Šฅ
  • allowDuplicates = true๋กœ ๋™์ผ ์ˆ˜์‹ ๋ฒˆํ˜ธ ์ค‘๋ณต ๋ฐœ์†ก ํ—ˆ์šฉ

์˜ˆ์•ฝ ๋ฐœ์†ก

Java:

SendRequestConfig config = new SendRequestConfig();
config.setScheduledDateFromLocalDateTime(
    LocalDateTime.now().plusMinutes(10),
    ZoneId.of("Asia/Seoul")
);
messageService.send(message, config);
  • ์ตœ์†Œ 10๋ถ„ ํ›„๋ถ€ํ„ฐ ์ตœ๋Œ€ 6๊ฐœ์›” ์ด๋‚ด ์˜ˆ์•ฝ ๊ฐ€๋Šฅ
  • ๊ณผ๊ฑฐ ์‹œ๊ฐ„ ์ง€์ • ์‹œ ์ฆ‰์‹œ ๋ฐœ์†ก ์ฒ˜๋ฆฌ

์นด์นด์˜ค ์•Œ๋ฆผํ†ก

Java:

Map<String, String> variables = new HashMap<>();
variables.put("name", "ํ™๊ธธ๋™");
variables.put("code", "123456");

KakaoOption kakaoOption = new KakaoOption();
kakaoOption.setPfId("์นด์นด์˜ค์ฑ„๋„ID");
kakaoOption.setTemplateId("ํ…œํ”Œ๋ฆฟID");
kakaoOption.setVariables(variables);

Message message = new Message();
message.setType(MessageType.ATA);
message.setFrom("๋ฐœ์‹ ๋ฒˆํ˜ธ");
message.setTo("์ˆ˜์‹ ๋ฒˆํ˜ธ");
message.setKakaoOptions(kakaoOption);
messageService.send(message, null);
  • ๊ฒ€์ˆ˜ ์Šน์ธ๋œ ํ…œํ”Œ๋ฆฟ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ์ •๋ณด์„ฑ ๋ฉ”์‹œ์ง€ ์ „์šฉ (๊ด‘๊ณ  ๋ถˆ๊ฐ€)

API ๋ ˆํผ๋Ÿฐ์Šค

๋ฉ”์‹œ์ง€ ๋ฐœ์†ก

๋ฉ”์„œ๋“œ ์„ค๋ช…
send(message) ๋‹จ๊ฑด ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก
send(messages) ๋‹ค๊ฑด ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก (์ตœ๋Œ€ 10,000๊ฑด)
send(message, config) ์„ค์ •๊ณผ ํ•จ๊ป˜ ๋ฐœ์†ก (์˜ˆ์•ฝ, ์ค‘๋ณต ํ—ˆ์šฉ ๋“ฑ)
uploadFile(file, type) ํŒŒ์ผ ์—…๋กœ๋“œ (MMS, FAX ๋“ฑ)

์กฐํšŒ

๋ฉ”์„œ๋“œ ์„ค๋ช…
getBalance() ์ž”์•ก ์กฐํšŒ
getQuota() ์ผ์ผ ๋ฐœ์†ก๋Ÿ‰ ํ•œ๋„ ์กฐํšŒ
getMessageList(request) ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ๋‚ด์—ญ ์กฐํšŒ

์นด์นด์˜ค ํ…œํ”Œ๋ฆฟ ๊ด€๋ฆฌ

๋ฉ”์„œ๋“œ ์„ค๋ช…
getKakaoAlimtalkTemplates() ์•Œ๋ฆผํ†ก ํ…œํ”Œ๋ฆฟ ๋ชฉ๋ก ์กฐํšŒ
getKakaoAlimtalkTemplate(id) ์•Œ๋ฆผํ†ก ํ…œํ”Œ๋ฆฟ ์ƒ์„ธ ์กฐํšŒ
createKakaoAlimtalkTemplate(request) ์•Œ๋ฆผํ†ก ํ…œํ”Œ๋ฆฟ ์ƒ์„ฑ
getSendableKakaoAlimtalkTemplates() ๋ฐœ์†ก ๊ฐ€๋Šฅํ•œ ํ…œํ”Œ๋ฆฟ ์กฐํšŒ
getKakaoBrandMessageTemplates() ๋ธŒ๋žœ๋“œ ๋ฉ”์‹œ์ง€ ํ…œํ”Œ๋ฆฟ ์กฐํšŒ

์—๋Ÿฌ ์ฒ˜๋ฆฌ

try {
    messageService.send(message, null);
} catch (SolapiBadRequestException e) {
    System.out.println("์ž˜๋ชป๋œ ์š”์ฒญ: " + e.getMessage());
} catch (SolapiInvalidApiKeyException e) {
    System.out.println("์ž˜๋ชป๋œ API ํ‚ค: " + e.getMessage());
} catch (SolapiMessageNotReceivedException e) {
    System.out.println("๋ฐœ์†ก ์‹คํŒจ: " + e.getMessage());
} catch (SolapiException e) {
    System.out.println("๊ธฐํƒ€ ์˜ค๋ฅ˜: " + e.getMessage());
}
์˜ˆ์™ธ ํด๋ž˜์Šค ์„ค๋ช…
SolapiBadRequestException ์ž˜๋ชป๋œ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ
SolapiInvalidApiKeyException ์œ ํšจํ•˜์ง€ ์•Š์€ API ํ‚ค
SolapiApiKeyException API ํ‚ค ๊ด€๋ จ ์˜ค๋ฅ˜
SolapiFileUploadException ํŒŒ์ผ ์—…๋กœ๋“œ ์‹คํŒจ
SolapiMessageNotReceivedException ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ์‹คํŒจ
SolapiEmptyResponseException ๋นˆ ์‘๋‹ต ์ˆ˜์‹ 
SolapiUnknownException ์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜

์š”๊ตฌ ์‚ฌํ•ญ

  • Java 8 ์ด์ƒ
  • Kotlin 2.2.0 ์ด์ƒ (Kotlin ์‚ฌ์šฉ ์‹œ)

๊ด€๋ จ ๋งํฌ

๋ผ์ด์„ ์Šค

MIT License - ์ž์„ธํ•œ ๋‚ด์šฉ์€ LICENSE ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

About

SOLAPI SDK for Kotlin(Includes Java)

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors