NOMO.asia

!알림! 아래의 API는 2019년 11월 14일부터 서드파티에서 사용이 불가능하도록 변경되었습니다. 따라서 더 이상 유효하지 않은 내용입니다. 자세한 내용은 다음의 포스트에 정리해두었으므로 참고해주세요. [Twitch 가 비공식적으로 제공하던 API 들의 제공이 중지됨]


Twitch.tv의 패널

Twitch.tv의 패널은 PC화면 기준 재생화면 하단에 표시되는 영역으로, 스트리머 프로필, 채널 정보, 채팅 규칙, 후원 배너, 확장프로그램 등을 표시하는 역할을 한다. 패널은 더 정확하게는 컨트롤 패널(Control panel) 이라고 불리고, 사람에 따라 그냥 대시보드 라고 부르기도 한다.

Twitch.tv 패널의 정보가 필요하게 된 배경

나는 기존에 내가 보고있는 스트리머에게 편하게 도네이션 할 수 있는 확장기능을 만들어 사용하고 있었다. 일단 이를 위한 모든 작업에 앞서 보고있는 스트리머의 후원 주소를 가져와야 하는데, 한국에서 가장 많이 사용하는 후원 서드파티인 트윕(twip.kr)의 후원 주소는 https://twip.kr/donate/{streamer-id} 형태라서 스트리머의 아이디로부터 바로 아는 것이 가능하다(아주 간혹 스트리머의 아이디와 트윕 후원 주소가 다른 경우도 있기는 하지만).

그런데 최근 한국 트위치의 후원 서드파티 환경이 트윕만 사용하던 것에서 투네이션(toon.at)까지 사용하는 것으로 확장되기 시작했다. 문제는 투네이션 후원 주소의 기본값은 https://toon.at/donate/{18자리의-고유숫자} 형태라서 스트리머 아이디로부터 후원 주소를 유추할 수 없다는 것이다.

그래서 거의 모든 스트리머는 트위치 패널에 자신의 후원 배너를 등록해두므로, 트위치 패널의 정보를 긁어와서 트윕을 사용하는지 투네이션을 사용하는지 구분하기로 했다. 이를 위하여 투네이션의 경우 후원 주소를 긁어오기 위해 패널의 정보를 긁어올 필요성이 생겼다.

Twitch.tv 패널 정보 긁어오기

Twitch 패널의 정보는 아래와 같은 형태의 주소로 접속하면 json 형태로 바로 확인할 수 있다.

https://api.twitch.tv/api/channels/{channel-id}/panels?client_id={client-id}

client-id 를 발급받는 방법은 https://nomo.asia/344 를 참고하면 된다.

ajax 로 호출하는 예시는 아래와 같다. (jQuery 사용)

$.ajax({
    url: "https://api.twitch.tv/api/channels/{channel-id}/panels?client_id={client-id}",
    dataType: "json",
    success: function(res) {
        console.log(res);
    },
    error: function(err){
        console.log(err);
    }
});
응답은 아래와 같다.

