twitch_chatter 0.1.1 → 0.2.1

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: 0cd70432c7cb5123a7377b95203e38f2c97cdd04d185a59dfd59356e59b4658c
4
- data.tar.gz: 2e46bc4c3fbfffe262716cef079b1e988a5624c31dc9a4fa623ea9021d753b1f
3
+ metadata.gz: fff1b37e345e021646f75631a1ec5515d10f05cbf4f238b4f2136878b5b9b02d
4
+ data.tar.gz: b47c19eaff099c6a439e864f80ed72e85b15a68f4fcbc2d4ef2a85454f47b947
5
5
  SHA512:
6
- metadata.gz: f9387375052d6c148931b7330f26701cefcb6dac48fab53a97ef8741db12833cb4d7a288f8dbc1d081cbf6cbcd802e4fdb7b8f82680cab40d2cc3566ea413645
7
- data.tar.gz: 5b6dc9d6a7cb115effb39016c309bbe1dd310cf1875c634841602238de1a123a9d41bf87f589c18046f5555dfaa2535f962c5b93996171af83b8fd74158b62bf
6
+ metadata.gz: 984d51eda98c57546a8e906cef1b7d2d96dfd7d0d9de91c2c42bb18ff825279f24b9f3d85eab199eaf3f6a427ddb2d446db946102e0a1d17e90aef1559bfafac
7
+ data.tar.gz: 58909f2b18253651a6cc2d37ec36fa5d2381279a5f203f332eebe5b6441cdaffcee71bb488e53212915f8ed1e2b53b37d2f4e9e3cf9bd9973f18dfbd6b525df1
@@ -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
- resume_pending
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
- message = Message.new(data, connection: self)
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
@@ -37,7 +37,7 @@ module Twitch
37
37
  @name.to_s
38
38
  end
39
39
 
40
- # @param other [Channel, Symbol]
40
+ # @param other [Channel, String, Symbol]
41
41
  # @return [Boolean]
42
42
  def ==(other)
43
43
  if other.is_a?(Channel)
@@ -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(":ttlnow!ttlnow@ttlnow.tmi.twitch.tv PRIVMSG #ttlnow :Hello world!\r\n")
14
- # message.sender.name # => :ttlnow
15
- # message.channel.name # => :ttlnow
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 # => ":ttlnow!ttlnow@ttlnow.tmi.twitch.tv PRIVMSG #ttlnow :Hello world!\r\n"
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(":ttlnow!ttlnow@ttlnow.tmi.twitch.tv PRIVMSG #ttlnow :Hello world!\r\n")
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
@@ -3,7 +3,6 @@
3
3
  require "async"
4
4
  require "async/http/endpoint"
5
5
  require "async/websocket/client"
6
- require_relative "twitch_chatter/concerns"
7
6
  require_relative "twitch_chatter/models"
8
7
  require_relative "twitch_chatter/bot"
9
8
 
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.1.1
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-21 00:00:00.000000000 Z
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/twitch-chat-gem
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/twitch-chat-gem
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
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Twitch
4
- require_relative "concerns/channels"
5
- end