Skip to content

Latest commit

ย 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

README.md

SOLAPI Elixir SDK ์˜ˆ์ œ

์ด ํด๋”์—๋Š” SOLAPI SDK์˜ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ ์˜ˆ์ œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ ๋ชฉ๋ก

ํŒŒ์ผ ์„ค๋ช… ๋‚œ์ด๋„
send_sms.exs SMS (๋‹จ๋ฌธ) ๋ฐœ์†ก ๊ธฐ๋ณธ
send_lms.exs LMS (์žฅ๋ฌธ) ๋ฐœ์†ก ๊ธฐ๋ณธ
send_mms.exs MMS (์ด๋ฏธ์ง€ ์ฒจ๋ถ€) ๋ฐœ์†ก ์ค‘๊ธ‰
send_kakao_alimtalk.exs ์นด์นด์˜ค ์•Œ๋ฆผํ†ก (ํ…œํ”Œ๋ฆฟ ๊ธฐ๋ฐ˜) ์ค‘๊ธ‰
send_kakao_friendtalk.exs ์นด์นด์˜ค ์นœ๊ตฌํ†ก (๋ฒ„ํŠผ ํฌํ•จ) ์ค‘๊ธ‰
send_multiple.exs ์—ฌ๋Ÿฌ ์ˆ˜์‹ ์ž์—๊ฒŒ ๋Œ€๋Ÿ‰ ๋ฐœ์†ก ๊ธฐ๋ณธ
error_handling.exs ์—๋Ÿฌ ์œ ํ˜•๋ณ„ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ• ๊ณ ๊ธ‰

์‚ฌ์ „ ์ค€๋น„

ํ•„์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ

  1. Elixir 1.14 ์ด์ƒ ์„ค์น˜

    elixir --version
  2. SOLAPI API ํ‚ค ๋ฐœ๊ธ‰

  3. ๋ฐœ์‹ ๋ฒˆํ˜ธ ๋“ฑ๋ก (ํ•„์ˆ˜)

    • SOLAPI ์ฝ˜์†”์—์„œ ๋ฐœ์‹ ๋ฒˆํ˜ธ ์‚ฌ์ „ ๋“ฑ๋ก
    • ํ•œ๊ตญ ํ†ต์‹ ๋ฒ•๊ทœ์ƒ ๋ฏธ๋“ฑ๋ก ๋ฒˆํ˜ธ๋Š” ๋ฐœ์†ก ๋ถˆ๊ฐ€

๋ฉ”์‹œ์ง€ ํƒ€์ž…๋ณ„ ์ถ”๊ฐ€ ์š”๊ตฌ์‚ฌํ•ญ

๋ฉ”์‹œ์ง€ ํƒ€์ž… ์ถ”๊ฐ€ ์ค€๋น„์‚ฌํ•ญ
MMS ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ํ›„ image_id ๋ฐœ๊ธ‰
์นด์นด์˜ค ์•Œ๋ฆผํ†ก ์นด์นด์˜ค ์ฑ„๋„ ์—ฐ๋™, ํ…œํ”Œ๋ฆฟ ์Šน์ธ
์นด์นด์˜ค ์นœ๊ตฌํ†ก ์นด์นด์˜ค ์ฑ„๋„ ์—ฐ๋™, ์นœ๊ตฌ ์ถ”๊ฐ€๋œ ์‚ฌ์šฉ์ž๋งŒ ๋ฐœ์†ก ๊ฐ€๋Šฅ

ํ™˜๊ฒฝ ์„ค์ •

๋ฐฉ๋ฒ• 1: ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์ง์ ‘ ์„ค์ • (๊ถŒ์žฅ)

export SOLAPI_API_KEY="your_api_key"
export SOLAPI_API_SECRET="your_api_secret"

๋ฐฉ๋ฒ• 2: .env ํŒŒ์ผ ์‚ฌ์šฉ

  1. .env.example์„ .env๋กœ ๋ณต์‚ฌ:

    cp .env.example .env
  2. .env ํŒŒ์ผ ํŽธ์ง‘:

    SOLAPI_API_KEY=your_api_key
    SOLAPI_API_SECRET=your_api_secret
    
  3. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋กœ๋“œ:

    source .env

์˜ˆ์ œ ์‹คํ–‰

๊ฐ ์˜ˆ์ œ๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์Šคํฌ๋ฆฝํŠธ์ž…๋‹ˆ๋‹ค:

