twitch_chatter 0.1.1 → 0.2.1
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fff1b37e345e021646f75631a1ec5515d10f05cbf4f238b4f2136878b5b9b02d
|
4
|
+
data.tar.gz: b47c19eaff099c6a439e864f80ed72e85b15a68f4fcbc2d4ef2a85454f47b947
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 984d51eda98c57546a8e906cef1b7d2d96dfd7d0d9de91c2c42bb18ff825279f24b9f3d85eab199eaf3f6a427ddb2d446db946102e0a1d17e90aef1559bfafac
|
7
|
+
data.tar.gz: 58909f2b18253651a6cc2d37ec36fa5d2381279a5f203f332eebe5b6441cdaffcee71bb488e53212915f8ed1e2b53b37d2f4e9e3cf9bd9973f18dfbd6b525df1
|
data/lib/twitch_chatter/bot.rb
CHANGED
@@ -21,8 +21,6 @@ module Twitch
|
|
21
21
|
websocket_url: "wss://irc-ws.chat.twitch.tv:443",
|
22
22
|
}.freeze
|
23
23
|
|
24
|
-
include Concerns::Channels
|
25
|
-
|
26
24
|
def initialize(**options)
|
27
25
|
@nick = options[:nick] || DEFAULT_OPTIONS[:nick]
|
28
26
|
@websocket_url = Async::HTTP::Endpoint.parse(options[:websocket_url] || DEFAULT_OPTIONS[:websocket_url])
|
@@ -45,8 +43,7 @@ module Twitch
|
|
45
43
|
Async::WebSocket::Client.connect(@websocket_url) do |ws|
|
46
44
|
@ws = ws
|
47
45
|
ws.write("NICK #{@nick}")
|
48
|
-
|
49
|
-
@ready_handle&.call
|
46
|
+
dispatch_ready
|
50
47
|
|
51
48
|
while (ws_message = ws.read)
|
52
49
|
data = ws_message.to_str
|
@@ -57,14 +54,109 @@ module Twitch
|
|
57
54
|
|
58
55
|
next unless data.include?("PRIVMSG")
|
59
56
|
|
60
|
-
|
61
|
-
@message_handle&.call(message)
|
62
|
-
streams[message.channel.to_sym].each do |block|
|
63
|
-
block.call(message)
|
64
|
-
end
|
57
|
+
dispatch(Message.new(data, connection: self))
|
65
58
|
end
|
66
59
|
end
|
67
60
|
end
|
68
61
|
end
|
62
|
+
|
63
|
+
# @return [Array<Symbol>]
|
64
|
+
def channels
|
65
|
+
streams.keys
|
66
|
+
end
|
67
|
+
|
68
|
+
# @yield
|
69
|
+
# @yieldparam streamer [Symbol]
|
70
|
+
# @yieldreturn [nil]
|
71
|
+
def joined(&block)
|
72
|
+
@join_handle = block
|
73
|
+
end
|
74
|
+
|
75
|
+
# @yield
|
76
|
+
# @yieldparam streamer [Symbol]
|
77
|
+
# @yieldreturn [nil]
|
78
|
+
def left(&block)
|
79
|
+
@leave_handle = block
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param streamer [Symbol, String]
|
83
|
+
# @yield
|
84
|
+
# @yieldparam message [Twitch::Message]
|
85
|
+
# @yieldreturn [nil]
|
86
|
+
# @example
|
87
|
+
# bot.join(:twitchgaming) do |message|
|
88
|
+
# puts "##{message.channel} #{message.sender}: #{message}"
|
89
|
+
# end
|
90
|
+
def join(streamer, &block)
|
91
|
+
streamer = streamer.to_sym
|
92
|
+
unless ready?
|
93
|
+
yield_join(streamer, &block)
|
94
|
+
return
|
95
|
+
end
|
96
|
+
|
97
|
+
streams[streamer] = [] unless streams.key?(streamer)
|
98
|
+
streams[streamer] << block if block_given?
|
99
|
+
@ws.write("JOIN ##{streamer}")
|
100
|
+
@join_handle&.call(streamer)
|
101
|
+
end
|
102
|
+
|
103
|
+
# @param streamer [Symbol, String]
|
104
|
+
# @example
|
105
|
+
# bot.leave(:twitchgaming)
|
106
|
+
def leave(streamer)
|
107
|
+
streamer = streamer.to_sym
|
108
|
+
streams[streamer] = []
|
109
|
+
@ws.write("PART ##{streamer}")
|
110
|
+
@leave_handle&.call(streamer)
|
111
|
+
end
|
112
|
+
|
113
|
+
# @yield
|
114
|
+
# @yieldparam message [Twitch::Message]
|
115
|
+
# @yieldreturn [nil]
|
116
|
+
# @example
|
117
|
+
# bot.message do |message|
|
118
|
+
# puts "##{message.channel} #{message.sender}: #{message}"
|
119
|
+
# end
|
120
|
+
def message(&block)
|
121
|
+
@message_handle = block
|
122
|
+
end
|
123
|
+
|
124
|
+
alias_method :part, :leave
|
125
|
+
alias_method :on_leave, :leave
|
126
|
+
alias_method :on_join, :joined
|
127
|
+
alias_method :on_message, :message
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def dispatch(message)
|
132
|
+
@message_handle&.call(message)
|
133
|
+
streams[message.channel.to_sym].each do |block|
|
134
|
+
block.call(message)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def dispatch_ready
|
139
|
+
join_all
|
140
|
+
@ready_handle&.call
|
141
|
+
end
|
142
|
+
|
143
|
+
def streams
|
144
|
+
@streams ||= {}
|
145
|
+
end
|
146
|
+
|
147
|
+
def pending
|
148
|
+
@pending ||= {}
|
149
|
+
end
|
150
|
+
|
151
|
+
def yield_join(streamer, &block)
|
152
|
+
pending[streamer] = [] if streamer
|
153
|
+
pending[streamer] << block
|
154
|
+
end
|
155
|
+
|
156
|
+
def join_all
|
157
|
+
pending.each do |streamer, blocks|
|
158
|
+
blocks.each { |block| join(streamer, &block) }
|
159
|
+
end
|
160
|
+
end
|
69
161
|
end
|
70
162
|
end
|
@@ -10,24 +10,25 @@ module Twitch
|
|
10
10
|
# @!attribute [r] raw
|
11
11
|
# @return [String] Raw message from Twitch
|
12
12
|
# @example
|
13
|
-
# message = Twitch::Message.new(":
|
14
|
-
# message.sender.name # => :
|
15
|
-
# message.channel.name # => :
|
13
|
+
# message = Twitch::Message.new(":justinfan!justinfan@justinfan.tmi.twitch.tv PRIVMSG #twitchgaming :Hello world!\r\n")
|
14
|
+
# message.sender.name # => :justinfan
|
15
|
+
# message.channel.name # => :twitchgaming
|
16
16
|
# message.content # => "Hello world!"
|
17
|
-
# message.raw # => ":
|
17
|
+
# message.raw # => ":justinfan!justinfan@justinfan.tmi.twitch.tv PRIVMSG #justinfan :Hello world!\r\n"
|
18
18
|
class Message < String
|
19
19
|
attr_reader :sender, :channel, :content, :raw
|
20
20
|
|
21
21
|
# @param raw [String] Raw IRC websocket message from Twitch
|
22
22
|
# @param connection [Bot, nil] For internal usage
|
23
23
|
# @example
|
24
|
-
# message = Twitch::Message.new(":
|
24
|
+
# message = Twitch::Message.new(":justinfan!justinfan@justinfan.tmi.twitch.tv PRIVMSG #twitchgaming :Hello world!\r\n")
|
25
25
|
def initialize(raw, connection: nil)
|
26
26
|
split = raw.split(" ")
|
27
27
|
content = split[3..-1].join(" ")[1..-1]
|
28
28
|
super(content)
|
29
29
|
|
30
30
|
@content = content
|
31
|
+
@connection = connection
|
31
32
|
@channel = Channel.new(split[2][1..-1], connection: connection)
|
32
33
|
@sender = Channel.new(split[0].split("!")[0][1..-1])
|
33
34
|
@raw = raw
|
@@ -35,5 +36,38 @@ module Twitch
|
|
35
36
|
|
36
37
|
alias_method :text, :content
|
37
38
|
alias_method :streamer, :channel
|
39
|
+
alias_method :user, :sender
|
40
|
+
|
41
|
+
USERNAME = /[a-zA-Z0-9_]{4,25}/
|
42
|
+
# @return [Array<Twitch::Channel>] List of usernames mentioned in the message
|
43
|
+
def mentions
|
44
|
+
return @mentions if @mentions
|
45
|
+
|
46
|
+
@mentions = []
|
47
|
+
@content.split(" ").each do |word|
|
48
|
+
match = word.match(/@#{USERNAME}/)
|
49
|
+
next unless match
|
50
|
+
|
51
|
+
@mentions << Channel.new(match[0][1..-1], connection: @connection)
|
52
|
+
end
|
53
|
+
|
54
|
+
@mentions
|
55
|
+
end
|
56
|
+
|
57
|
+
LINK = %r{(https?://[^\s]+)}
|
58
|
+
# @return [Array<String>] List of links mentioned in the message
|
59
|
+
def links
|
60
|
+
return @links if @links
|
61
|
+
|
62
|
+
@links = []
|
63
|
+
@content.split(" ").each do |word|
|
64
|
+
match = word.match(LINK)
|
65
|
+
next unless match
|
66
|
+
|
67
|
+
@links << match[0]
|
68
|
+
end
|
69
|
+
|
70
|
+
@links
|
71
|
+
end
|
38
72
|
end
|
39
73
|
end
|
data/lib/twitch_chatter.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twitch_chatter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dylan Hackworth
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-websocket
|
@@ -32,17 +32,15 @@ extra_rdoc_files: []
|
|
32
32
|
files:
|
33
33
|
- lib/twitch_chatter.rb
|
34
34
|
- lib/twitch_chatter/bot.rb
|
35
|
-
- lib/twitch_chatter/concerns.rb
|
36
|
-
- lib/twitch_chatter/concerns/channels.rb
|
37
35
|
- lib/twitch_chatter/models.rb
|
38
36
|
- lib/twitch_chatter/models/channel.rb
|
39
37
|
- lib/twitch_chatter/models/message.rb
|
40
|
-
homepage: https://github.com/dylhack/
|
38
|
+
homepage: https://github.com/dylhack/twitch_chatter
|
41
39
|
licenses:
|
42
40
|
- MIT
|
43
41
|
metadata:
|
44
|
-
source_code_uri: https://github.com/dylhack/
|
45
|
-
post_install_message:
|
42
|
+
source_code_uri: https://github.com/dylhack/twitch_chatter
|
43
|
+
post_install_message:
|
46
44
|
rdoc_options: []
|
47
45
|
require_paths:
|
48
46
|
- lib
|
@@ -58,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
56
|
version: '0'
|
59
57
|
requirements: []
|
60
58
|
rubygems_version: 3.5.9
|
61
|
-
signing_key:
|
59
|
+
signing_key:
|
62
60
|
specification_version: 4
|
63
61
|
summary: Read-only Twitch chat client.
|
64
62
|
test_files: []
|
@@ -1,98 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Twitch
|
4
|
-
# Mixin modules
|
5
|
-
# @private
|
6
|
-
module Concerns
|
7
|
-
# Mixin for channel-related methods
|
8
|
-
# @private
|
9
|
-
module Channels
|
10
|
-
# @return [Array<Symbol>]
|
11
|
-
def channels
|
12
|
-
streams.keys
|
13
|
-
end
|
14
|
-
|
15
|
-
# @yield
|
16
|
-
# @yieldparam streamer [Symbol]
|
17
|
-
# @yieldreturn [nil]
|
18
|
-
def joined(&block)
|
19
|
-
@join_handle = block
|
20
|
-
end
|
21
|
-
|
22
|
-
# @yield
|
23
|
-
# @yieldparam streamer [Symbol]
|
24
|
-
# @yieldreturn [nil]
|
25
|
-
def left(&block)
|
26
|
-
@leave_handle = block
|
27
|
-
end
|
28
|
-
|
29
|
-
# @param streamer [Symbol, String]
|
30
|
-
# @yield
|
31
|
-
# @yieldparam message [Twitch::Message]
|
32
|
-
# @yieldreturn [nil]
|
33
|
-
# @example
|
34
|
-
# bot.join(:twitchgaming) do |message|
|
35
|
-
# puts "##{message.channel} #{message.sender}: #{message}"
|
36
|
-
# end
|
37
|
-
def join(streamer, &block)
|
38
|
-
streamer = streamer.to_sym
|
39
|
-
unless ready?
|
40
|
-
yield_join(streamer, &block)
|
41
|
-
return
|
42
|
-
end
|
43
|
-
|
44
|
-
streams[streamer] = [] unless streams.key?(streamer)
|
45
|
-
streams[streamer] << block if block_given?
|
46
|
-
@ws.write("JOIN ##{streamer}")
|
47
|
-
@join_handle&.call(streamer)
|
48
|
-
end
|
49
|
-
|
50
|
-
# @param streamer [Symbol, String]
|
51
|
-
# @example
|
52
|
-
# bot.leave(:twitchgaming)
|
53
|
-
def leave(streamer)
|
54
|
-
streamer = streamer.to_sym
|
55
|
-
streams[streamer] = []
|
56
|
-
@ws.write("PART ##{streamer}")
|
57
|
-
@leave_handle&.call(streamer)
|
58
|
-
end
|
59
|
-
|
60
|
-
# @yield
|
61
|
-
# @yieldparam message [Twitch::Message]
|
62
|
-
# @yieldreturn [nil]
|
63
|
-
# @example
|
64
|
-
# bot.message do |message|
|
65
|
-
# puts "##{message.channel} #{message.sender}: #{message}"
|
66
|
-
# end
|
67
|
-
def message(&block)
|
68
|
-
@message_handle = block
|
69
|
-
end
|
70
|
-
|
71
|
-
alias_method :part, :leave
|
72
|
-
alias_method :on_leave, :leave
|
73
|
-
alias_method :on_join, :joined
|
74
|
-
alias_method :on_message, :message
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def streams
|
79
|
-
@streams ||= {}
|
80
|
-
end
|
81
|
-
|
82
|
-
def pending
|
83
|
-
@pending ||= {}
|
84
|
-
end
|
85
|
-
|
86
|
-
def yield_join(streamer, &block)
|
87
|
-
pending[streamer] = [] if streamer
|
88
|
-
pending[streamer] << block
|
89
|
-
end
|
90
|
-
|
91
|
-
def resume_pending
|
92
|
-
pending.each do |streamer, blocks|
|
93
|
-
blocks.each { |block| join(streamer, &block) }
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|