twitchrb 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0641bf783f69ad1e15ce425ab0a04932376a98403eb996cae29e44cb04509869
4
- data.tar.gz: c50b205b48bc9671724f848e81329ff980873f598fb278da24c344c753ff1768
3
+ metadata.gz: 8228b593acef6a0efdcdd04dbacf8ce080f810703398f75d641fb0e3a2df560d
4
+ data.tar.gz: 96d303d92f782fd156b30f4a0d4d8219e90511d90d78d16ff1ef289f2d731328
5
5
  SHA512:
6
- metadata.gz: f5f5d1850b6595dce58b11f9b2cd4756f3ae00043ce22c6643d20fd133232270abf6d24360b4d2a2ef7c3220b1b1cf888745ac418ce7582c3cf220c022bfca4a
7
- data.tar.gz: 32e637838de8ea70e207655e3d870a7f7f80a021f4fb3afe4211f74293f6fcfce54e525d7f79ea859908bc2cf7f26277d3109812132610e7b48b4fe0659c0322
6
+ metadata.gz: 44755a65de44e98a714c4a762b544059ca70a942c723e741f7570a1a23de6488005e3e22700a5df2262514ac03bd748da225968951481096ebd93f24bc246c1a
7
+ data.tar.gz: 6057bade63a8527544adf8f201c1f71eb794e96d0b50fc29c2755fb54454809d4c4265574b4f7c6985a0f28cd33206b867f0352c47f885d83b0c906cb0d7028b
data/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@ All notable changes to `twitchrb` are documented in this file.
4
4
 
5
5
  Published release notes were sourced from GitHub releases where available. Older tag-only versions and the current unreleased work were reconstructed from local git history.
6
6
 
7
+ ## [2.1.0] - 2026-09-27
8
+
9
+ Completes the 2.0 cleanup: response objects no longer depend on OpenStruct.
10
+
11
+ ### Changed
12
+
13
+ - Response objects no longer use `OpenStruct`, and the `ostruct` dependency has been removed. `Twitch::Object` now
14
+ stores attributes in a hash and reads them through dot notation or hash access (`object[:id]`). Building objects is
15
+ much faster and uses less memory. Missing attributes still return `nil`.
16
+ - Nested objects are now `Twitch::Object`s rather than `OpenStruct`s, and so are the responses from `Twitch::OAuth`.
17
+ Code that checks for `OpenStruct` or calls `OpenStruct`-only methods needs updating.
18
+ - The packaged gem now only contains `lib/`, the README, LICENSE and CHANGELOG, instead of every file in the repo.
19
+
20
+ ### Added
21
+
22
+ - `key?` on response objects, to check whether an attribute is present.
23
+
7
24
  ## [2.0.0] - 2026-09-23
8
25
 
9
26
  This release adds every remaining Helix endpoint, automatic pagination, automatic token refresh, and EventSub
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 Dean Perry
3
+ Copyright (c) 2020-2026 Dean Perry
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -103,7 +103,19 @@ granted `user:bot`, and the broadcaster to have granted `channel:bot` or made th
103
103
  The gem maps as closely as we can to the Twitch API so you can easily convert API examples to gem code.
104
104
 
105
105
  Responses are created as objects like `Twitch::Channel`. Having types like `Twitch::User` is handy for understanding what
106
- type of object you're working with. They're built using OpenStruct so you can easily access data in a Ruby-ish way.
106
+ type of object you're working with. Attributes can be read with dot notation or like a hash, and nested data is wrapped too:
107
+
108
+ ```ruby
109
+ user = @client.users.retrieve(username: "twitchdev")
110
+
111
+ user.display_name #=> "TwitchDev"
112
+ user[:display_name] #=> "TwitchDev"
113
+ user.missing_attribute #=> nil
114
+
115
+ # Convert back to a hash or JSON, including nested data
116
+ user.to_h
117
+ user.to_json
118
+ ```
107
119
 