# SMS ๋ฐœ์†ก
elixir examples/send_sms.exs

# LMS (์žฅ๋ฌธ) ๋ฐœ์†ก
elixir examples/send_lms.exs

# MMS (์ด๋ฏธ์ง€) ๋ฐœ์†ก
elixir examples/send_mms.exs

# ์นด์นด์˜ค ์•Œ๋ฆผํ†ก
elixir examples/send_kakao_alimtalk.exs

# ์นด์นด์˜ค ์นœ๊ตฌํ†ก
elixir examples/send_kakao_friendtalk.exs

# ๋Œ€๋Ÿ‰ ๋ฐœ์†ก
elixir examples/send_multiple.exs

# ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์˜ˆ์ œ
elixir examples/error_handling.exs

์˜ˆ์ œ๋ณ„ ์ƒ์„ธ ์„ค๋ช…

SMS ๋ฐœ์†ก (send_sms.exs)

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋‹จ๋ฌธ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

์šฉ๋„: 90๋ฐ”์ดํŠธ ์ดํ•˜์˜ ์งง์€ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก

์ฃผ์š” ์ฝ”๋“œ:

Solapi.send(client, %{
  to: "01012345678",
  from: "0212345678",
  text: "์•ˆ๋…•ํ•˜์„ธ์š”!"
})

์‹คํ–‰:

elixir examples/send_sms.exs

LMS ๋ฐœ์†ก (send_lms.exs)

์žฅ๋ฌธ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. ์ œ๋ชฉ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฉ๋„: 90๋ฐ”์ดํŠธ ์ดˆ๊ณผ ~ 2,000๋ฐ”์ดํŠธ ์ดํ•˜ ๋ฉ”์‹œ์ง€

SMS vs LMS ์ฐจ์ด์ :

  • SMS: 90๋ฐ”์ดํŠธ ์ดํ•˜, ์ œ๋ชฉ ์—†์Œ
  • LMS: 2,000๋ฐ”์ดํŠธ ์ดํ•˜, ์ œ๋ชฉ ํฌํ•จ ๊ฐ€๋Šฅ

์ฃผ์š” ์ฝ”๋“œ:

Solapi.send(client, %{
  to: "01012345678",
  from: "0212345678",
  type: "LMS",
  subject: "๊ณต์ง€์‚ฌํ•ญ",
  text: "์žฅ๋ฌธ ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ..."
})

์ฐธ๊ณ : type: "LMS"๋ฅผ ์ƒ๋žตํ•ด๋„ 90๋ฐ”์ดํŠธ ์ดˆ๊ณผ ์‹œ ์ž๋™ LMS ์ „ํ™˜


MMS ๋ฐœ์†ก (send_mms.exs)

์ด๋ฏธ์ง€๊ฐ€ ์ฒจ๋ถ€๋œ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

์šฉ๋„: ์ด๋ฏธ์ง€์™€ ํ•จ๊ป˜ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก

์‚ฌ์ „ ์ค€๋น„:

  1. SOLAPI ์ฝ˜์†”์—์„œ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
  2. ๋ฐœ๊ธ‰๋ฐ›์€ image_id ์‚ฌ์šฉ

์ฃผ์š” ์ฝ”๋“œ:

Solapi.send(client, %{
  to: "01012345678",
  from: "0212345678",
  type: "MMS",
  subject: "์ด๋ฒคํŠธ ์•ˆ๋‚ด",
  text: "๋ณธ๋ฌธ ๋‚ด์šฉ",
  image_id: "IMG_XXXXXXXXXX"
})

์นด์นด์˜ค ์•Œ๋ฆผํ†ก (send_kakao_alimtalk.exs)

ํ…œํ”Œ๋ฆฟ ๊ธฐ๋ฐ˜ ์นด์นด์˜ค ์•Œ๋ฆผ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

์šฉ๋„: ์ฃผ๋ฌธ ํ™•์ธ, ๋ฐฐ์†ก ์•Œ๋ฆผ, ์˜ˆ์•ฝ ํ™•์ธ ๋“ฑ ์ •๋ณด์„ฑ ๋ฉ”์‹œ์ง€

