parent
f94abaef5f
commit
65f3e83afd
19 changed files with 542 additions and 61 deletions
|
@ -32,9 +32,16 @@ class V2::ReportBuilder
|
|||
private
|
||||
|
||||
def scope
|
||||
return account if params[:type].match?('account')
|
||||
return inbox if params[:type].match?('inbox')
|
||||
return user if params[:type].match?('agent')
|
||||
case params[:type]
|
||||
when :account
|
||||
account
|
||||
when :inbox
|
||||
inbox
|
||||
when :agent
|
||||
user
|
||||
when :label
|
||||
label
|
||||
end
|
||||
end
|
||||
|
||||
def inbox
|
||||
|
@ -45,6 +52,10 @@ class V2::ReportBuilder
|
|||
@user ||= account.users.where(id: params[:id]).first
|
||||
end
|
||||
|
||||
def label
|
||||
@label ||= account.labels.where(id: params[:id]).first
|
||||
end
|
||||
|
||||
def conversations_count
|
||||
scope.conversations
|
||||
.group_by_day(:created_at, range: range, default_value: 0)
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
|
||||
before_action :check_authorization
|
||||
|
||||
def account
|
||||
builder = V2::ReportBuilder.new(Current.account, account_report_params)
|
||||
def index
|
||||
builder = V2::ReportBuilder.new(Current.account, report_params)
|
||||
data = builder.build
|
||||
render json: data
|
||||
end
|
||||
|
||||
def account_summary
|
||||
render json: account_summary_metrics
|
||||
def summary
|
||||
render json: summary_metrics
|
||||
end
|
||||
|
||||
def agents
|
||||
|
@ -23,31 +23,39 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
|
|||
render layout: false, template: 'api/v2/accounts/reports/inboxes.csv.erb', format: 'csv'
|
||||
end
|
||||
|
||||
def labels
|
||||
response.headers['Content-Type'] = 'text/csv'
|
||||
response.headers['Content-Disposition'] = 'attachment; filename=labels_report.csv'
|
||||
render layout: false, template: 'api/v2/accounts/reports/labels.csv.erb', format: 'csv'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_authorization
|
||||
raise Pundit::NotAuthorizedError unless Current.account_user.administrator?
|
||||
end
|
||||
|
||||
def account_summary_params
|
||||
def summary_params
|
||||
{
|
||||
type: :account,
|
||||
type: params[:type].to_sym,
|
||||
since: params[:since],
|
||||
until: params[:until]
|
||||
until: params[:until],
|
||||
id: params[:id]
|
||||
}
|
||||
end
|
||||
|
||||
def account_report_params
|
||||
def report_params
|
||||
{
|
||||
metric: params[:metric],
|
||||
type: :account,
|
||||
type: params[:type].to_sym,
|
||||
since: params[:since],
|
||||
until: params[:until]
|
||||
until: params[:until],
|
||||
id: params[:id]
|
||||
}
|
||||
end
|
||||
|
||||
def account_summary_metrics
|
||||
builder = V2::ReportBuilder.new(Current.account, account_summary_params)
|
||||
def summary_metrics
|
||||
builder = V2::ReportBuilder.new(Current.account, summary_params)
|
||||
builder.summary
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,14 +7,14 @@ class ReportsAPI extends ApiClient {
|
|||
}
|
||||
|
||||
getAccountReports(metric, since, until) {
|
||||
return axios.get(`${this.url}/account`, {
|
||||
params: { metric, since, until },
|
||||
return axios.get(`${this.url}`, {
|
||||
params: { metric, since, until, type: 'account' },
|
||||
});
|
||||
}
|
||||
|
||||
getAccountSummary(since, until) {
|
||||
return axios.get(`${this.url}/account_summary`, {
|
||||
params: { since, until },
|
||||
return axios.get(`${this.url}/summary`, {
|
||||
params: { since, until, type: 'account' },
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -23,12 +23,13 @@ describe('#Reports API', () => {
|
|||
1621621800
|
||||
);
|
||||
expect(context.axiosMock.get).toHaveBeenCalledWith(
|
||||
'/api/v2/reports/account',
|
||||
'/api/v2/reports',
|
||||
{
|
||||
params: {
|
||||
metric: 'conversations_count',
|
||||
since: 1621103400,
|
||||
until: 1621621800,
|
||||
type: 'account'
|
||||
},
|
||||
}
|
||||
);
|
||||
|
@ -37,11 +38,12 @@ describe('#Reports API', () => {
|
|||
it('#getAccountSummary', () => {
|
||||
reportsAPI.getAccountSummary(1621103400, 1621621800);
|
||||
expect(context.axiosMock.get).toHaveBeenCalledWith(
|
||||
'/api/v2/reports/account_summary',
|
||||
'/api/v2/reports/summary',
|
||||
{
|
||||
params: {
|
||||
since: 1621103400,
|
||||
until: 1621621800,
|
||||
type: 'account'
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -28,4 +28,16 @@ class Label < ApplicationRecord
|
|||
before_validation do
|
||||
self.title = title.downcase if attribute_present?('title')
|
||||
end
|
||||
|
||||
def conversations
|
||||
account.conversations.tagged_with(title)
|
||||
end
|
||||
|
||||
def messages
|
||||
account.messages.where(conversation_id: conversations.pluck(:id))
|
||||
end
|
||||
|
||||
def events
|
||||
account.events.where(conversation_id: conversations.pluck(:id))
|
||||
end
|
||||
end
|
||||
|
|
12
app/views/api/v2/accounts/reports/labels.csv.erb
Normal file
12
app/views/api/v2/accounts/reports/labels.csv.erb
Normal file
|
@ -0,0 +1,12 @@
|
|||
<% headers = ['Label Title', 'Conversations count', 'Avg first response time (Minutes)', 'Avg resolution time (Minutes)'] %>
|
||||
<%= CSV.generate_line headers %>
|
||||
<% Current.account.labels.each do |label| %>
|
||||
<% label_report = V2::ReportBuilder.new(Current.account, {
|
||||
type: :label,
|
||||
id: label.id,
|
||||
since: params[:since],
|
||||
until: params[:until]
|
||||
}).summary %>
|
||||
<% row = [ label.title, label_report[:conversations_count], (label_report[:avg_first_response_time]/60).to_i, (label_report[:avg_resolution_time]/60).to_i ] %>
|
||||
<%= CSV.generate_line row %>
|
||||
<% end %>
|
|
@ -175,12 +175,12 @@ Rails.application.routes.draw do
|
|||
|
||||
namespace :v2 do
|
||||
resources :accounts, only: [], module: :accounts do
|
||||
resources :reports, only: [] do
|
||||
resources :reports, only: [:index] do
|
||||
collection do
|
||||
get :account
|
||||
get :account_summary
|
||||
get :summary
|
||||
get :agents
|
||||
get :inboxes
|
||||
get :labels
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,8 @@ describe ::V2::ReportBuilder do
|
|||
let!(:user) { create(:user, account: account) }
|
||||
let!(:inbox) { create(:inbox, account: account) }
|
||||
let(:inbox_member) { create(:inbox_member, user: user, inbox: inbox) }
|
||||
let!(:label_1) { create(:label, title: 'Label_1', account: account) }
|
||||
let!(:label_2) { create(:label, title: 'Label_2', account: account) }
|
||||
|
||||
# Running jobs inline to calculate the exact metrics
|
||||
around do |test|
|
||||
|
@ -17,7 +19,6 @@ describe ::V2::ReportBuilder do
|
|||
end
|
||||
|
||||
describe '#timeseries' do
|
||||
context 'when report type is account' do
|
||||
before do
|
||||
10.times do
|
||||
conversation = create(:conversation, account: account,
|
||||
|
@ -30,7 +31,11 @@ describe ::V2::ReportBuilder do
|
|||
account: account, inbox: inbox,
|
||||
conversation: conversation,
|
||||
created_at: Time.zone.today + 3.hours)
|
||||
conversation.update_labels('label_1')
|
||||
conversation.label_list
|
||||
conversation.save!
|
||||
end
|
||||
|
||||
5.times do
|
||||
conversation = create(:conversation, account: account,
|
||||
inbox: inbox, assignee: user,
|
||||
|
@ -43,9 +48,13 @@ describe ::V2::ReportBuilder do
|
|||
account: account, inbox: inbox,
|
||||
conversation: conversation,
|
||||
created_at: (Time.zone.today - 2.days))
|
||||
conversation.update_labels('label_2')
|
||||
conversation.label_list
|
||||
conversation.save!
|
||||
end
|
||||
end
|
||||
|
||||
context 'when report type is account' do
|
||||
it 'return conversations count' do
|
||||
params = {
|
||||
metric: 'conversations_count',
|
||||
|
@ -139,5 +148,105 @@ describe ::V2::ReportBuilder do
|
|||
expect(metrics[:resolutions_count]).to be 0
|
||||
end
|
||||
end
|
||||
|
||||
context 'when report type is label' do
|
||||
it 'return conversations count' do
|
||||
params = {
|
||||
metric: 'conversations_count',
|
||||
type: :label,
|
||||
id: label_2.id,
|
||||
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
|
||||
until: Time.zone.today.to_time.to_i.to_s
|
||||
}
|
||||
|
||||
builder = V2::ReportBuilder.new(account, params)
|
||||
metrics = builder.timeseries
|
||||
|
||||
expect(metrics[Time.zone.today - 2.days]).to be 5
|
||||
end
|
||||
|
||||
it 'return incoming messages count' do
|
||||
params = {
|
||||
metric: 'incoming_messages_count',
|
||||
type: :label,
|
||||
id: label_1.id,
|
||||
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
|
||||
until: Time.zone.today.to_time.to_i.to_s
|
||||
}
|
||||
|
||||
builder = V2::ReportBuilder.new(account, params)
|
||||
metrics = builder.timeseries
|
||||
|
||||
expect(metrics[Time.zone.today]).to be 20
|
||||
expect(metrics[Time.zone.today - 2.days]).to be 5
|
||||
end
|
||||
|
||||
it 'return outgoing messages count' do
|
||||
params = {
|
||||
metric: 'outgoing_messages_count',
|
||||
type: :label,
|
||||
id: label_1.id,
|
||||
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
|
||||
until: Time.zone.today.to_time.to_i.to_s
|
||||
}
|
||||
|
||||
builder = V2::ReportBuilder.new(account, params)
|
||||
metrics = builder.timeseries
|
||||
|
||||
expect(metrics[Time.zone.today]).to be 50
|
||||
expect(metrics[Time.zone.today - 2.days]).to be 15
|
||||
end
|
||||
|
||||
it 'return resolutions count' do
|
||||
params = {
|
||||
metric: 'resolutions_count',
|
||||
type: :label,
|
||||
id: label_2.id,
|
||||
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
|
||||
until: Time.zone.today.to_time.to_i.to_s
|
||||
}
|
||||
|
||||
conversations = account.conversations.where('created_at < ?', 1.day.ago)
|
||||
conversations.each(&:resolved!)
|
||||
builder = V2::ReportBuilder.new(account, params)
|
||||
metrics = builder.timeseries
|
||||
|
||||
expect(metrics[Time.zone.today - 2.days]).to be 5
|
||||
end
|
||||
|
||||
it 'returns average first response time' do
|
||||
FactoryBot.create(:event, conversation: label_2.conversations.last, account: account, name: 'first_response')
|
||||
|
||||
params = {
|
||||
metric: 'avg_first_response_time',
|
||||
type: :label,
|
||||
id: label_2.id,
|
||||
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
|
||||
until: Time.zone.today.to_time.to_i.to_s
|
||||
}
|
||||
|
||||
builder = V2::ReportBuilder.new(account, params)
|
||||
metrics = builder.timeseries
|
||||
expect(metrics[Time.zone.today].to_f).to be 0.15e1
|
||||
end
|
||||
|
||||
it 'returns summary' do
|
||||
params = {
|
||||
type: :label,
|
||||
id: label_2.id,
|
||||
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
|
||||
until: Time.zone.today.to_time.to_i.to_s
|
||||
}
|
||||
|
||||
builder = V2::ReportBuilder.new(account, params)
|
||||
metrics = builder.summary
|
||||
|
||||
expect(metrics[:conversations_count]).to be 5
|
||||
expect(metrics[:incoming_messages_count]).to be 25
|
||||
expect(metrics[:outgoing_messages_count]).to be 65
|
||||
expect(metrics[:avg_resolution_time]).to be 0
|
||||
expect(metrics[:resolutions_count]).to be 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ RSpec.describe 'Reports API', type: :request do
|
|||
describe 'GET /api/v2/accounts/:account_id/reports/account' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/account"
|
||||
get "/api/v2/accounts/#{account.id}/reports"
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
|
@ -31,7 +31,7 @@ RSpec.describe 'Reports API', type: :request do
|
|||
}
|
||||
|
||||
it 'returns unauthorized for agents' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/account",
|
||||
get "/api/v2/accounts/#{account.id}/reports",
|
||||
params: params,
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
|
@ -40,7 +40,7 @@ RSpec.describe 'Reports API', type: :request do
|
|||
end
|
||||
|
||||
it 'return timeseries metrics' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/account",
|
||||
get "/api/v2/accounts/#{account.id}/reports",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
|
@ -55,10 +55,10 @@ RSpec.describe 'Reports API', type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v2/accounts/:account_id/reports/account_summary' do
|
||||
describe 'GET /api/v2/accounts/:account_id/reports/summary' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/account_summary"
|
||||
get "/api/v2/accounts/#{account.id}/reports/summary"
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
|
@ -72,7 +72,7 @@ RSpec.describe 'Reports API', type: :request do
|
|||
}
|
||||
|
||||
it 'returns unauthorized for agents' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/account_summary",
|
||||
get "/api/v2/accounts/#{account.id}/reports/summary",
|
||||
params: params,
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
|
@ -81,7 +81,7 @@ RSpec.describe 'Reports API', type: :request do
|
|||
end
|
||||
|
||||
it 'returns summary metrics' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/account_summary",
|
||||
get "/api/v2/accounts/#{account.id}/reports/summary",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
|
@ -142,7 +142,7 @@ RSpec.describe 'Reports API', type: :request do
|
|||
until: Time.zone.today.to_time.to_i.to_s
|
||||
}
|
||||
|
||||
it 'returns unauthorized for agents' do
|
||||
it 'returns unauthorized for inboxes' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/inboxes",
|
||||
params: params,
|
||||
headers: agent.create_new_auth_token
|
||||
|
@ -159,4 +159,37 @@ RSpec.describe 'Reports API', type: :request do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v2/accounts/:account_id/reports/labels' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/labels.csv"
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated user' do
|
||||
params = {
|
||||
since: 30.days.ago.to_i.to_s,
|
||||
until: Time.zone.today.to_time.to_i.to_s
|
||||
}
|
||||
|
||||
it 'returns unauthorized for labels' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/labels.csv",
|
||||
params: params,
|
||||
headers: agent.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
|
||||
it 'returns summary' do
|
||||
get "/api/v2/accounts/#{account.id}/reports/labels.csv",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -140,3 +140,12 @@ extended_message:
|
|||
- $ref: '#/definitions/generic_id'
|
||||
- $ref: '#/definitions/message'
|
||||
- $ref: ./resource/extension/message/with_source_sender.yml
|
||||
|
||||
|
||||
## report list
|
||||
report:
|
||||
type: array
|
||||
description: 'array of conversation count based on date'
|
||||
items:
|
||||
allOf:
|
||||
- $ref: './resource/report.yml'
|
||||
|
|
6
swagger/definitions/resource/report.yml
Normal file
6
swagger/definitions/resource/report.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
type: object
|
||||
properties:
|
||||
value:
|
||||
type: number
|
||||
timestamp:
|
||||
type: string
|
|
@ -63,6 +63,7 @@ x-tagGroups:
|
|||
- Profile
|
||||
- Teams
|
||||
- Custom Filter
|
||||
- Reports
|
||||
- name: Public
|
||||
tags:
|
||||
- Contacts API
|
||||
|
|
|
@ -31,6 +31,12 @@ platform_user_id:
|
|||
custom_filter_id:
|
||||
$ref: ./custom_filter_id.yml
|
||||
|
||||
report_type:
|
||||
$ref: ./report_type.yml
|
||||
|
||||
report_metric:
|
||||
$ref: ./report_metric.yml
|
||||
|
||||
public_inbox_identifier:
|
||||
$ref: ./public/inbox_identifier.yml
|
||||
|
||||
|
|
7
swagger/parameters/report_metric.yml
Normal file
7
swagger/parameters/report_metric.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
in: query
|
||||
name: metric
|
||||
schema:
|
||||
type: string
|
||||
enum: [conversations_count, incoming_messages_count, outgoing_messages_count, avg_first_response_time, avg_resolution_time, resolutions_count]
|
||||
required: true
|
||||
description: The type of metric
|
7
swagger/parameters/report_type.yml
Normal file
7
swagger/parameters/report_type.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
in: query
|
||||
name: report_type
|
||||
schema:
|
||||
type: string
|
||||
enum: [account,agent,inbox,label]
|
||||
required: true
|
||||
description: Type of report
|
|
@ -269,7 +269,7 @@ public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversat
|
|||
delete:
|
||||
$ref: ./teams/delete.yml
|
||||
|
||||
### Custom Filters
|
||||
### Custom Filters goes here
|
||||
|
||||
# Teams
|
||||
/api/v1/accounts/{account_id}/custom_filters:
|
||||
|
@ -296,3 +296,52 @@ public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversat
|
|||
$ref: ./custom_filters/update.yml
|
||||
delete:
|
||||
$ref: ./custom_filters/delete.yml
|
||||
|
||||
### Reports
|
||||
|
||||
# List
|
||||
/api/v1/accounts/{id}/reports:
|
||||
parameters:
|
||||
- $ref: '#/parameters/account_id'
|
||||
- $ref: '#/parameters/report_metric'
|
||||
- $ref: '#/parameters/report_type'
|
||||
- in: query
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
description: The Id of specific object in case of agent/inbox/label
|
||||
- in: query
|
||||
name: since
|
||||
schema:
|
||||
type: string
|
||||
description: The timestamp from where report should start.
|
||||
- in: query
|
||||
name: until
|
||||
schema:
|
||||
type: string
|
||||
description: The timestamp from where report should stop.
|
||||
get:
|
||||
$ref: './reports/index.yml'
|
||||
|
||||
# Summary
|
||||
/api/v1/accounts/{id}/reports/summary:
|
||||
parameters:
|
||||
- $ref: '#/parameters/account_id'
|
||||
- $ref: '#/parameters/report_type'
|
||||
- in: query
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
description: The Id of specific object in case of agent/inbox/label
|
||||
- in: query
|
||||
name: since
|
||||
schema:
|
||||
type: string
|
||||
description: The timestamp from where report should start.
|
||||
- in: query
|
||||
name: until
|
||||
schema:
|
||||
type: string
|
||||
description: The timestamp from where report should stop.
|
||||
get:
|
||||
$ref: './reports/summary.yml'
|
||||
|
|
17
swagger/paths/reports/index.yml
Normal file
17
swagger/paths/reports/index.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
tags:
|
||||
- Reports
|
||||
operationId: list-all-conversation-statistics
|
||||
summary: Get Account reports
|
||||
description: Get Account reports for a specific type, metric and date range
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
schema:
|
||||
type: array
|
||||
description: 'Array of date based conversation statistics'
|
||||
items:
|
||||
$ref: '#/definitions/report'
|
||||
404:
|
||||
description: reports not found
|
||||
403:
|
||||
description: Access denied
|
17
swagger/paths/reports/summary.yml
Normal file
17
swagger/paths/reports/summary.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
tags:
|
||||
- Reports
|
||||
operationId: list-all-conversation-statistics-summary
|
||||
summary: Get Account reports summary
|
||||
description: Get Account reports summary for a specific type and date range
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
schema:
|
||||
type: array
|
||||
description: 'Array of date based conversation statistics'
|
||||
items:
|
||||
$ref: '#/definitions/report'
|
||||
404:
|
||||
description: reports not found
|
||||
403:
|
||||
description: Access denied
|
|
@ -2757,6 +2757,129 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/accounts/{id}/reports": {
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/account_id"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/report_metric"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/report_type"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The Id of specific object in case of agent/inbox/label"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "since",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The timestamp from where report should start."
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "until",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The timestamp from where report should stop."
|
||||
}
|
||||
],
|
||||
"get": {
|
||||
"tags": [
|
||||
"Reports"
|
||||
],
|
||||
"operationId": "list-all-conversation-statistics",
|
||||
"summary": "Get Account reports",
|
||||
"description": "Get Account reports for a specific type, metric and date range",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"description": "Array of date based conversation statistics",
|
||||
"items": {
|
||||
"$ref": "#/definitions/report"
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "reports not found"
|
||||
},
|
||||
"403": {
|
||||
"description": "Access denied"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/accounts/{id}/reports/summary": {
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/account_id"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/report_type"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The Id of specific object in case of agent/inbox/label"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "since",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The timestamp from where report should start."
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "until",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The timestamp from where report should stop."
|
||||
}
|
||||
],
|
||||
"get": {
|
||||
"tags": [
|
||||
"Reports"
|
||||
],
|
||||
"operationId": "list-all-conversation-statistics-summary",
|
||||
"summary": "Get Account reports summary",
|
||||
"description": "Get Account reports summary for a specific type and date range",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"description": "Array of date based conversation statistics",
|
||||
"items": {
|
||||
"$ref": "#/definitions/report"
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "reports not found"
|
||||
},
|
||||
"403": {
|
||||
"description": "Access denied"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
@ -3844,6 +3967,25 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"report": {
|
||||
"type": "array",
|
||||
"description": "array of conversation count based on date",
|
||||
"items": {
|
||||
"allOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {
|
||||
"type": "number"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
|
@ -3952,6 +4094,38 @@
|
|||
"required": true,
|
||||
"description": "The numeric ID of the custom filter"
|
||||
},
|
||||
"report_type": {
|
||||
"in": "query",
|
||||
"name": "report_type",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"account",
|
||||
"agent",
|
||||
"inbox",
|
||||
"label"
|
||||
]
|
||||
},
|
||||
"required": true,
|
||||
"description": "Type of report"
|
||||
},
|
||||
"report_metric": {
|
||||
"in": "query",
|
||||
"name": "metric",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"conversations_count",
|
||||
"incoming_messages_count",
|
||||
"outgoing_messages_count",
|
||||
"avg_first_response_time",
|
||||
"avg_resolution_time",
|
||||
"resolutions_count"
|
||||
]
|
||||
},
|
||||
"required": true,
|
||||
"description": "The type of metric"
|
||||
},
|
||||
"public_inbox_identifier": {
|
||||
"in": "path",
|
||||
"name": "inbox_identifier",
|
||||
|
@ -3994,7 +4168,8 @@
|
|||
"Integrations",
|
||||
"Profile",
|
||||
"Teams",
|
||||
"Custom Filter"
|
||||
"Custom Filter",
|
||||
"Reports"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue