-
Ref - Session | CHZZK
-
μ±ν λ©μμ§ μ‘°νμ (νμ ꡬλ μ΄ νμν μ)νμ μ‘°νScopeμ λν κΆν μ¬μ¬κ° λͺ¨λ λ§μ³€μμ κ°μ ν©λλ€.μ΄λ₯Ό μλ£νμ§ μμ κ²½μ°
500 Internal Server Errorμ ν¨κ» μΈμ μ°κ²° URL λ°κΈλΆν° λΆκ°λ₯ν©λλ€.
-
λ§μ μΈμμ Eventλ₯Ό ꡬλ ν΄μΌνλ κ²½μ°(μ: λ§μΈν¬λννΈ μ€νΈλ¦¬λ¨Έ νμμ 1μ²λͺ μ°λνλ κ²½μ° λ±), κ° μ€νΈλ¦¬λ¨Έκ° κ°λ°μμ μ ν리μΌμ΄μ μ OAuth λ‘κ·ΈμΈμ νκ²λ νμ¬ Access Tokenμ λ°κΈ λ°μ μΈμ μ μμ±νλ λ°©μμ μΆμ²λ립λλ€.
μλ₯Ό λ€μ΄ μν©μ κ°μ ν΄λ³΄κ² μ΅λλ€. Client μΈμ¦μΌλ‘ μΈμ URLμ λ°κΈ λ°μ μ΄ 15κ°μ μ±λμ μ±ν λ° νμ μ΄λ²€νΈλ₯Ό λͺ¨λ ꡬλ νλ κ²½μ°, Client μΈμ¦μΌλ‘ μμ±λ μΈμ μ΄ μ΄ 30κ°κ° λμ΄ μΆκ°μ μΈ μΈμ μ°κ²° μ μ§μ μ νμ΄ λ°μν©λλ€.
ννΈ, Access Tokenμ ν΅ν μΈμ URL λ°κΈ λ°©μμ ν μΈμ λΉ μ΅λ 3κ°μ μ°κ²°μ μ μ§ν μ μμΌλ©°, μ΄λ μ€νΈλ¦¬λ¨Έ μκ° λ§μλ κ°λ³μ μΌλ‘ μΈμ μ΄ κ΄λ¦¬λκΈ° λλ¬Έμ μ°κ²°μ΄ λκΈ°λ μν©μ λλΉλ₯Ό μ ν΄λμλ€λ©΄ μΈμ μ°κ²° μ μ§ μ νμ 걸리λ μν©μ νΌν μ μμ΅λλ€.
-
APIλ‘ λ°κΈλ μΈμ URLμ μ μ μ ν¨μκ°μ μ ννκ² μ μ μμΌλ λ§μ½ μ°κ²°μ μλνμ λ URLμ΄ μ¬λ°λ¦μλ λΆκ΅¬ μ°κ²° μλμ μ°κ²°μ΄ λ°λ‘ λκΈ°λ κ²½μ°, ν΄λΉ URLμ΄ λ§λ£λκ²μ λλ€. μ΄ κ²½μ° μλ‘ λ°κΈνμ¬ μ°κ²°ν΄μ£Όμ μΌν©λλ€.
κ°μΈμ μΈ ν μ€νΈμμλ μ½ 30μ΄ ~ 1λΆκ° μ°κ²° μλκ° μ‘΄μ¬νμ§ μλ κ²½μ° URLμ΄ λ§λ£λλκ²μΌλ‘ νμΈνμ΅λλ€.
-
Client μΈμ¦λ§μ μ΄μ©ν΄μ κ°λ°μμ μ±λ μ΄μΈ ν μ€νΈλ¦¬λ¨Έμ μ±ν μ΄λ νμμ ꡬλ νκ³ μΆμ κ²½μ°, REST APIλ‘ κ΅¬λ μμ²μ μ μ‘ ν λ Authorization ν€λμ ν ν° κ°μ μ€νΈλ¦¬λ¨Έκ° μ¬μ μ μΈμ¦ μμ μ μλ£νμ¬ λ°κΈν Access Token κ°μΌλ‘ μ§μ ν΄μΌν©λλ€.
λ€λ§ μμμ μμ νμλ―μ΄ ν μΈμ λΉ μ΅λλ‘ κ΅¬λ ν μ μλ μ΄λ²€νΈ κ°μλ₯Ό κ³ λ €νμ¬, κ°μΈμ μΌλ‘ μΈμ μ체λ₯Ό Access Token λ°©μμΌλ‘ μμ±νλ κ²μ μΆμ²λ립λλ€.
-
λ΄μ©μ μ½μΌμ ¨λ€λ©΄ μκ² μ§λ§, λ€. μ€νΈλ¦¬λ¨Έμ λ‘κ·ΈμΈμ μ§ννμ§ μκ³ ν μ€νΈλ¦¬λ¨Έμ μ±ν μ΄λ νμ μ΄λ²€νΈλ₯Ό ꡬλ ν μ μλ λ°©λ²μ μμ μμ΅λλ€.
κ°λ°μ λ³ΈμΈμ μ ν리μΌμ΄μ Client μ 보λ§μ μ΄μ©ν΄μ κ°λ°μ λ³ΈμΈμ μ±λ ꡬλ λ μμ λΆκ°λ₯ν©λλ€. μμ μ μ±λμ ꡬλ ν λμλ REST APIμ μΈμ¦ ν ν°μ λ£μ΄μΌνλκΉμ.
-
-
νμ¬ Client μΈμ¦μ ν΅ν΄ μμ±λ μΈμ λ° μΈμ ν€μ λν΄ μλμ λ΄μ©μ νμΈμ΄ μ΄λ ΅κ±°λ λΆκ°λ₯νκ²μΌλ‘ νμ λ©λλ€.
- μΈμ URLμ λ°κΈ ν λ€ μ°κ²°μ μ§ννμΌλ, μΈμ μ°κ²°μ΄ λμ€μ κ°μκΈ° λκΈ΄ κ²½μ°μ μ΅μ΄ μ°κ²° μ ν μκ°μ΄ λ§λ£λ κ²½μ°μ μΈμ λͺ©λ‘μμ μ°κ²°λμ§ μμ μΈμ μ λ³΄κ° μΈμ λͺ©λ‘μμ μ¬λΌμ§λ μκ° (νμ¬ μ΅λ 39κ°μ μΈμ μμ± μ΄ν μΆκ° μΈμ μ μμ±νλ €κ³ ν λ μ¬λΌμ§λ 쑰건μΌλ‘ μΆμΈ‘λ©λλ€.)
- κ°μ λ‘ μΈμ μ μΈμ λͺ©λ‘μμ μ κ±°ν μ μλ λ°©λ² (νμ¬λ‘μ¨λ λ°©λ²μ΄ μμ΅λλ€.)
-
κ°μ₯ λ§μ μ°©μ€κ° λ°μ ν μ μλ λΆλΆμΌλ‘, 곡μ λ¬Έμμμ "μ΅λ nκ°μ API μ°κ²°μ μ μ§ ν μ μμ" μ΄λΌ μ ν λ΄μ©μ λμμ μ°κ²°μ μ μ§μν¬ μ μλ κ°μλ₯Ό λ»νλ©°, κ°λ°μκ° μ΅λλ‘ μμ± ν μ μλ μΈμ μ κ°μκ° μλλλ€. μΈμ μ μΈμ λ μ§ μ¬λ¬κ° μμ±ν μ μλκ²μΌλ‘ 보μ λλ€.
λ€λ§ μ΅λ μΈμ μ‘°ν κ°λ₯ κ°μμΈ 39κ° μ΄μμ μμ±νλ©΄ μ΄λ»κ² λλμ§μ λν΄μλ νμΈν΄λ³΄μ§ λͺ»νμ΅λλ€.
-
μ΄μ΄μ, μ΄λ²€νΈλ₯Ό ꡬλ /ꡬλ μ·¨μ ν λ μ¬μ©νλ
sessionKeyκ°μ POST μμ²μ΄μ΄λ Query Parameter(?sessionKey=XXXXXX)λ‘ μ€μ ν΄μΌνλ©° μμ² Bodyμ JSON ννλ‘ μμ±νλ λ°©μμ μ§μλμ§ μμ΅λλ€. (μ¬λ΄..) -
WebSocket μ°κ²°μ΄ λμ΄μμ§ μμ μνμμ REST APIλ₯Ό ν΅ν΄ μΈμ ν€λ§ μ΄μ©νμ¬ Eventλ₯Ό ꡬλ ν μ μμ΅λλ€. μΉμ§μ§ μΈ‘μμ
400 Bad Requestμ μ°κ²° νμΈ μ€λ₯ λ©μμ§λ₯Ό μλ΄ν©λλ€.
- TypeScript κΈ°μ€ socket.io-client λ²μ 2.0.3, @types/socket.io-client λ²μ 1.4.36μ΄ κ°λ₯ν μ΅λ λ²μ μΌλ‘ 보μ λλ€. μ΄μΈμ λ²μ μ μ¬μ©νλ©΄ μλ²λ¨μμ κ°μ λ‘ μ°κ²°ν΄μ£Όμ§ μμ΅λλ€.
- Java/Kotlin κΈ°μ€ socket.io-client-java λ²μ 1.0.2κ° κ°λ₯ν μ΅λ λ²μ μΌλ‘ 보μ λλ€. μ΄μΈμ λ²μ μ μ¬μ©νλ©΄ μλ²λ¨μμ κ°μ λ‘ μ°κ²°ν΄μ£Όμ§ μμ΅λλ€.
-
Session Socket URL(λ°κΈ λ°μ μΈμ μ°κ²° URLμ μλ―Έ)μ
https://ssio<λ²νΈ>.nchat.naver.com:443?auth=<AUTH_TOKEN>λ‘ λ°νλλ©° μ£Όλ‘ νμΈλ λ²νΈλ€λ‘07,09,27μ΄ μ‘΄μ¬ν©λλ€. λ°κΈλ URL λ΄μ μ«μ μ΄μΈ λ€λ₯Έ μ«μλ‘ μ°κ²°μ΄ μ μμ μΌλ‘ μ§νλλμ§λ μλν΄λ³΄μ§ μμμ΅λλ€. -
ν μ€νΈλ₯Ό μ§ννκΈ° μν΄ μ¬μ©ν μ½λ μμ μ΄ Gistμ 첨λΆν©λλ€.
μλμ λ΄μ©μ μΈμ μ°κ²° μ΄ν SYSTEM μ΄λ²€νΈλ₯Ό ꡬλ νμμ λ μμ λ°μ μ μλ λ©μμ§ μ’ λ₯μ λλ€.
λͺ¨λ λ©μμ§λ JSON λ©μμ§λ‘ μ΄λ£¨μ΄μ ΈμμΌλ©°, κ°λ μ±μ μν΄ Indentλ₯Ό μ£Όμμ΅λλ€. μ€μ λ‘λ ν μ€λ‘ νμλ©λλ€.
λΆκ°μ μΈ μ€λͺ μ μνμ¬ λ¬Έμμ JSONμ λͺ¨λ JSONCλ‘ μμ±λμμ΅λλ€! μ€μ JSONμμλ μ£Όμμ΄ λΆκ°λ₯ν μ μ μνμκΈΈ λ°λλλ€.
- μ±ν μ°κ²° μ§ν μ
{
"type": "connected",
"data": {
"sessionKey": "<SOCKET_SESSION_KEY>"
// νμ¬ μ°κ²°λ μΈμ
μ Session Key κ°μ νλνμ€ μ μμ΅λλ€.
// μ μ 보λ₯Ό μ΄μ©νμ¬ Eventλ₯Ό ꡬλ
νκ±°λ μΈμ
μ ꡬλΆνλ μ©λλ‘ μ¬μ©ν μ μμ΅λλ€.
}
}- POST μμ²μΌλ‘ μ±ν
Eventλ₯Ό ꡬλ
ν μ (
/open/v1/sessions/events/subscribe/chat?sessionKey=<SOCKET_SESSION_KEY>)
{
"type": "subscribed",
"data": {
"eventType": "CHAT", // ꡬλ
Event νμ
, μμ κ°λ₯ν κ°μ CHAT, DONATIONμ
λλ€.
"channelId": "<SUBSCRIBED_CHANNEL_ID>" // ꡬλ
ν μ±λ ID
}
}- POST μμ²μΌλ‘ νμ Eventλ₯Ό ꡬλ
ν μ (
/open/v1/sessions/events/subscribe/donation?sessionKey=<SOCKET_SESSION_KEY>)
{
"type": "subscribed",
"data": {
"eventType": "DONATION", // ꡬλ
Event νμ
, μμ κ°λ₯ν κ°μ CHAT, DONATIONμ
λλ€.
"channelId": "<SUBSCRIBED_CHANNEL_ID>" // ꡬλ
ν μ±λ ID
}
}- POST μμ²μΌλ‘ μ±ν
Eventλ₯Ό ꡬλ
μ·¨μν μ (
/open/v1/sessions/events/unsubscribe/chat?sessionKey=<SOCKET_SESSION_KEY>)
{
"type": "unsubscribed",
"data": {
"eventType": "CHAT", // ꡬλ
ν΄μ§ Event νμ
, μμ κ°λ₯ν κ°μ CHAT, DONATIONμ
λλ€.
"channelId": "<UNSUBSCRIBED_CHANNEL_ID>" // ꡬλ
ν΄μ§ν μ±λ ID
}
}- POST μμ²μΌλ‘ νμ Eventλ₯Ό ꡬλ
μ·¨μν μ (
/open/v1/sessions/events/unsubscribe/donation?sessionKey=<SOCKET_SESSION_KEY>)
{
"type": "unsubscribed",
"data": {
"eventType": "DONATION", // ꡬλ
ν΄μ§ Event νμ
, μμ κ°λ₯ν κ°μ CHAT, DONATIONμ
λλ€.
"channelId": "<UNSUBSCRIBED_CHANNEL_ID>" // ꡬλ
ν΄μ§ν μ±λ ID
}
}μλμ λ΄μ©μ μΈμ μ°κ²° μ΄ν CHAT μ΄λ²€νΈλ₯Ό ꡬλ νμμ λ μμ λ°μ μ μλ λ©μμ§ μ’ λ₯μ λλ€.
λͺ¨λ λ©μμ§λ JSON λ©μμ§λ‘ μ΄λ£¨μ΄μ ΈμμΌλ©°, κ°λ μ±μ μν΄ Indentλ₯Ό μ£Όμμ΅λλ€. μ€μ λ‘λ ν μ€λ‘ νμλ©λλ€.
λΆκ°μ μΈ μ€λͺ μ μνμ¬ λ¬Έμμ JSONμ λͺ¨λ JSONCλ‘ μμ±λμμ΅λλ€! μ€μ JSONμμλ μ£Όμμ΄ λΆκ°λ₯ν μ μ μνμκΈΈ λ°λλλ€.
- μΌλ° μ±ν
{
"channelId": "<STREAMING_CHANNEL_ID>", // λ°©μ‘μΈμ μ±λ ID
"senderChannelId": "<CHAT_SENDER_CHANNEL_ID>", // λ©μμ§λ₯Ό μ μ‘ν μ¬λμ μ±λ ID
"profile": { // μΉμ§μ§ νλ‘ν μ 보
"nickname": "<CHAT_SENDER_NICKNAME>", // λ©μμ§λ₯Ό μ μ‘ν μ¬λμ λλ€μ
"verifiedMark": false, // μΉμ§μ§ μΈμ¦ λ§ν¬ (ννΈλ μ€νΈλ¦¬λ¨Έ μΈμ¦ λ§ν¬λ‘ μΆμ )
"badges": [ // λ±μ§ μ΄λ―Έμ§ URL λͺ©λ‘
{
"imageUrl": "https://ssl.pstatic.net/static/nng/glive/icon/streamer.png" // μ€νΈλ¦¬λ¨Έ λ³ΈμΈμ λ±μ§ μ΄λ―Έμ§
}
// λ±μ§ μ’
λ₯λ λ€μν λ§νΌ, λͺ¨λ λ±μ§μ URLμ κΈ°μ
νκΈ°λ μ΄λ €μ΄ μ μν΄ λΆνλ립λλ€.
]
},
"content": "do test {:d_47:}", // μ±ν
λ΄μ©, μΉμ§μ§ μ±ν
μ΄λͺ¨μ§λ μ€κ΄νΈ λ΄μ μ½λ‘ νμμ κ·Έ μμ μ΄λͺ¨μ§ μ΄λ¦μ λ΄λ ννλ‘ κ΅¬μ±λμ΄μμ΅λλ€.
"emojis": { // μ΄λͺ¨μ§ μ΄λ¦ λ° URL
"d_47": "https://ssl.pstatic.net/static/nng/glive/icon/b_07.gif?type=f60_60"
},
"messageTime": 1739110481425 // λ©μμ§ μ μ‘ μκ°
}μλμ λ΄μ©μ μΈμ μ°κ²° μ΄ν DONATION μ΄λ²€νΈλ₯Ό ꡬλ νμμ λ μμ λ°μ μ μλ λ©μμ§ μ’ λ₯μ λλ€.
λͺ¨λ λ©μμ§λ JSON λ©μμ§λ‘ μ΄λ£¨μ΄μ ΈμμΌλ©°, κ°λ μ±μ μν΄ Indentλ₯Ό μ£Όμμ΅λλ€. μ€μ λ‘λ ν μ€λ‘ νμλ©λλ€.
λΆκ°μ μΈ μ€λͺ μ μνμ¬ λ¬Έμμ JSONμ λͺ¨λ JSONCλ‘ μμ±λμμ΅λλ€! μ€μ JSONμμλ μ£Όμμ΄ λΆκ°λ₯ν μ μ μνμκΈΈ λ°λλλ€.
- μΌλ° νμ
{
"donationType": "CHAT", // νμ νμ
, κ°λ₯ν νμ
μ νμ¬ CHAT, VIDEO λ μ’
λ₯ μ
λλ€.
"channelId": "<DONATION_RECEIVED_CHANNEL_ID>", // νμμ μμ ν μ±λ ID (μ€νΈλ¦¬λ¨Έ)
"donatorChannelId": "<DONATOR_CHANNEL_ID>", // νμμ λ³΄λΈ μ±λ ID (μμ²μ)
"donatorNickname": "<DONATOR_NICKNAME>", // νμμ λ³΄λΈ μ±λμ λλ€μ (μμ²μ λλ€μ)
"payAmount": 1000, // νμ κΈμ‘
"donationText": "TEST" // νμ λ΄μ©
}- μμ νμ
- μμ URLμ λν λ³λ μ 보λ μ λ¬λμ§ μμ΅λλ€.
{
"donationType": "VIDEO", // νμ νμ
, κ°λ₯ν νμ
μ νμ¬ CHAT, VIDEO λ μ’
λ₯ μ
λλ€.
"channelId": "<DONATION_RECEIVED_CHANNEL_ID>", // νμμ μμ ν μ±λ ID (μ€νΈλ¦¬λ¨Έ)
"donatorChannelId": "<DONATOR_CHANNEL_ID>", // νμμ λ³΄λΈ μ±λ ID (μμ²μ)
"donatorNickname": "<DONATOR_NICKNAME>", // νμμ λ³΄λΈ μ±λμ λλ€μ (μμ²μ λλ€μ)
"payAmount": 1000, // νμ κΈμ‘
"donationText": "μΉμ§μ§, μ€νΈλ¦¬λ°μ΄ μμλ©λλ€." // νμ λ΄μ©, μμ νμμ κ²½μ° νμ λ΄μ©μ΄ μμμ μ λͺ©μ
λλ€.
}-
νμ μ΄λ²€νΈλ λλΆλΆ μ€μ νμ μ΄λ²€νΈμ λν΄μλ§ λμν©λλ€. νμμ ν μ€νΈ νκ³ μΆλ€λ©΄ μμ΅ μ°½μΆμ΄ νμ±ν λ μ±λ κΈ°μ€μΌλ‘
μΉμ§μ§ μ€νλμ€ β λ°©μ‘ κ΄λ¦¬ β μλ¦Ό β νμ μλ¦ΌμΌλ‘ μ΄λνμ¬νμ μλ¦Ό ꡬμ μ΅νλ¨μ "ν μ€νΈ μλ¦Ό 보λ΄κΈ°"κΈ°λ₯μ μ΄μ©ν΄μ£ΌμκΈΈ λ°λλλ€. (https://studio.chzzk.naver.com/μ±λ ID/notification) -
μ΅λͺ νμμ μ§νν μ
donatorChannelIdλ"anonymous",donatorNicknameμ""μ λλ€. -
μ€νΈλ¦¬λ¨Έμ νμ κΈμ‘ νμ μ¬λΆμ κ΄κ³ μμ΄ κ³΅μ APIλ₯Ό ν΅νμ¬ λ°μ Eventμμλ
payAmountκ° νμλ©λλ€.
Q. μ΄κ±° 곡μ ν΄λ λλμ?
A. λ€ λ©λλ€.
Q. λ¬Έμμ μλͺ»λ μ 보λ μ€λ₯, μ€λλ μ λ³΄κ° ν¬ν¨λμ΄μμ΄μ μμ νκ³ μΆμ΄μ.
A. λκΈ λ¬μμ£ΌμΈμ. κ°μΈ μ΄λ©μΌλ‘ GitHubλ₯Ό ν΅ν΄ μλ¦Όμ΄ μ€κΈ° λλ¬Έμ, μ¬μ μκ°μ μμ ν΄λκ² μ΅λλ€.
@HyunWinter
λ©μμ§ μμ νμΈμ΄ λ¦κ² λμ΄ μ²¨μΈν©λλ€.
A. μμ½κ²λ νμ¬λ‘μ¨λ λ°©λ²μ΄ μμ κ² κ°μ΅λλ€... π
μ μ§μΈμ΄ νλ‘λμ μ 곡μ APIλ₯Ό μ¬μ©νλ©΄μ μ€μ λ‘ Access Token κ΄λ¦¬ μ½λμμ Refresh λ‘μ§μ λΉ λ¨λ € Tokenμ΄ λ§λ£λ μν©μ΄ μμμ΅λλ€. κΈ΄κΈνκ² μ¬λ‘κ·ΈμΈμ΄ νμν μν©μμ μ€λ₯ μμΈ κ²μ¦ λ° μ€νΈλ¦¬λ¨Έμκ² μ¬λ‘κ·ΈμΈ μμ²μ μ§ννλλ°μ κ½€λ νμ μΌλ€κ³ ν©λλ€..
λ€νν κ·Έ μν©μμλ μ€νΈλ¦¬λ¨ΈλΆμ΄ λΉ λ₯΄κ² λ‘κ·ΈμΈν΄μ£Όμ μ λ¬Έμ κ° ν΄μλμμ΅λλ€λ§, μ€μκ° μν©μ΄ μ€μν νΉμ λν μλΉμ€ νλ‘λμ νκ²½μμλ 골머리 μ©μ λ¬Έμ λ‘ λ³΄μ λλ€.
λ€μ΄λ²κ° μ΄ λΆλΆμ μ‘°κΈ λ κ°μ ν΄μ£ΌμμΌλ©΄ νλλ°(Response Codeλ μμΈν μ€λ₯ λ©μμ§ λ±), λ μ΄μ©κ² μ΅λκΉ. μΌλ¨ 곡μ APIλΌλ μ€κ±°μ κ°μ¬νκ² μκ°νκ³ μμ΅λλ€ π