์‚ฌ์ „ ์ค€๋น„:

  1. ์นด์นด์˜ค ๋น„์ฆˆ๋‹ˆ์Šค ์ฑ„๋„ ์ƒ์„ฑ ๋ฐ SOLAPI ์—ฐ๋™
  2. ์•Œ๋ฆผํ†ก ํ…œํ”Œ๋ฆฟ ๋“ฑ๋ก ๋ฐ ์Šน์ธ
  3. pfId (์ฑ„๋„ ID)์™€ templateId ํ™•์ธ

์ฃผ์š” ์ฝ”๋“œ:

Solapi.send(client, %{
  to: "01012345678",
  from: "0212345678",
  kakao_options: %{
    "pfId" => "KA01PF...",
    "templateId" => "KA01TP...",
    "variables" => %{
      "#{๊ณ ๊ฐ๋ช…}" => "ํ™๊ธธ๋™",
      "#{์ฃผ๋ฌธ๋ฒˆํ˜ธ}" => "ORD-001"
    }
  }
})

ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜: #{๋ณ€์ˆ˜๋ช…} ํ˜•์‹์œผ๋กœ ํ…œํ”Œ๋ฆฟ์— ์ •์˜๋œ ๋ณ€์ˆ˜์™€ ์ผ์น˜ํ•ด์•ผ ํ•จ


์นด์นด์˜ค ์นœ๊ตฌํ†ก (send_kakao_friendtalk.exs)

์ฑ„๋„ ์นœ๊ตฌ์—๊ฒŒ ์ž์œ  ํ˜•์‹ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœ์†กํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

์šฉ๋„: ๋งˆ์ผ€ํŒ… ๋ฉ”์‹œ์ง€, ํ”„๋กœ๋ชจ์…˜, ์ฟ ํฐ ๋ฐœ์†ก

์•Œ๋ฆผํ†ก vs ์นœ๊ตฌํ†ก ์ฐจ์ด์ :

๊ตฌ๋ถ„ ์•Œ๋ฆผํ†ก ์นœ๊ตฌํ†ก
ํ…œํ”Œ๋ฆฟ ํ•„์ˆ˜ (์‚ฌ์ „ ์Šน์ธ) ๋ถˆํ•„์š”
์ˆ˜์‹ ์ž ๋ชจ๋“  ์‚ฌ์šฉ์ž ์ฑ„๋„ ์นœ๊ตฌ๋งŒ
์šฉ๋„ ์ •๋ณด์„ฑ ๋ฉ”์‹œ์ง€ ๊ด‘๊ณ /๋งˆ์ผ€ํŒ…
๋ฒ„ํŠผ ํ…œํ”Œ๋ฆฟ์— ์ •์˜ ์ž์œ ๋กญ๊ฒŒ ์ถ”๊ฐ€

์ฃผ์š” ์ฝ”๋“œ:

Solapi.send(client, %{
  to: "01012345678",
  from: "0212345678",
  text: "์นœ๊ตฌํ†ก ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ",
  kakao_options: %{
    "pfId" => "KA01PF...",
    "imageId" => "KAKAO_IMG_ID",  # ์„ ํƒ
    "buttons" => [
      %{
        "buttonType" => "WL",
        "buttonName" => "์ž์„ธํžˆ ๋ณด๊ธฐ",
        "linkMo" => "https://example.com"
      }
    ]
  }
})

๋ฒ„ํŠผ ํƒ€์ž…:

  • WL: ์›น ๋งํฌ
  • AL: ์•ฑ ๋งํฌ
  • BK: ๋ด‡ ํ‚ค์›Œ๋“œ
  • MD: ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ

๋Œ€๋Ÿ‰ ๋ฐœ์†ก (send_multiple.exs)

์—ฌ๋Ÿฌ ์ˆ˜์‹ ์ž์—๊ฒŒ ํ•œ ๋ฒˆ์— ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœ์†กํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

์šฉ๋„: ๊ณต์ง€์‚ฌํ•ญ, ์ด๋ฒคํŠธ ์•ˆ๋‚ด ๋“ฑ ๋‹ค์ˆ˜ ์ˆ˜์‹ ์ž ๋Œ€์ƒ ๋ฐœ์†ก

์žฅ์ :

  • 1ํšŒ API ํ˜ธ์ถœ๋กœ ๋‹ค์ค‘ ๋ฐœ์†ก (ํšจ์œจ์ )
  • Rate Limit ์ ˆ์•ฝ
  • ๋„คํŠธ์›Œํฌ ์˜ค๋ฒ„ํ—ค๋“œ ๊ฐ์†Œ

