Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions lib/stream-chat/channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,41 @@ def delete_image(url)
@client.delete("#{self.url}/image", params: { url: url })
end

# Creates or updates a draft message for this channel.
#
# @param [StringKeyHash] message The draft message content
# @param [String] user_id The ID of the user creating/updating the draft
# @return [StreamChat::StreamResponse]
sig { params(message: StringKeyHash, user_id: String).returns(StreamChat::StreamResponse) }
def create_draft(message, user_id)
payload = { message: add_user_id(message, user_id) }
@client.post("#{url}/draft", data: payload)
end

# Deletes a draft message for this channel.
#
# @param [String] user_id The ID of the user deleting the draft
# @param [String] parent_id Optional parent message ID for thread drafts
# @return [StreamChat::StreamResponse]
sig { params(user_id: String, parent_id: T.nilable(String)).returns(StreamChat::StreamResponse) }
def delete_draft(user_id, parent_id: nil)
params = { user_id: user_id }
params[:parent_id] = parent_id if parent_id
@client.delete("#{url}/draft", params: params)
end

# Gets a draft message for this channel.
#
# @param [String] user_id The ID of the user getting the draft
# @param [String] parent_id Optional parent message ID for thread drafts
# @return [StreamChat::StreamResponse]
sig { params(user_id: String, parent_id: T.nilable(String)).returns(StreamChat::StreamResponse) }
def get_draft(user_id, parent_id: nil)
params = { user_id: user_id }
params[:parent_id] = parent_id if parent_id
@client.get("#{url}/draft", params: params)
end

private

sig { params(payload: StringKeyHash, user_id: String).returns(StringKeyHash) }
Expand Down
16 changes: 16 additions & 0 deletions lib/stream-chat/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,22 @@ def create_command(command)
post('commands', data: command)
end

# Queries draft messages for the current user.
#
# @param [String] user_id The ID of the user to query drafts for
# @param [StringKeyHash] filter Optional filter conditions for the query
# @param [Array] sort Optional sort parameters
# @param [Hash] options Additional query options
# @return [StreamChat::StreamResponse]
sig { params(user_id: String, filter: T.nilable(StringKeyHash), sort: T.nilable(T::Array[StringKeyHash]), options: T.untyped).returns(StreamChat::StreamResponse) }
def query_drafts(user_id, filter: nil, sort: nil, **options)
data = { user_id: user_id }
data['filter'] = filter if filter
data['sort'] = sort if sort
data.merge!(options) if options
post('drafts/query', data: data)
end

# Gets a comamnd.
sig { params(name: String).returns(StreamChat::StreamResponse) }
def get_command(name)
Expand Down
61 changes: 61 additions & 0 deletions spec/channel_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -430,4 +430,65 @@ def loop_times(times)
# Verify the custom field was unset
expect(updated_msg['message']).not_to include 'custom_field'
end

it 'can create draft message' do
draft_message = { 'text' => 'This is a draft message' }
response = @channel.create_draft(draft_message, @random_user[:id])

expect(response).to include 'draft'
expect(response['draft']['message']['text']).to eq 'This is a draft message'
expect(response['draft']['channel_cid']).to eq @channel.cid
end

it 'can get draft message' do
# First create a draft
draft_message = { 'text' => 'This is a draft to retrieve' }
@channel.create_draft(draft_message, @random_user[:id])

# Then get the draft
response = @channel.get_draft(@random_user[:id])

expect(response).to include 'draft'
expect(response['draft']['message']['text']).to eq 'This is a draft to retrieve'
expect(response['draft']['channel_cid']).to eq @channel.cid
end

it 'can delete draft message' do
# First create a draft
draft_message = { 'text' => 'This is a draft to delete' }
@channel.create_draft(draft_message, @random_user[:id])

# Then delete the draft
@channel.delete_draft(@random_user[:id])

# Verify it's deleted by trying to get it
expect { @channel.get_draft(@random_user[:id]) }.to raise_error(StreamChat::StreamAPIException)
end

it 'can create and manage thread draft' do
# First create a parent message
msg = @channel.send_message({ 'text' => 'Parent message' }, @random_user[:id])
parent_id = msg['message']['id']

# Create a draft reply
draft_reply = { 'text' => 'This is a draft reply', 'parent_id' => parent_id }
response = @channel.create_draft(draft_reply, @random_user[:id])

expect(response).to include 'draft'
expect(response['draft']['message']['text']).to eq 'This is a draft reply'
expect(response['draft']['parent_id']).to eq parent_id

# Get the draft reply
response = @channel.get_draft(@random_user[:id], parent_id: parent_id)

expect(response).to include 'draft'
expect(response['draft']['message']['text']).to eq 'This is a draft reply'
expect(response['draft']['parent_id']).to eq parent_id

# Delete the draft reply
@channel.delete_draft(@random_user[:id], parent_id: parent_id)

# Verify it's deleted
expect { @channel.get_draft(@random_user[:id], parent_id: parent_id) }.to raise_error(StreamChat::StreamAPIException)
end
end
45 changes: 45 additions & 0 deletions spec/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,51 @@ def loop_times(times)
list_resp = @client.list_imports({ limit: 1 })
expect(list_resp['import_tasks'].length).to eq 1
end

it 'can query drafts' do
# Create multiple drafts in different channels
draft1 = { 'text' => 'Draft in channel 1' }
@channel.create_draft(draft1, @random_user[:id])

# Create another channel with a draft
channel2 = @client.channel('messaging', data: { 'members' => @random_users.map { |u| u[:id] } })
channel2.create(@random_user[:id])

draft2 = { 'text' => 'Draft in channel 2' }
channel2.create_draft(draft2, @random_user[:id])

# Sort by created_at
sort = [{ 'field' => 'created_at', 'direction' => 1 }]
response = @client.query_drafts(@random_user[:id], sort: sort)
expect(response['drafts']).not_to be_empty
expect(response['drafts'].length).to eq(2)
expect(response['drafts'][0]['channel']['id']).to eq(@channel.id)
expect(response['drafts'][1]['channel']['id']).to eq(channel2.id)

# Query for a specific channel
response = @client.query_drafts(@random_user[:id], filter: { 'channel_cid' => @channel.cid })
expect(response['drafts']).not_to be_empty
expect(response['drafts'].length).to eq(1)
expect(response['drafts'][0]['channel']['id']).to eq(@channel.id)

# Query all drafts for the user
response = @client.query_drafts(@random_user[:id])
expect(response['drafts']).not_to be_empty
expect(response['drafts'].length).to eq(2)

# Paginate
response = @client.query_drafts(@random_user[:id], sort: sort, limit: 1)
expect(response['drafts']).not_to be_empty
expect(response['drafts'].length).to eq(1)
expect(response['drafts'][0]['channel']['id']).to eq(@channel.id)

# Cleanup
begin
channel2.delete
rescue StandardError
# Ignore errors if channel is already deleted
end
end
end

describe 'permissions' do
Expand Down