rocket_chat-realtime 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.gitlab-ci.yml +50 -0
  4. data/.overcommit.yml +20 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +12 -0
  7. data/.travis.yml +6 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +23 -0
  10. data/Gemfile.lock +100 -0
  11. data/LICENSE +201 -0
  12. data/README.md +40 -0
  13. data/Rakefile +8 -0
  14. data/bin/console +12 -0
  15. data/bin/setup +8 -0
  16. data/lib/rocket_chat/realtime.rb +58 -0
  17. data/lib/rocket_chat/realtime/adapter.rb +51 -0
  18. data/lib/rocket_chat/realtime/async_task.rb +60 -0
  19. data/lib/rocket_chat/realtime/client.rb +100 -0
  20. data/lib/rocket_chat/realtime/connector.rb +79 -0
  21. data/lib/rocket_chat/realtime/dispatcher.rb +80 -0
  22. data/lib/rocket_chat/realtime/event_emitter.rb +65 -0
  23. data/lib/rocket_chat/realtime/handlers/base.rb +52 -0
  24. data/lib/rocket_chat/realtime/handlers/changed.rb +31 -0
  25. data/lib/rocket_chat/realtime/handlers/ready.rb +23 -0
  26. data/lib/rocket_chat/realtime/handlers/result.rb +34 -0
  27. data/lib/rocket_chat/realtime/message.rb +40 -0
  28. data/lib/rocket_chat/realtime/messages/changed.rb +44 -0
  29. data/lib/rocket_chat/realtime/messages/method.rb +37 -0
  30. data/lib/rocket_chat/realtime/messages/result.rb +40 -0
  31. data/lib/rocket_chat/realtime/messages/subscribe.rb +37 -0
  32. data/lib/rocket_chat/realtime/methods/auth.rb +33 -0
  33. data/lib/rocket_chat/realtime/methods/message.rb +33 -0
  34. data/lib/rocket_chat/realtime/reactor.rb +123 -0
  35. data/lib/rocket_chat/realtime/subscriptions/room.rb +30 -0
  36. data/lib/rocket_chat/realtime/version.rb +7 -0
  37. data/rocket_chat-realtime.gemspec +31 -0
  38. metadata +122 -0
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'concurrent'
4
+
5
+ module RocketChat
6
+ module Realtime
7
+ # Provide event listener support
8
+ #
9
+ # @since 0.1.0
10
+ module EventEmitter
11
+ # Register event listener
12
+ #
13
+ # @param event [String] event name
14
+ # @param callback [Proc] event handler
15
+ #
16
+ # @since 0.1.0
17
+ def on(event, &callback)
18
+ listeners.compute(event.to_s) do |current|
19
+ current ||= []
20
+ current.push(callback)
21
+ current
22
+ end
23
+ end
24
+
25
+ # Deregister event listener
26
+ #
27
+ # @param event [String] event name
28
+ # @param callback [Proc] callback to remove
29
+ #
30
+ # @since 0.1.0
31
+ def off(event, &callback)
32
+ listeners.compute(event.to_s) do |current|
33
+ current ||= []
34
+ current.delete(callback)
35
+ return nil if current.empty?
36
+
37
+ current
38
+ end
39
+ end
40
+
41
+ # Publish event
42
+ #
43
+ # @param event [String] event name
44
+ # @param data [Object] event to publish
45
+ #
46
+ # @since 0.1.0
47
+ def emit(event, data)
48
+ listeners[event.to_s]&.each do |listener|
49
+ listener.call(data)
50
+ end
51
+ end
52
+
53
+ protected
54
+
55
+ # Event Listeners
56
+ #
57
+ # @return [Concurrent::Map]
58
+ #
59
+ # @since 0.1.0
60
+ def listeners
61
+ @listeners ||= Concurrent::Map.new
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ require 'rocket_chat/realtime/handlers/base'
6
+
7
+ module RocketChat
8
+ module Realtime
9
+ module Handlers
10
+ # Base Message Handler
11
+ #
12
+ # @since 0.1.0
13
+ class Base
14
+ class << self
15
+ # Dispatch message
16
+ #
17
+ # @param dispatcher [RocketChat::Realtime::Dispatcher]
18
+ # @param message [Hash] the message from server
19
+ #
20
+ # @since 0.1.0
21
+ def call(dispatcher, message)
22
+ new(dispatcher, message).process
23
+ end
24
+ end
25
+
26
+ extend Forwardable
27
+
28
+ # @since 0.1.0
29
+ attr_reader :dispatcher, :message
30
+
31
+ # @since 0.1.0
32
+ delegate %w[client] => :dispatcher
33
+
34
+ # @param dispatcher [RocketChat::Realtime::Dispatcher]
35
+ # @param message [Hash] the message from server
36
+ #
37
+ # @since 0.1.0
38
+ def initialize(dispatcher, message)
39
+ @dispatcher = dispatcher
40
+ @message = message
41
+ end
42
+
43
+ # Process message
44
+ #
45
+ # @since 0.1.0
46
+ def process
47
+ raise NotImplementedError
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rocket_chat/realtime/handlers/base'
4
+ require 'rocket_chat/realtime/messages/changed'
5
+
6
+ module RocketChat
7
+ module Realtime
8
+ module Handlers
9
+ # Changed Message Handler
10
+ #
11
+ # The DDP Subscribe changed event
12
+ #
13
+ # @since 0.1.0
14
+ class Changed < Base
15
+ # Changed
16
+ #
17
+ # @return [RocketChat::Realtime::Messages::Changed]
18
+ #
19
+ # @since 0.1.0
20
+ def changed
21
+ Messages::Changed.new(message['id'], message)
22
+ end
23
+
24
+ # @see RocketChat::Realtime::Handlers::Base#process
25
+ def process
26
+ client.emit(changed.collection, changed)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rocket_chat/realtime/handlers/base'
4
+
5
+ module RocketChat
6
+ module Realtime
7
+ module Handlers
8
+ # Ready Message Handler
9
+ #
10
+ # The DDP Subscribe success event
11
+ #
12
+ # @since 0.1.0
13
+ class Ready < Base
14
+ # @see RocketChat::Realtime::Handlers::Base#process
15
+ def process
16
+ message['subs']&.each do |id|
17
+ AsyncTask.resolve(id)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rocket_chat/realtime/handlers/base'
4
+ require 'rocket_chat/realtime/messages/result'
5
+
6
+ module RocketChat
7
+ module Realtime
8
+ module Handlers
9
+ # Result Message Handler
10
+ #
11
+ # The DDP RPC return value
12
+ #
13
+ # @since 0.1.0
14
+ class Result < Base
15
+ # The message result
16
+ #
17
+ # @return [RocketChat::Realtime::Messages::Result]
18
+ #
19
+ # @since 0.1.0
20
+ def result
21
+ Messages::Result.new(
22
+ message['id'],
23
+ message['result']
24
+ )
25
+ end
26
+
27
+ # @see RocketChat::Realtime::Handlers::Base#process
28
+ def process
29
+ AsyncTask.resolve(result.id, result)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module RocketChat
6
+ module Realtime
7
+ # Abstract message model to send a method
8
+ #
9
+ # @since 0.1.0
10
+ class Message
11
+ # @since 0.1.0
12
+ attr_reader :id, :type
13
+
14
+ # @param type [String] message type
15
+ # @param id [String] unique id to identity command
16
+ #
17
+ # @since 0.1.0
18
+ def initialize(type = 'method', id = nil)
19
+ @id = id || SecureRandom.uuid
20
+ @type = type
21
+ end
22
+
23
+ # Body
24
+ #
25
+ # @return [Hash] the message body
26
+ def body
27
+ {}
28
+ end
29
+
30
+ # Convert to JSON
31
+ #
32
+ # @return [String] message json
33
+ def to_json(options = nil)
34
+ body
35
+ .merge(id: @id, msg: @type)
36
+ .to_json(options)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rocket_chat/realtime/message'
4
+
5
+ module RocketChat
6
+ module Realtime
7
+ module Messages
8
+ # The changed message
9
+ #
10
+ # The DDP subscription changed message
11
+ #
12
+ # @since 0.1.0
13
+ class Changed < Message
14
+ # @since 0.1.0
15
+ attr_reader :fields, :cleared, :collection
16
+
17
+ # @param args [Array] the parameters for method
18
+ def initialize(id, message)
19
+ super('changed', id)
20
+
21
+ @fields = message.fetch('fields', nil)
22
+ @cleared = message.fetch('cleared', nil)
23
+ @collection = message.fetch('collection', nil)
24
+ end
25
+
26
+ # @see RocketChat::Realtime::Message#body
27
+ #
28
+ # @since 0.1.0
29
+ def body
30
+ {
31
+ fields: fields,
32
+ cleared: cleared,
33
+ collection: collection
34
+ }
35
+ end
36
+
37
+ # :nodoc:
38
+ def [](key)
39
+ fields.fetch(key.to_s, nil)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rocket_chat/realtime/message'
4
+
5
+ module RocketChat
6
+ module Realtime
7
+ module Messages
8
+ # The method message
9
+ #
10
+ # The DDP RPC method call
11
+ #
12
+ # @since 0.1.0
13
+ class Method < Message
14
+ # @since 0.1.0
15
+ attr_reader :name, :parameters
16
+
17
+ # @param args [Array] the parameters for method
18
+ def initialize(name, *parameters)
19
+ super('method')
20
+
21
+ @name = name
22
+ @parameters = parameters
23
+ end
24
+
25
+ # @see RocketChat::Realtime::Message#body
26
+ #
27
+ # @since 0.1.0
28
+ def body
29
+ {
30
+ method: name,
31
+ params: parameters
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rocket_chat/realtime/message'
4
+
5
+ module RocketChat
6
+ module Realtime
7
+ module Messages
8
+ # The result message
9
+ #
10
+ # The DDP RPC result message
11
+ #
12
+ # @since 0.1.0
13
+ class Result < Message
14
+ # @since 0.1.0
15
+ attr_reader :result
16
+
17
+ # @param args [Array] the parameters for method
18
+ def initialize(id, result)
19
+ super('result', id)
20
+
21
+ @result = result
22
+ end
23
+
24
+ # @see RocketChat::Realtime::Message#body
25
+ #
26
+ # @since 0.1.0
27
+ def body
28
+ {
29
+ result: result
30
+ }
31
+ end
32
+
33
+ # :nodoc:
34
+ def [](key)
35
+ result.fetch(key.to_s, nil)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rocket_chat/realtime/message'
4
+
5
+ module RocketChat
6
+ module Realtime
7
+ module Messages
8
+ # The subscribe message
9
+ #
10
+ # The DDP subscribe message
11
+ #
12
+ # @since 0.1.0
13
+ class Subscribe < Message
14
+ # @since 0.1.0
15
+ attr_reader :name, :parameters
16
+
17
+ # @param args [Array] the parameters for method
18
+ def initialize(name, *parameters)
19
+ super('sub')
20
+
21
+ @name = name
22
+ @parameters = parameters
23
+ end
24
+
25
+ # @see RocketChat::Realtime::Message#body
26
+ #
27
+ # @since 0.1.0
28
+ def body
29
+ {
30
+ name: name,
31
+ params: parameters
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest'
4
+
5
+ require 'rocket_chat/realtime/messages/method'
6
+
7
+ module RocketChat
8
+ module Realtime
9
+ module Methods
10
+ # Auth methods
11
+ #
12
+ # @since 0.1.0
13
+ module Auth
14
+ # Login into server
15
+ #
16
+ # @param username [String]
17
+ # @param password [String]
18
+ #
19
+ # @since 0.1.0
20
+ def login(username, password)
21
+ method = Messages::Method.new(
22
+ 'login',
23
+ user: { username: username },
24
+ password: { algorithm: 'sha-256', digest: Digest::SHA256.hexdigest(password) }
25
+ )
26
+ AsyncTask.start(method.id) do
27
+ driver.text(method.to_json)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end