From 846f520ad262cb3f78ae49686e5cb99077ea85a9 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Wed, 26 Jul 2023 20:40:48 +0300 Subject: [PATCH] feat: toggle typing and update last seen endpoints for client apis (#7621) - Add toggle_typing endpoint for client APIs - Adds update last seen endpoint for client APIs Fixes: #7581 --- .../v1/inboxes/conversations_controller.rb | 27 ++++++++++++++++ .../widgets/conversation/bubble/Actions.vue | 2 +- config/routes.rb | 5 +++ .../v1/inbox/conversations_controller_spec.rb | 31 +++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/app/controllers/public/api/v1/inboxes/conversations_controller.rb b/app/controllers/public/api/v1/inboxes/conversations_controller.rb index a399bc749..3d86ca87c 100644 --- a/app/controllers/public/api/v1/inboxes/conversations_controller.rb +++ b/app/controllers/public/api/v1/inboxes/conversations_controller.rb @@ -1,4 +1,7 @@ class Public::Api::V1::Inboxes::ConversationsController < Public::Api::V1::InboxesController + include Events::Types + before_action :set_conversation, only: [:toggle_typing, :update_last_seen] + def index @conversations = @contact_inbox.hmac_verified? ? @contact.conversations : @contact_inbox.conversations end @@ -7,12 +10,36 @@ class Public::Api::V1::Inboxes::ConversationsController < Public::Api::V1::Inbox @conversation = create_conversation end + def toggle_typing + case params[:typing_status] + when 'on' + trigger_typing_event(CONVERSATION_TYPING_ON) + when 'off' + trigger_typing_event(CONVERSATION_TYPING_OFF) + end + head :ok + end + + def update_last_seen + @conversation.contact_last_seen_at = DateTime.now.utc + @conversation.save! + head :ok + end + private + def set_conversation + @conversation = @contact_inbox.contact.conversations.find_by!(display_id: params[:id]) + end + def create_conversation ::Conversation.create!(conversation_params) end + def trigger_typing_event(event) + Rails.configuration.dispatcher.dispatch(event, Time.zone.now, conversation: @conversation, user: @conversation.contact) + end + def conversation_params { account_id: @contact_inbox.contact.account_id, diff --git a/app/javascript/dashboard/components/widgets/conversation/bubble/Actions.vue b/app/javascript/dashboard/components/widgets/conversation/bubble/Actions.vue index 9ce28a474..58b9db26b 100644 --- a/app/javascript/dashboard/components/widgets/conversation/bubble/Actions.vue +++ b/app/javascript/dashboard/components/widgets/conversation/bubble/Actions.vue @@ -233,7 +233,7 @@ export default { return false; } - if (this.isAWebWidgetInbox) { + if (this.isAWebWidgetInbox || this.isAPIInbox) { const { contact_last_seen_at: contactLastSeenAt } = this.currentChat; return contactLastSeenAt >= this.createdAt; } diff --git a/config/routes.rb b/config/routes.rb index cb589b562..a89f32079 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -337,6 +337,11 @@ Rails.application.routes.draw do scope module: :inboxes do resources :contacts, only: [:create, :show, :update] do resources :conversations, only: [:index, :create] do + member do + post :toggle_typing + post :update_last_seen + end + resources :messages, only: [:index, :create, :update] end end diff --git a/spec/controllers/public/api/v1/inbox/conversations_controller_spec.rb b/spec/controllers/public/api/v1/inbox/conversations_controller_spec.rb index 5c00b0543..19f08d49b 100644 --- a/spec/controllers/public/api/v1/inbox/conversations_controller_spec.rb +++ b/spec/controllers/public/api/v1/inbox/conversations_controller_spec.rb @@ -45,4 +45,35 @@ RSpec.describe 'Public Inbox Contact Conversations API', type: :request do expect(data['id']).not_to be_nil end end + + describe 'POST /public/api/v1/inboxes/{identifier}/contact/{source_id}/conversations/{conversation_id}/toggle_typing' do + let!(:conversation) { create(:conversation, contact_inbox: contact_inbox, contact: contact) } + let(:toggle_typing_path) do + "/public/api/v1/inboxes/#{api_channel.identifier}/contacts/#{contact_inbox.source_id}/conversations/#{conversation.display_id}/toggle_typing" + end + + it 'dispatches the correct typing status' do + allow(Rails.configuration.dispatcher).to receive(:dispatch) + post toggle_typing_path, params: { typing_status: 'on' } + + expect(response).to have_http_status(:success) + expect(Rails.configuration.dispatcher).to have_received(:dispatch) + .with(Conversation::CONVERSATION_TYPING_ON, kind_of(Time), { conversation: conversation, user: contact }) + end + end + + describe 'POST /public/api/v1/inboxes/{identifier}/contact/{source_id}/conversations/{conversation_id}/update_last_seen' do + let!(:conversation) { create(:conversation, contact_inbox: contact_inbox, contact: contact) } + let(:update_last_seen_path) do + "/public/api/v1/inboxes/#{api_channel.identifier}/contacts/#{contact_inbox.source_id}/conversations/#{conversation.display_id}/update_last_seen" + end + + it 'updates the last seen of the conversation contact' do + contact_last_seen_at = conversation.contact_last_seen_at + post update_last_seen_path + + expect(response).to have_http_status(:success) + expect(conversation.reload.contact_last_seen_at).not_to eq contact_last_seen_at + end + end end