twitch-bot 2.1.1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55f8f1fa119d4344d036c5644cc8544ab4b0f9b9bac3d2d5dad21ccf157f4bed
4
- data.tar.gz: d0df1fc16260d45e0187377e3aa7574dad0a85fe57c907b648e943c3c5d9303a
3
+ metadata.gz: 38e0242c3bca6c9dbf21deab310f99435146e3e7be852ba50d26a489c81f2f24
4
+ data.tar.gz: 17963e5b6af86dcd2892d20a80661f2a44afc46692375b207c2f55600664e5b3
5
5
  SHA512:
6
- metadata.gz: 4a966f66085b1767a136e11947c316f9ece94893658b8dda98a1e519aadc7d2e720b9bd0dba904e3ee070041f799231ade30be3a78a33d275370dd426fba4cc8
7
- data.tar.gz: f7340c7b36d5e2cf6f3e84a64d898013fe0c519361cffc6f6ad8eeacbd8b5c369f539ddfdebea90dabf034eaf648b32026805df27cca02538ae5eafbbd89357f
6
+ metadata.gz: 3d77d780322da5aeb3df98caa3991995be44e0b67c8510473fa66ccc533b8c3cfd0169dc1082726fcf4c7f26f324ac4086d3f6af300d933a47882263d5372203
7
+ data.tar.gz: 4c1e4e6cbbde65ce58dc0683e43f6de1ebdeaa62582375304b554beaad604b8f69f95a6bfa3821490e6cdb03f1eb02b2b3d37972ea0eee7a4189803aa0661156
@@ -0,0 +1,47 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - name: Set up Ruby
14
+ uses: actions/setup-ruby@v1
15
+ with:
16
+ ruby-version: 2.6.x
17
+ - name: Bundle
18
+ run: |
19
+ gem install bundler
20
+ bundle install --jobs 4 --retry 3
21
+ - name: Build and test
22
+ run: |
23
+ bundle exec rake test
24
+
25
+ release:
26
+ if: startsWith(github.ref, 'refs/tags/v')
27
+ needs: test
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v2
31
+ - name: Set up Ruby
32
+ uses: actions/setup-ruby@v1
33
+ with:
34
+ ruby-version: 2.6.x
35
+ - name: Bundle
36
+ run: |
37
+ gem install bundler
38
+ bundle install --jobs 4 --retry 3
39
+ - name: Publish to RubyGems
40
+ run: |
41
+ mkdir -p $HOME/.gem
42
+ touch $HOME/.gem/credentials
43
+ chmod 0600 $HOME/.gem/credentials
44
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
45
+ rake release
46
+ env:
47
+ GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog Twitch::Bot
2
2
 
3
+ ## v3.1.0
4
+
5
+ * [NEW] Client provides a persistent memory in form of a key/value store.
6
+
7
+ ## v3.0.0
8
+
9
+ * [BREAKING] Instead of choosing and creating the `Adapter` in the `Client`, we now inject a `Config` class into `Client` that carries our choice of Adapter. This change also makes the `Connection` class obsolete; its information went into `Config` as well.
10
+
3
11
  ## v2.1.1
4
12
 
5
13
  * [FIXED] Fix a few bugs missed by not running tests. We need CI...
data/README.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  `twitch-bot` provides a Twitch chat client object that can be used for building Twitch chat bots.
4
4
 