์ฃผ์š” ์ฝ”๋“œ:

messages = [
  %{to: "01012345678", from: "0212345678", text: "๋ฉ”์‹œ์ง€ 1"},
  %{to: "01087654321", from: "0212345678", text: "๋ฉ”์‹œ์ง€ 2"},
  %{to: "01011112222", from: "0212345678", text: "๋ฉ”์‹œ์ง€ 3"}
]

Solapi.send(client, messages)

๋™์  ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ:

recipients = [
  %{phone: "01012345678", name: "ํ™๊ธธ๋™"},
  %{phone: "01087654321", name: "๊น€์ฒ ์ˆ˜"}
]

messages = Enum.map(recipients, fn r ->
  %{to: r.phone, from: "0212345678", text: "#{r.name}๋‹˜, ์•ˆ๋…•ํ•˜์„ธ์š”!"}
end)

Solapi.send(client, messages)

์—๋Ÿฌ ์ฒ˜๋ฆฌ (error_handling.exs)

๋‹ค์–‘ํ•œ ์—๋Ÿฌ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

ํ•™์Šต ๋‚ด์šฉ:

  • ValidationError: ์ž…๋ ฅ๊ฐ’ ๊ฒ€์ฆ ์‹คํŒจ
  • ApiError: API ์‘๋‹ต ์—๋Ÿฌ (์ธ์ฆ ์‹คํŒจ, ๊ถŒํ•œ ๋ถ€์กฑ ๋“ฑ)
  • NetworkError: ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜ (ํƒ€์ž„์•„์›ƒ, ์—ฐ๊ฒฐ ์‹คํŒจ ๋“ฑ)

์—๋Ÿฌ ํƒ€์ž…๋ณ„ ์ฒ˜๋ฆฌ:

case Solapi.send(client, message) do
  {:ok, response} ->
    IO.puts("์„ฑ๊ณต!")

  {:error, %Solapi.Error.ValidationError{field: field, message: msg}} ->
    IO.puts("๊ฒ€์ฆ ์‹คํŒจ [#{field}]: #{msg}")

  {:error, %Solapi.Error.ApiError{status: 401}} ->
    IO.puts("์ธ์ฆ ์‹คํŒจ - API ํ‚ค ํ™•์ธ")

  {:error, %Solapi.Error.ApiError{status: 429}} ->
    IO.puts("์š”์ฒญ ํ•œ๋„ ์ดˆ๊ณผ - ์ž ์‹œ ํ›„ ์žฌ์‹œ๋„")

  {:error, %Solapi.Error.NetworkError{retries_exhausted: true}} ->
    IO.puts("๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜ - ์žฌ์‹œ๋„ ์†Œ์ง„")
end

์˜ˆ์ƒ ์ถœ๋ ฅ ๊ฒฐ๊ณผ

์„ฑ๊ณต ์‹œ

$ elixir examples/send_sms.exs
SMS ๋ฐœ์†ก ์ค‘...
๋ฐœ์†ก ์„ฑ๊ณต!
์‘๋‹ต: %{
  "groupId" => "G4V20241225123456ABCDEF",
  "messageId" => "M4V20241225123456ABCDEF",
  "to" => "01012345678",
  "from" => "0212345678",
  "type" => "SMS",
  "statusCode" => "2000",
  "statusMessage" => "์ •์ƒ ์ ‘์ˆ˜"
}

๊ฒ€์ฆ ์—๋Ÿฌ ์‹œ

$ elixir examples/error_handling.exs
=== ํ…Œ์ŠคํŠธ 1: ์ˆ˜์‹ ๋ฒˆํ˜ธ ๋ˆ„๋ฝ ===
์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ!
  ๋ฉ”์‹œ์ง€: to is required
  ํ•„๋“œ: to

์ธ์ฆ ์—๋Ÿฌ ์‹œ

$ elixir examples/send_sms.exs
SMS ๋ฐœ์†ก ์ค‘...
๋ฐœ์†ก ์‹คํŒจ!
์—๋Ÿฌ: %Solapi.Error.ApiError{
  status: 401,
  code: "Unauthorized",
  message: "์ธ์ฆ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค."
}

์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ

1. "to is required" ์—๋Ÿฌ

์›์ธ: ์ˆ˜์‹ ๋ฒˆํ˜ธ(to)๊ฐ€ ๋ˆ„๋ฝ๋จ