108
120
  ### Pagination
109
121
 
data/lib/twitch/oauth.rb CHANGED
@@ -59,7 +59,7 @@ module Twitch
59
59
 
60
60
  return false if response.status != 200
61
61
 
62
- JSON.parse(response.body, object_class: OpenStruct)
62
+ Object.new(JSON.parse(response.body))
63
63
  end
64
64
 
65
65
  def revoke(token:)
@@ -86,7 +86,7 @@ module Twitch
86
86
 
87
87
  raise ErrorFactory.create(response.body, response.status) if response.status != 200
88
88
 
89
- JSON.parse(response.body, object_class: OpenStruct)
89
+ Object.new(JSON.parse(response.body))
90
90
  end
91
91
 
92
92
  def scope_string(scopes)
data/lib/twitch/object.rb CHANGED
@@ -1,25 +1,40 @@
1
- require "ostruct"
2
-
3
1
  module Twitch
4
- class Object < OpenStruct
5
- def initialize(attributes)
6
- super to_ostruct(attributes)
7
- end
8
-
9
- def to_ostruct(obj)
10
- if obj.is_a?(Hash)
11
- OpenStruct.new(obj.map { |key, val| [ key, to_ostruct(val) ] }.to_h)
12
- elsif obj.is_a?(Array)
13
- obj.map { |o| to_ostruct(o) }
14
- else # Assumed to be a primitive value
15
- obj
16
- end
2
+ # A lightweight wrapper around API response data. Attributes can be read with dot notation
3
+ # (object.id) or like a hash (object[:id] or object["id"]). Nested hashes are wrapped too.
4
+ class Object
5
+ def initialize(attributes = {})
6
+ @attributes = {}
7
+ (attributes || {}).each { |key, val| self[key] = val }
8
+ end
9
+
10
+ def [](key)
11
+ @attributes[key.to_sym]
12
+ end
13
+
14
+ def []=(key, val)
15
+ @attributes[key.to_sym] = wrap(val)
16
+ end
17
+
18
+ def key?(key)
19
+ @attributes.key?(key.to_sym)
20
+ end
21
+
22
+ def dig(key, *rest)
23
+ val = self[key]
24
+ rest.empty? || val.nil? ? val : val.dig(*rest)
17
25
  end
18
26
 
19
- # Unlike OpenStruct#to_h, converts nested objects back into hashes too,
27
+ def each_pair(&block)
28
+ return enum_for(:each_pair) unless block_given?
29
+
30
+ @attributes.each_pair(&block)
31
+ self
32
+ end
33
+
34
+ # Returns the attributes as a hash, with nested objects converted to hashes too,
20
35
  # so the result can be serialized
21
36
  def to_h(&block)
22
- hash = super(&nil).transform_values { |value| to_hash_value(value) }
37
+ hash = @attributes.transform_values { |val| unwrap(val) }
23
38
  block ? hash.to_h(&block) : hash
24
39
  end
25
40
 
@@ -31,16 +46,52 @@ module Twitch
31
46
  to_h.to_json(*args)
32
47
  end
33
48
 
49
+ def ==(other)
50
+ other.is_a?(Twitch::Object) && to_h == other.to_h
51
+ end
52
+ alias eql? ==
53
+
54
+ def hash
55
+ to_h.hash
56
+ end
57
+
58
+ def inspect
59
+ attrs = @attributes.map { |key, val| "#{key}=#{val.inspect}" }.join(", ")
60
+ "#<#{self.class.name}#{" " unless attrs.empty?}#{attrs}>"
61
+ end
62
+ alias to_s inspect
63
+
34
64
  private
35
65
 
36
- def to_hash_value(value)
37
- case value
38
- when OpenStruct
39
- value.to_h.transform_values { |v| to_hash_value(v) }
40
- when Array
41
- value.map { |v| to_hash_value(v) }
66
+ # Unknown attributes return nil, like a hash
67
+ def method_missing(name, *args)
68
+ if name.end_with?("=") && args.size == 1
69
+ self[name.to_s.chomp("=")] = args.first
70
+ elsif args.empty? && !name.end_with?("=", "?", "!")
71
+ self[name]
42
72
  else