5
- This gem is based on the `twitch-chat` gem by https://github.com/EnotPoloskun.
6
-
7
- _As of April 2020, this gem is under heavy development. I've created it to develop my own Twitch chat bot and will add more functionality. Feel free to add issues with suggestions and feature requests!_
5
+ This gem is based on [`twitch-chat`](https://github.com/EnotPoloskun/twitch-chat).
8
6
 
9
7
  ## Installation
10
8
 
@@ -28,57 +26,7 @@ $ gem install twitch-bot
28
26
 
29
27
  ## Usage
30
28
 
31
- ```ruby
32
- require "twitch/bot"
33
-
34
- class JoinHandler < Twitch::Bot::EventHandler
35
- def call
36
- client.send_message "Hi guys!"
37
- end
38
-
39
- def self.handled_events
40
- [:join]
41
- end
42
- end
43
-
44
- class SubscriptionHandler < Twitch::Bot::EventHandler
45
- def call
46
- client.send_message "Hi #{event.user}, thank you for your subscription"
47
- end
48
-
49
- def self.handled_events
50
- [:subscription]
51
- end
52
- end
53
-
54
- class TimeCommandHandler < Twitch::Bot::EventHandler
55
- def call
56
- if event.bot_command?("time")
57
- client.send_message "Current time: #{Time.now.utc}"
58
- end
59
- end
60
-
61
- def self.handled_events
62
- [:chat_message]
63
- end
64
- end
65
-
66
- connection = Twitch::Bot::Connection.new(
67
- nickname: "test",
68
- password: "secret",
69
- )
70
-
71
- client = Twitch::Bot::Client.new(
72
- connection: connection,
73
- channel: "test",
74
- ) do
75
- register_handler(JoinHandler)
76
- register_handler(SubscriptionHandler)
77
- register_handler(TimeCommandHandler)
78
- end
79
-
80
- client.run
81
- ```
29
+ Refer to the [Teneggs](https://www.github.com/geewiz/teneggs) repository for an example bot implementation.
82
30
 
83
31
  ## Supported event types
84
32
 
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
+ task default: :test
3
4
  task test: %i[rubocop spec]
4
5
 
5
6
  begin
@@ -52,10 +52,9 @@ module Twitch
52
52
  attr_reader :socket, :client, :channel
53
53
 
54
54
  def open_socket
55
- connection = client.connection
56
55
  @socket = ::TCPSocket.new(
57
- connection.hostname,
58
- connection.port,
56
+ client.config.setting("irc_hostname") || "irc.chat.twitch.tv",
57
+ client.config.setting("irc_port") || 6667,
59
58
  )
60
59
 
61
60
  Twitch::Bot::Logger.debug "Socket open"
@@ -95,9 +94,9 @@ module Twitch
95
94
  end
96
95
 
97
96
  def authenticate
98
- connection = client.connection
99
- send_data "PASS #{connection.password}"
100
- send_data "NICK #{connection.nickname}"
97
+ config = client.config
98
+ send_data "PASS #{config.setting('irc_password')}"
99
+ send_data "NICK #{config.setting('irc_nickname')}"
101
100
  end
102
101
 
103
102
  def sanitize_data(data)
@@ -5,9 +5,7 @@ module Twitch
5
5
  module Adapter
6
6
  # This adapter connects the chat client to the terminal
7
7
  class Terminal
8
- def initialize(client:)
9
- @client = client
10
- end
8
+ def initialize(client:); end
11
9
 
12
10
  def connect; end
13
11
 
@@ -22,7 +20,7 @@ module Twitch
22
20
  end
23
21
 
24
22
  def send_data(data)
25
- puts sanitize_data(data)
23
+ puts data
26
24
  end
27
25
 
28
26
  def join_channel(_channel); end
@@ -33,12 +31,6 @@ module Twitch
33
31
 
34
32
  attr_reader :client
35
33
 
36
- def sanitize_data(data)
37
- data.gsub(/(PASS oauth:)(\w+)/) do
38
- "#{Regexp.last_match(1)}#{'*' * Regexp.last_match(2).size}"
39
- end
40
- end
41
-
42
34
  def read_message_from_terminal
43
35
  Twitch::Bot::Logger.debug "Waiting for input..."
44
36
  input = gets
@@ -19,23 +19,35 @@ module Twitch
19
19
  USER_MESSAGES_COUNT = 20
20
20
  TWITCH_PERIOD = 30.0
21
21
 
22
- attr_reader :connection
22
+ attr_reader :channel, :config, :memory
23
23
 
24
24
  def initialize(
25
- connection:, channel: nil, &block
25
+ channel: nil, config:, &block
26
26
  )
27
- @connection = connection
27
+ @config = config
28
28
  @channel = Twitch::Bot::Channel.new(channel) if channel
29
+
29
30
  @messages_queue = []
30
31
  @event_handlers = {}
31
32
  @event_loop_running = false
32
33
 
33
- create_adapter
34
+ setup_logging
35
+
36
+ memory_class = config.setting("memory") || "Twitch::Bot::Memory::Hash"
37
+ @memory = Object.const_get(memory_class).new
38
+
39
+ adapter_class = config.setting("adapter") || "Twitch::Bot::Adapter::Irc"
40
+ @adapter = Object.const_get(adapter_class).new(client: self)
34
41
 
35
42
  execute_initialize_block block if block
36
43
  register_default_handlers
37
44
  end
38
45
 
46
+ #
47
+ # Register an event handler for specific event types
48
+ #
49
+ # @param [<EventHandler>] handler EventHandler class to register
50
+ #
39
51
  def register_handler(handler)
40
52
  handler.handled_events.each do |event_type|
41
53
  (event_handlers[event_type] ||= []) << handler
@@ -95,15 +107,13 @@ module Twitch
95
107
  private
96
108
 
97
109
  attr_reader :adapter, :event_handlers, :event_loop_running,
98
- :input_thread, :output_thread, :channel, :messages_queue
110
+ :input_thread, :output_thread, :messages_queue
99
111
 
100
- def create_adapter
101
- adapter_class = if development_mode?
102
- Twitch::Bot::Adapter::Terminal
103
- else
104
- Twitch::Bot::Adapter::Irc
105
- end
106
- @adapter = adapter_class.new(client: self)
112
+ def setup_logging
113
+ Twitch::Bot::Logger.output =
114
+ config.setting(:log_file) || "twitchbot.log"
115
+ Twitch::Bot::Logger.level =
116
+ (config.setting(:log_level) || "info").to_sym
107
117
  end
108
118
 
109
119
  def startup
@@ -156,10 +166,6 @@ module Twitch
156
166
  end
157
167
  end
158
168
 
159
- def development_mode?
160
- ENV["BOT_MODE"] == "development"
161
- end
162
-
163
169
  def execute_initialize_block(block)
164
170
  if block.arity == 1
165
171
  block.call self
@@ -175,7 +181,7 @@ module Twitch
175
181
  end
176
182
 
177
183
  def max_messages_count
178
- if channel.moderators.include?(connection.nickname)
184
+ if channel.moderators.include?(config.setting("botname"))
179
185
  MODERATOR_MESSAGES_COUNT
180
186
  else
181
187
  USER_MESSAGES_COUNT
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Twitch
4
+ module Bot
5
+ # This class stores the connection details for the client.
6
+ class Config
7
+ def initialize(settings: {})
8
+ @settings = settings
9
+ end
10
+
11
+ def setting(name)
12
+ conf = settings
13
+ name_str = name.to_s
14
+ name_str.split("_").each do |key|
15
+ return nil if conf.nil?
16
+
17
+ conf = conf.fetch(key.to_sym, nil)
18
+ end
19
+ conf
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :settings
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Twitch
4
+ module Bot
5
+ # Manage a key/value store for our bot
6
+ module Memory
7
+ class Hash
8
+ def initialize
9
+ @kvstore = {}
10
+ end
11
+
12
+ def store(key, value)
13
+ kvstore[key] = value
14
+ end
15
+
16
+ def retrieve(key)
17
+ kvstore[key]
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :kvstore
23
+ end
24
+ end
25
+ end
26
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Twitch
4
4
  module Bot
5
- VERSION = "2.1.1"
5
+ VERSION = "3.1.0"
6
6
  end
7
7
  end
data/lib/twitch/bot.rb CHANGED
@@ -4,6 +4,7 @@ require "bundler/setup"
4
4
  Bundler.require(:default)
5
5
 
6
6
  require_relative "bot/version"
7
+ require_relative "bot/config"
7
8
  require_relative "bot/logger"
8
9
  require_relative "bot/event"
9
10
  require_relative "bot/event_handler"
@@ -11,8 +12,8 @@ require_relative "bot/default_handlers"
11
12
  require_relative "bot/message"
12
13
  require_relative "bot/irc_message"
13
14
  require_relative "bot/message_parser"
15
+ require_relative "bot/memory/hash"
14
16
  require_relative "bot/channel"
15
- require_relative "bot/connection"
16
17
  require_relative "bot/adapter/irc"
17
18
  require_relative "bot/adapter/terminal"
18
19
  require_relative "bot/client"
@@ -2,10 +2,16 @@
2
2
 
3
3
  RSpec.describe Twitch::Bot::Client do
4
4
  let!(:client) do
5
- connection = Twitch::Bot::Connection.new(
6
- nickname: "test", password: "test",
5
+ config = Twitch::Bot::Config.new(
6
+ settings: {
7
+ bot_user: "testuser",
8
+ adapter: "Twitch::Bot::Adapter::Terminal",
9
+ },
10
+ )
11
+ described_class.new(
12
+ config: config,
13
+ channel: "testchannel",
7
14
  )
8
- described_class.new(connection: connection)
9
15
  end
10
16
 
11
17
  describe "#trigger" do
@@ -49,4 +55,20 @@ RSpec.describe Twitch::Bot::Client do
49
55
  expect(client).to have_received(:remove_moderator)
50
56
  end
51
57
  end
58
+
59
+ describe "#channel" do
60
+ it "returns the channel object" do
61
+ channel = client.channel
62
+
63
+ expect(channel.name).to eq "testchannel"
64
+ end
65
+ end
66
+
67
+ describe "#memory" do
68
+ it "stores and retrieves data" do
69
+ client.memory.store("foo", "bar")
70
+
71
+ expect(client.memory.retrieve("foo")).to eq "bar"
72
+ end
73
+ end
52
74
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Twitch::Bot::Config do
4
+ describe "#setting" do
5
+ it "returns a first-level setting" do
6
+ config = described_class.new(
7
+ settings: {
8
+ test: "Test",
9
+ foo: "bar",
10
+ },
11
+ )
12
+
13
+ expect(config.setting("test")).to eq "Test"
14
+ end
15
+
16
+ it "returns a second-level setting" do
17
+ config = described_class.new(
18
+ settings: {
19
+ test: {
20
+ foo: "bar",
21
+ },
22
+ },
23
+ )
24
+
25
+ expect(config.setting("test_foo")).to eq "bar"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Twitch::Bot::Memory::Hash do
4
+ describe "#store" do
5
+ it "persists a value for a key" do
6
+ mem = described_class.new
7
+
8
+ mem.store("foo", "bar")
9
+
10
+ expect(mem.retrieve("foo")).to eq "bar"
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitch-bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jochen Lillich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-18 00:00:00.000000000 Z
11
+ date: 2020-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -174,6 +174,7 @@ extensions: []
174
174
  extra_rdoc_files: []
175
175
  files:
176
176
  - ".editorconfig"
177
+ - ".github/workflows/main.yml"
177
178
  - ".gitignore"
178
179
  - ".rspec"
179
180
  - ".rubocop.yml"
@@ -191,18 +192,21 @@ files:
191
192
  - lib/twitch/bot/adapter/terminal.rb
192
193
  - lib/twitch/bot/channel.rb
193
194
  - lib/twitch/bot/client.rb
194
- - lib/twitch/bot/connection.rb
195
+ - lib/twitch/bot/config.rb
195
196
  - lib/twitch/bot/default_handlers.rb
196
197
  - lib/twitch/bot/event.rb
197
198
  - lib/twitch/bot/event_handler.rb
198
199
  - lib/twitch/bot/irc_message.rb
199
200
  - lib/twitch/bot/logger.rb
201
+ - lib/twitch/bot/memory/hash.rb
200
202
  - lib/twitch/bot/message.rb
201
203
  - lib/twitch/bot/message/user_message.rb
202
204
  - lib/twitch/bot/message_parser.rb
203
205
  - lib/twitch/bot/version.rb
204
206
  - spec/spec_helper.rb
205
207
  - spec/twitch/bot/client_spec.rb
208
+ - spec/twitch/bot/config_spec.rb
209
+ - spec/twitch/bot/memory/hash_spec.rb
206
210
  - spec/twitch/bot/message/user_message_spec.rb
207
211
  - spec/twitch/bot/message_parser_spec.rb
208
212
  - twitch-bot.gemspec
@@ -233,5 +237,7 @@ summary: twitch-bot is a Twitch chat client that uses Twitch IRC that can be use
233
237
  test_files:
234
238
  - spec/spec_helper.rb
235
239
  - spec/twitch/bot/client_spec.rb
240
+ - spec/twitch/bot/config_spec.rb
241
+ - spec/twitch/bot/memory/hash_spec.rb
236
242
  - spec/twitch/bot/message/user_message_spec.rb
237
243
  - spec/twitch/bot/message_parser_spec.rb
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Twitch
4
- module Bot
5
- # This class stores the connection details for the client.
6
- class Connection
7
- attr_reader :nickname, :password, :hostname, :port
8
-
9
- def initialize(
10
- nickname:, password:, hostname: "irc.chat.twitch.tv", port: "6667"
11
- )
12
- @nickname = nickname
13
- @password = password
14
- @hostname = hostname
15
- @port = port
16
- end
17
- end
18
- end
19
- end