ํ•ด๊ฒฐ: ๋ฉ”์‹œ์ง€ ๋งต์— to ํ•„๋“œ ์ถ”๊ฐ€

%{to: "01012345678", from: "0212345678", text: "๋ฉ”์‹œ์ง€"}

2. "๋ฐœ์‹ ๋ฒˆํ˜ธ ๋ฏธ๋“ฑ๋ก" ์—๋Ÿฌ

์›์ธ: from ๋ฒˆํ˜ธ๊ฐ€ SOLAPI์— ๋“ฑ๋ก๋˜์ง€ ์•Š์Œ

ํ•ด๊ฒฐ:

  1. SOLAPI ์ฝ˜์†” ์ ‘์†
  2. ๋ฐœ์‹ ๋ฒˆํ˜ธ ๊ด€๋ฆฌ์—์„œ ๋ฒˆํ˜ธ ๋“ฑ๋ก
  3. ๋ณธ์ธ ์ธ์ฆ ์™„๋ฃŒ

3. ์ธ์ฆ ์‹คํŒจ (401 ์—๋Ÿฌ)

์›์ธ: API ํ‚ค ๋˜๋Š” ์‹œํฌ๋ฆฟ์ด ์ž˜๋ชป๋จ

ํ•ด๊ฒฐ:

# ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํ™•์ธ
echo $SOLAPI_API_KEY
echo $SOLAPI_API_SECRET

# ํ‚ค์— ๊ณต๋ฐฑ์ด๋‚˜ ์ค„๋ฐ”๊ฟˆ์ด ์—†๋Š”์ง€ ํ™•์ธ

4. ์นด์นด์˜ค ์•Œ๋ฆผํ†ก "ํ…œํ”Œ๋ฆฟ ์—†์Œ" ์—๋Ÿฌ

์›์ธ: templateId๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ๋ฏธ์Šน์ธ ์ƒํƒœ

ํ•ด๊ฒฐ:

  1. SOLAPI ์ฝ˜์†”์—์„œ ํ…œํ”Œ๋ฆฟ ID ํ™•์ธ
  2. ํ…œํ”Œ๋ฆฟ ์Šน์ธ ์ƒํƒœ ํ™•์ธ (๊ฒ€์ˆ˜์ค‘/์Šน์ธ/๋ฐ˜๋ ค)
  3. variables ํ‚ค๊ฐ€ ํ…œํ”Œ๋ฆฟ๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ

5. ์นด์นด์˜ค ์นœ๊ตฌํ†ก ๋ฐœ์†ก ์‹คํŒจ

์›์ธ: ์ˆ˜์‹ ์ž๊ฐ€ ์ฑ„๋„ ์นœ๊ตฌ๊ฐ€ ์•„๋‹˜

ํ•ด๊ฒฐ: ์นœ๊ตฌํ†ก์€ ์นด์นด์˜ค ์ฑ„๋„์„ ์นœ๊ตฌ ์ถ”๊ฐ€ํ•œ ์‚ฌ์šฉ์ž์—๊ฒŒ๋งŒ ๋ฐœ์†ก ๊ฐ€๋Šฅ


6. MMS "์ด๋ฏธ์ง€ ์—†์Œ" ์—๋Ÿฌ

์›์ธ: image_id๊ฐ€ ์ž˜๋ชป๋จ

ํ•ด๊ฒฐ:

  1. SOLAPI ์ฝ˜์†”์—์„œ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
  2. ๋ฐœ๊ธ‰๋ฐ›์€ image_id ์‚ฌ์šฉ
  3. ์ด๋ฏธ์ง€๊ฐ€ ๋งŒ๋ฃŒ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธ

7. SMS๊ฐ€ LMS๋กœ ์ž๋™ ๋ณ€ํ™˜๋จ

์›์ธ: ๋ฉ”์‹œ์ง€๊ฐ€ 90๋ฐ”์ดํŠธ๋ฅผ ์ดˆ๊ณผ

ํ™•์ธ ๋ฐฉ๋ฒ•:

text = "๋ฉ”์‹œ์ง€ ๋‚ด์šฉ"
IO.puts("๋ฐ”์ดํŠธ ํฌ๊ธฐ: #{byte_size(text)}")

์ฐธ๊ณ : ํ•œ๊ธ€ 1์ž = 3๋ฐ”์ดํŠธ (UTF-8)


๋ฌธ์„œ