43
- value
73
+ super
74
+ end
75
+ end
76
+
77
+ def respond_to_missing?(name, include_private = false)
78
+ key?(name.to_s.chomp("=")) || super
79
+ end
80
+
81
+ def wrap(val)
82
+ case val
83
+ when Twitch::Object then val
84
+ when Hash then Twitch::Object.new(val)
85
+ when Array then val.map { |v| wrap(v) }
86
+ else val
87
+ end
88
+ end
89
+
90
+ def unwrap(val)
91
+ case val
92
+ when Twitch::Object then val.to_h
93
+ when Array then val.map { |v| unwrap(v) }
94
+ else val
44
95
  end
45
96
  end
46
97
  end
@@ -1,3 +1,3 @@
1
1
  module Twitch
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
data/lib/twitch.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "faraday"
2
2
  require "json"
3
- require "ostruct"
4
3
  require "twitch/version"
5
4
 
6
5
  module Twitch
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitchrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dean Perry
8
- bindir: exe
8
+ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
@@ -29,41 +29,15 @@ dependencies:
29
29
  - - "<"
30
30
  - !ruby/object:Gem::Version
31
31
  version: '3'
32
- - !ruby/object:Gem::Dependency
33
- name: ostruct
34
- requirement: !ruby/object:Gem::Requirement
35
- requirements:
36
- - - "~>"
37
- - !ruby/object:Gem::Version
38
- version: 0.6.0
39
- type: :runtime
40
- prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
42
- requirements:
43
- - - "~>"
44
- - !ruby/object:Gem::Version
45
- version: 0.6.0
46
32
  email:
47
- - dean@deanpcmad.com
33
+ - dean@voupe.com
48
34
  executables: []
49
35
  extensions: []
50
36
  extra_rdoc_files: []
51
37
  files:
52
- - ".env.example"
53
- - ".github/FUNDING.yml"
54
- - ".github/dependabot.yml"
55
- - ".github/workflows/ci.yml"
56
- - ".gitignore"
57
- - ".rubocop.yml"
58
38
  - CHANGELOG.md
59
- - Gemfile
60
- - Gemfile.lock
61
39
  - LICENSE.txt
62
40
  - README.md
63
- - Rakefile
64
- - bin/console
65
- - bin/setup
66
- - bin/smoke
67
41
  - lib/twitch.rb
68
42
  - lib/twitch/client.rb
69
43
  - lib/twitch/collection.rb
@@ -191,8 +165,6 @@ files:
191
165
  - lib/twitch/resources/whispers.rb
192
166
  - lib/twitch/version.rb
193
167
  - lib/twitchrb.rb
194
- - mise.toml
195
- - twitchrb.gemspec
196
168
  homepage: https://github.com/d34ndev/twitchrb
197
169
  licenses:
198
170
  - MIT
