package main import ( "bytes" "encoding/json" "io" "net/http" ) type Variables struct { ID string `json:"id"` } type GqlQuery struct { OperationName string `json:"operationName"` Variables Variables `json:"variables"` Query string `json:"query"` } type Chatterino struct { Badges []struct { Tooltip string `json:"tooltip"` Image1 string `json:"image1"` Image2 string `json:"image2"` Image3 string `json:"image3"` Users []string `json:"users"` } `json:"badges"` } type SevenTv struct { Query GqlQuery `json:"query"` User struct { ID string `json:"id"` } `json:"user"` UserCosmetics struct { Data struct { User struct { ID string `json:"id"` Cosmetics []struct { ID string `json:"id"` Kind string `json:"kind"` Selected bool `json:"selected"` Typename string `json:"__typename"` } `json:"cosmetics"` Typename string `json:"__typename"` } `json:"user"` } `json:"data"` } // 7tv Badges Badges struct { Data struct { Cosmetics struct { Badges []struct { ID string `json:"id"` Kind string `json:"kind"` Name string `json:"name"` Tooltip string `json:"tooltip"` Tag string `json:"tag"` Typename string `json:"__typename"` } `json:"badges"` Typename string `json:"__typename"` } `json:"cosmetics"` } `json:"data"` } `json:"sevenTvBadges"` // 7tv Paints Paints struct { Data struct { Cosmetics struct { Paints []struct { ID string `json:"id"` Kind string `json:"kind"` Name string `json:"name"` Function string `json:"function"` Color interface{} `json:"color"` Angle int64 `json:"angle"` Shape string `json:"shape"` ImageURL string `json:"image_url"` Repeat bool `json:"repeat"` Stops []struct { At float64 `json:"at"` Color int64 `json:"color"` Typename string `json:"__typename"` } `json:"stops"` Shadows []struct { XOffset float64 `json:"x_offset"` YOffset float64 `json:"y_offset"` Radius float64 `json:"radius"` Color int64 `json:"color"` Typename string `json:"__typename"` } `json:"shadows"` Typename string `json:"__typename"` } `json:"paints"` Typename string `json:"__typename"` } `json:"cosmetics"` } `json:"data"` } `json:"sevenTvPaints"` } type FrankerFz struct { Badges []struct { ID int64 `json:"id"` Name string `json:"name"` Title string `json:"title"` Slot int64 `json:"slot"` Replaces *string `json:"replaces"` Color string `json:"color"` Image string `json:"image"` Urls map[string]string `json:"urls"` CSS interface{} `json:"css"` } `json:"badges"` Users map[string][]int64 `json:"users"` } type Bttv []struct { ID string `json:"id"` Name string `json:"name"` DisplayName string `json:"displayName"` ProviderID string `json:"providerId"` Badge struct { Type int64 `json:"type"` Description string `json:"description"` } `json:"badge"` SVG string `json:"svg"` } type DankChat struct { Badges []struct { Type string `json:"type"` URL string `json:"url"` Users []string `json:"users"` } } type Homies struct { UserBadges struct { Badges []struct { UserID string `json:"userId"` BadgeID string `json:"badgeId"` BadgeFileType string `json:"badgeFileType"` Username string `json:"username"` Tooltip string `json:"tooltip"` Image1 string `json:"image1"` Image2 string `json:"image2"` Image3 string `json:"image3"` V int64 `json:"__v"` } `json:"badges"` } Badges struct { Badges []struct { ID string `json:"id"` Tooltip string `json:"tooltip"` Image1 string `json:"image1"` Users []string `json:"users"` Image2 string `json:"image2"` Image3 string `json:"image3"` } `json:"badges"` } BadgesTwo struct { Badges []struct { Tooltip string `json:"tooltip"` Image1 string `json:"image1"` Users []string `json:"users"` Image2 string `json:"image2"` Image3 string `json:"image3"` } `json:"badges"` } } type PurpleTV struct { DefaultBadgeURL string `json:"defaultBadgeUrl"` Users []struct { UserID string `json:"userId"` UserName string `json:"userName"` DisplayName string `json:"displayName"` Date string `json:"date"` // Always "null" Type interface{} `json:"type"` BadgeURL string `json:"badgeUrl"` } `json:"users"` } type Chatty []struct { ID string `json:"id"` Version string `json:"version"` ImageURL string `json:"image_url"` ImageURL2 string `json:"image_url_2"` ImageURL4 string `json:"image_url_4"` Color *string `json:"color"` Position *string `json:"position,omitempty"` MetaTitle string `json:"meta_title"` MetaURL *string `json:"meta_url"` Usernames []string `json:"usernames"` Userids []string `json:"userids,omitempty"` } func doGetRequest(url string) []byte { request, err := http.NewRequest("GET", url, nil) if err != nil { logger.Error().Msg(err.Error()) } res, err := client.Do(request) if err != nil { logger.Error().Msg(err.Error()) } defer res.Body.Close() body, err := io.ReadAll(res.Body) return body } func doPostRequest(url string, data []byte) []byte { request, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) if err != nil { logger.Error().Msg(err.Error()) } res, err := client.Do(request) if err != nil { logger.Error().Msg(err.Error()) } defer res.Body.Close() body, err := io.ReadAll(res.Body) return body } func (s *SevenTv) getUserID(userId string) (string, error) { req := doGetRequest("https://7tv.io/v3/users/twitch/" + userId) json.Unmarshal(req, &s) return string(s.User.ID), nil } func (s *SevenTv) getBadges() *SevenTv { query := ` query GetCosmestics($list: [ObjectID!]) { cosmetics(list: $list) { badges { id kind name tooltip tag __typename } __typename } }` s.Query = GqlQuery{ OperationName: "GetCosmestics", Query: query, } data, err := json.Marshal(s.Query) if err != nil { logger.Error().Msg(err.Error()) } res := doPostRequest("https://7tv.io/v3/gql", data) logger.Trace().Msg(string(res)) err = json.Unmarshal(res, &s.Badges) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *SevenTv) getPaints() (string, error) { query := ` query GetCosmestics($list: [ObjectID!]) { cosmetics(list: $list) { paints { id kind name function color angle shape image_url repeat stops { at color __typename } shadows { x_offset y_offset radius color __typename } __typename } } }` s.Query = GqlQuery{ OperationName: "GetCosmestics", Query: query, } data, err := json.Marshal(s.Query) if err != nil { return "", err } res := doPostRequest("https://7tv.io/v3/gql", data) // logger.Trace().Msg(string(res)) err = json.Unmarshal(res, &s.Paints) if err != nil { logger.Error().Msg(err.Error()) } return string(res), nil } // Returns the costmetrics that a user has. // userId, needs to be a 7TV ULID, call getUserID first. func (s *SevenTv) getUserCosmetics(userId string) (string, error) { query := ` query GetUserCosmetics($id: ObjectID!) { user(id: $id) { id cosmetics { id kind selected __typename } __typename } }` s.Query = GqlQuery{ OperationName: "GetUserCosmetics", Variables: Variables{ ID: userId, }, Query: query, } data, err := json.Marshal(s.Query) if err != nil { return "", err } // logger.Trace().Msg(string(data)) res := doPostRequest("https://7tv.io/v3/gql", data) err = json.Unmarshal(res, &s.UserCosmetics) if err != nil { logger.Error().Msg(err.Error()) } return string(res), nil } func (s *Chatterino) getBadges() *Chatterino { res := doGetRequest("https://api.chatterino.com/badges") err := json.Unmarshal(res, &s) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *FrankerFz) getBadges() *FrankerFz { res := doGetRequest("https://api.frankerfacez.com/v1/badges/ids") err := json.Unmarshal(res, &s) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *Bttv) getBadges() *Bttv { res := doGetRequest("https://api.betterttv.net/3/cached/badges/twitch") err := json.Unmarshal(res, &s) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *Chatty) getBadges() *Chatty { res := doGetRequest("https://tduva.com/res/badges") err := json.Unmarshal(res, &s) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *DankChat) getBadges() *DankChat { res := doGetRequest("https://flxrs.com/api/badges") err := json.Unmarshal(res, &s.Badges) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *Homies) getUserBadges() *Homies { res := doGetRequest("https://chatterinohomies.com/api/badges/list") err := json.Unmarshal(res, &s.UserBadges) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *Homies) getBadges() *Homies { res := doGetRequest("https://itzalex.github.io/badges") err := json.Unmarshal(res, &s.Badges) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *Homies) getBadgesTwo() *Homies { res := doGetRequest("https://itzalex.github.io/badges2") err := json.Unmarshal(res, &s.BadgesTwo) if err != nil { logger.Error().Msg(err.Error()) } return s } func (s *PurpleTV) getBadges() *PurpleTV { res := doGetRequest("https://api.nopbreak.ru/orange/donations") err := json.Unmarshal(res, &s) if err != nil { logger.Error().Msg(err.Error()) } return s }