feat: Ability to search conversation with message content (#1265)
- API end point which takes message content as search parameter - end point supports additional filtering with labels and inbox ids - swagger doc
This commit is contained in:
parent
bc8becf49c
commit
532331edb6
7 changed files with 122 additions and 9 deletions
|
@ -15,6 +15,12 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
|
|||
@conversations_count = result[:count]
|
||||
end
|
||||
|
||||
def search
|
||||
result = conversation_finder.perform
|
||||
@conversations = result[:conversations]
|
||||
@conversations_count = result[:count]
|
||||
end
|
||||
|
||||
def create
|
||||
@conversation = ::Conversation.create!(conversation_params)
|
||||
end
|
||||
|
|
|
@ -27,6 +27,7 @@ class ConversationFinder
|
|||
find_all_conversations
|
||||
filter_by_status
|
||||
filter_by_labels if params[:labels]
|
||||
filter_by_query if params[:q]
|
||||
|
||||
mine_count, unassigned_count, all_count = set_count_for_all_conversations
|
||||
|
||||
|
@ -76,6 +77,12 @@ class ConversationFinder
|
|||
@conversations
|
||||
end
|
||||
|
||||
def filter_by_query
|
||||
@conversations = @conversations.joins(:messages).where('messages.content LIKE :search',
|
||||
search: "%#{params[:q]}%").includes(:messages).where('messages.content LIKE :search',
|
||||
search: "%#{params[:q]}%")
|
||||
end
|
||||
|
||||
def filter_by_status
|
||||
@conversations = @conversations.where(status: params[:status] || DEFAULT_STATUS)
|
||||
end
|
||||
|
|
22
app/views/api/v1/accounts/conversations/search.json.jbuilder
Normal file
22
app/views/api/v1/accounts/conversations/search.json.jbuilder
Normal file
|
@ -0,0 +1,22 @@
|
|||
json.data do
|
||||
json.meta do
|
||||
json.mine_count @conversations_count[:mine_count]
|
||||
json.unassigned_count @conversations_count[:unassigned_count]
|
||||
json.all_count @conversations_count[:all_count]
|
||||
end
|
||||
json.payload do
|
||||
json.array! @conversations do |conversation|
|
||||
json.inbox_id conversation.inbox_id
|
||||
json.messages conversation.messages
|
||||
json.status conversation.status
|
||||
json.muted conversation.muted?
|
||||
json.can_reply conversation.can_reply?
|
||||
json.timestamp conversation.messages.last.try(:created_at).try(:to_i)
|
||||
json.contact_last_seen_at conversation.contact_last_seen_at.to_i
|
||||
json.agent_last_seen_at conversation.agent_last_seen_at.to_i
|
||||
json.additional_attributes conversation.additional_attributes
|
||||
json.account_id conversation.account_id
|
||||
json.labels conversation.label_list
|
||||
end
|
||||
end
|
||||
end
|
|
@ -47,6 +47,7 @@ Rails.application.routes.draw do
|
|||
end
|
||||
resources :conversations, only: [:index, :create, :show] do
|
||||
get 'meta', on: :collection
|
||||
get 'search', on: :collection
|
||||
scope module: :conversations do
|
||||
resources :messages, only: [:index, :create]
|
||||
resources :assignments, only: [:create]
|
||||
|
|
|
@ -59,6 +59,39 @@ RSpec.describe 'Conversations API', type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/accounts/{account.id}/conversations/search' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
get "/api/v1/accounts/#{account.id}/conversations/search", params: { q: 'test' }
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated user' do
|
||||
let(:agent) { create(:user, account: account, role: :agent) }
|
||||
|
||||
before do
|
||||
conversation = create(:conversation, account: account)
|
||||
create(:message, conversation: conversation, account: account, content: 'test1')
|
||||
create(:message, conversation: conversation, account: account, content: 'test2')
|
||||
create(:inbox_member, user: agent, inbox: conversation.inbox)
|
||||
end
|
||||
|
||||
it 'returns all conversations with messages containing the search query' do
|
||||
get "/api/v1/accounts/#{account.id}/conversations/search",
|
||||
headers: agent.create_new_auth_token,
|
||||
params: { q: 'test1' },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
response_data = JSON.parse(response.body, symbolize_names: true)[:data]
|
||||
expect(response_data[:meta][:all_count]).to eq(1)
|
||||
expect(response_data[:payload].first[:messages].first[:content]).to eq 'test1'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/accounts/{account.id}/conversations/:id' do
|
||||
let(:conversation) { create(:conversation, account: account) }
|
||||
|
||||
|
|
|
@ -39,6 +39,48 @@ get:
|
|||
$ref: '#/definitions/bad_request_error'
|
||||
description: Access denied
|
||||
|
||||
get:
|
||||
tags:
|
||||
- Conversation
|
||||
operationId: conversationSearch
|
||||
description: Search for conversations containing a messages with the query string
|
||||
summary: Conversations Search
|
||||
parameters:
|
||||
- name: q
|
||||
in: query
|
||||
type: string
|
||||
- name: assignee_type
|
||||
in: query
|
||||
type: string
|
||||
enum: ['me', 'unassigned', 'all']
|
||||
- name: status
|
||||
in: query
|
||||
type: string
|
||||
enum: ['open', 'resolved', 'bot']
|
||||
- name: page
|
||||
in: query
|
||||
type: integer
|
||||
- name: inbox_id
|
||||
in: query
|
||||
type: integer
|
||||
- name: labels
|
||||
in: query
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
schema:
|
||||
$ref: '#/definitions/conversation_list'
|
||||
400:
|
||||
description: Bad Request Error
|
||||
schema:
|
||||
$ref: '#/definitions/bad_request_error'
|
||||
description: Access denied
|
||||
|
||||
|
||||
post:
|
||||
tags:
|
||||
- Conversation
|
||||
|
|
|
@ -283,10 +283,15 @@
|
|||
"tags": [
|
||||
"Conversation"
|
||||
],
|
||||
"operationId": "conversationList",
|
||||
"description": "List all the conversations with pagination",
|
||||
"summary": "Conversations List",
|
||||
"operationId": "conversationSearch",
|
||||
"description": "Search for conversations containing a messages with the query string",
|
||||
"summary": "Conversations Search",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "q",
|
||||
"in": "query",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "assignee_type",
|
||||
"in": "query",
|
||||
|
@ -295,8 +300,7 @@
|
|||
"me",
|
||||
"unassigned",
|
||||
"all"
|
||||
],
|
||||
"required": true
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
|
@ -306,14 +310,12 @@
|
|||
"open",
|
||||
"resolved",
|
||||
"bot"
|
||||
],
|
||||
"required": true
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "page",
|
||||
"in": "query",
|
||||
"type": "integer",
|
||||
"required": true
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"name": "inbox_id",
|
||||
|
|
Loading…
Reference in a new issue