data/.env.example DELETED
@@ -1,3 +0,0 @@
1
- TWITCH_CLIENT_ID=
2
- TWITCH_CLIENT_SECRET=
3
- TWITCH_ACCESS_TOKEN=
data/.github/FUNDING.yml DELETED
@@ -1,5 +0,0 @@
1
- # These are supported funding model platforms
2
-
3
- github: deanpcmad
4
- buy_me_a_coffee: deanpcmad
5
- ko_fi: deanpcmad
@@ -1,11 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: bundler
4
- directory: "/"
5
- schedule:
6
- interval: weekly
7
- open-pull-requests-limit: 10
8
- - package-ecosystem: github-actions
9
- directory: "/"
10
- schedule:
11
- interval: monthly
@@ -1,39 +0,0 @@
1
- name: CI
2
- on:
3
- push:
4
- pull_request:
5
- jobs:
6
- lint:
7
- runs-on: ubuntu-latest
8
- continue-on-error: true
9
- steps:
10
- - name: Checkout code
11
- uses: actions/checkout@v7
12
- - name: Set up Ruby
13
- uses: ruby/setup-ruby@v1
14
- with:
15
- ruby-version: '4.0'
16
- bundler-cache: true
17
- - name: Lint code for consistent style
18
- run: bundle exec rubocop -f github
19
-
20
- test:
21
- runs-on: ubuntu-latest
22
- needs: lint
23
- strategy:
24
- fail-fast: false
25
- matrix:
26
- ruby_version:
27
- - '3.3'
28
- - '3.4'
29
- - '4.0'
30
- steps:
31
- - uses: actions/checkout@v7
32
- - uses: ruby/setup-ruby@v1
33
- with:
34
- ruby-version: ${{ matrix.ruby_version }}
35
- bundler: default
36
- bundler-cache: true
37
-
38
- - name: Run tests
39
- run: bundle exec rake test
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- .env
data/.rubocop.yml DELETED
@@ -1,16 +0,0 @@
1
- # Omakase Ruby styling for Rails
2
- inherit_gem: { rubocop-rails-omakase: rubocop.yml }
3
-
4
- AllCops:
5
- Exclude:
6
- - 'test/**/*'
7
- TargetRubyVersion: 3.3
8
-
9
- # Overwrite or add rules to create your own house style
10
- #
11
- # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
12
- # Layout/SpaceInsideArrayLiteralBrackets:
13
- # Enabled: false
14
-
15
- Rails/RefuteMethods:
16
- Enabled: false
data/Gemfile DELETED
@@ -1,13 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in twitch.gemspec
4
- gemspec
5
-
6
- gem "rake", "~> 12.0"
7
- gem "minitest", "~> 5.0"
8
- gem "dotenv"
9
- gem "webmock"
10
- gem "rubocop-rails-omakase", require: false
11
- gem "activesupport", ">= 4.2.0", "< 8.0"
12
- gem "irb"
13
- gem "cgi"
data/Gemfile.lock DELETED
@@ -1,144 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- twitchrb (2.0.0)
5
- faraday (>= 2.14.3, < 3)
6
- ostruct (~> 0.6.0)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- activesupport (7.2.3.1)
12
- base64
13
- benchmark (>= 0.3)
14
- bigdecimal
15
- concurrent-ruby (~> 1.0, >= 1.3.1)
16
- connection_pool (>= 2.2.5)
17
- drb
18
- i18n (>= 1.6, < 2)
19
- logger (>= 1.4.2)
20
- minitest (>= 5.1, < 6)
21
- securerandom (>= 0.3)
22
- tzinfo (~> 2.0, >= 2.0.5)
23
- addressable (2.9.0)
24
- public_suffix (>= 2.0.2, < 8.0)
25
- ast (2.4.3)
26
- base64 (0.3.0)
27
- benchmark (0.5.0)
28
- bigdecimal (4.1.2)
29
- cgi (0.5.1)
30
- concurrent-ruby (1.3.8)
31
- connection_pool (3.0.2)
32
- crack (1.0.1)
33
- bigdecimal
34
- rexml
35
- date (3.5.1)
36
- dotenv (3.2.0)
37
- drb (2.2.3)
38
- erb (6.0.4)
39
- faraday (2.14.3)
40
- faraday-net_http (>= 2.0, < 3.5)
41
- json
42
- logger
43
- faraday-net_http (3.4.2)
44
- net-http (~> 0.5)
45
- hashdiff (1.2.1)
46
- i18n (1.14.8)
47
- concurrent-ruby (~> 1.0)
48
- io-console (0.8.2)
49
- irb (1.18.0)
50
- pp (>= 0.6.0)
51
- prism (>= 1.3.0)
52
- rdoc (>= 4.0.0)
53
- reline (>= 0.4.2)
54
- json (2.21.2)
55
- language_server-protocol (3.17.0.5)
56
- lint_roller (1.1.0)
57
- logger (1.7.0)
58
- minitest (5.27.0)
59
- net-http (0.9.1)
60
- uri (>= 0.11.1)
61
- ostruct (0.6.3)
62
- parallel (2.1.0)
63
- parser (3.3.11.1)
64
- ast (~> 2.4.1)
65
- racc
66
- pp (0.6.3)
67
- prettyprint
68
- prettyprint (0.2.0)
69
- prism (1.9.0)
70
- psych (5.3.1)
71
- date
72
- stringio
73
- public_suffix (7.0.5)
74
- racc (1.8.1)
75
- rack (3.2.6)
76
- rainbow (3.1.1)
77
- rake (12.3.3)
78
- rdoc (7.2.0)
79
- erb
80
- psych (>= 4.0.0)
81
- tsort
82
- regexp_parser (2.12.0)
83
- reline (0.6.3)
84
- io-console (~> 0.5)
85
- rexml (3.4.4)
86
- rubocop (1.86.2)
87
- json (~> 2.3)
88
- language_server-protocol (~> 3.17.0.2)
89
- lint_roller (~> 1.1.0)
90
- parallel (>= 1.10)
91
- parser (>= 3.3.0.2)
92
- rainbow (>= 2.2.2, < 4.0)
93
- regexp_parser (>= 2.9.3, < 3.0)
94
- rubocop-ast (>= 1.49.0, < 2.0)
95
- ruby-progressbar (~> 1.7)
96
- unicode-display_width (>= 2.4.0, < 4.0)
97
- rubocop-ast (1.49.1)
98
- parser (>= 3.3.7.2)
99
- prism (~> 1.7)
100
- rubocop-performance (1.26.1)
101
- lint_roller (~> 1.1)
102
- rubocop (>= 1.75.0, < 2.0)
103
- rubocop-ast (>= 1.47.1, < 2.0)
104
- rubocop-rails (2.35.0)
105
- activesupport (>= 4.2.0)
106
- lint_roller (~> 1.1)
107
- rack (>= 1.1)
108
- rubocop (>= 1.75.0, < 2.0)
109
- rubocop-ast (>= 1.44.0, < 2.0)
110
- rubocop-rails-omakase (1.1.0)
111
- rubocop (>= 1.72)
112
- rubocop-performance (>= 1.24)
113
- rubocop-rails (>= 2.30)
114
- ruby-progressbar (1.13.0)
115
- securerandom (0.4.1)
116
- stringio (3.2.0)
117
- tsort (0.2.0)
118
- tzinfo (2.0.6)
119
- concurrent-ruby (~> 1.0)
120
- unicode-display_width (3.2.0)
121
- unicode-emoji (~> 4.1)
122
- unicode-emoji (4.2.0)
123
- uri (1.1.1)
124
- webmock (3.26.2)
125
- addressable (>= 2.8.0)
126
- crack (>= 0.3.2)
127
- hashdiff (>= 0.4.0, < 2.0.0)
128
-
129
- PLATFORMS
130
- ruby
131
-
132
- DEPENDENCIES
133
- activesupport (>= 4.2.0, < 8.0)
134
- cgi
135
- dotenv
136
- irb
137
- minitest (~> 5.0)
138
- rake (~> 12.0)
139
- rubocop-rails-omakase
140
- twitchrb!
141
- webmock
142
-
143
- BUNDLED WITH
144
- 4.0.11
data/Rakefile DELETED
@@ -1,10 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
8
- end
9
-
10
- task default: :test
data/bin/console DELETED
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "twitch"
5
-
6
- # Load environment variables from .env file
7
- require 'dotenv/load'
8
-
9
- # You can add fixtures and/or initialization code here to make experimenting
10
- # with your gem easier. You can also use a different console, if you like.
11
-
12
- # (If you use this, don't forget to add pry to your Gemfile!)
13
- # require "pry"
14
- # Pry.start
15
-
16
- @oauth = Twitch::OAuth.new(client_id: ENV["TWITCH_CLIENT_ID"], client_secret: ENV["TWITCH_CLIENT_SECRET"])
17
-
18
- @client = Twitch::Client.new(client_id: ENV["TWITCH_CLIENT_ID"], access_token: ENV["TWITCH_ACCESS_TOKEN"])
19
-
20
- @clientapp = Twitch::Client.new(client_id: ENV["TWITCH_CLIENT_ID"], access_token: ENV["TWITCH_APP_ACCESS_TOKEN"])
21
-
22
- require "irb"
23
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/bin/smoke DELETED
@@ -1,118 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # Hits the real Twitch API to verify the gem still matches what Twitch returns.
3
- # Run before releases, or on a schedule. Unit tests use WebMock and won't catch
4
- # Twitch-side schema drift; this will.
5
- #
6
- # Required env (load via .env):
7
- # TWITCH_CLIENT_ID
8
- # TWITCH_ACCESS_TOKEN # user token
9
- # TWITCH_CLIENT_SECRET # only needed for app-token checks
10
- #
11
- # Optional env — enables write checks that actually send messages:
12
- # TWITCH_SMOKE_BROADCASTER_ID # channel to post into
13
- # TWITCH_SMOKE_MODERATOR_ID # must match the user/bot in the token
14
- # # (also used as sender_id for chat messages)
15
- #
16
- # Usage:
17
- # bin/smoke # run all checks
18
- # bin/smoke users games # run only the named checks
19
-
20
- require "bundler/setup"
21
- require "twitch"
22
- require "dotenv/load"
23
-
24
- unless ENV["TWITCH_CLIENT_ID"] && ENV["TWITCH_ACCESS_TOKEN"]
25
- abort "Missing TWITCH_CLIENT_ID / TWITCH_ACCESS_TOKEN — set them in .env"
26
- end
27
-
28
- client = Twitch::Client.new(
29
- client_id: ENV["TWITCH_CLIENT_ID"],
30
- access_token: ENV["TWITCH_ACCESS_TOKEN"]
31
- )
32
-
33
- app_client = nil
34
- if ENV["TWITCH_CLIENT_SECRET"]
35
- oauth = Twitch::OAuth.new(
36
- client_id: ENV["TWITCH_CLIENT_ID"],
37
- client_secret: ENV["TWITCH_CLIENT_SECRET"]
38
- )
39
- token = oauth.create(grant_type: "client_credentials")
40
- app_client = Twitch::Client.new(client_id: ENV["TWITCH_CLIENT_ID"], access_token: token.access_token) if token
41
- end
42
-
43
- broadcaster_id = ENV["TWITCH_SMOKE_BROADCASTER_ID"]
44
- moderator_id = ENV["TWITCH_SMOKE_MODERATOR_ID"]
45
- timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
46
-
47
- CHECKS = {
48
- "users" => -> { client.users.retrieve(username: "twitchdev") },
49
- "users_many" => -> { client.users.retrieve(usernames: [ "twitchdev", "twitch" ]) },
50
- "channels" => -> { client.channels.retrieve(id: 141981764) },
51
- "games" => -> { client.games.retrieve(name: "Just Chatting") },
52
- "games_top" => -> { client.games.top(first: 5) },
53
- "streams" => -> { client.streams.list(first: 5) },
54
- "clips" => -> { client.clips.list(broadcaster_id: "141981764", first: 3) },
55
- "videos" => -> { client.videos.list(user_id: "141981764", first: 3) },
56
- "badges_global" => -> { client.badges.global },
57
- "badges_channel" => -> { client.badges.channel(broadcaster_id: "141981764") },
58
- "emotes_global" => -> { client.emotes.global },
59
- "emotes_channel" => -> { client.emotes.channel(broadcaster_id: "141981764") },
60
- "eventsub_list" => -> { client.eventsub_subscriptions.list },
61
-
62
- # app-token only
63
- "conduits_list" => -> { app_client && app_client.eventsub_conduits.list },
64
- "app_subs_list" => -> { app_client && app_client.eventsub_subscriptions.list },
65
-
66
- # write checks — only run when broadcaster + moderator ids are set
67
- "chat_message" => -> {
68
- client.chat_messages.create(
69
- broadcaster_id: broadcaster_id,
70
- sender_id: moderator_id,
71
- message: "twitchrb smoke test #{timestamp}"
72
- )
73
- },
74
- "announcement" => -> {
75
- client.announcements.create(
76
- broadcaster_id: broadcaster_id,
77
- moderator_id: moderator_id,
78
- message: "twitchrb smoke test announcement #{timestamp}",
79
- color: "primary"
80
- )
81
- }
82
- }.freeze
83
-
84
- requested = ARGV.empty? ? CHECKS.keys : ARGV
85
- unknown = requested - CHECKS.keys
86
- abort "Unknown check(s): #{unknown.join(", ")}\nAvailable: #{CHECKS.keys.join(", ")}" if unknown.any?
87
-
88
- failures = 0
89
- write_checks = %w[chat_message announcement]
90
-
91
- requested.each do |name|
92
- if name.start_with?("conduits", "app_subs") && app_client.nil?
93
- puts "- #{name.ljust(18)} skipped (no TWITCH_CLIENT_SECRET)"
94
- next
95
- end
96
-
97
- if write_checks.include?(name) && (broadcaster_id.nil? || moderator_id.nil?)
98
- puts "- #{name.ljust(18)} skipped (set TWITCH_SMOKE_BROADCASTER_ID + TWITCH_SMOKE_MODERATOR_ID)"
99
- next
100
- end
101
-
102
- begin
103
- result = CHECKS[name].call
104
- count = result.respond_to?(:data) ? result.data.size : 1
105
- puts "✓ #{name.ljust(18)} (#{count} record#{"s" unless count == 1})"
106
- rescue => e
107
- failures += 1
108
- puts "✗ #{name.ljust(18)} #{e.class}: #{e.message}"
109
- end
110
- end
111
-
112
- puts
113
- if failures.zero?
114
- puts "All checks passed."
115
- else
116
- puts "#{failures} check(s) failed."
117
- exit 1
118
- end
data/mise.toml DELETED
@@ -1,2 +0,0 @@
1
- [tools]
2
- ruby = "4.0"
data/twitchrb.gemspec DELETED
@@ -1,29 +0,0 @@
1
- require_relative 'lib/twitch/version'
2
-
3
- Gem::Specification.new do |spec|
4
- spec.name = "twitchrb"
5
- spec.version = Twitch::VERSION
6
- spec.authors = [ "Dean Perry" ]
7
- spec.email = [ "dean@deanpcmad.com" ]
8
-
9
- spec.summary = "A Ruby library for interacting with the Twitch Helix API"
10
- spec.homepage = "https://github.com/d34ndev/twitchrb"
11
- spec.license = "MIT"
12
- spec.required_ruby_version = Gem::Requirement.new(">= 3.3")
13
-
14
- spec.metadata["homepage_uri"] = spec.homepage
15
- spec.metadata["changelog_uri"] = "https://github.com/d34ndev/twitchrb/blob/main/CHANGELOG.md"
16
- spec.metadata["bug_tracker_uri"] = "https://github.com/d34ndev/twitchrb/issues"
17
-
18
- # Specify which files should be added to the gem when it is released.
19
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
- end
23
- spec.bindir = "exe"
24
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
- spec.require_paths = [ "lib" ]
26
-
27
- spec.add_dependency "faraday", ">= 2.14.3", "< 3"
28
- spec.add_dependency "ostruct", "~> 0.6.0"
29
- end