[
  {
    "_id": 39866760,
    "user_id": 56648155,
    "display_order": 1,
    "kind": "default",
    "data": {
      "image": "https://static-cdn.jtvnw.net/jtv_user_pictures/panel-56648155-image-b2f7a598-b25c-429a-88f8-47c24b3065c5",
      "description": "In Twitch Plays Pokemon (TPP), you can bet on and influence matches of **Pokemon Battle Revolution** (PBR) in chat!\n\nYou have two currencies:\n\n**Pokeyen** - virtual currency, used to bet on Pokemon matches\n\n**Tokens** - virtual currency, based on stream donations, subscriptions, give-aways, and [PBR avatar creation](https://twitchplayspokemon.tv/avatars).\n\nPBR has four main phases: **Betting Phase, Match Phase, Results Phase** and **Sidegame**\n\n***Note:** TPP collects and uses some of your data so you can play. Find out what data we collect, how we collect it, and what we use it for by reading our privacy statement [here](https://github.com/TwitchPlaysPokemon/tpp-streamdocs/blob/master/privacy/privacy-statement.md).*"
    },
    "html_description": "

In Twitch Plays Pokemon (TPP), you can bet on and influence matches of Pokemon Battle Revolution (PBR) in chat!

\n\n

You have two currencies:

\n\n

Pokeyen - virtual currency, used to bet on Pokemon matches

\n\n

Tokens - virtual currency, based on stream donations, subscriptions, give-aways, and PBR avatar creation.

\n\n

PBR has four main phases: Betting Phase, Match Phase, Results Phase and Sidegame

\n\n

*Note: TPP collects and uses some of your data so you can play. Find out what data we collect, how we collect it, and what we use it for by reading our privacy statement here.*

\n", "channel": "twitchplayspokemon" }, { "_id": 40281076, "user_id": 56648155, "display_order": 2, "kind": "default", "data": { "image": "https://static-cdn.jtvnw.net/jtv_user_pictures/panel-56648155-image-7539b1bb-e51d-4a53-8483-ef8d875d48ae", "description": "**Place a bet** by typing: *!bet [amount] [team]* or *!bet [percentage of your balance]% [team]*\n\nSo if you want to place a P100 bet on Team Red, simply type: *!bet 100 red*\n\n* Odds aren’t locked in until match phase\n* Your payout multiplier is displayed at the top as percentages - so if you bet on Team Red with a 50% multiplier, you’ll get 50% of your bet amount back on top of how much you bet!\n* Your balance cannot drop below P100 (or P500 if you’re a subscriber)\n* Bets larger than P50,000 must be made before the 40 second mark\n* Bets larger than P5,000 must be made before the 20 second mark\n\n**Tip**: Ready to go with your gut? If you bet early and your team wins, you'll get a bonus! Keep an eye on the chat to see what bonus is available for the current match. You'd better hurry though; your bonus decreases the later you bet." }, "html_description": "

Place a bet by typing: !bet [amount] [team] or !bet [percentage of your balance]% [team]

\n\n

So if you want to place a P100 bet on Team Red, simply type: !bet 100 red

\n\n
    \n
  • Odds aren’t locked in until match phase
  • \n
  • Your payout multiplier is displayed at the top as percentages - so if you bet on Team Red with a 50% multiplier, you’ll get 50% of your bet amount back on top of how much you bet!
  • \n
  • Your balance cannot drop below P100 (or P500 if you’re a subscriber)
  • \n
  • Bets larger than P50,000 must be made before the 40 second mark
  • \n
  • Bets larger than P5,000 must be made before the 20 second mark
  • \n
\n\n

Tip: Ready to go with your gut? If you bet early and your team wins, you'll get a bonus! Keep an eye on the chat to see what bonus is available for the current match. You'd better hurry though; your bonus decreases the later you bet.

\n", "channel": "twitchplayspokemon" }, // 중략 { "_id": 39866913, "user_id": 56648155, "display_order": 19, "kind": "default", "data": { "image": "https://static-cdn.jtvnw.net/jtv_user_pictures/panel-56648155-image-3ac3b172-21ba-4692-ab9c-b5d76297b076", "description": "Firstly, a huge thanks to our past staff, developers, and anyone else who has contributed to the stream either directly, or indirectly. Thank you for all you've done with your help to maintain and keep the stream running!\n\n## Stream Owners\n- TwitchPlaysPokemon - **Original Streamer, Creator, and Owner**\n- Chaos_lord2 - **Current Streamer**\n- m4_used_rollout - **Host**\n*****\n## Mods\n- Chaos_lord2\n- HonshouReimu\n- Its_Reyn_Time\n- mathfreak231\n- xxmoonlotusxx\n- red031000\n- Sandoz1\n*****\n## Stream Developers\n- asdf14396\n- Chaos_lord2\n- chfoo\n- Felkcraft\n- ferraro\n- LittleToonCat\n- mathfreak231\n- Monstarules\n- red031000\n## Artists\n- AngelofSloths\n- BEXXXXXXX\n- GlaceonMyst\n- Mapper\n- Pioxys\n- Sev\n- tppTeiHard\n*****\n## ROM Developers\n- asdf14396\n- BloodlessNS\n- Charmybee99\n- KipTheFlareon\n- LightningXCE\n- PikalaxALT\n- m4_used_rollout\n- Monstarules\n*****\n## PBR Developers\n- Chaos_lord2\n- Felkcraft\n- ferraro\n## PBR Movesets\n- DANIMG12_\n- ferraro\n- Juicytoaster\n- Lavaseeker\n- Maiohneee\n- mathfreak231\n- MegaZard\n- rtrtrtrtrt\n- Sandoz1\n*****\n## Music\n- boombafunk\n- Legtendga\n- Ninjanitor\n- [smashcustommusic.com](https://www.smashcustommusic.com/)\n- [Winamp](http://www.winamp.com/) + [Chipamp plugin bundle](http://www.chipamp.org/)\n## Commentary\n- Dullagamer - **Commentary Admin**\n- Geforcefly\n- IronHammer\n- Monstarules\n- Nalaiscool\n- PokemonGod777\n- SingABrightSong\n*****\n## Description Updaters\n- evolem\n- KipTheFlareon\n- LightningXCE\n## Twitter Managers\n- Chaos_lord2\n- Sandoz1\n- Some1Funny\n*****\n## Sprites\n- Generation I - IV Pokemon GIFs obtained from TilableToast ([Twitch Link](https://www.twitch.tv/tilabletoast))\n- Generation I - V sprites obtained from Veekun ([Link](https://veekun.com/dex/downloads))\n- Generation VI sprites obtained from PokeCommunity ([Link & Full Credits](https://www.pokecommunity.com/showthread.php?t=314422))\n- Generation VII sprites obtained from PokeCommunity ([Link & Full Credits](https://www.pokecommunity.com/showthread.php?t=368703))\n- Custom Pokemon sprites by Pioxys ([Twitch Link](https://www.twitch.tv/Pioxys))" } ]

배열에 대해 for 문을 돌면서 Object 내의 필요한 정보를 확인하면 된다.

스트리머가 패널에 어떤 패널 요소를 이용하여 등록하였는지에 따라 Object 의 구성과 값이 달라지기 때문에, undefined 인지 확인해주지 않으면 코드 실행 도중 에러가 날 수 있다.

투네이션 링크가 존재하는 경우 가져오는 예제는 아래와 같다. (jQuery 사용)

$.ajax({
    url: "https://api.twitch.tv/api/channels/{channel-id}/panels?client_id={client-id}",
    dataType: "json",
    success: function(res) {
        console.log(res);
        $.each(res, function(index, value){
            if(res.data !== undefined && res.data.link !== undefined && res.data.link.indexOf("https://toon.at/donate/") !== -1){
                var toonat_link = res.data.link;
                console.log("투네이션 링크를 찾았다", toonat_link);
                return false;
            }
        });
    },
    error: function(err){
        console.log(err);
    }
});