summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/twitcr/mappings/game.cr21
-rw-r--r--src/twitcr/rest.cr58
2 files changed, 76 insertions, 3 deletions
diff --git a/src/twitcr/mappings/game.cr b/src/twitcr/mappings/game.cr
new file mode 100644
index 0000000..2915eb5
--- /dev/null
+++ b/src/twitcr/mappings/game.cr
@@ -0,0 +1,21 @@
+require "./converters"
+
+module Twitcr
+ struct GameList
+ JSON.mapping({data: Array(Game)})
+ end
+
+ struct Game
+ JSON.mapping({
+ id: {type: UInt64, converter: ID::Converter},
+ name: String,
+ box_art_url: String,
+ })
+ end
+end
+
+module ID::Converter
+ def self.from_json(value : JSON::PullParser) : UInt64
+ UInt64.new(value.read_string)
+ end
+end
diff --git a/src/twitcr/rest.cr b/src/twitcr/rest.cr
index f3af85c..0fc59c1 100644
--- a/src/twitcr/rest.cr
+++ b/src/twitcr/rest.cr
@@ -14,6 +14,7 @@ module Twitcr::REST
Api # typically undocumented APIs go here
Kraken # v5, "deprecated" with no real replacement for half of the functions
Helix # "new api"
+ Oauth2 # id
PubSub # FIXME: put this in another module, probably
end
@@ -22,10 +23,12 @@ module Twitcr::REST
headers = HTTP::Headers.new
headers["Client-ID"] = @settings["client_id"].not_nil!
+ url_base = API_BASE
api = twitchapi.to_s.downcase
case api
when "helix"
+ headers["Client-ID"] = @settings["client_id"].not_nil!
# FIXME: maybe don't send this every time?
headers["Authorization"] = "Bearer #{@settings["access_token"].not_nil!}"
when "kraken"
@@ -34,6 +37,17 @@ module Twitcr::REST
when "api"
# typically twitch restricts these to the twitch client id
headers["Client-ID"] = @settings["client_id_twitch"].not_nil!
+ when "oauth2"
+ url_base = "https://id.twitch.tv/"
+ headers["Authorization"] = "OAuth #{@settings["app_access_token"].not_nil!}"
+ else
+ end
+
+ case route
+ when /^\/validate/
+ headers["Authorization"] = "OAuth #{@settings["app_access_token"].not_nil!}"
+ when /^\/eventsub/
+ headers["Authorization"] = "Bearer #{@settings["app_access_token"].not_nil!}"
else
end
@@ -45,14 +59,14 @@ module Twitcr::REST
ENV["DEBUG"]
rescue KeyError
else
- puts method + " " + API_BASE + api + route
+ puts method + " " + url_base + api + route
#pp headers# probably too sensitive
pp body
end
response = HTTP::Client.exec(
method,
- API_BASE + api + route,
+ url_base + api + route,
headers,
body,
tls: SSL_CONTEXT
@@ -93,6 +107,16 @@ module Twitcr::REST
if ! query_string.empty?; query_string = "?" + query_string end
request( "GET", Api::Helix, "/users/follows" + query_string )
end
+ def get_user_follows( *, to : UInt64, from : UInt64, after : String? = nil )
+ params = Hash( String, String ).new
+ params["first"] = "100"
+ params["from_id"] = from.to_s
+ params["to_id"] = to.to_s
+ if after ; params["after"] = after end
+ query_string = HTTP::Params.encode( params )
+ if ! query_string.empty?; query_string = "?" + query_string end
+ request( "GET", Api::Helix, "/users/follows" + query_string )
+ end
# FIXME: support array of mixed UInt64/String
def get_games( name : String ); request( "GET", Api::Helix, "/games?name=#{URI.encode_www_form( name )}" ) end
def get_games( id : UInt64 ); request( "GET", Api::Helix, "/games?id=#{id.to_s}" ) end
@@ -125,6 +149,7 @@ module Twitcr::REST
def get_banned( broadcaster_id : UInt64, user_id : UInt64 ); request( "GET", Api::Helix, "/moderation/banned?broadcaster_id=#{broadcaster_id.to_s}&user_id=#{user_id}" ) end
def get_banned( broadcaster_id : UInt64, user_id : Array( UInt64 ) ); request( "GET", Api::Helix, "/moderation/banned?broadcaster_id=#{broadcaster_id.to_s}&user_id=#{user_id.join("&user_id=")}" ) end
def get_banned_events( broadcaster_id : UInt64, first : UInt64 = 100 ); request( "GET", Api::Helix, "/moderation/banned/events?broadcaster_id=#{broadcaster_id.to_s}&first=#{first.to_s}" ) end
+ def get_clips( name : String ); request( "GET", Api::Kraken, "/clips/top?channel=#{name}&first=100&period=all" ) end
def get_videos( id : UInt64, sort : String = "time", type : String = "all" ); request( "GET", Api::Helix, "/videos?user_id=#{id.to_s}&first=100&sort=#{sort}&type=#{type}" ) end
def get_channels_videos( id : UInt64, sort : String = "time", type : String = "all" ); request( "GET", Api::Kraken, "/channels/#{id.to_s}/videos?limit=100&sort=#{sort}&broadcast_type=#{type}" ) end
def get_channel( ); request( "GET", Api::Kraken, "/channel" ) end
@@ -139,7 +164,34 @@ module Twitcr::REST
def delete_key!( id : UInt64); request( "DELETE", Api::Kraken, "/channels/#{id.to_s}/stream_key" ) end
def get_hosts( id : UInt64 ); request( "GET", Api::Kraken, "/channels/#{id.to_s}/hosts" ) end
def get_subs( id : UInt64 ); request( "GET", Api::Kraken, "/channels/#{id.to_s}/subscriptions" ) end
-
+ def get_eventsubs( ); request( "GET", Api::Helix, "/eventsub/subscriptions" ) end
+ def delete_eventsubs!( id : String ); request( "DELETE",
+ Api::Helix, "/eventsub/subscriptions?id=#{id}" ) end
+ def put_eventsubs!( type : String, id : UInt64, url : String );
+ version = "1"
+ varname = "broadcaster_user_id"
+ case type
+ when "channel.raid"
+ version = "beta"
+ varname = "to_broadcaster_user_id"
+ when "user.update"
+ varname = "user_id"
+ end
+ body = Hash( String, String | Hash( String, String ) ).new
+
+ body = {
+ "type" => type,
+ "version" => version,
+ "condition" => { varname => id.to_s },
+ "transport" => {
+ "method" => "webhook",
+ "callback" => url,
+ "secret" => @settings["eventsub_secret"] # FIXME
+ },
+ }
+ request( "POST", Api::Helix, "/eventsub/subscriptions", body.to_json, contenttype: "application/json" ) end
+ def get_app_token( ); request( "POST", Api::Oauth2, "/token?client_id=#{@settings["client_id"].not_nil!}&client_secret=#{@settings["client_secret"].not_nil!}&grant_type=client_credentials" ) end
+ def get_token_validation( ); request( "GET", Api::Oauth2, "/validate" ) end
# These APIs might require the official Twitch.com web Client-ID now?
def get_panels( login : String ); request( "GET", Api::Api, "/channels/#{login}/panels" ) end
# https://github.com/justintv/Twitch-API/issues/545 requires weird scopes that normal client_ids can't get