feat: Add APIs to create custom views on the dashboard (#2498)
This commit is contained in:
parent
fa37f8e185
commit
30832d8a34
27 changed files with 654 additions and 9 deletions
50
app/controllers/api/v1/accounts/custom_filters_controller.rb
Normal file
50
app/controllers/api/v1/accounts/custom_filters_controller.rb
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
class Api::V1::Accounts::CustomFiltersController < Api::V1::Accounts::BaseController
|
||||||
|
protect_from_forgery with: :null_session
|
||||||
|
before_action :fetch_custom_filters, except: [:create]
|
||||||
|
before_action :fetch_custom_filter, only: [:show, :update, :destroy]
|
||||||
|
DEFAULT_FILTER_TYPE = 'conversation'.freeze
|
||||||
|
|
||||||
|
def index; end
|
||||||
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@custom_filter = current_user.custom_filters.create!(
|
||||||
|
permitted_payload.merge(account_id: Current.account.id)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@custom_filter.update!(permitted_payload)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@custom_filter.destroy
|
||||||
|
head :no_content
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def fetch_custom_filters
|
||||||
|
@custom_filters = current_user.custom_filters.where(
|
||||||
|
account_id: Current.account.id,
|
||||||
|
filter_type: permitted_params[:filter_type] || DEFAULT_FILTER_TYPE
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_custom_filter
|
||||||
|
@custom_filter = @custom_filters.find(permitted_params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def permitted_payload
|
||||||
|
params.require(:custom_filter).permit(
|
||||||
|
:name,
|
||||||
|
:filter_type,
|
||||||
|
query: {}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def permitted_params
|
||||||
|
params.permit(:id, :filter_type)
|
||||||
|
end
|
||||||
|
end
|
|
@ -59,6 +59,7 @@ class Account < ApplicationRecord
|
||||||
has_many :kbase_categories, dependent: :destroy, class_name: '::Kbase::Category'
|
has_many :kbase_categories, dependent: :destroy, class_name: '::Kbase::Category'
|
||||||
has_many :kbase_articles, dependent: :destroy, class_name: '::Kbase::Article'
|
has_many :kbase_articles, dependent: :destroy, class_name: '::Kbase::Article'
|
||||||
has_many :teams, dependent: :destroy
|
has_many :teams, dependent: :destroy
|
||||||
|
has_many :custom_filters, dependent: :destroy
|
||||||
has_flags ACCOUNT_SETTINGS_FLAGS.merge(column: 'settings_flags').merge(DEFAULT_QUERY_SETTING)
|
has_flags ACCOUNT_SETTINGS_FLAGS.merge(column: 'settings_flags').merge(DEFAULT_QUERY_SETTING)
|
||||||
|
|
||||||
enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_1_code], key] }.to_h
|
enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_1_code], key] }.to_h
|
||||||
|
|
24
app/models/custom_filter.rb
Normal file
24
app/models/custom_filter.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: custom_filters
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# filter_type :integer default("conversation"), not null
|
||||||
|
# name :string not null
|
||||||
|
# query :jsonb not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# account_id :bigint not null
|
||||||
|
# user_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_custom_filters_on_account_id (account_id)
|
||||||
|
# index_custom_filters_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
class CustomFilter < ApplicationRecord
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :account
|
||||||
|
|
||||||
|
enum filter_type: { conversation: 0, contact: 1, report: 2 }
|
||||||
|
end
|
|
@ -83,6 +83,7 @@ class User < ApplicationRecord
|
||||||
has_many :team_members, dependent: :destroy
|
has_many :team_members, dependent: :destroy
|
||||||
has_many :teams, through: :team_members
|
has_many :teams, through: :team_members
|
||||||
has_many :notes, dependent: :nullify
|
has_many :notes, dependent: :nullify
|
||||||
|
has_many :custom_filters, dependent: :destroy
|
||||||
|
|
||||||
before_validation :set_password_and_uid, on: :create
|
before_validation :set_password_and_uid, on: :create
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
json.partial! 'api/v1/models/custom_filter.json.jbuilder', resource: @custom_filter
|
|
@ -0,0 +1,3 @@
|
||||||
|
json.array! @custom_filters do |custom_filter|
|
||||||
|
json.partial! 'api/v1/models/custom_filter.json.jbuilder', resource: custom_filter
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
json.partial! 'api/v1/models/custom_filter.json.jbuilder', resource: @custom_filter
|
|
@ -0,0 +1 @@
|
||||||
|
json.partial! 'api/v1/models/custom_filter.json.jbuilder', resource: @custom_filter
|
6
app/views/api/v1/models/_custom_filter.json.jbuilder
Normal file
6
app/views/api/v1/models/_custom_filter.json.jbuilder
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
json.id resource.id
|
||||||
|
json.name resource.name
|
||||||
|
json.filter_type resource.filter_type
|
||||||
|
json.query resource.query
|
||||||
|
json.created_at resource.created_at
|
||||||
|
json.updated_at resource.updated_at
|
|
@ -87,7 +87,7 @@ Rails.application.routes.draw do
|
||||||
resources :labels, only: [:create, :index]
|
resources :labels, only: [:create, :index]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
resources :custom_filters, only: [:index, :show, :create, :update, :destroy]
|
||||||
resources :inboxes, only: [:index, :create, :update, :destroy] do
|
resources :inboxes, only: [:index, :create, :update, :destroy] do
|
||||||
get :assignable_agents, on: :member
|
get :assignable_agents, on: :member
|
||||||
get :campaigns, on: :member
|
get :campaigns, on: :member
|
||||||
|
|
12
db/migrate/20210623150613_create_custom_filters.rb
Normal file
12
db/migrate/20210623150613_create_custom_filters.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class CreateCustomFilters < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
create_table :custom_filters do |t|
|
||||||
|
t.string :name, null: false
|
||||||
|
t.integer :filter_type, null: false, default: 0
|
||||||
|
t.jsonb :query, null: false, default: '{}'
|
||||||
|
t.references :account, index: true, null: false
|
||||||
|
t.references :user, index: true, null: false
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
14
db/schema.rb
14
db/schema.rb
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2021_06_18_095823) do
|
ActiveRecord::Schema.define(version: 2021_06_23_150613) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_stat_statements"
|
enable_extension "pg_stat_statements"
|
||||||
|
@ -267,6 +267,18 @@ ActiveRecord::Schema.define(version: 2021_06_18_095823) do
|
||||||
t.index ["team_id"], name: "index_conversations_on_team_id"
|
t.index ["team_id"], name: "index_conversations_on_team_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "custom_filters", force: :cascade do |t|
|
||||||
|
t.string "name", null: false
|
||||||
|
t.integer "filter_type", default: 0, null: false
|
||||||
|
t.jsonb "query", default: "{}", null: false
|
||||||
|
t.bigint "account_id", null: false
|
||||||
|
t.bigint "user_id", null: false
|
||||||
|
t.datetime "created_at", precision: 6, null: false
|
||||||
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
|
t.index ["account_id"], name: "index_custom_filters_on_account_id"
|
||||||
|
t.index ["user_id"], name: "index_custom_filters_on_user_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "data_imports", force: :cascade do |t|
|
create_table "data_imports", force: :cascade do |t|
|
||||||
t.bigint "account_id", null: false
|
t.bigint "account_id", null: false
|
||||||
t.string "data_type", null: false
|
t.string "data_type", null: false
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Custom Filters API', type: :request do
|
||||||
|
let(:account) { create(:account) }
|
||||||
|
|
||||||
|
describe 'GET /api/v1/accounts/{account.id}/custom_filters' do
|
||||||
|
context 'when it is an unauthenticated user' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
get "/api/v1/accounts/#{account.id}/custom_filters"
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated user' do
|
||||||
|
let(:user) { create(:user, account: account) }
|
||||||
|
let!(:custom_filter) { create(:custom_filter, user: user, account: account) }
|
||||||
|
|
||||||
|
it 'returns all custom_filter related to the user' do
|
||||||
|
get "/api/v1/accounts/#{account.id}/custom_filters",
|
||||||
|
headers: user.create_new_auth_token,
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
response_body = JSON.parse(response.body)
|
||||||
|
expect(response_body.first['name']).to eq(custom_filter.name)
|
||||||
|
expect(response_body.first['query']).to eq(custom_filter.query)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET /api/v1/accounts/{account.id}/custom_filters/:id' do
|
||||||
|
let(:user) { create(:user, account: account) }
|
||||||
|
let!(:custom_filter) { create(:custom_filter, user: user, account: account) }
|
||||||
|
|
||||||
|
context 'when it is an unauthenticated user' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
get "/api/v1/accounts/#{account.id}/custom_filters/#{custom_filter.id}"
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated user' do
|
||||||
|
it 'shows the custom filter' do
|
||||||
|
get "/api/v1/accounts/#{account.id}/custom_filters/#{custom_filter.id}",
|
||||||
|
headers: user.create_new_auth_token,
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(response.body).to include(custom_filter.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST /api/v1/accounts/{account.id}/custom_filters' do
|
||||||
|
let(:payload) { { custom_filter: { name: 'vip-customers', filter_type: 'conversation', query: { labels: ['vip-customers'] } } } }
|
||||||
|
|
||||||
|
context 'when it is an unauthenticated user' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
expect { post "/api/v1/accounts/#{account.id}/custom_filters", params: payload }.to change(CustomFilter, :count).by(0)
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated user' do
|
||||||
|
let(:user) { create(:user, account: account) }
|
||||||
|
|
||||||
|
it 'creates the filter' do
|
||||||
|
expect do
|
||||||
|
post "/api/v1/accounts/#{account.id}/custom_filters", headers: user.create_new_auth_token,
|
||||||
|
params: payload
|
||||||
|
end.to change(CustomFilter, :count).by(1)
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
json_response = JSON.parse(response.body)
|
||||||
|
expect(json_response['name']).to eq 'vip-customers'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'PATCH /api/v1/accounts/{account.id}/custom_filters/:id' do
|
||||||
|
let(:payload) { { custom_filter: { name: 'vip-customers', filter_type: 'contact', query: { labels: ['vip-customers'] } } } }
|
||||||
|
let(:user) { create(:user, account: account) }
|
||||||
|
let!(:custom_filter) { create(:custom_filter, user: user, account: account) }
|
||||||
|
|
||||||
|
context 'when it is an unauthenticated user' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
put "/api/v1/accounts/#{account.id}/custom_filters/#{custom_filter.id}",
|
||||||
|
params: payload
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated user' do
|
||||||
|
it 'updates the custom filter' do
|
||||||
|
patch "/api/v1/accounts/#{account.id}/custom_filters/#{custom_filter.id}",
|
||||||
|
headers: user.create_new_auth_token,
|
||||||
|
params: payload,
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(custom_filter.reload.name).to eq('vip-customers')
|
||||||
|
expect(custom_filter.reload.filter_type).to eq('contact')
|
||||||
|
expect(custom_filter.reload.query['labels']).to eq(['vip-customers'])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'prevents the update of custom filter of another user/account' do
|
||||||
|
other_account = create(:account)
|
||||||
|
other_user = create(:user, account: other_account)
|
||||||
|
other_custom_filter = create(:custom_filter, user: other_user, account: other_account)
|
||||||
|
|
||||||
|
patch "/api/v1/accounts/#{account.id}/custom_filters/#{other_custom_filter.id}",
|
||||||
|
headers: user.create_new_auth_token,
|
||||||
|
params: payload,
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:not_found)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE /api/v1/accounts/{account.id}/custom_filters/:id' do
|
||||||
|
let(:user) { create(:user, account: account) }
|
||||||
|
let!(:custom_filter) { create(:custom_filter, user: user, account: account) }
|
||||||
|
|
||||||
|
context 'when it is an unauthenticated user' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
delete "/api/v1/accounts/#{account.id}/custom_filters/#{custom_filter.id}"
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated admin user' do
|
||||||
|
it 'deletes custom filter if it is attached to the current user and account' do
|
||||||
|
delete "/api/v1/accounts/#{account.id}/custom_filters/#{custom_filter.id}",
|
||||||
|
headers: user.create_new_auth_token,
|
||||||
|
as: :json
|
||||||
|
expect(response).to have_http_status(:no_content)
|
||||||
|
expect(user.custom_filters.count).to be 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
spec/factories/custom_filters.rb
Normal file
11
spec/factories/custom_filters.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :custom_filter do
|
||||||
|
sequence(:name) { |n| "Custom Filter #{n}" }
|
||||||
|
filter_type { 0 }
|
||||||
|
query { { labels: ['customer-support'], status: 'open' } }
|
||||||
|
user
|
||||||
|
account
|
||||||
|
end
|
||||||
|
end
|
|
@ -28,6 +28,8 @@ contact_inboxes:
|
||||||
$ref: ./resource/contact_inboxes.yml
|
$ref: ./resource/contact_inboxes.yml
|
||||||
contactable_inboxes:
|
contactable_inboxes:
|
||||||
$ref: ./resource/contactable_inboxes.yml
|
$ref: ./resource/contactable_inboxes.yml
|
||||||
|
custom_filter:
|
||||||
|
$ref: ./resource/custom_filter.yml
|
||||||
account:
|
account:
|
||||||
$ref: ./resource/account.yml
|
$ref: ./resource/account.yml
|
||||||
platform_account:
|
platform_account:
|
||||||
|
@ -74,6 +76,10 @@ conversation_message_create:
|
||||||
team_create_update_payload:
|
team_create_update_payload:
|
||||||
$ref: ./request/team/create_update_payload.yml
|
$ref: ./request/team/create_update_payload.yml
|
||||||
|
|
||||||
|
# Custom Filter request Payload
|
||||||
|
custom_filter_create_update_payload:
|
||||||
|
$ref: ./request/custom_filter/create_update_payload.yml
|
||||||
|
|
||||||
integrations_hook_create_payload:
|
integrations_hook_create_payload:
|
||||||
$ref: ./request/integrations/hook_create_payload.yml
|
$ref: ./request/integrations/hook_create_payload.yml
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: The name of the custom filter
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
enum: ["conversation", "contact", "report"]
|
||||||
|
description: The description about the custom filter
|
||||||
|
query:
|
||||||
|
type: object
|
||||||
|
description: A query that needs to be saved as a custom filter
|
21
swagger/definitions/resource/custom_filter.yml
Normal file
21
swagger/definitions/resource/custom_filter.yml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: number
|
||||||
|
description: The ID of the custom filter
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: The name of the custom filter
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
enum: ["conversation", "contact", "report"]
|
||||||
|
description: The description about the custom filter
|
||||||
|
query:
|
||||||
|
type: object
|
||||||
|
description: A query that needs to be saved as a custom filter
|
||||||
|
created_at:
|
||||||
|
type: datetime
|
||||||
|
description: The time at which the custom filter was created
|
||||||
|
updated_at:
|
||||||
|
type: datetime
|
||||||
|
description: The time at which the custom filter was updated
|
|
@ -10,7 +10,7 @@ info:
|
||||||
name: MIT License
|
name: MIT License
|
||||||
url: https://opensource.org/licenses/MIT
|
url: https://opensource.org/licenses/MIT
|
||||||
host: app.chatwoot.com
|
host: app.chatwoot.com
|
||||||
basePath:
|
basePath:
|
||||||
schemes:
|
schemes:
|
||||||
- https
|
- https
|
||||||
produces:
|
produces:
|
||||||
|
@ -62,8 +62,9 @@ x-tagGroups:
|
||||||
- Integrations
|
- Integrations
|
||||||
- Profile
|
- Profile
|
||||||
- Teams
|
- Teams
|
||||||
|
- Custom Filter
|
||||||
- name: Public
|
- name: Public
|
||||||
tags:
|
tags:
|
||||||
- Contacts API
|
- Contacts API
|
||||||
- Conversations API
|
- Conversations API
|
||||||
- Messages API
|
- Messages API
|
||||||
|
|
6
swagger/parameters/custom_filter_id.yml
Normal file
6
swagger/parameters/custom_filter_id.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
in: path
|
||||||
|
name: custom_filter_id
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
required: true
|
||||||
|
description: The numeric ID of the custom filter
|
|
@ -28,9 +28,11 @@ page:
|
||||||
platform_user_id:
|
platform_user_id:
|
||||||
$ref: ./platform_user_id.yml
|
$ref: ./platform_user_id.yml
|
||||||
|
|
||||||
|
custom_filter_id:
|
||||||
|
$ref: ./custom_filter_id.yml
|
||||||
|
|
||||||
public_inbox_identifier:
|
public_inbox_identifier:
|
||||||
$ref: ./public/inbox_identifier.yml
|
$ref: ./public/inbox_identifier.yml
|
||||||
|
|
||||||
public_contact_identifier:
|
public_contact_identifier:
|
||||||
$ref: ./public/contact_identifier.yml
|
$ref: ./public/contact_identifier.yml
|
||||||
|
|
19
swagger/paths/custom_filters/create.yml
Normal file
19
swagger/paths/custom_filters/create.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
tags:
|
||||||
|
- Custom Filter
|
||||||
|
operationId: create-a-custom-filter
|
||||||
|
summary: Create a custom filter
|
||||||
|
description: Create a custom filter in the account
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/account_id'
|
||||||
|
- name: data
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/custom_filter_create_update_payload'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/custom_filter'
|
||||||
|
401:
|
||||||
|
description: Unauthorized
|
12
swagger/paths/custom_filters/delete.yml
Normal file
12
swagger/paths/custom_filters/delete.yml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
tags:
|
||||||
|
- Custom Filter
|
||||||
|
operationId: delete-a-custom-filter
|
||||||
|
summary: Delete a custom filter
|
||||||
|
description: Delete a custom filter from the account
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
401:
|
||||||
|
description: Unauthorized
|
||||||
|
404:
|
||||||
|
description: The custom filter does not exist in the account
|
15
swagger/paths/custom_filters/index.yml
Normal file
15
swagger/paths/custom_filters/index.yml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
tags:
|
||||||
|
- Custom Filter
|
||||||
|
operationId: list-all-filters
|
||||||
|
summary: List all custom filters
|
||||||
|
description: List all custom filters in a category of a user
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
description: 'Array of custom filters'
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/custom_filter'
|
||||||
|
401:
|
||||||
|
description: Unauthorized
|
14
swagger/paths/custom_filters/show.yml
Normal file
14
swagger/paths/custom_filters/show.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
tags:
|
||||||
|
- Custom Filter
|
||||||
|
operationId: get-details-of-a-single-custom-filter
|
||||||
|
summary: Get a custom filter details
|
||||||
|
description: Get the details of a custom filter in the account
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/custom_filter'
|
||||||
|
401:
|
||||||
|
description: Unauthorized
|
||||||
|
404:
|
||||||
|
description: The given team ID does not exist in the account
|
18
swagger/paths/custom_filters/update.yml
Normal file
18
swagger/paths/custom_filters/update.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
tags:
|
||||||
|
- Custom Filter
|
||||||
|
operationId: update-a-custom-filter
|
||||||
|
summary: Update a custom filter
|
||||||
|
description: Update a custom filter's attributes
|
||||||
|
parameters:
|
||||||
|
- name: data
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/custom_filter_create_update_payload'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/custom_filter'
|
||||||
|
401:
|
||||||
|
description: Unauthorized
|
|
@ -92,7 +92,7 @@ public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversat
|
||||||
- $ref: '#/parameters/public_contact_identifier'
|
- $ref: '#/parameters/public_contact_identifier'
|
||||||
post:
|
post:
|
||||||
$ref: ./public/inboxes/conversations/create.yml
|
$ref: ./public/inboxes/conversations/create.yml
|
||||||
get:
|
get:
|
||||||
$ref: ./public/inboxes/conversations/index.yml
|
$ref: ./public/inboxes/conversations/index.yml
|
||||||
|
|
||||||
public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations/{conversation_id}/messages:
|
public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations/{conversation_id}/messages:
|
||||||
|
@ -102,7 +102,7 @@ public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversat
|
||||||
- $ref: '#/parameters/conversation_id'
|
- $ref: '#/parameters/conversation_id'
|
||||||
post:
|
post:
|
||||||
$ref: ./public/inboxes/messages/create.yml
|
$ref: ./public/inboxes/messages/create.yml
|
||||||
get:
|
get:
|
||||||
$ref: ./public/inboxes/messages/index.yml
|
$ref: ./public/inboxes/messages/index.yml
|
||||||
public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations/{conversation_id}/messages/{message_id}:
|
public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations/{conversation_id}/messages/{message_id}:
|
||||||
parameters:
|
parameters:
|
||||||
|
@ -264,3 +264,31 @@ public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversat
|
||||||
$ref: ./teams/update.yml
|
$ref: ./teams/update.yml
|
||||||
delete:
|
delete:
|
||||||
$ref: ./teams/delete.yml
|
$ref: ./teams/delete.yml
|
||||||
|
|
||||||
|
### Custom Filters
|
||||||
|
|
||||||
|
# Teams
|
||||||
|
/api/v1/accounts/{account_id}/custom_filters:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/account_id'
|
||||||
|
- in: query
|
||||||
|
name: filter_type
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: ['conversation', 'contact', 'report']
|
||||||
|
required: false
|
||||||
|
description: The type of custom filter
|
||||||
|
get:
|
||||||
|
$ref: ./custom_filters/index.yml
|
||||||
|
post:
|
||||||
|
$ref: ./custom_filters/create.yml
|
||||||
|
/api/v1/accounts/{account_id}/custom_filters/{custom_filter_id}:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/account_id'
|
||||||
|
- $ref: '#/parameters/custom_filter_id'
|
||||||
|
get:
|
||||||
|
$ref: './custom_filters/show.yml'
|
||||||
|
patch:
|
||||||
|
$ref: ./custom_filters/update.yml
|
||||||
|
delete:
|
||||||
|
$ref: ./custom_filters/delete.yml
|
||||||
|
|
|
@ -2527,6 +2527,162 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/accounts/{account_id}/custom_filters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/account_id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "filter_type",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"conversation",
|
||||||
|
"contact",
|
||||||
|
"report"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"required": false,
|
||||||
|
"description": "The type of custom filter"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Custom Filter"
|
||||||
|
],
|
||||||
|
"operationId": "list-all-filters",
|
||||||
|
"summary": "List all custom filters",
|
||||||
|
"description": "List all custom filters in a category of a user",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Array of custom filters",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/custom_filter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Custom Filter"
|
||||||
|
],
|
||||||
|
"operationId": "create-a-custom-filter",
|
||||||
|
"summary": "Create a custom filter",
|
||||||
|
"description": "Create a custom filter in the account",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/account_id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "data",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/custom_filter_create_update_payload"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/custom_filter"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/accounts/{account_id}/custom_filters/{custom_filter_id}": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/account_id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/custom_filter_id"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Custom Filter"
|
||||||
|
],
|
||||||
|
"operationId": "get-details-of-a-single-custom-filter",
|
||||||
|
"summary": "Get a custom filter details",
|
||||||
|
"description": "Get the details of a custom filter in the account",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/custom_filter"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "The given team ID does not exist in the account"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patch": {
|
||||||
|
"tags": [
|
||||||
|
"Custom Filter"
|
||||||
|
],
|
||||||
|
"operationId": "update-a-custom-filter",
|
||||||
|
"summary": "Update a custom filter",
|
||||||
|
"description": "Update a custom filter's attributes",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "data",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/custom_filter_create_update_payload"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/custom_filter"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"Custom Filter"
|
||||||
|
],
|
||||||
|
"operationId": "delete-a-custom-filter",
|
||||||
|
"summary": "Delete a custom filter",
|
||||||
|
"description": "Delete a custom filter from the account",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success"
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "The custom filter does not exist in the account"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
@ -2846,6 +3002,40 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"custom_filter": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The ID of the custom filter"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of the custom filter"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"conversation",
|
||||||
|
"contact",
|
||||||
|
"report"
|
||||||
|
],
|
||||||
|
"description": "The description about the custom filter"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "A query that needs to be saved as a custom filter"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "datetime",
|
||||||
|
"description": "The time at which the custom filter was created"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "datetime",
|
||||||
|
"description": "The time at which the custom filter was updated"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"account": {
|
"account": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -3191,6 +3381,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"custom_filter_create_update_payload": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of the custom filter"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"conversation",
|
||||||
|
"contact",
|
||||||
|
"report"
|
||||||
|
],
|
||||||
|
"description": "The description about the custom filter"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "A query that needs to be saved as a custom filter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"integrations_hook_create_payload": {
|
"integrations_hook_create_payload": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -3643,6 +3855,15 @@
|
||||||
"required": true,
|
"required": true,
|
||||||
"description": "The numeric ID of the user on the platform"
|
"description": "The numeric ID of the user on the platform"
|
||||||
},
|
},
|
||||||
|
"custom_filter_id": {
|
||||||
|
"in": "path",
|
||||||
|
"name": "custom_filter_id",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"description": "The numeric ID of the custom filter"
|
||||||
|
},
|
||||||
"public_inbox_identifier": {
|
"public_inbox_identifier": {
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"name": "inbox_identifier",
|
"name": "inbox_identifier",
|
||||||
|
@ -3684,7 +3905,8 @@
|
||||||
"Messages",
|
"Messages",
|
||||||
"Integrations",
|
"Integrations",
|
||||||
"Profile",
|
"Profile",
|
||||||
"Teams"
|
"Teams",
|
||||||
|
"Custom Filter"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue