chat_sdk 1.0.0 → 1.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.
@@ -32,6 +32,22 @@ module ChatSDK
32
32
  @children << ChatSDK::Cards::Node.new(:input, attributes: attrs, children: ctx.nodes)
33
33
  end
34
34
 
35
+ def date_input(id:, label:, initial_value: nil, placeholder: nil, optional: false)
36
+ attrs = {id: id, label: label, input_type: :date, optional: optional}
37
+ attrs[:initial_value] = initial_value if initial_value
38
+ attrs[:placeholder] = placeholder if placeholder
39
+ @children << ChatSDK::Cards::Node.new(:input, attributes: attrs)
40
+ end
41
+
42
+ def number_input(id:, label:, min: nil, max: nil, initial_value: nil, placeholder: nil, decimal: false, optional: false)
43
+ attrs = {id: id, label: label, input_type: :number, decimal: decimal, optional: optional}
44
+ attrs[:min] = min unless min.nil?
45
+ attrs[:max] = max unless max.nil?
46
+ attrs[:initial_value] = initial_value unless initial_value.nil?
47
+ attrs[:placeholder] = placeholder if placeholder
48
+ @children << ChatSDK::Cards::Node.new(:input, attributes: attrs)
49
+ end
50
+
35
51
  def static_text(content)
36
52
  @children << ChatSDK::Cards::Node.new(:text, attributes: {content: content})
37
53
  end
@@ -42,6 +42,22 @@ module ChatSDK
42
42
  def set_if_absent(key, value, ttl: nil)
43
43
  raise NotImplementedError
44
44
  end
45
+
46
+ def enqueue(key, value, max_size:, drop: :drop_oldest)
47
+ raise NotImplementedError
48
+ end
49
+
50
+ def drain_queue(key)
51
+ raise NotImplementedError
52
+ end
53
+
54
+ def queue_depth(key)
55
+ raise NotImplementedError
56
+ end
57
+
58
+ def extend_lock(key, owner:, ttl:)
59
+ raise NotImplementedError
60
+ end
45
61
  end
46
62
  end
47
63
  end
@@ -9,6 +9,7 @@ module ChatSDK
9
9
  @expirations = {}
10
10
  @subscriptions = Set.new
11
11
  @locks = {}
12
+ @queues = {}
12
13
  end
13
14
 
14
15
  def subscribe(thread_id)
@@ -47,6 +48,16 @@ module ChatSDK
47
48
  end
48
49
  end
49
50
 
51
+ def extend_lock(key, owner:, ttl:)
52
+ @mutex.synchronize do
53
+ expire_if_needed(key)
54
+ return false unless @locks[key] && @locks[key][:owner] == owner
55
+
56
+ @locks[key][:expires_at] = Time.now.to_f + ttl
57
+ true
58
+ end
59
+ end
60
+
50
61
  def get(key)
51
62
  @mutex.synchronize do
52
63
  expire_if_needed(key)
@@ -80,12 +91,32 @@ module ChatSDK
80
91
  end
81
92
  end
82
93
 
94
+ def enqueue(key, value, max_size:, drop: :drop_oldest)
95
+ @mutex.synchronize do
96
+ queue = (@queues[key] ||= [])
97
+ return queue.length if queue.length >= max_size && drop.to_sym == :drop_newest
98
+
99
+ queue << value
100
+ queue.shift while queue.length > max_size
101
+ queue.length
102
+ end
103
+ end
104
+
105
+ def drain_queue(key)
106
+ @mutex.synchronize { @queues.delete(key) || [] }
107
+ end
108
+
109
+ def queue_depth(key)
110
+ @mutex.synchronize { Array(@queues[key]).length }
111
+ end
112
+
83
113
  def clear
84
114
  @mutex.synchronize do
85
115
  @store.clear
86
116
  @expirations.clear
87
117
  @subscriptions.clear
88
118
  @locks.clear
119
+ @queues.clear
89
120
  end
90
121
  end
91
122
 
@@ -5,11 +5,13 @@ module ChatSDK
5
5
  class FakeAdapter < Adapter::Base
6
6
  capabilities :edit_messages, :delete_messages, :ephemeral_messages,
7
7
  :file_uploads, :reactions, :modals, :typing_indicator,
8
- :streaming_edit, :threads, :direct_messages, :message_history
8
+ :streaming_edit, :threads, :direct_messages, :message_history,
9
+ :replies, :read_receipts
9
10
 
10
11
  attr_reader :posted_messages, :edited_messages, :deleted_messages,
11
12
  :ephemeral_messages_sent, :reactions_added, :reactions_removed,
12
- :files_uploaded, :modals_opened, :typing_started, :dm_channels
13
+ :files_uploaded, :modals_opened, :typing_started, :dm_channels,
14
+ :replies_sent, :read_receipts_sent
13
15
 
14
16
  def initialize
15
17
  reset!
@@ -54,6 +56,18 @@ module ChatSDK
54
56
  record
55
57
  end
56
58
 
59
+ def reply_message(channel_id:, message_id:, message:, thread_id: nil)
60
+ record = RecordedCall.new(:reply_message, channel_id: channel_id, message_id: message_id, message: message, thread_id: thread_id)
61
+ @replies_sent << record
62
+ record
63
+ end
64
+
65
+ def mark_as_read(channel_id:, message_id:, thread_id: nil, message: nil)
66
+ record = RecordedCall.new(:mark_as_read, channel_id: channel_id, message_id: message_id, thread_id: thread_id, message: message)
67
+ @read_receipts_sent << record
68
+ record
69
+ end
70
+
57
71
  def delete_message(channel_id:, message_id:)
58
72
  record = RecordedCall.new(:delete_message, channel_id: channel_id, message_id: message_id)
59
73
  @deleted_messages << record
@@ -94,6 +108,14 @@ module ChatSDK
94
108
  [[], nil]
95
109
  end
96
110
 
111
+ def fetch_channel_messages(channel_id:, cursor: nil, limit: 50)
112
+ [[], nil]
113
+ end
114
+
115
+ def list_threads(channel_id:, cursor: nil, limit: 50)
116
+ [[], nil]
117
+ end
118
+
97
119
  def open_modal(trigger_id:, modal:)
98
120
  record = RecordedCall.new(:open_modal, trigger_id: trigger_id, modal: modal)
99
121
  @modals_opened << record
@@ -189,6 +211,8 @@ module ChatSDK
189
211
  @modals_opened = []
190
212
  @typing_started = []
191
213
  @dm_channels = []
214
+ @replies_sent = []
215
+ @read_receipts_sent = []
192
216
  end
193
217
  end
194
218
  end
@@ -2,13 +2,14 @@
2
2
 
3
3
  module ChatSDK
4
4
  class Thread
5
- attr_reader :id, :channel_id, :adapter, :chat
5
+ attr_reader :id, :channel_id, :adapter, :chat, :current_message
6
6
 
7
- def initialize(id:, channel_id:, adapter:, chat:)
7
+ def initialize(id:, channel_id:, adapter:, chat:, current_message: nil)
8
8
  @id = id
9
9
  @channel_id = channel_id
10
10
  @adapter = adapter
11
11
  @chat = chat
12
+ @current_message = current_message
12
13
  end
13
14
 
14
15
  def subscribe
@@ -28,6 +29,28 @@ module ChatSDK
28
29
  adapter.post_message(channel_id: channel_id, message: message, thread_id: id)
29
30
  end
30
31
 
32
+ def reply(target, content)
33
+ target_id = target.is_a?(ChatSDK::Message) ? target.id : target.to_s
34
+ if target.is_a?(ChatSDK::Message) && target.thread_id != id
35
+ raise ArgumentError, "cannot reply to a message from another thread"
36
+ end
37
+
38
+ message = PostableMessage.from(content)
39
+ adapter.reply_message(channel_id: channel_id, thread_id: id, message_id: target_id, message: message)
40
+ end
41
+
42
+ def mark_as_read(message = nil)
43
+ target = message
44
+ target ||= current_message
45
+ raise ArgumentError, "a message or message ID is required" unless target
46
+ if target.is_a?(ChatSDK::Message) && target.thread_id != id
47
+ raise ArgumentError, "cannot mark a message from another thread as read"
48
+ end
49
+
50
+ message_id = target.is_a?(ChatSDK::Message) ? target.id : target.to_s
51
+ adapter.mark_as_read(channel_id: channel_id, thread_id: id, message_id: message_id, message: target.is_a?(ChatSDK::Message) ? target : nil)
52
+ end
53
+
31
54
  def post_ephemeral(content, user_id:)
32
55
  message = PostableMessage.from(content)
33
56
  adapter.post_ephemeral(channel_id: channel_id, user_id: user_id, message: message, thread_id: id)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ChatSDK
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
data/lib/chat_sdk.rb CHANGED
@@ -17,8 +17,8 @@ module ChatSDK
17
17
  end
18
18
  end
19
19
 
20
- def card(title: nil, subtitle: nil, &block)
21
- Cards::Builder.new(title: title, subtitle: subtitle, &block).build
20
+ def card(title: nil, subtitle: nil, width: nil, &block)
21
+ Cards::Builder.new(title: title, subtitle: subtitle, width: width, &block).build
22
22
  end
23
23
  end
24
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chat_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Quentin Rousseau
@@ -51,6 +51,7 @@ files:
51
51
  - lib/chat_sdk/adapter/media_types.rb
52
52
  - lib/chat_sdk/adapter/meta_verification.rb
53
53
  - lib/chat_sdk/ai.rb
54
+ - lib/chat_sdk/ai/conversation_scope.rb
54
55
  - lib/chat_sdk/ai/converter.rb
55
56
  - lib/chat_sdk/ai/stream_handler.rb
56
57
  - lib/chat_sdk/ai/tool_builder.rb
@@ -70,14 +71,18 @@ files:
70
71
  - lib/chat_sdk/dispatcher.rb
71
72
  - lib/chat_sdk/errors.rb
72
73
  - lib/chat_sdk/event_registry.rb
74
+ - lib/chat_sdk/event_serializer.rb
73
75
  - lib/chat_sdk/events/action.rb
74
76
  - lib/chat_sdk/events/base.rb
75
77
  - lib/chat_sdk/events/direct_message.rb
76
78
  - lib/chat_sdk/events/mention.rb
79
+ - lib/chat_sdk/events/message_deleted.rb
80
+ - lib/chat_sdk/events/message_updated.rb
77
81
  - lib/chat_sdk/events/reaction.rb
78
82
  - lib/chat_sdk/events/slash_command.rb
79
83
  - lib/chat_sdk/events/subscribed_message.rb
80
84
  - lib/chat_sdk/format/converter.rb
85
+ - lib/chat_sdk/history.rb
81
86
  - lib/chat_sdk/instrumentation.rb
82
87
  - lib/chat_sdk/log.rb
83
88
  - lib/chat_sdk/message.rb