From 7fbc39436b4a9c1cf859960ee2ad824c9e9772ae Mon Sep 17 00:00:00 2001 From: Fijxu Date: Sun, 26 May 2024 02:29:18 -0400 Subject: [PATCH] Ok everything is working now lol --- README.md | 10 +- config/config.example.yml | 10 + src/routes/api/users.cr | 403 ++++++++++++++++++++++++++++++++++---- src/routes/routes.cr | 31 ++- src/twitchapi/gql.cr | 276 ++++++++++++++++++++++++-- src/twitchapi/helix.cr | 26 +-- 6 files changed, 682 insertions(+), 74 deletions(-) create mode 100644 config/config.example.yml diff --git a/README.md b/README.md index c4a78d2..567c81b 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ ### TODO -- Use Redis to cache replies and add a new key to report for how much time the JSON is going to be stored in cache (**Already started, but I need to fix it!!**) -- Add other endpoints from api.ivr.fi +- ~Use Redis to cache replies and add a new key to report for how much time the JSON is going to be stored in cache (**Already started, but I need to fix it!!**)~ (Only done for the user endpoint) +- ~Add other endpoints from api.ivr.fi~ (Almost everything) - CAPTURE MORE THAN 1 PARAM `?login=fuck,fuck` ### NOT SO IMPORTANT TODO - Rate limiting (can be done in the reverse proxy side) -- Better shitcode -- STOP USING KEMAL FOR SIMPLE THINGS! +- ~Better shitcode~ Better goodcode +- ~STOP USING KEMAL FOR SIMPLE THINGS!~ Nevermind, kemal is pretty useful and it should stay ### Suggestions -3:45 RyanPotat: add team \ No newline at end of file +3:45 RyanPotat: add team diff --git a/config/config.example.yml b/config/config.example.yml new file mode 100644 index 0000000..7f7859e --- /dev/null +++ b/config/config.example.yml @@ -0,0 +1,10 @@ +# Please fill everything + +helixOAuth: "" +helixClientID: "" +gqlOAuth: "" +gqlClientID: "" +apiEndpoint: "https://api.twitch.tv/helix" +gqlEndpoint: "https://gql.twitch.tv/gql" +redis_url: "tcp://127.0.0.1:6379" +port: 8080 diff --git a/src/routes/api/users.cr b/src/routes/api/users.cr index 36bb029..87ef944 100644 --- a/src/routes/api/users.cr +++ b/src/routes/api/users.cr @@ -18,11 +18,15 @@ module TwAPI::Routes::Twitch end def parseData(params) + if !params.has_key?("login") && !params.has_key?("id") + err = {"error" => "No query parameters found"} + return err.to_json + end login = params["login"]? id = params["id"]? if login && (json = REDIS_DB.get(login)) - puts(JSON.parse(json)) + # puts(JSON.parse(json)) return json elsif id && (json = REDIS_DB.get(id)) return json @@ -37,7 +41,12 @@ module TwAPI::Routes::Twitch # end gql = GqlAPI.queryUser(params) - puts gql + + if (gql["user"] == nil) + err = {"message" => "Specified user does not exist"} + return err.to_json + end + # puts gql panels = gql["user"]["panels"] banned = checkBanned(gql) @@ -102,7 +111,7 @@ module TwAPI::Routes::Twitch begin parseData(params) rescue ex - env.response.status_code = 401 + env.response.status_code = 404 err = {"error" => "#{ex.message}"} err.to_json end @@ -110,57 +119,368 @@ module TwAPI::Routes::Twitch begin parseData(params) rescue ex - env.response.status_code = 401 + env.response.status_code = 404 err = {"error" => "#{ex.message}"} err.to_json end else - env.response.status_code = 401 + env.response.status_code = 404 err = {"error" => "Parameter 'login' or 'id' is missing"} err.to_json end else - env.response.status_code = 401 + env.response.status_code = 404 err = {"error" => "No query parameters found"} err.to_json end end def modvip(env) - if !env.params.query.has_key?("login") && !env.params.query.has_key?("id") - err = {"error" => "No query parameters found"} + # if !env.params.query.has_key?("login") && !env.params.query.has_key?("id") + # err = {"error" => "No query parameters found"} + # return err.to_json + # else + if !env.params.url.has_key?("channel") + err = {"error" => "Please insert a channel"} return err.to_json - else - gql = GqlAPI.queryModsVips(env.params.query)["user"] - # puts (gql["user"]["mods"]["edges"].size.times) - i, j = 0, 0 + end - json_data = JSON.build do |json| - json.object do - json.field "modCount", gql["mods"]["edges"].size.to_i - json.field "vipCount", gql["vips"]["edges"].size.to_i - json.field "mods" do - json.array do - while i < gql["mods"]["edges"].size # There is a better way to do this? - json.object do - json.field "id", gql["mods"]["edges"][i]["node"]["id"]? - json.field "login", gql["mods"]["edges"][i]["node"]["login"]? - json.field "displayName", gql["mods"]["edges"][i]["node"]["displayName"]? - json.field "grantedAt", gql["mods"]["edges"][i]["grantedAt"]? - i += 1 + gql = GqlAPI.getModsVips(env.params.url)["user"] + + if (gql == nil) + err = {"message" => "Specified user does not exist"} + return err.to_json + end + + json_data = JSON.build do |json| + json.object do + json.field "modCount", gql["mods"]["edges"].size + json.field "vipCount", gql["vips"]["edges"].size + json.field "mods" do + json.array do + gql["mods"]["edges"]?.try &.as_a.each do |edges| + json.object do + if edges.try &.["node"]? == nil + json.field "id", nil + json.field "login", nil + json.field "displayName", nil + json.field "grantedAt", nil + else + json.field "id", edges["node"]["id"]? + json.field "login", edges["node"]["login"]? + json.field "displayName", edges["node"]["displayName"]? + json.field "grantedAt", edges["grantedAt"]? end end end - json.field "vips" do - json.array do - while j < gql["vips"]["edges"].size - json.object do - # puts gql["vips"]["edges"][j]["node"]["id"] - json.field "id", gql["vips"]["edges"][j].try &.["node"]?.try &.["id"] - json.field "login", gql["vips"]["edges"][j].try &.["node"]["login"] || "" - json.field "displayName", gql["vips"]["edges"][j].try &.["node"]["displayName"] || "" - json.field "grantedAt", gql["vips"]["edges"][j]["grantedAt"]? - j += 1 + end + json.field "vips" do + json.array do + gql["vips"]["edges"]?.try &.as_a.each do |edges| + json.object do + if edges.try &.["node"]? == nil + json.field "id", nil + json.field "login", nil + json.field "displayName", nil + json.field "grantedAt", nil + else + json.field "id", edges["node"]["id"] + json.field "login", edges["node"]["login"] + json.field "displayName", edges["node"]["displayName"] + json.field "grantedAt", edges["grantedAt"] + end + end + end + end + end + end + end + end + return json_data + end + + # TODO: Add error message if query doesn't exist at all + + def founders(env) + # if !env.params.query.has_key?("login") && !env.params.query.has_key?("id") + # err = {"error" => "No query parameters found"} + # return err.to_json + # else + if !env.params.url.has_key?("login") + err = {"error" => "Please insert a channel"} + return err.to_json + end + gql = GqlAPI.getFounders(env.params.url)["user"] + + if (gql == nil) + err = {"message" => "Specified user does not exist"} + return err.to_json + end + + json_data = JSON.build do |json| + json.object do + json.field "foundersCount", gql["channel"]["founders"].size + json.field "founders" do + json.array do + gql["channel"]["founders"]?.try &.as_a.each do |founders| + json.object do + json.field "isSubscribed", founders["isSubscribed"]? + json.field "entitlementStart", founders["entitlementStart"]? + + if founders.try &.["user"]? == nil + json.field "id", nil + json.field "login", nil + json.field "displayName", nil + else + json.field "id", founders["user"]["id"] + json.field "login", founders["user"]["login"] + json.field "displayName", founders["user"]["displayName"] + end + end + end + end + end + end + end + end + + def clip(env) + # if !env.params.query.has_key?("slug") + # err = {"error" => "No query parameters found"} + # return err.to_jso + # else + if !env.params.url.has_key?("slug") + err = {"error" => "Please insert a slug"} + return err.to_json + end + + gql = GqlAPI.getClips(env.params.url)["clip"] + + if (gql == nil) + err = {"message" => "Specified user does not exist"} + return err.to_json + end + + json_data = JSON.build do |json| + json.object do + json.field "clip" do + json.object do + json.field "durationSeconds", gql["durationSeconds"] + json.field "id", gql["id"] + json.field "slug", gql["slug"] + json.field "url", gql["url"] + # TODO: Add tiny, small and medium previews + # "tiny": "https://clips-media-assets2.twitch.tv/MEtZsD4gcXcJb1kGQRbUYg/42368009784-offset-19328-preview-86x45.jpg", + # "small": "https://clips-media-assets2.twitch.tv/MEtZsD4gcXcJb1kGQRbUYg/42368009784-offset-19328-preview-260x147.jpg", + # "medium": "https://clips-media-assets2.twitch.tv/MEtZsD4gcXcJb1kGQRbUYg/42368009784-offset-19328-preview-480x272.jpg", + json.field "createdAt", gql["createdAt"] + json.field "title", gql["title"] + json.field "viewCount", gql["viewCount"] + # Game + json.field "game" do + json.object do + json.field "id", gql["game"]["id"] + json.field "name", gql["game"]["name"] + end + end + # Broadcaster + json.field "broadcaster" do + json.object do + json.field "id", gql["broadcaster"]["id"] + json.field "displayName", gql["broadcaster"]["displayName"] + end + end + + # Curator + json.field "curator" do + json.object do + json.field "id", gql["curator"]["id"] + json.field "displayName", gql["curator"]["displayName"] + end + end + # Array of available video qualities + json.field "videoQualities" do + json.array do + gql["videoQualities"]?.try &.as_a.each do |videoQualities| + json.object do + if videoQualities.try &.["frameRate"]? == nil + json.field "error", "No data" + else + json.field "frameRate", videoQualities["frameRate"] + json.field "quality", videoQualities["quality"] + json.field "sourceURL", videoQualities["sourceURL"] + end + end + end + end + end + # TODO: get ClipKey + # "clipKey": "?sig=5cc70f40c61313db289a132ab58c7b27d16220ab&token=%7B%22authorization%22:%7B%22forbidden%22:false,%22reason%22:%22%22%7D,%22clip_uri%22:%22https://production.assets.clips.twitchcdn.net/WclEPrSCziCGI7bKo8Md-w/AT-cm%257CWclEPrSCziCGI7bKo8Md-w.mp4%22,%22clip_slug%22:%22AltruisticSarcasticQuailSoBayed-tILOIIYjtsqjwx37%22,%22device_id%22:null,%22expires%22:1716487243,%22user_id%22:%22%22,%22version%22:2%7D" + json.field "clipKey", "How the fuck I get this shit" + end + end + end + end + end + + def subage(env) + if !env.params.url.has_key?("user") || !env.params.url.has_key?("channel") + err = {"error" => "No query parameters found"} + return err.to_json + end + + gql = GqlAPI.getSubage(env.params.url["user"], env.params.url["channel"]) + if (gql == nil) + err = {"message" => "Specified user does not exist"} + return err.to_json + end + + json_data = JSON.build do |json| + json.object do + json.field "user" do + json.object do + json.field "id", gql["userData"]["id"]? + json.field "login", gql["userData"]["login"]? + json.field "displayName", gql["userData"]["displayName"]? + end + end + json.field "channel" do + json.object do + json.field "id", gql["channelData"]["id"]? + json.field "login", gql["channelData"]["login"]? + json.field "displayName", gql["channelData"]["displayName"]? + end + end + json.field "statusHidden", false # TODO: what is this? I need to get it NOW! + json.field "followedAt", gql["info"]["relationship"]["followedAt"] + if (gql["info"]["relationship"]["streak"] == nil) + json.field "streak", nil + else + json.field "streak" do + json.object do + json.field "elapsedDays", gql["info"]["relationship"]["streak"]["elapsedDays"]? + json.field "daysRemaining", gql["info"]["relationship"]["streak"]["daysRemaining"]? + json.field "months", gql["info"]["relationship"]["streak"]["months"]? + json.field "end", gql["info"]["relationship"]["streak"]["end"]? + json.field "start", gql["info"]["relationship"]["streak"]["elapsedDays"]? + end + end + end + if (gql["info"]["relationship"]["cumulative"] == nil) + json.field "cumulative", nil + else + json.field "cumulative" do + json.object do + json.field "elapsedDays", gql["info"]["relationship"]["cumulative"]["elapsedDays"]? + json.field "daysRemaining", gql["info"]["relationship"]["cumulative"]["daysRemaining"]? + json.field "months", gql["info"]["relationship"]["cumulative"]["months"]? + json.field "end", gql["info"]["relationship"]["cumulative"]["end"]? + json.field "start", gql["info"]["relationship"]["cumulative"]["elapsedDays"]? + end + end + end + if (gql["info"]["relationship"]["meta"] == nil) + json.field "meta", nil + else + json.field "meta" do + json.object do + json.field "type", nil # TODO: get the type of the sub, could be paid or something else gql["info"]["relationship"]["meta"][""] + json.field "tier", (gql["info"]["relationship"]["meta"]["tier"].to_s.to_i / 1000) + json.field "endsAt", gql["info"]["relationship"]["meta"]["endsAt"] + json.field "renewsAt", gql["info"]["relationship"]["meta"]["renewsAt"] + json.field "giftMeta", nil # TODO: fill giftMeta is sub is gifted + end + end + end + end + end + end + + def emotes(env) + if !env.params.url.has_key?("emote") + err = {"error" => "No query parameters found"} + return err.to_json + end + + gql = GqlAPI.getEmotes(env.params.url["emote"])["emote"] # TODO: support if ID or emote name + + if (gql == nil) + err = {"message" => "Specified emote does not exist"} + return err.to_json + end + + json_data = JSON.build do |json| + json.object do + json.field "channelName", gql["owner"]["displayName"] + json.field "channelLogin", gql["owner"]["login"] + json.field "channelID", gql["owner"]["id"] + json.field "artist", nil # TODO: ADD SUPPORT FOR ARTIST OBJECT + json.field "emoteID", gql["id"] + json.field "emoteCode", gql["text"] + json.field "emoteSetID", gql["setID"] + json.field "emoteAssetType", gql["assetType"] + json.field "emoteState", gql["state"] + json.field "emoteType", gql["type"] + json.field "emoteTier", gql["subscriptionTier"] + end + end + end + + def channelEmotes(env) + if !env.params.query.has_key?("channel") + err = {"error" => "No query parameters found"} + return err.to_json + end + gql = GqlAPI.getChannelEmotes(env.params.query["channel"]) # TODO: Add support for IDs an not just the channel name + if (gql == nil) + err = {"message" => "Specified user does not exist"} + return err.to_json + end + json_data = JSON.build do |json| + json.object do + json.field "subProducts" do + json.array do + gql["user"]["subEmotes"]?.try &.as_a.each do |subEmotes| + json.object do + json.field "displayName", subEmotes["displayName"] + json.field "emoteSetID", subEmotes["id"] + json.field "tier", subEmotes["tier"] + json.field "emotes" do + json.array do + subEmotes["emotes"]?.try &.as_a.each do |emotes| + json.object do + json.field "id", emotes["id"] + json.field "setID", emotes["setID"] + json.field "code", emotes["text"] + json.field "type", emotes["type"] + json.field "assetType", emotes["assetType"] + end + end + end + end + end + end + end + # TODO: Emotes available by donating bits + # # # # # # + # json.field "bitEmotes" do + # json.array do + # end + json.field "localEmotes" do + json.array do + json.object do + json.field "id", gql["user"]["channel"]["localEmoteSets"][0]["id"] # TODO: Detect if channel has more than one localEmoteSets (since it's a fucking array) + json.field "emotes" do + json.array do + gql["user"]["channel"]["localEmoteSets"][0]["localEmotes"]?.try &.as_a.each do |localEmotes| + json.object do + json.field "artist", localEmotes["artist"] # TODO: Add support for artist (again) + json.field "id", localEmotes["id"] + json.field "type", localEmotes["type"] + json.field "assetType", localEmotes["assetType"] + json.field "code", localEmotes["text"] + end + end end end end @@ -168,8 +488,17 @@ module TwAPI::Routes::Twitch end end end - return json_data end - # TODO: Add error message if query doesn't exist at all end end + +# I'll do this later fuck this shit + +# def globalEmotes(env) +# if !env.params.query.has_key?("id") || !env.params.query.has_key?("login") +# err = "[]" +# return err.to_json +# else +# gql = GqlAPI.getChannelEmotes(env.params.query) +# json_data = JSON.build do |json| +# end diff --git a/src/routes/routes.cr b/src/routes/routes.cr index ea98bea..5981bb3 100644 --- a/src/routes/routes.cr +++ b/src/routes/routes.cr @@ -1,8 +1,8 @@ module TwAPI::Routing - extend self # To prevent writing self. at the start of every function + extend self # To prevent writing self. at the start of every function - # Thanks Invidious devs - {% for http_method in {"get", "post", "delete", "options", "patch", "put"} %} + # Thanks Invidious devs + {% for http_method in {"get", "post", "delete", "options", "patch", "put"} %} macro {{http_method.id}}(path, controller, method = :handle) unless Kemal::Utils.path_starts_with_slash?(\{{path}}) @@ -16,9 +16,24 @@ module TwAPI::Routing {% end %} - def register_all - # get "/" - get "/v2/twitch/user", TwAPI::Routes::Twitch, :user - get "/v2/twitch/modvip", TwAPI::Routes::Twitch, :modvip - end + def register_all + # get "/" + get "/v2/twitch/user", TwAPI::Routes::Twitch, :user + + get "/v2/twitch/modvip/", TwAPI::Routes::Twitch, :modvip + get "/v2/twitch/modvip/:channel", TwAPI::Routes::Twitch, :modvip + + get "/v2/twitch/founders", TwAPI::Routes::Twitch, :founders + get "/v2/twitch/founders/:login", TwAPI::Routes::Twitch, :founders + + get "/v2/twitch/clip", TwAPI::Routes::Twitch, :clip + get "/v2/twitch/clip/:slug", TwAPI::Routes::Twitch, :clip + + get "/v2/twitch/subage", TwAPI::Routes::Twitch, :subage + get "/v2/twitch/subage/:user/:channel", TwAPI::Routes::Twitch, :subage + + get "/v2/twitch/emotes", TwAPI::Routes::Twitch, :emotes + get "/v2/twitch/emotes/:emote", TwAPI::Routes::Twitch, :emotes + # get "/v2/twitch/emotes/channel", TwAPI::Routes::Twitch, :channelEmotes + end end diff --git a/src/twitchapi/gql.cr b/src/twitchapi/gql.cr index 56f0bbe..76d970a 100644 --- a/src/twitchapi/gql.cr +++ b/src/twitchapi/gql.cr @@ -21,19 +21,29 @@ module GqlAPI end end + def targetUser(params) + if params.has_key?("id") + return %(targetUserID: "#{params["id"]}" ) + else + return %(targetUserLogin: "#{params["login"]}") + end + end + def loginOrID(params) if params.has_key?("id") - return %(userResultByID(id: "#{params["id"]}")), %(user(id: "#{params["id"]}" lookupType: ALL)) + return %(id: "#{params["id"]}") else - return %(userResultByLogin(login: "#{params["login"]}")), %(user(login: "#{params["login"]}" lookupType: ALL)) + return %(login: "#{params["login"]}") end end def user(params) if params.has_key?("id") - return %(user(id: "#{params["id"]}" lookupType: ALL)) - else - return %(user(login: "#{params["login"]}" lookupType: ALL)) + return %(id: "#{params["id"]}" lookupType: ALL) + elsif params.has_key?("login") + return %(login: "#{params["login"]}" lookupType: ALL) + else + return %(login: "#{params["channel"]}" lookupType: ALL) end end @@ -41,13 +51,13 @@ module GqlAPI @@urb = userResultBy(params) query = %( query { - #{@@urb} { + #{userResultBy(params)} { ... on UserDoesNotExist { key reason } } - #{user(params)} { + user(#{user(params)}) { id language login @@ -128,13 +138,13 @@ module GqlAPI } } ) - return (JSON.parse(gqlReq(params, query)))["data"] + return (JSON.parse(gqlReq(query)))["data"] end - def queryModsVips(params) + def getModsVips(env) query = %( query { - #{user(params)} { + user(#{user(env)}) { mods(first: 100) { edges { grantedAt @@ -159,15 +169,255 @@ module GqlAPI } } ) - return (JSON.parse(gqlReq(params, query)))["data"] + return (JSON.parse(gqlReq(query)))["data"] end - def gqlReq(params, query) + def getFounders(env) + query = %( + query { + user(#{user(env)}) { + id + login + displayName + channel { + founderBadgeAvailability + founders { + isSubscribed + entitlementStart + user { + id + login + displayName + } + } + } + } + } + ) + return (JSON.parse(gqlReq(query)))["data"] + end + + def getClips(params) + query = %( + query { + clip(slug: "#{params["slug"]}") { + createdAt + creationState + durationSeconds + embedURL + id + isPublished + language + slug + thumbnailURL + title + url + videoOffsetSeconds + viewCount + game { + id + name + } + broadcaster { + id + displayName + } + curator { + id + displayName + } + videoQualities { + frameRate + quality + sourceURL + } + } + } + ) + return (JSON.parse(gqlReq(query)))["data"] + end + + def getSubage(user, channel) + channelId = HelixAPI.getId(channel) + query = %( + query { + userData: userResultByLogin (login: "#{user}") { + ... on UserDoesNotExist { key reason } + ... on UserError { key } + ... on User { id displayName login } + } + channelData: userResultByLogin (login: "#{channel}") { + ... on UserDoesNotExist { key reason } + ... on UserError { key } + ... on User { id displayName login roles { isAffiliate isPartner } } + } + info: user (login: "#{user}" lookupType: ALL) { + relationship (targetUserID: "#{channelId}") { + followedAt + cumulative: subscriptionTenure(tenureMethod: CUMULATIVE) { + daysRemaining + elapsedDays + end + months + start + } + streak: subscriptionTenure(tenureMethod: STREAK) { + daysRemaining + elapsedDays + end + months + start + } + meta: subscriptionBenefit { + endsAt + purchasedWithPrime + renewsAt + tier + giftMeta: gift { + giftDate + isGift + gifter { + displayName + login + id + } + } + } + } + } +} + ) + return (JSON.parse(gqlReq(query)))["data"] + end + + def getEmotes(emote) + query = %( + query { + emote(id: "#{emote}") { + setID + assetType + id + state + suffix + text + subscriptionTier + owner { + id + login + displayName + } + artist { + id + login + displayName + } + bitsBadgeTierSummary { + threshold + } + type + } + } + ) + return (JSON.parse(gqlReq(query)))["data"] + end + + def getChannelEmotes(channel) + query = %( + { + user(login: "#{channel}") { + channel { + localEmoteSets { + id + localEmotes: emotes { + artist { id } + id + type + assetType + text + } + } + } + subEmotes: subscriptionProducts { + displayName + id + tier + emotes { + id + setID + text + type + assetType + } + } + } +} + ) + return (JSON.parse(gqlReq(query)))["data"] + end + + def getEmotes(emote) + query = %( + query { + emote(id: "#{emote}") { + setID + assetType + id + state + suffix + text + subscriptionTier + owner { + id + login + displayName + } + artist { + id + login + displayName + } + bitsBadgeTierSummary { + threshold + } + type + } + } + ) + return (JSON.parse(gqlReq(query)))["data"] + end + + def getChannelBadges(channel) + query = %( + query { + user(login: "#{channel}") { + broadcastBadges { + id + normalImageURL: imageURL(size: NORMAL) + doubleImageURL: imageURL(size: DOUBLE) + quadrupleImageURL: imageURL(size: QUADRUPLE) + title + description + onClickAction + clickURL + } + channel { + creatorBadgeFlair { + assets { + tier + } + } + } + } + } + ) + return (JSON.parse(gqlReq(query)))["data"] + end + + def gqlReq(query) data = {"query" => query} response = HTTP::Client.post(CONFIG.gqlEndpoint.to_s, headers: @@headers, body: data.to_json) if response.success? - # puts (typeof(response.body)) return (response.body) else raise "GQL Twitch API returned #{response.status_code}: #{response.body.to_s}" diff --git a/src/twitchapi/helix.cr b/src/twitchapi/helix.cr index 5fe3918..29a45df 100644 --- a/src/twitchapi/helix.cr +++ b/src/twitchapi/helix.cr @@ -1,11 +1,13 @@ module HelixAPI + extend self + @@headers = HTTP::Headers{ "Content-Type" => "application/json", "Authorization" => "Bearer #{CONFIG.helixOAuth}", "Client-Id" => "#{CONFIG.helixClientID}", } - def self.users(params) + def users(params) if params.has_key?("login") endpoint = "#{CONFIG.apiEndpoint}/users?login=#{params["login"]}" else @@ -14,7 +16,6 @@ module HelixAPI response = HTTP::Client.get(endpoint, headers: @@headers) - # puts response.body if response.success? return (response.body) else @@ -22,15 +23,18 @@ module HelixAPI end end - # def self.chatColor(id) - # endpoint = "#{CONFIG.apiEndpoint}/chat/color?user_id=#{id}" + def getId(login) + request = "#{CONFIG.apiEndpoint.to_s}/users?login=#{login}" + return JSON.parse(helixReq(request))["data"][0]["id"] + end - # response = HTTP::Client.get(endpoint, headers: @@headers) + def helixReq(request) + response = HTTP::Client.get(request, headers: @@headers) - # if response.success? - # return (response.body) - # else - # raise "Helix Twitch API returned #{response.status_code}: #{response.body.to_s}" - # end - # end + if response.success? + return (response.body) + else + raise "Helix Twitch API returned #{response.status_code}: #{response.body.to_s}" + end + end end