stream-chat-ruby 3.20.0 → 3.22.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e89ecd3155db957b904e2809c181c36cec909742bae06ef17e02932d4713b991
4
- data.tar.gz: 545cdf669a3f4cc739951dac5e3cede7abdd91b5691940bcd9765fee8e82a008
3
+ metadata.gz: ef599aa75d34eac737ec0477c2c2dfa76583c7cdde1cebf6a5e21b494ea9abaa
4
+ data.tar.gz: 9f5170f70e6c4490f691ee364c8f12efe2c45729bba0c877e064c748b31cb7cd
5
5
  SHA512:
6
- metadata.gz: d1b8be8b38c7bfdfcd563e6ad018ed960e9f78c63f3de343cd84823c9c0a9428d6cdad11da6c454de1bfd9893e4e52570f0a103cf2aafbbbefb25944a0f357e0
7
- data.tar.gz: f482e06931fe46fcb5163b22a5a453347ea3a990038b492e1fe3bc59cedf619c4c414d07794122b4310cabd984b87538912f6def954dbbe1f7a387439d374a98
6
+ metadata.gz: bae2b355732b9fcd45e66f34ea948cd19bdd68f394961b0c7e56c10ab35f012f296ff8d1b7e06613c90fbce2209778fc1d48bb4a7af124440bced0427aa51d6e
7
+ data.tar.gz: 1240cd43dcba18db93d412fccb3b6b453e2e5c87090d19969063c34bbdd80197b4a92a8980f50ebddc13394d328f3fe9e4abefd5f65377e2b1c933361ad5094a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [3.22.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.21.0...v3.22.0) (2026-01-15)
6
+
7
+ ## [3.21.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.20.0...v3.21.0) (2025-11-12)
8
+
9
+
10
+ ### Features
11
+
12
+ * add filter tags support for channels ([#183](https://github.com/GetStream/stream-chat-ruby/issues/183)) ([e4844de](https://github.com/GetStream/stream-chat-ruby/commit/e4844de6325ac89a130f7eafbd1a86eaa57c893e))
13
+ * add hide_history_before option for adding members ([#182](https://github.com/GetStream/stream-chat-ruby/issues/182)) ([ccc2f94](https://github.com/GetStream/stream-chat-ruby/commit/ccc2f94f29af19f1d1127ff0add61ba3d02de37a))
14
+
5
15
  ## [3.20.0](https://github.com/GetStream/stream-chat-ruby/compare/v3.19.0...v3.20.0) (2025-10-06)
6
16
 
7
17
 
@@ -0,0 +1,111 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require 'stream-chat/client'
5
+ require 'stream-chat/errors'
6
+ require 'stream-chat/util'
7
+ require 'stream-chat/types'
8
+
9
+ module StreamChat
10
+ class Campaign
11
+ extend T::Sig
12
+
13
+ sig { returns(T.nilable(String)) }
14
+ attr_reader :campaign_id
15
+
16
+ sig { returns(T.nilable(StringKeyHash)) }
17
+ attr_reader :data
18
+
19
+ sig { params(client: StreamChat::Client, campaign_id: T.nilable(String), data: T.nilable(StringKeyHash)).void }
20
+ def initialize(client, campaign_id = nil, data = nil)
21
+ @client = client
22
+ @campaign_id = campaign_id
23
+ @data = data
24
+ end
25
+
26
+ # Creates a campaign.
27
+ #
28
+ # @param [String, nil] campaign_id Optional campaign ID. If provided, sets the campaign_id.
29
+ # @param [StringKeyHash, nil] data Optional campaign data to merge with existing data.
30
+ # @return [StreamChat::StreamResponse] API response
31
+ sig { params(campaign_id: T.nilable(String), data: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
32
+ def create(campaign_id: nil, data: nil)
33
+ @campaign_id = campaign_id if campaign_id
34
+ @data = merge_campaign_data(@data, data) if data
35
+
36
+ state = @client.create_campaign(campaign_id: @campaign_id, data: @data)
37
+
38
+ @campaign_id = state['campaign']['id'] if @campaign_id.nil? && state.status_code >= 200 && state.status_code < 300 && state['campaign']
39
+ state
40
+ end
41
+
42
+ # Gets a campaign by ID.
43
+ #
44
+ # @return [StreamChat::StreamResponse] API response
45
+ sig { returns(StreamChat::StreamResponse) }
46
+ def get
47
+ raise StreamChannelException, 'campaign does not have an id' if @campaign_id.nil?
48
+
49
+ @client.get_campaign(@campaign_id)
50
+ end
51
+
52
+ # Updates a campaign.
53
+ #
54
+ # @param [StringKeyHash] data Campaign data to update
55
+ # @return [StreamChat::StreamResponse] API response
56
+ sig { params(data: StringKeyHash).returns(StreamChat::StreamResponse) }
57
+ def update(data)
58
+ raise StreamChannelException, 'campaign does not have an id' if @campaign_id.nil?
59
+
60
+ @client.update_campaign(@campaign_id, data)
61
+ end
62
+
63
+ # Deletes a campaign.
64
+ #
65
+ # @param [Hash] options Optional deletion options
66
+ # @return [StreamChat::StreamResponse] API response
67
+ sig { params(options: T.untyped).returns(StreamChat::StreamResponse) }
68
+ def delete(**options)
69
+ raise StreamChannelException, 'campaign does not have an id' if @campaign_id.nil?
70
+
71
+ @client.delete_campaign(@campaign_id, **options)
72
+ end
73
+
74
+ # Starts a campaign.
75
+ #
76
+ # @param [DateTime, Time, String, nil] scheduled_for Optional scheduled start time
77
+ # @param [DateTime, Time, String, nil] stop_at Optional scheduled stop time
78
+ # @return [StreamChat::StreamResponse] API response
79
+ sig { params(scheduled_for: T.nilable(T.any(DateTime, Time, String)), stop_at: T.nilable(T.any(DateTime, Time, String))).returns(StreamChat::StreamResponse) }
80
+ def start(scheduled_for: nil, stop_at: nil)
81
+ raise StreamChannelException, 'campaign does not have an id' if @campaign_id.nil?
82
+
83
+ @client.start_campaign(@campaign_id, scheduled_for: scheduled_for, stop_at: stop_at)
84
+ end
85
+
86
+ # Stops a campaign.
87
+ #
88
+ # @return [StreamChat::StreamResponse] API response
89
+ sig { returns(StreamChat::StreamResponse) }
90
+ def stop
91
+ raise StreamChannelException, 'campaign does not have an id' if @campaign_id.nil?
92
+
93
+ @client.stop_campaign(@campaign_id)
94
+ end
95
+
96
+ private
97
+
98
+ # Merges two campaign data hashes.
99
+ #
100
+ # @param [StringKeyHash, nil] data1 First campaign data hash
101
+ # @param [StringKeyHash, nil] data2 Second campaign data hash
102
+ # @return [StringKeyHash] Merged campaign data
103
+ sig { params(data1: T.nilable(StringKeyHash), data2: T.nilable(StringKeyHash)).returns(StringKeyHash) }
104
+ def merge_campaign_data(data1, data2)
105
+ return T.must(data2) if data1.nil?
106
+ return data1 if data2.nil?
107
+
108
+ data1.merge(data2)
109
+ end
110
+ end
111
+ end
@@ -234,7 +234,9 @@ module StreamChat
234
234
  # Adds members to the channel.
235
235
  sig { params(user_ids: T::Array[String], options: T.untyped).returns(StreamChat::StreamResponse) }
236
236
  def add_members(user_ids, **options)
237
- payload = options.merge({ add_members: user_ids })
237
+ payload = options.dup
238
+ payload[:hide_history_before] = StreamChat.normalize_timestamp(payload[:hide_history_before]) if payload[:hide_history_before]
239
+ payload = payload.merge({ add_members: user_ids })
238
240
  update(nil, nil, **payload)
239
241
  end
240
242
 
@@ -265,6 +267,18 @@ module StreamChat
265
267
  update(nil, nil, add_moderators: user_ids)
266
268
  end
267
269
 
270
+ # Adds filter tags to the channel.
271
+ sig { params(tags: T::Array[String]).returns(StreamChat::StreamResponse) }
272
+ def add_filter_tags(tags)
273
+ update(nil, nil, add_filter_tags: tags)
274
+ end
275
+
276
+ # Removes filter tags from the channel.
277
+ sig { params(tags: T::Array[String]).returns(StreamChat::StreamResponse) }
278
+ def remove_filter_tags(tags)
279
+ update(nil, nil, remove_filter_tags: tags)
280
+ end
281
+
268
282
  # Removes members from the channel.
269
283
  sig { params(user_ids: T::Array[String]).returns(StreamChat::StreamResponse) }
270
284
  def remove_members(user_ids)
@@ -10,6 +10,7 @@ require 'time'
10
10
  require 'date'
11
11
  require 'sorbet-runtime'
12
12
  require 'stream-chat/channel'
13
+ require 'stream-chat/campaign'
13
14
  require 'stream-chat/errors'
14
15
  require 'stream-chat/stream_response'
15
16
  require 'stream-chat/version'
@@ -555,6 +556,101 @@ module StreamChat
555
556
  StreamChat::Channel.new(self, channel_type, channel_id, data)
556
557
  end
557
558
 
559
+ # Creates a campaign instance
560
+ #
561
+ # @param [String, nil] campaign_id the campaign identifier
562
+ # @param [StringKeyHash, nil] data additional campaign data
563
+ #
564
+ # @return [StreamChat::Campaign]
565
+ #
566
+ sig { params(campaign_id: T.nilable(String), data: T.nilable(StringKeyHash)).returns(StreamChat::Campaign) }
567
+ def campaign(campaign_id: nil, data: nil)
568
+ StreamChat::Campaign.new(self, campaign_id, data)
569
+ end
570
+
571
+ # Creates a campaign.
572
+ #
573
+ # @param [String, nil] campaign_id Optional campaign ID
574
+ # @param [StringKeyHash, nil] data Campaign data including message_template, sender_id, segment_ids or user_ids, etc.
575
+ # @return [StreamChat::StreamResponse] API response
576
+ sig { params(campaign_id: T.nilable(String), data: T.nilable(StringKeyHash)).returns(StreamChat::StreamResponse) }
577
+ def create_campaign(campaign_id: nil, data: nil)
578
+ payload = {}
579
+ payload['id'] = campaign_id if campaign_id
580
+ payload.merge!(data) if data
581
+ post('campaigns', data: payload)
582
+ end
583
+
584
+ # Gets a campaign by ID.
585
+ #
586
+ # @param [String] campaign_id The campaign ID
587
+ # @return [StreamChat::StreamResponse] API response
588
+ sig { params(campaign_id: String).returns(StreamChat::StreamResponse) }
589
+ def get_campaign(campaign_id)
590
+ get("campaigns/#{campaign_id}")
591
+ end
592
+
593
+ # Updates a campaign.
594
+ #
595
+ # @param [String] campaign_id The campaign ID
596
+ # @param [StringKeyHash] data Campaign data to update
597
+ # @return [StreamChat::StreamResponse] API response
598
+ sig { params(campaign_id: String, data: StringKeyHash).returns(StreamChat::StreamResponse) }
599
+ def update_campaign(campaign_id, data)
600
+ put("campaigns/#{campaign_id}", data: data)
601
+ end
602
+
603
+ # Deletes a campaign.
604
+ #
605
+ # @param [String] campaign_id The campaign ID
606
+ # @param [Hash] options Optional deletion options (e.g., gdpr: true)
607
+ # @return [StreamChat::StreamResponse] API response
608
+ sig { params(campaign_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
609
+ def delete_campaign(campaign_id, **options)
610
+ delete("campaigns/#{campaign_id}", params: options)
611
+ end
612
+
613
+ # Starts a campaign.
614
+ #
615
+ # @param [String] campaign_id The campaign ID
616
+ # @param [DateTime, Time, String, nil] scheduled_for Optional scheduled start time
617
+ # @param [DateTime, Time, String, nil] stop_at Optional scheduled stop time
618
+ # @return [StreamChat::StreamResponse] API response
619
+ sig { params(campaign_id: String, scheduled_for: T.nilable(T.any(DateTime, Time, String)), stop_at: T.nilable(T.any(DateTime, Time, String))).returns(StreamChat::StreamResponse) }
620
+ def start_campaign(campaign_id, scheduled_for: nil, stop_at: nil)
621
+ payload = {}
622
+ payload['scheduled_for'] = StreamChat.normalize_timestamp(scheduled_for) if scheduled_for
623
+ payload['stop_at'] = StreamChat.normalize_timestamp(stop_at) if stop_at
624
+ post("campaigns/#{campaign_id}/start", data: payload)
625
+ end
626
+
627
+ # Stops a campaign.
628
+ #
629
+ # @param [String] campaign_id The campaign ID
630
+ # @return [StreamChat::StreamResponse] API response
631
+ sig { params(campaign_id: String).returns(StreamChat::StreamResponse) }
632
+ def stop_campaign(campaign_id)
633
+ post("campaigns/#{campaign_id}/stop")
634
+ end
635
+
636
+ # Queries campaigns.
637
+ #
638
+ # You can query campaigns based on built-in fields as well as any custom field you add to campaigns.
639
+ # Multiple filters can be combined using AND, OR logical operators, each filter can use its
640
+ # comparison (equality, inequality, greater than, greater or equal, etc.).
641
+ # @param [StringKeyHash] filter_conditions Filter conditions for the query
642
+ # @param [Hash, nil] sort Optional sort parameters (e.g., { 'created_at' => -1 })
643
+ # @param [Hash] options Additional query options (limit, offset, etc.)
644
+ # @return [StreamChat::StreamResponse] API response
645
+ sig { params(filter_conditions: StringKeyHash, sort: T.nilable(T::Hash[String, Integer]), options: T.untyped).returns(StreamChat::StreamResponse) }
646
+ def query_campaigns(filter_conditions, sort: nil, **options)
647
+ data = options.merge({
648
+ filter: filter_conditions,
649
+ sort: StreamChat.get_sort_fields(sort)
650
+ })
651
+ post('campaigns/query', data: data)
652
+ end
653
+
558
654
  # Adds a device to a user.
559
655
  sig { params(device_id: String, push_provider: String, user_id: String, push_provider_name: T.nilable(String)).returns(StreamChat::StreamResponse) }
560
656
  def add_device(device_id, push_provider, user_id, push_provider_name = nil)
@@ -738,7 +834,7 @@ module StreamChat
738
834
  # Revoke tokens for an application issued since the given date.
739
835
  sig { params(before: T.any(DateTime, String)).returns(StreamChat::StreamResponse) }
740
836
  def revoke_tokens(before)
741
- before = before.rfc3339 if before.instance_of?(DateTime)
837
+ before = StreamChat.normalize_timestamp(before)
742
838
  update_app_settings({ 'revoke_tokens_issued_before' => before })
743
839
  end
744
840
 
@@ -751,7 +847,7 @@ module StreamChat
751
847
  # Revoke tokens for users issued since.
752
848
  sig { params(user_ids: T::Array[String], before: T.any(DateTime, String)).returns(StreamChat::StreamResponse) }
753
849
  def revoke_users_token(user_ids, before)
754
- before = before.rfc3339 if before.instance_of?(DateTime)
850
+ before = StreamChat.normalize_timestamp(before)
755
851
 
756
852
  updates = []
757
853
  user_ids.map do |user_id|
@@ -1024,7 +1120,7 @@ module StreamChat
1024
1120
  sig { params(message_id: String, user_id: String, remind_at: T.nilable(DateTime)).returns(StreamChat::StreamResponse) }
1025
1121
  def create_reminder(message_id, user_id, remind_at = nil)
1026
1122
  data = { user_id: user_id }
1027
- data[:remind_at] = remind_at.rfc3339 if remind_at.instance_of?(DateTime)
1123
+ data[:remind_at] = StreamChat.normalize_timestamp(remind_at) if remind_at
1028
1124
  post("messages/#{message_id}/reminders", data: data)
1029
1125
  end
1030
1126
 
@@ -1036,7 +1132,7 @@ module StreamChat
1036
1132
  sig { params(message_id: String, user_id: String, remind_at: T.nilable(DateTime)).returns(StreamChat::StreamResponse) }
1037
1133
  def update_reminder(message_id, user_id, remind_at = nil)
1038
1134
  data = { user_id: user_id }
1039
- data[:remind_at] = remind_at.rfc3339 if remind_at
1135
+ data[:remind_at] = StreamChat.normalize_timestamp(remind_at) if remind_at
1040
1136
  patch("messages/#{message_id}/reminders", data: data)
1041
1137
  end
1042
1138
 
@@ -1058,7 +1154,7 @@ module StreamChat
1058
1154
  sig { params(user_id: String, filter_conditions: T::Hash[T.untyped, T.untyped], sort: T.nilable(T::Array[T::Hash[T.untyped, T.untyped]]), options: T.untyped).returns(StreamChat::StreamResponse) }
1059
1155
  def query_reminders(user_id, filter_conditions = {}, sort: nil, **options)
1060
1156
  params = options.merge({
1061
- filter_conditions: filter_conditions,
1157
+ filter: filter_conditions,
1062
1158
  sort: sort || [{ field: 'remind_at', direction: 1 }],
1063
1159
  user_id: user_id
1064
1160
  })
@@ -14,4 +14,14 @@ module StreamChat
14
14
  end
15
15
  sort_fields
16
16
  end
17
+
18
+ # Normalizes a timestamp to RFC 3339 / ISO 8601 string format.
19
+ sig { params(timestamp: T.any(DateTime, Time, String)).returns(String) }
20
+ def self.normalize_timestamp(timestamp)
21
+ case timestamp
22
+ when DateTime then timestamp.rfc3339
23
+ when Time then timestamp.iso8601
24
+ else timestamp
25
+ end
26
+ end
17
27
  end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module StreamChat
5
- VERSION = '3.20.0'
5
+ VERSION = '3.22.0'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stream-chat-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.20.0
4
+ version: 3.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - getstream.io
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-10-06 00:00:00.000000000 Z
11
+ date: 2026-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -113,6 +113,7 @@ files:
113
113
  - Rakefile
114
114
  - SECURITY.md
115
115
  - lib/stream-chat.rb
116
+ - lib/stream-chat/campaign.rb
116
117
  - lib/stream-chat/channel.rb
117
118
  - lib/stream-chat/client.rb
118
119
  - lib/stream-chat/errors.rb