Skip to content
27 changes: 27 additions & 0 deletions lib/stream-chat/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,33 @@ def query_drafts(user_id, filter: nil, sort: nil, **options)
post('drafts/query', data: data)
end

# Get active_live_locations for the current user
#
# @return [StreamChat::StreamResponse]
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
def get_active_live_locations(user_id)
get('users/live_locations', params: { user_id: user_id })
end

# Update live location
#
# @param [String] user_id The ID of the user to update the location
# @param [String] created_by_device_id The device ID that created the location
# @param [String] message_id The message ID associated with the location
# @param [Float] latitude Optional latitude coordinate
# @param [Float] longitude Optional longitude coordinate
# @param [String] end_at Optional end time for the location sharing
# @return [StreamChat::StreamResponse]
sig { params(user_id: String, created_by_device_id: String, message_id: String, options: T.untyped).returns(StreamChat::StreamResponse) }
def update_location(user_id, created_by_device_id:, message_id:, **options)
data = {
created_by_device_id: created_by_device_id,
message_id: message_id
}
data.merge!(options) if options
put('users/live_locations', data: data, params: { user_id: user_id })
end

# Gets a comamnd.
sig { params(name: String).returns(StreamChat::StreamResponse) }
def get_command(name)
Expand Down
88 changes: 88 additions & 0 deletions spec/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,9 @@ def loop_times(times)
list_resp = @client.list_imports({ limit: 1 })
expect(list_resp['import_tasks'].length).to eq 1
end
end

describe 'drafts' do
it 'can query drafts' do
# Create multiple drafts in different channels
draft1 = { 'text' => 'Draft in channel 1' }
Expand Down Expand Up @@ -1215,4 +1217,90 @@ def loop_times(times)
end
end
end

describe 'live locations' do
before(:all) do
@location_test_user = { id: SecureRandom.uuid }
@client.upsert_users([@location_test_user])
@location_channel = @client.channel('messaging', channel_id: SecureRandom.uuid)
@location_channel.create(@location_test_user[:id])
@location_channel.update_partial({ config_overrides: { shared_locations: true } })
@location_message = @location_channel.send_message({ text: 'Location sharing message' }, @location_test_user[:id])
end

after(:all) do
@location_channel.delete
@client.delete_user(@location_test_user[:id])
end

it 'can create and update a location' do
location = {
created_by_device_id: SecureRandom.uuid,
latitude: 40.7128,
longitude: -74.0060,
end_at: (Time.now + 3600).iso8601
}

response = @location_channel.send_message(
{
text: 'Location sharing message',
shared_location: location
}, @location_test_user[:id]
)

expect(response['message']).to include 'shared_location'
expect(response['message']['shared_location']['created_by_device_id']).to eq(location[:created_by_device_id])
expect(response['message']['shared_location']['latitude']).to eq(location[:latitude])
expect(response['message']['shared_location']['longitude']).to eq(location[:longitude])

new_latitude = location[:latitude] + 10
response = @client.update_location(
response['message']['user']['id'],
created_by_device_id: location[:created_by_device_id],
message_id: response['message']['id'],
latitude: new_latitude,
longitude: location[:longitude],
end_at: location[:end_at]
)

expect(response['created_by_device_id']).to eq(location[:created_by_device_id])
expect(response['latitude']).to eq(new_latitude)
expect(response['longitude']).to eq(location[:longitude])
end

it 'can get active live locations' do
device_id = SecureRandom.uuid
latitude = 40.7128
longitude = -74.0060
end_at = (Time.now + 3600).iso8601

@location_channel.send_message(
{
text: 'Location sharing message',
shared_location: {
created_by_device_id: device_id,
latitude: latitude,
longitude: longitude,
end_at: end_at
}
}, @location_test_user[:id]
)

response = @client.get_active_live_locations(@location_test_user[:id])
expect(response).to include 'active_live_locations'
expect(response['active_live_locations']).to be_an(Array)
expect(response['active_live_locations'].length).to be >= 1
location = response['active_live_locations'].find { |loc| loc['created_by_device_id'] == device_id }
expect(location).not_to be_nil
expect(location['latitude']).to eq(latitude)
expect(location['longitude']).to eq(longitude)
expect(DateTime.parse(location['end_at']).iso8601).to eq(end_at)
end

it 'should have active live locations on the channel' do
response = @location_channel.query
expect(response).to include 'active_live_locations'
expect(response['active_live_locations'].length).to be >= 1
end
end
end