Skip to content

Commit

Permalink
Use v3 api (#1)
Browse files Browse the repository at this point in the history
* add tests which actually poll the BTTV api and ensure certain emotes exist.

Emotes we check are:
NaM in global emote set
WAYTOODANK in pajlada's channel emote set
  • Loading branch information
pajlada committed Nov 16, 2019
1 parent e617d01 commit b9ebf8c
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 38 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ Uses [jsonapi](https://github.com/dankeroni/jsonapi) by [dankeroni](https://gith

Inspired by [gotwitch](https://github.com/dankeroni/gotwitch)

## Example for getting a Room object
Uses BetterTTV's v3 api

## Example for getting a Channel object
```go
package main

Expand All @@ -17,7 +19,8 @@ import (
var api = gobttv.New()

func main() {
api.GetEmotes("pajlada", onSuccess, onHTTPError, onInternalError)
// 11148817 is the user ID for pajlada
api.GetEmotes("11148817", onSuccess, onHTTPError, onInternalError)
}

func onSuccess(emotes gobttv.EmotesResponse) {
Expand Down
34 changes: 17 additions & 17 deletions channels.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@ package gobttv

import "github.com/dankeroni/jsonapi"

// ChannelEmoteData json to struct
type ChannelEmoteData struct {
ID string `json:"id"`
Channel string `json:"channel"`
Code string `json:"code"`
ImageType string `json:"imageType"`
}

// ChannelResponse json to struct
type ChannelResponse struct {
Status int `json:"status"`
URLTemplate string `json:"urlTemplate"`
Bots []string `json:"bots"`
Emotes []ChannelEmoteData `json:"emotes"`
ID string `json:"id"`
Bots []string `json:"bots"`
ChannelEmotes []Emote `json:"channelEmotes"`
SharedEmotes []Emote `json:"sharedEmotes"`
}

// GetChannel request for GET https://api.betterttv.net/channels/:channelName
func (bttvAPI *BTTVAPI) GetChannel(channelName string, onSuccess func(ChannelResponse),
// GetChannel request for GET https://api.betterttv.net/3/cached/users/twitch/:channelID
func (bttvAPI *BTTVAPI) GetChannel(channelID string, onSuccess func(ChannelResponse),
onHTTPError jsonapi.HTTPErrorCallback, onInternalError jsonapi.InternalErrorCallback) {
var channel ChannelResponse
var response ChannelResponse
onSuccessfulRequest := func() {
onSuccess(channel)
for i := range response.ChannelEmotes {
response.ChannelEmotes[i].populateURLs()
}

for i := range response.SharedEmotes {
response.SharedEmotes[i].populateURLs()
}

onSuccess(response)
}
bttvAPI.Get("/2/channels/"+channelName, nil, &channel, onSuccessfulRequest,
bttvAPI.Get("/cached/users/twitch/"+channelID, nil, &response, onSuccessfulRequest,
onHTTPError, onInternalError)
}
39 changes: 39 additions & 0 deletions channels_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package gobttv

import "testing"

func TestFindChannelEmoteWAYTOODANK(t *testing.T) {
e := Emote{
ID: "5ad22a7096065b6c6bddf7f3",
Code: "WAYTOODANK",
ImageType: "gif",

URLs: URLs{
X1: "https://cdn.betterttv.net/emote/5ad22a7096065b6c6bddf7f3/1x",
X2: "https://cdn.betterttv.net/emote/5ad22a7096065b6c6bddf7f3/2x",
X4: "https://cdn.betterttv.net/emote/5ad22a7096065b6c6bddf7f3/3x",
},
}

found := false

c := make(chan struct{})
onResponse := func(response ChannelResponse) {
for _, emote := range response.ChannelEmotes {
if emote == e {
found = true
break
}
}

close(c)
}

api.GetChannel("11148817", onResponse, onHTTPError(t), onInternalError(t))

<-c
if !found {
t.Fatalf("Did not find WAYTOODANK in set of channel emotes, this might be due to the API being changed")
}

}
15 changes: 15 additions & 0 deletions common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package gobttv

import "testing"

func onHTTPError(t *testing.T) func(statusCode int, statusMessage, errorMessage string) {
return func(statusCode int, statusMessage, errorMessage string) {
t.Fatalf("HTTP error %d (%s): %s", statusCode, statusMessage, errorMessage)
}
}

func onInternalError(t *testing.T) func(err error) {
return func(err error) {
t.Fatal(err)
}
}
21 changes: 21 additions & 0 deletions emote.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gobttv

const emoteURLPrefix = "https://cdn.betterttv.net/emote/"

// Emote is the lowest common description of the BetterTTV emote
type Emote struct {
// Fetched straight from the API
ID string `json:"id"`
Code string `json:"code"`
ImageType string `json:"imageType"`

// Filled in by us with populateURLs
URLs URLs
}

func (e *Emote) populateURLs() {
var emoteURL = emoteURLPrefix + e.ID
e.URLs.X1 = emoteURL + "/1x"
e.URLs.X2 = emoteURL + "/2x"
e.URLs.X4 = emoteURL + "/3x"
}
29 changes: 11 additions & 18 deletions emotes.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
package gobttv

import "github.com/dankeroni/jsonapi"

// GlobalEmoteData json to struct
type GlobalEmoteData struct {
URL string `json:"url"`
Width int `json:"width"`
Height int `json:"height"`
ImageType string `json:"imageType"`
Regex string `json:"regex"`
Channel interface{} `json:"channel"`
EmoticonSet string `json:"emoticon_set,omitempty"`
}
import (
"github.com/dankeroni/jsonapi"
)

// EmotesResponse json to struct
type EmotesResponse struct {
Status int `json:"status"`
Emotes []GlobalEmoteData `json:"emotes"`
}
type EmotesResponse []Emote

// GetEmotes request for GET https://api.betterttv.net/emotes
// GetEmotes request for GET https://api.betterttv.net/3/cached/emotes/global
func (bttvAPI *BTTVAPI) GetEmotes(onSuccess func(EmotesResponse),
onHTTPError jsonapi.HTTPErrorCallback, onInternalError jsonapi.InternalErrorCallback) {
var emotes EmotesResponse
onSuccessfulRequest := func() {
for i := range emotes {
emotes[i].populateURLs()
}

onSuccess(emotes)
}
bttvAPI.Get("/emotes", nil, &emotes, onSuccessfulRequest,

bttvAPI.Get("/cached/emotes/global", nil, &emotes, onSuccessfulRequest,
onHTTPError, onInternalError)
}
42 changes: 42 additions & 0 deletions emotes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package gobttv

import (
"testing"
)

var api = New()

func TestEnsureNaMExists(t *testing.T) {
NaM := Emote{
ID: "566ca06065dbbdab32ec054e",
Code: "NaM",
ImageType: "png",

URLs: URLs{
X1: "https://cdn.betterttv.net/emote/566ca06065dbbdab32ec054e/1x",
X2: "https://cdn.betterttv.net/emote/566ca06065dbbdab32ec054e/2x",
X4: "https://cdn.betterttv.net/emote/566ca06065dbbdab32ec054e/3x",
},
}

foundNaM := false

c := make(chan struct{})
onResponse := func(emotes EmotesResponse) {
for _, emote := range emotes {
if emote == NaM {
foundNaM = true
break
}
}

close(c)
}

api.GetEmotes(onResponse, onHTTPError(t), onInternalError(t))

<-c
if !foundNaM {
t.Fatalf("Did not find NaM in set of global emotes, this might be due to the API being changed")
}
}
2 changes: 1 addition & 1 deletion gobttv.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type BTTVAPI struct {
func New() *BTTVAPI {
return &BTTVAPI{
JSONAPI: jsonapi.JSONAPI{
BaseURL: "https://api.betterttv.net",
BaseURL: "https://api.betterttv.net/3",
},
}
}
8 changes: 8 additions & 0 deletions url.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package gobttv

// URLs describes a list of possible URLs for various sizes of an emote
type URLs struct {
X1 string
X2 string
X4 string
}

0 comments on commit b9ebf8c

Please sign in to comment.