Twip API 만들기

junah201·2022년 7월 30일
9
post-thumbnail

3줄요약
1. Twip을 이용한 프로그램을 만들려다가 API를 만들게 됨
2. 웹소켓과 함수형으로 개발하는 것이 어려웠지만 어찌어찌 하게 됨
3. PyPi에 처음 배포해 봄

링크
Github
PyPi

프로젝트를 시작하게 된 계기

어느날 갑자기 유튜브에서 후원을 통해 마인크래프트로 주변에 몬스터를 소환하는 컨텐츠를 하는 유튜버를 보게 되어 어? 나도 이런식으로 한번 만들어볼까?하는 마음에 가볍게 시작하게 되었다.

Twip이 뭐죠?

Twip은 트위치에서 스트리머에게 후원을 할 수 있는 플랫폼이고, 트위치 내부에서 후원 기능을 제공하지만 수수료가 Twip에 비해 2배 이상 높기 때문에 대부분 외부 후원 플랫폼을 사용합니다.

왜 API로 만들었나요?

처음에는 단순히 작동하는 프로그램만 만들려고 했으나 다른 사람도 쉽게 만들 수 있게 접하기 쉬운 Python으로 API로 만들면 나중에 비슷한 프로그램을 만들기 쉬울 것 같다는 생각이 들어서 API로 만들게 되었다.

또한 이런식으로 후원, 팔로우 등의 이벤트를 파싱하는 것이 Twip 약관에 위반되는 사항일까 혹시 몰라 공식 Twip 디스코드에서 물어봤더니 문제 없다는 답변을 받아서 바로 제작을 시작하였다.

본격적인 개발

Alert Box를 이용해야되는데...

Alert Box : Alert Box를 추가하시면 후원, 비트, 구독, 팔로우, 호스팅 등이 발생했을 때 방송 화면에 알려줄 수 있고, Alert Box URL 주소를 방송 프로그램의 브라우저 소스에 추가하여 사용한다.

Alert Box에서 F12를 눌러 개발자 콘솔을 통해 HTML과 JS를 사용해보니 wss://io.mytwip.net/socket.io과 같은 웹소켓 주소를 통해 이벤트를 수신 받을 수 있었다.

이 웹소켓에 보내야 하는 항목은 다음과 같다.

Alert Box id : https://twip.kr/widgets/alertbox/XXXXXXX 에서 XXXXXXX 부분에 해당하는 것으로 API 사용자가 직접 입력하는 값
Alert Box Version : 아마도 Alert Box의 버전으로 추측하고 있으며, Alert Box Url에서 얻을 수 있다.
Alert Box Token : 아마도 스트리머의 토큰으로 추측하고 있으며, Alert Box Url에서 얻을 수 있다.

이 항목을 이용해서 아래 URL로 웹소켓 연결을 하면 이벤트를 수신 받을 수 있다.

wss://io.mytwip.net/socket.io/?alertbox_key={alert_id}&version={version}&{token)}&transport=websocket

이벤트 처리

처음 계획했을 때는 아래 이벤트들을 수신 받기로 하였다.

on_donate : 트윕 후원이 왔을 때
on_follow : 팔로우가 왔을 때
on_subscribe : 구독이 왔을 때
on_hosting : 호스팅이 왔을 때
on_cheer : 비트 후원이 왔을 때
on_sound : 영상 후원이 왔을 때
on_ready : 모든 이벤트를 수신 받을 준비가 되었을 때

각 이벤트에 대해서 하나의 클래스에 모든 값을 넣어둔 후에 각 이벤트에서 얻은 요소를 API 사용자가 사용할 수 있도록 전송하려고 하였다.

# __init__ 함수

class Donate:
	def __init__(self):
          self.type = "donate"
          self.id = None
          self.nickname = None
          self.amount = None
          self.comment = None
          self.watcher_id = None
          self.subbed = None
          self.repeat = None
          self.tts_type = None
          self.tts_url = None
          self.slotmachine = self.Slotmachine()
          self.effect = None
          self.variation_id = None
          
          
# 이벤트 처리 함수

@staticmethod
def __data_convert(data: list):
	data_type = data[0]
    if data_type == "new donate":
        data_value = data[1]
        donate = Twip.Donate()

        donate.id = data_value.get("_id")
        donate.nickname = data_value.get("nickname")
        donate.amount = data_value.get("amount")
        donate.comment = data_value.get("comment")
        donate.watcher_id = data_value.get("watcher_id")
        donate.subbed = data_value.get("subbed")
        donate.repeat = data_value.get("repeat")
        donate.tts_type = data_value.get("ttstype")
        donate.tts_url = data_value.get("ttsurl")
        if data_value.get("slotmachine_data") != None:
            donate.slotmachine.items = data_value.get("slotmachine_data").get("items")
            donate.slotmachine.result = data_value.get("slotmachine_data").get("gotcha")
            donate.slotmachine.sound = data_value.get("slotmachine_data").get("config").get("sound")
            donate.slotmachine.point = data_value.get("slotmachine_data").get("config").get("point")
            donate.slotmachine.duration = data_value.get("slotmachine_data").get("config").get("duration")
        donate.effect = data_value.get("effect")
        donate.variation_id = data_value.get("variation_id")

        return donate

함수형으로 개발

import twip

Twip = twip.Twip()

@Twip.event
def on_donate(ctx):
    print(f"id : {ctx.id}")
    print(f"nickname : {ctx.nickname}")
    print(f"amount : {ctx.amount}")
    print(f"comment : {ctx.comment}")
    
Twip.run("your alert box id", "your twip api token"")

위와 같은 방식으로 event 처리를 하고 싶었다.
하지만 한번도 다음과 같은 방식으로 이벤트를 처리하는 방법을 몰랐기 때문에 많은 뻘짓이 있었지만

# Twip 클래스

def event(self, func):
    if func.__name__[:3] != "on_":
        raise Exception("Event name must start with 'on_'")
    self.events[self.__event_name_convert(func.__name__)] = func

클래스 내부에 self.event에 사용자가 지정한 이벤트에 대한 함수를 저장해두고, 해당 이벤트가 왔을 때 그 함수를 실행하는 식으로 구현하였다.

사실 이런식으로 구현된 모듈을 discord.py 밖에 못봐서 이런식으로 구현하는 것이 일반적인 방법인지는 잘 모르겠다. 암튼 그냥 구현되기만하면 된거겠지?

PyPi에 배포

PyPi가 뭔가요?

pip라는 도구를 통해 다른 모듈을 쉽게 다운받을 수 있게 해둔 npm 같은 패키지 관리 도구 입니다.

배포

단순히 PyPi 계정만 있으면 누구나 쉽게 배포할 수 있는 점이 신기하였다.

개발 후기

이렇게 Twip API 개발이 무사히 완료되었다. 처음 시작할 때는 웹소켓 수신이 어려울 것이라고 걱정했었지만, 스텍오버플로우 고인물 개발자분이 질문을 남기면 신속 정확하게 대답해주셔서 쉽게 해결 할 수 있었다. 오히려 함수만으로 작동하게 하는 구조를 만드는 것이 오히려 더 어려웠다. 아무튼 성공적으로 개발을 완료했고 이것을 이용해서 간단한 프로그램을 개발해보려고 한다.

링크

Github
PyPi

profile
개발자가 되고 싶은 고딩

2개의 댓글

comment-user-thumbnail
3일 전

글 잘 봤습니다. :) 혹시 팀 단위로 개발을 하시는 건가요?

1개의 답글