twitchrb 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env.example +3 -0
- data/.github/FUNDING.yml +4 -0
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +28 -9
- data/README.md +46 -6
- data/bin/console +5 -0
- data/lib/twitch/client.rb +131 -75
- data/lib/twitch/collection.rb +21 -0
- data/lib/twitch/error.rb +4 -0
- data/lib/twitch/object.rb +19 -0
- data/lib/twitch/objects/badge.rb +4 -0
- data/lib/twitch/objects/banned_event.rb +4 -0
- data/lib/twitch/objects/banned_user.rb +4 -0
- data/lib/twitch/objects/blocked_user.rb +4 -0
- data/lib/twitch/objects/channel.rb +4 -0
- data/lib/twitch/objects/channel_editor.rb +4 -0
- data/lib/twitch/objects/clip.rb +4 -0
- data/lib/twitch/objects/custom_reward.rb +4 -0
- data/lib/twitch/objects/custom_reward_redemption.rb +4 -0
- data/lib/twitch/objects/emote.rb +4 -0
- data/lib/twitch/objects/event_sub_subscription.rb +4 -0
- data/lib/twitch/objects/followed_user.rb +4 -0
- data/lib/twitch/objects/game.rb +4 -0
- data/lib/twitch/objects/goal.rb +4 -0
- data/lib/twitch/objects/hype_train_event.rb +4 -0
- data/lib/twitch/objects/moderator.rb +4 -0
- data/lib/twitch/objects/moderator_event.rb +4 -0
- data/lib/twitch/objects/poll.rb +4 -0
- data/lib/twitch/objects/prediction.rb +4 -0
- data/lib/twitch/objects/search_result.rb +4 -0
- data/lib/twitch/objects/stream.rb +4 -0
- data/lib/twitch/objects/stream_marker.rb +4 -0
- data/lib/twitch/objects/stream_schedule.rb +4 -0
- data/lib/twitch/objects/subscription.rb +4 -0
- data/lib/twitch/objects/subscription_count.rb +4 -0
- data/lib/twitch/objects/tag.rb +4 -0
- data/lib/twitch/objects/user.rb +4 -0
- data/lib/twitch/objects/video.rb +4 -0
- data/lib/twitch/resource.rb +57 -0
- data/lib/twitch/resources/badges.rb +15 -0
- data/lib/twitch/resources/banned_events.rb +10 -0
- data/lib/twitch/resources/banned_users.rb +11 -0
- data/lib/twitch/resources/channels.rb +20 -0
- data/lib/twitch/resources/clips.rb +19 -0
- data/lib/twitch/resources/custom_reward_redemptions.rb +22 -0
- data/lib/twitch/resources/custom_rewards.rb +30 -0
- data/lib/twitch/resources/emotes.rb +20 -0
- data/lib/twitch/resources/event_sub_subscriptions.rb +21 -0
- data/lib/twitch/resources/games.rb +20 -0
- data/lib/twitch/resources/goals.rb +12 -0
- data/lib/twitch/resources/hype_train_events.rb +12 -0
- data/lib/twitch/resources/moderator_events.rb +11 -0
- data/lib/twitch/resources/moderators.rb +11 -0
- data/lib/twitch/resources/polls.rb +27 -0
- data/lib/twitch/resources/predictions.rb +32 -0
- data/lib/twitch/resources/search.rb +17 -0
- data/lib/twitch/resources/stream_markers.rb +19 -0
- data/lib/twitch/resources/stream_schedule.rb +47 -0
- data/lib/twitch/resources/streams.rb +19 -0
- data/lib/twitch/resources/subscriptions.rb +73 -0
- data/lib/twitch/resources/tags.rb +20 -0
- data/lib/twitch/resources/users.rb +54 -0
- data/lib/twitch/resources/videos.rb +17 -0
- data/lib/twitch/version.rb +1 -1
- data/lib/twitch.rb +80 -32
- data/twitchrb.gemspec +3 -2
- metadata +79 -16
- data/lib/twitch/badges.rb +0 -39
- data/lib/twitch/channels.rb +0 -25
- data/lib/twitch/emotes.rb +0 -58
- data/lib/twitch/games.rb +0 -49
- data/lib/twitch/initializable.rb +0 -16
- data/lib/twitch/kraken/channels.rb +0 -22
- data/lib/twitch/kraken/clips.rb +0 -22
- data/lib/twitch/kraken/user.rb +0 -23
- data/lib/twitch/kraken/users.rb +0 -33
@@ -0,0 +1,57 @@
|
|
1
|
+
module Twitch
|
2
|
+
class Resource
|
3
|
+
attr_reader :client
|
4
|
+
|
5
|
+
def initialize(client)
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def get_request(url, params: {}, headers: {})
|
12
|
+
handle_response client.connection.get(url, params, headers)
|
13
|
+
end
|
14
|
+
|
15
|
+
def post_request(url, body:, headers: {})
|
16
|
+
handle_response client.connection.post(url, body, headers)
|
17
|
+
end
|
18
|
+
|
19
|
+
def patch_request(url, body:, headers: {})
|
20
|
+
handle_response client.connection.patch(url, body, headers)
|
21
|
+
end
|
22
|
+
|
23
|
+
def put_request(url, body:, headers: {})
|
24
|
+
handle_response client.connection.put(url, body, headers)
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete_request(url, params: {}, headers: {})
|
28
|
+
handle_response client.connection.delete(url, params, headers)
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle_response(response)
|
32
|
+
case response.status
|
33
|
+
when 400
|
34
|
+
raise Error, "Error 400: Your request was malformed. '#{response.body["message"]}'"
|
35
|
+
when 401
|
36
|
+
raise Error, "Error 401: You did not supply valid authentication credentials. '#{response.body["error"]}'"
|
37
|
+
when 403
|
38
|
+
raise Error, "Error 403: You are not allowed to perform that action. '#{response.body["error"]}'"
|
39
|
+
when 404
|
40
|
+
raise Error, "Error 404: No results were found for your request. '#{response.body["error"]}'"
|
41
|
+
when 409
|
42
|
+
raise Error, "Error 409: Your request was a conflict. '#{response.body["message"]}'"
|
43
|
+
when 429
|
44
|
+
raise Error, "Error 429: Your request exceeded the API rate limit. '#{response.body["error"]}'"
|
45
|
+
when 500
|
46
|
+
raise Error, "Error 500: We were unable to perform the request due to server-side problems. '#{response.body["error"]}'"
|
47
|
+
when 503
|
48
|
+
raise Error, "Error 503: You have been rate limited for sending more than 20 requests per second. '#{response.body["error"]}'"
|
49
|
+
when 204
|
50
|
+
# 204 is a response for success on Twitch's API
|
51
|
+
return true
|
52
|
+
end
|
53
|
+
|
54
|
+
response
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Twitch
|
2
|
+
class BadgesResource < Resource
|
3
|
+
|
4
|
+
def channel(broadcaster_id:)
|
5
|
+
response = get_request("chat/badges?broadcaster_id=#{broadcaster_id}")
|
6
|
+
Collection.from_response(response, type: Badge)
|
7
|
+
end
|
8
|
+
|
9
|
+
def global
|
10
|
+
response = get_request("chat/badges/global")
|
11
|
+
Collection.from_response(response, type: Badge)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Twitch
|
2
|
+
class BannedEventsResource < Resource
|
3
|
+
|
4
|
+
def list(broadcaster_id:, **params)
|
5
|
+
response = get_request("moderation/banned/events", params: params.merge(broadcaster_id: broadcaster_id))
|
6
|
+
Collection.from_response(response, type: BannedEvent)
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Twitch
|
2
|
+
class BannedUsersResource < Resource
|
3
|
+
|
4
|
+
# Broadcaster ID must match the user in the OAuth token
|
5
|
+
def list(broadcaster_id:, **params)
|
6
|
+
response = get_request("moderation/banned", params: params.merge(broadcaster_id: broadcaster_id))
|
7
|
+
Collection.from_response(response, type: BannedUser)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Twitch
|
2
|
+
class ChannelsResource < Resource
|
3
|
+
|
4
|
+
def get(broadcaster_id:)
|
5
|
+
User.new get_request("channels?broadcaster_id=#{broadcaster_id}").body.dig("data")[0]
|
6
|
+
end
|
7
|
+
|
8
|
+
# Requires scope: channel:manage:broadcast
|
9
|
+
def update(broadcaster_id:, **attributes)
|
10
|
+
patch_request("channels", body: attributes.merge(broadcaster_id: broadcaster_id))
|
11
|
+
end
|
12
|
+
|
13
|
+
# Requires scope: channel:read:editors
|
14
|
+
def editors(broadcaster_id:)
|
15
|
+
response = get_request("channels/editors?broadcaster_id=#{broadcaster_id}")
|
16
|
+
Collection.from_response(response, type: ChannelEditor)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Twitch
|
2
|
+
class ClipsResource < Resource
|
3
|
+
|
4
|
+
def list(**params)
|
5
|
+
raise "id, broadcaster_id or game_id is required" unless !params[:id].nil? || !params[:broadcaster_id].nil? || !params[:game_id].nil?
|
6
|
+
|
7
|
+
response = get_request("clips", params: params)
|
8
|
+
Collection.from_response(response, type: Clip)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Required scope: clips:edit
|
12
|
+
def create(broadcaster_id:, **attributes)
|
13
|
+
response = post_request("clips", body: attributes.merge(broadcaster_id: broadcaster_id))
|
14
|
+
|
15
|
+
Clip.new(response.body.dig("data")[0]) if response.success?
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Twitch
|
2
|
+
class CustomRewardRedemptionsResource < Resource
|
3
|
+
|
4
|
+
# Required scope: channel:read:redemptions
|
5
|
+
# Broadcaster ID must match the user in the OAuth token
|
6
|
+
def list(broadcaster_id:, reward_id:, status:, **params)
|
7
|
+
attributes = {broadcaster_id: broadcaster_id, reward_id: reward_id, status: status.upcase}
|
8
|
+
response = get_request("channel_points/custom_rewards/redemptions", params: attributes.merge(params))
|
9
|
+
Collection.from_response(response, type: CustomRewardRedemption)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Currently disabled as getting this error and can't work out why
|
13
|
+
# Twitch::Error (Error 400: Your request was malformed. 'The parameter "id" was malformed: the value must be greater than or equal to 1')
|
14
|
+
# def update(broadcaster_id:, reward_id:, redemption_id:, status:)
|
15
|
+
# attributes = {broadcaster_id: broadcaster_id, reward_id: reward_id, id: redemption_id, status: status.upcase}
|
16
|
+
# response = patch_request("channel_points/custom_rewards/redemptions", body: attributes)
|
17
|
+
|
18
|
+
# CustomRewardRedemption.new(response.body.dig("data")[0]) if response.success?
|
19
|
+
# end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Twitch
|
2
|
+
class CustomRewardsResource < Resource
|
3
|
+
|
4
|
+
# Required scope: channel:read:redemptions
|
5
|
+
# Broadcaster ID must match the user in the OAuth token
|
6
|
+
def list(broadcaster_id:, **params)
|
7
|
+
response = get_request("channel_points/custom_rewards", params: params.merge(broadcaster_id: broadcaster_id))
|
8
|
+
Collection.from_response(response, type: CustomReward)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(broadcaster_id:, title:, cost:, **params)
|
12
|
+
attributes = {broadcaster_id: broadcaster_id, title: title, cost: cost}
|
13
|
+
response = post_request("channel_points/custom_rewards", body: attributes.merge(params))
|
14
|
+
|
15
|
+
CustomReward.new(response.body.dig("data")[0]) if response.success?
|
16
|
+
end
|
17
|
+
|
18
|
+
def update(broadcaster_id:, reward_id:, **params)
|
19
|
+
attributes = {broadcaster_id: broadcaster_id, id: reward_id}
|
20
|
+
response = patch_request("channel_points/custom_rewards", body: attributes.merge(params))
|
21
|
+
|
22
|
+
CustomReward.new(response.body.dig("data")[0]) if response.success?
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete(broadcaster_id:, reward_id:)
|
26
|
+
delete_request("channel_points/custom_rewards", params: {broadcaster_id: broadcaster_id, id: reward_id})
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Twitch
|
2
|
+
class EmotesResource < Resource
|
3
|
+
|
4
|
+
def channel(broadcaster_id:)
|
5
|
+
response = get_request("chat/emotes?broadcaster_id=#{broadcaster_id}")
|
6
|
+
Collection.from_response(response, type: Emote)
|
7
|
+
end
|
8
|
+
|
9
|
+
def global
|
10
|
+
response = get_request("chat/emotes/global")
|
11
|
+
Collection.from_response(response, type: Emote)
|
12
|
+
end
|
13
|
+
|
14
|
+
def sets(emote_set_id:)
|
15
|
+
response = get_request("chat/emotes/set?emote_set_id=#{emote_set_id}")
|
16
|
+
Collection.from_response(response, type: Emote)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Twitch
|
2
|
+
class EventSubSubscriptionsResource < Resource
|
3
|
+
|
4
|
+
def list(**params)
|
5
|
+
response = get_request("eventsub/subscriptions", params: params)
|
6
|
+
Collection.from_response(response, type: EventSubSubscription)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(type:, version:, condition:, transport:)
|
10
|
+
attributes = {type: type, version: version, condition: condition, transport: transport}
|
11
|
+
response = post_request("eventsub/subscriptions", body: attributes)
|
12
|
+
|
13
|
+
EventSubSubscription.new(response.body.dig("data")[0]) if response.success?
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(id:)
|
17
|
+
delete_request("eventsub/subscriptions", params: {id: id})
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Twitch
|
2
|
+
class GamesResource < Resource
|
3
|
+
|
4
|
+
def get_by_id(game_id:)
|
5
|
+
response = get_request("games?id=#{game_id}")
|
6
|
+
Collection.from_response(response, type: Game)
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_by_name(name:)
|
10
|
+
response = get_request("games?name=#{name}")
|
11
|
+
Collection.from_response(response, type: Game)
|
12
|
+
end
|
13
|
+
|
14
|
+
def top(**params)
|
15
|
+
response = get_request("games/top", params: params)
|
16
|
+
Collection.from_response(response, type: Game)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Twitch
|
2
|
+
class GoalsResource < Resource
|
3
|
+
|
4
|
+
# Required scope: channel:read:goals
|
5
|
+
# Broadcaster ID must match the user in the OAuth token
|
6
|
+
def list(broadcaster_id:)
|
7
|
+
response = get_request("goals", params: {broadcaster_id: broadcaster_id})
|
8
|
+
Collection.from_response(response, type: Goal)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Twitch
|
2
|
+
class HypeTrainEventsResource < Resource
|
3
|
+
|
4
|
+
# Required scope: channel:read:hype_train
|
5
|
+
# Broadcaster ID must match the user in the OAuth token
|
6
|
+
def list(broadcaster_id:)
|
7
|
+
response = get_request("hypetrain/events", params: {broadcaster_id: broadcaster_id})
|
8
|
+
Collection.from_response(response, type: HypeTrainEvent)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Twitch
|
2
|
+
class ModeratorEventsResource < Resource
|
3
|
+
|
4
|
+
# Broadcaster ID must match the user in the OAuth token
|
5
|
+
def list(broadcaster_id:, **params)
|
6
|
+
response = get_request("moderation/moderators/events", params: params.merge(broadcaster_id: broadcaster_id))
|
7
|
+
Collection.from_response(response, type: ModeratorEvent)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Twitch
|
2
|
+
class ModeratorsResource < Resource
|
3
|
+
|
4
|
+
# Broadcaster ID must match the user in the OAuth token
|
5
|
+
def list(broadcaster_id:, **params)
|
6
|
+
response = get_request("moderation/moderators", params: params.merge(broadcaster_id: broadcaster_id))
|
7
|
+
Collection.from_response(response, type: Moderator)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Twitch
|
2
|
+
class PollsResource < Resource
|
3
|
+
|
4
|
+
# Broadcaster ID must match the user in the OAuth token
|
5
|
+
def list(broadcaster_id:, **params)
|
6
|
+
response = get_request("polls", params: params.merge(broadcaster_id: broadcaster_id))
|
7
|
+
Collection.from_response(response, type: Poll)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Broadcaster ID must match the user in the OAuth token
|
11
|
+
def create(broadcaster_id:, title:, choices:, duration:, **params)
|
12
|
+
attrs = {broadcaster_id: broadcaster_id, title: title, choices: choices, duration: duration}
|
13
|
+
response = post_request("polls", body: attrs.merge(params))
|
14
|
+
|
15
|
+
Poll.new(response.body.dig("data")[0]) if response.success?
|
16
|
+
end
|
17
|
+
|
18
|
+
# Broadcaster ID must match the user in the OAuth token
|
19
|
+
def end(broadcaster_id:, id:, status:)
|
20
|
+
attrs = {broadcaster_id: broadcaster_id, id: id, status: status.upcase}
|
21
|
+
response = patch_request("polls", body: attrs)
|
22
|
+
|
23
|
+
Poll.new(response.body.dig("data")[0]) if response.success?
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Twitch
|
2
|
+
class PredictionsResource < Resource
|
3
|
+
|
4
|
+
# Broadcaster ID must match the user in the OAuth token
|
5
|
+
def list(broadcaster_id:, **params)
|
6
|
+
response = get_request("predictions", params: params.merge(broadcaster_id: broadcaster_id))
|
7
|
+
|
8
|
+
if response.body["data"]
|
9
|
+
Collection.from_response(response, type: Prediction)
|
10
|
+
else
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Broadcaster ID must match the user in the OAuth token
|
16
|
+
def create(broadcaster_id:, title:, outcomes:, duration:, **params)
|
17
|
+
attrs = {broadcaster_id: broadcaster_id, title: title, outcomes: outcomes, prediction_window: duration}
|
18
|
+
response = post_request("predictions", body: attrs.merge(params))
|
19
|
+
|
20
|
+
Prediction.new(response.body.dig("data")[0]) if response.success?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Broadcaster ID must match the user in the OAuth token
|
24
|
+
def end(broadcaster_id:, id:, status:, **params)
|
25
|
+
attrs = {broadcaster_id: broadcaster_id, id: id, status: status.upcase}
|
26
|
+
response = patch_request("predictions", body: attrs.merge(params))
|
27
|
+
|
28
|
+
Prediction.new(response.body.dig("data")[0]) if response.success?
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Twitch
|
2
|
+
class SearchResource < Resource
|
3
|
+
|
4
|
+
def categories(query:, **params)
|
5
|
+
response = get_request("search/categories", params: params.merge(query: query))
|
6
|
+
|
7
|
+
Collection.from_response(response, type: SearchResult)
|
8
|
+
end
|
9
|
+
|
10
|
+
def channels(query:, **params)
|
11
|
+
response = get_request("search/channels", params: params.merge(query: query))
|
12
|
+
|
13
|
+
Collection.from_response(response, type: SearchResult)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Twitch
|
2
|
+
class StreamMarkersResource < Resource
|
3
|
+
|
4
|
+
# Required scope: user:read:broadcast
|
5
|
+
def list(**params)
|
6
|
+
response = get_request("streams/markers", params: params)
|
7
|
+
|
8
|
+
Collection.from_response(response, type: StreamMarker)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Required scope: channel:manage:broadcast
|
12
|
+
def create(user_id:, **params)
|
13
|
+
response = post_request("streams/markers", body: params.merge(user_id: user_id))
|
14
|
+
|
15
|
+
StreamMarker.new(response.body.dig("data")[0]) if response.success?
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Twitch
|
2
|
+
class StreamScheduleResource < Resource
|
3
|
+
|
4
|
+
# Broadcaster ID must match the user in the OAuth token
|
5
|
+
def list(broadcaster_id:, **params)
|
6
|
+
response = get_request("schedule", params: params.merge(broadcaster_id: broadcaster_id))
|
7
|
+
|
8
|
+
StreamSchedule.new(response.body) if response.success?
|
9
|
+
end
|
10
|
+
|
11
|
+
# Broadcaster ID must match the user in the OAuth token
|
12
|
+
def icalendar(broadcaster_id:)
|
13
|
+
response = get_request("schedule/icalendar", params: {broadcaster_id: broadcaster_id})
|
14
|
+
|
15
|
+
response.body
|
16
|
+
end
|
17
|
+
|
18
|
+
# Broadcaster ID must match the user in the OAuth token
|
19
|
+
# TODO: Allow the user to put any date format and then convert it to RFC3339
|
20
|
+
def update(broadcaster_id:, **params)
|
21
|
+
patch_request("schedule/settings", body: params.merge(broadcaster_id: broadcaster_id))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Broadcaster ID must match the user in the OAuth token
|
25
|
+
def create_segment(broadcaster_id:, start_time:, timezone:, duration:, is_recurring:, **params)
|
26
|
+
attrs = {broadcaster_id: broadcaster_id, start_time: start_time, duration: duration, timezone: timezone, is_recurring: is_recurring}
|
27
|
+
response = post_request("schedule/segment", body: attrs.merge(params))
|
28
|
+
|
29
|
+
StreamSchedule.new(response.body) if response.success?
|
30
|
+
end
|
31
|
+
|
32
|
+
# Broadcaster ID must match the user in the OAuth token
|
33
|
+
def update_segment(broadcaster_id:, id:, **params)
|
34
|
+
attrs = {broadcaster_id: broadcaster_id, id: id}
|
35
|
+
response = patch_request("schedule/segment", body: attrs.merge(params))
|
36
|
+
|
37
|
+
StreamSchedule.new(response.body) if response.success?
|
38
|
+
end
|
39
|
+
|
40
|
+
# Broadcaster ID must match the user in the OAuth token
|
41
|
+
def delete_segment(broadcaster_id:, id:)
|
42
|
+
attrs = {broadcaster_id: broadcaster_id, id: id}
|
43
|
+
delete_request("schedule/segment", params: attrs)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Twitch
|
2
|
+
class StreamsResource < Resource
|
3
|
+
|
4
|
+
def list(**params)
|
5
|
+
response = get_request("streams", params: params)
|
6
|
+
|
7
|
+
Collection.from_response(response, type: Stream)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Required scope: user:read:follows
|
11
|
+
# User ID must match the user in the OAuth token
|
12
|
+
def followed(user_id:, **params)
|
13
|
+
response = get_request("streams/followed", params: params.merge(user_id: user_id))
|
14
|
+
|
15
|
+
Collection.from_response(response, type: Stream)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Twitch
|
2
|
+
class SubscriptionsResource < Resource
|
3
|
+
|
4
|
+
# Get all subscriptions for a broadcaster
|
5
|
+
# Broadcaster ID must match the user in the OAuth token
|
6
|
+
# Required scope: channel:read:subscriptions
|
7
|
+
def list(broadcaster_id:, **params)
|
8
|
+
response = get_request("subscriptions", params: params.merge(broadcaster_id: broadcaster_id))
|
9
|
+
Collection.from_response(response, type: Subscription)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Checks if a User is subscribed to a Broadcaster
|
13
|
+
# If 404 then the user is not subscribed
|
14
|
+
# User ID must match the user in the OAuth token
|
15
|
+
# Required scope: user:read:subscriptions
|
16
|
+
def is_subscribed(broadcaster_id:, user_id:, **params)
|
17
|
+
attrs = {broadcaster_id: broadcaster_id, user_id: user_id}
|
18
|
+
response = get_request("subscriptions/user", params: attrs.merge(params))
|
19
|
+
Collection.from_response(response, type: Subscription)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Calculate the number of Subscribers & Subscriber Points a broadcaster has
|
23
|
+
# Broadcaster ID must match the user in the OAuth token
|
24
|
+
# Required scope: channel:read:subscriptions
|
25
|
+
def calculate(broadcaster_id:, remove_count: 0, remove_points: 0)
|
26
|
+
calculate_subs(broadcaster_id: broadcaster_id, remove_count: remove_count, remove_points: remove_points)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def get_subscriptions(broadcaster_id:)
|
32
|
+
subs = []
|
33
|
+
cursor = nil
|
34
|
+
count = 1
|
35
|
+
|
36
|
+
while count > 0
|
37
|
+
sub_response = list(broadcaster_id: broadcaster_id, first: 100, after: cursor)
|
38
|
+
|
39
|
+
subs += sub_response.data
|
40
|
+
|
41
|
+
cursor = sub_response.cursor
|
42
|
+
count = sub_response.total
|
43
|
+
end
|
44
|
+
|
45
|
+
return subs
|
46
|
+
end
|
47
|
+
|
48
|
+
def calculate_subs(broadcaster_id:, remove_count:, remove_points:)
|
49
|
+
subs = get_subscriptions(broadcaster_id: broadcaster_id)
|
50
|
+
|
51
|
+
count = 0
|
52
|
+
points = 0
|
53
|
+
|
54
|
+
if !subs.empty? && subs.count >= 1
|
55
|
+
subs.each do |sub|
|
56
|
+
# We don't want to add the broadcaster into the count
|
57
|
+
next if sub.user_id.to_s == broadcaster_id.to_s
|
58
|
+
|
59
|
+
count += 1
|
60
|
+
points += 1 if sub.tier == "1000"
|
61
|
+
points += 2 if sub.tier == "2000"
|
62
|
+
points += 6 if sub.tier == "3000"
|
63
|
+
end
|
64
|
+
|
65
|
+
count = (count - remove_count)
|
66
|
+
points = (points - remove_points)
|
67
|
+
end
|
68
|
+
|
69
|
+
SubscriptionCount.new(count: count, points: points)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Twitch
|
2
|
+
class TagsResource < Resource
|
3
|
+
|
4
|
+
def list(**params)
|
5
|
+
response = get_request("tags/streams", params: params)
|
6
|
+
Collection.from_response(response, type: Tag)
|
7
|
+
end
|
8
|
+
|
9
|
+
def stream(broadcaster_id:, **params)
|
10
|
+
response = get_request("streams/tags", params: params.merge(broadcaster_id: broadcaster_id))
|
11
|
+
Collection.from_response(response, type: Tag)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Required scope: channel:manage:broadcast
|
15
|
+
def replace(broadcaster_id:, **params)
|
16
|
+
put_request("streams/tags", body: params.merge(broadcaster_id: broadcaster_id))
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Twitch
|
2
|
+
class UsersResource < Resource
|
3
|
+
|
4
|
+
def get_by_id(user_id:)
|
5
|
+
User.new get_request("users/?id=#{user_id}").body.dig("data")[0]
|
6
|
+
end
|
7
|
+
|
8
|
+
def get_by_username(username:)
|
9
|
+
User.new get_request("users/?login=#{username}").body.dig("data")[0]
|
10
|
+
end
|
11
|
+
|
12
|
+
# Updates the current users description
|
13
|
+
# Required scope: user:edit
|
14
|
+
def update(description:)
|
15
|
+
response = put_request("users", body: {description: description})
|
16
|
+
User.new response.body.dig("data")[0]
|
17
|
+
end
|
18
|
+
|
19
|
+
def follows(**params)
|
20
|
+
raise "from_id or to_id is required" unless !params[:from_id].nil? || !params[:to_id].nil?
|
21
|
+
|
22
|
+
response = get_request("users/follows", params: params)
|
23
|
+
Collection.from_response(response, type: FollowedUser)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Required scope: user:read:blocked_users
|
27
|
+
def blocks(broadcaster_id:, **params)
|
28
|
+
response = get_request("users/blocks?broadcaster_id=#{broadcaster_id}", params: params)
|
29
|
+
Collection.from_response(response, type: BlockedUser)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Required scope: user:manage:blocked_users
|
33
|
+
def block_user(target_user_id:, **attributes)
|
34
|
+
put_request("users/blocks?target_user_id=#{target_user_id}", body: attributes)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Required scope: user:manage:blocked_users
|
38
|
+
def unblock_user(target_user_id:)
|
39
|
+
delete_request("users/blocks?target_user_id=#{target_user_id}")
|
40
|
+
end
|
41
|
+
|
42
|
+
# A quick method to see if a user is following a channel
|
43
|
+
def following?(from_id:, to_id:)
|
44
|
+
response = get_request("users/follows", params: {from_id: from_id, to_id: to_id})
|
45
|
+
|
46
|
+
if response.body["data"].empty?
|
47
|
+
false
|
48
|
+
else
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Twitch
|
2
|
+
class VideosResource < Resource
|
3
|
+
|
4
|
+
def list(**params)
|
5
|
+
raise "id, user_id or game_id is required" unless !params[:id].nil? || !params[:user_id].nil? || !params[:game_id].nil?
|
6
|
+
|
7
|
+
response = get_request("videos", params: params)
|
8
|
+
Collection.from_response(response, type: Video)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Required scope: channel:manage:videos
|
12
|
+
# def delete(video_id:)
|
13
|
+
# delete_request("videos?id=#{video_id}")
|
14
|
+
# end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/twitch/version.rb
CHANGED