From 30832d8a34e97b753b6c0d959d6f902e949c3f72 Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Tue, 29 Jun 2021 19:29:57 +0530 Subject: [PATCH] feat: Add APIs to create custom views on the dashboard (#2498) --- .../v1/accounts/custom_filters_controller.rb | 50 ++++ app/models/account.rb | 1 + app/models/custom_filter.rb | 24 ++ app/models/user.rb | 1 + .../custom_filters/create.json.jbuilder | 1 + .../custom_filters/index.json.jbuilder | 3 + .../custom_filters/show.json.jbuilder | 1 + .../custom_filters/update.json.jbuilder | 1 + .../v1/models/_custom_filter.json.jbuilder | 6 + config/routes.rb | 2 +- .../20210623150613_create_custom_filters.rb | 12 + db/schema.rb | 14 +- .../custom_filters_controller_spec.rb | 146 ++++++++++++ spec/factories/custom_filters.rb | 11 + swagger/definitions/index.yml | 6 + .../custom_filter/create_update_payload.yml | 12 + .../definitions/resource/custom_filter.yml | 21 ++ swagger/index.yml | 7 +- swagger/parameters/custom_filter_id.yml | 6 + swagger/parameters/index.yml | 4 +- swagger/paths/custom_filters/create.yml | 19 ++ swagger/paths/custom_filters/delete.yml | 12 + swagger/paths/custom_filters/index.yml | 15 ++ swagger/paths/custom_filters/show.yml | 14 ++ swagger/paths/custom_filters/update.yml | 18 ++ swagger/paths/index.yml | 32 ++- swagger/swagger.json | 224 +++++++++++++++++- 27 files changed, 654 insertions(+), 9 deletions(-) create mode 100644 app/controllers/api/v1/accounts/custom_filters_controller.rb create mode 100644 app/models/custom_filter.rb create mode 100644 app/views/api/v1/accounts/custom_filters/create.json.jbuilder create mode 100644 app/views/api/v1/accounts/custom_filters/index.json.jbuilder create mode 100644 app/views/api/v1/accounts/custom_filters/show.json.jbuilder create mode 100644 app/views/api/v1/accounts/custom_filters/update.json.jbuilder create mode 100644 app/views/api/v1/models/_custom_filter.json.jbuilder create mode 100644 db/migrate/20210623150613_create_custom_filters.rb create mode 100644 spec/controllers/api/v1/accounts/custom_filters_controller_spec.rb create mode 100644 spec/factories/custom_filters.rb create mode 100644 swagger/definitions/request/custom_filter/create_update_payload.yml create mode 100644 swagger/definitions/resource/custom_filter.yml create mode 100644 swagger/parameters/custom_filter_id.yml create mode 100644 swagger/paths/custom_filters/create.yml create mode 100644 swagger/paths/custom_filters/delete.yml create mode 100644 swagger/paths/custom_filters/index.yml create mode 100644 swagger/paths/custom_filters/show.yml create mode 100644 swagger/paths/custom_filters/update.yml diff --git a/app/controllers/api/v1/accounts/custom_filters_controller.rb b/app/controllers/api/v1/accounts/custom_filters_controller.rb new file mode 100644 index 000000000..169b6cd1e --- /dev/null +++ b/app/controllers/api/v1/accounts/custom_filters_controller.rb @@ -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 diff --git a/app/models/account.rb b/app/models/account.rb index 57d1b88c4..e042b7a95 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -59,6 +59,7 @@ class Account < ApplicationRecord has_many :kbase_categories, dependent: :destroy, class_name: '::Kbase::Category' has_many :kbase_articles, dependent: :destroy, class_name: '::Kbase::Article' has_many :teams, dependent: :destroy + has_many :custom_filters, dependent: :destroy 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 diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb new file mode 100644 index 000000000..e506edc5a --- /dev/null +++ b/app/models/custom_filter.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 3fc8d7668..d8d5931e1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -83,6 +83,7 @@ class User < ApplicationRecord has_many :team_members, dependent: :destroy has_many :teams, through: :team_members has_many :notes, dependent: :nullify + has_many :custom_filters, dependent: :destroy before_validation :set_password_and_uid, on: :create diff --git a/app/views/api/v1/accounts/custom_filters/create.json.jbuilder b/app/views/api/v1/accounts/custom_filters/create.json.jbuilder new file mode 100644 index 000000000..085761e41 --- /dev/null +++ b/app/views/api/v1/accounts/custom_filters/create.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'api/v1/models/custom_filter.json.jbuilder', resource: @custom_filter diff --git a/app/views/api/v1/accounts/custom_filters/index.json.jbuilder b/app/views/api/v1/accounts/custom_filters/index.json.jbuilder new file mode 100644 index 000000000..0fc3e67b4 --- /dev/null +++ b/app/views/api/v1/accounts/custom_filters/index.json.jbuilder @@ -0,0 +1,3 @@ +json.array! @custom_filters do |custom_filter| + json.partial! 'api/v1/models/custom_filter.json.jbuilder', resource: custom_filter +end diff --git a/app/views/api/v1/accounts/custom_filters/show.json.jbuilder b/app/views/api/v1/accounts/custom_filters/show.json.jbuilder new file mode 100644 index 000000000..085761e41 --- /dev/null +++ b/app/views/api/v1/accounts/custom_filters/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'api/v1/models/custom_filter.json.jbuilder', resource: @custom_filter diff --git a/app/views/api/v1/accounts/custom_filters/update.json.jbuilder b/app/views/api/v1/accounts/custom_filters/update.json.jbuilder new file mode 100644 index 000000000..085761e41 --- /dev/null +++ b/app/views/api/v1/accounts/custom_filters/update.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'api/v1/models/custom_filter.json.jbuilder', resource: @custom_filter diff --git a/app/views/api/v1/models/_custom_filter.json.jbuilder b/app/views/api/v1/models/_custom_filter.json.jbuilder new file mode 100644 index 000000000..473f2d2c2 --- /dev/null +++ b/app/views/api/v1/models/_custom_filter.json.jbuilder @@ -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 diff --git a/config/routes.rb b/config/routes.rb index 82876ceba..60898723c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -87,7 +87,7 @@ Rails.application.routes.draw do resources :labels, only: [:create, :index] end end - + resources :custom_filters, only: [:index, :show, :create, :update, :destroy] resources :inboxes, only: [:index, :create, :update, :destroy] do get :assignable_agents, on: :member get :campaigns, on: :member diff --git a/db/migrate/20210623150613_create_custom_filters.rb b/db/migrate/20210623150613_create_custom_filters.rb new file mode 100644 index 000000000..fe9d920ce --- /dev/null +++ b/db/migrate/20210623150613_create_custom_filters.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 2e93206de..232aba915 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # 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 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" 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| t.bigint "account_id", null: false t.string "data_type", null: false diff --git a/spec/controllers/api/v1/accounts/custom_filters_controller_spec.rb b/spec/controllers/api/v1/accounts/custom_filters_controller_spec.rb new file mode 100644 index 000000000..76798898f --- /dev/null +++ b/spec/controllers/api/v1/accounts/custom_filters_controller_spec.rb @@ -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 diff --git a/spec/factories/custom_filters.rb b/spec/factories/custom_filters.rb new file mode 100644 index 000000000..009e4094f --- /dev/null +++ b/spec/factories/custom_filters.rb @@ -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 diff --git a/swagger/definitions/index.yml b/swagger/definitions/index.yml index 56aeeef2b..a330326bf 100644 --- a/swagger/definitions/index.yml +++ b/swagger/definitions/index.yml @@ -28,6 +28,8 @@ contact_inboxes: $ref: ./resource/contact_inboxes.yml contactable_inboxes: $ref: ./resource/contactable_inboxes.yml +custom_filter: + $ref: ./resource/custom_filter.yml account: $ref: ./resource/account.yml platform_account: @@ -74,6 +76,10 @@ conversation_message_create: team_create_update_payload: $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: $ref: ./request/integrations/hook_create_payload.yml diff --git a/swagger/definitions/request/custom_filter/create_update_payload.yml b/swagger/definitions/request/custom_filter/create_update_payload.yml new file mode 100644 index 000000000..86a6cd8c1 --- /dev/null +++ b/swagger/definitions/request/custom_filter/create_update_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 diff --git a/swagger/definitions/resource/custom_filter.yml b/swagger/definitions/resource/custom_filter.yml new file mode 100644 index 000000000..130377d62 --- /dev/null +++ b/swagger/definitions/resource/custom_filter.yml @@ -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 diff --git a/swagger/index.yml b/swagger/index.yml index c0e36a5ec..2010f1de6 100644 --- a/swagger/index.yml +++ b/swagger/index.yml @@ -10,7 +10,7 @@ info: name: MIT License url: https://opensource.org/licenses/MIT host: app.chatwoot.com -basePath: +basePath: schemes: - https produces: @@ -62,8 +62,9 @@ x-tagGroups: - Integrations - Profile - Teams + - Custom Filter - name: Public - tags: + tags: - Contacts API - Conversations API - - Messages API \ No newline at end of file + - Messages API diff --git a/swagger/parameters/custom_filter_id.yml b/swagger/parameters/custom_filter_id.yml new file mode 100644 index 000000000..46776511f --- /dev/null +++ b/swagger/parameters/custom_filter_id.yml @@ -0,0 +1,6 @@ +in: path +name: custom_filter_id +schema: + type: integer +required: true +description: The numeric ID of the custom filter diff --git a/swagger/parameters/index.yml b/swagger/parameters/index.yml index 3e123b868..4926fe166 100644 --- a/swagger/parameters/index.yml +++ b/swagger/parameters/index.yml @@ -28,9 +28,11 @@ page: platform_user_id: $ref: ./platform_user_id.yml +custom_filter_id: + $ref: ./custom_filter_id.yml public_inbox_identifier: $ref: ./public/inbox_identifier.yml public_contact_identifier: - $ref: ./public/contact_identifier.yml \ No newline at end of file + $ref: ./public/contact_identifier.yml diff --git a/swagger/paths/custom_filters/create.yml b/swagger/paths/custom_filters/create.yml new file mode 100644 index 000000000..6fbc4c7f8 --- /dev/null +++ b/swagger/paths/custom_filters/create.yml @@ -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 diff --git a/swagger/paths/custom_filters/delete.yml b/swagger/paths/custom_filters/delete.yml new file mode 100644 index 000000000..3ae042e9b --- /dev/null +++ b/swagger/paths/custom_filters/delete.yml @@ -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 diff --git a/swagger/paths/custom_filters/index.yml b/swagger/paths/custom_filters/index.yml new file mode 100644 index 000000000..b66e7b6f8 --- /dev/null +++ b/swagger/paths/custom_filters/index.yml @@ -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 diff --git a/swagger/paths/custom_filters/show.yml b/swagger/paths/custom_filters/show.yml new file mode 100644 index 000000000..e2e2bf529 --- /dev/null +++ b/swagger/paths/custom_filters/show.yml @@ -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 diff --git a/swagger/paths/custom_filters/update.yml b/swagger/paths/custom_filters/update.yml new file mode 100644 index 000000000..23ff97781 --- /dev/null +++ b/swagger/paths/custom_filters/update.yml @@ -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 diff --git a/swagger/paths/index.yml b/swagger/paths/index.yml index b358d307e..0d3791fa9 100644 --- a/swagger/paths/index.yml +++ b/swagger/paths/index.yml @@ -92,7 +92,7 @@ public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversat - $ref: '#/parameters/public_contact_identifier' post: $ref: ./public/inboxes/conversations/create.yml - get: + get: $ref: ./public/inboxes/conversations/index.yml 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' post: $ref: ./public/inboxes/messages/create.yml - get: + get: $ref: ./public/inboxes/messages/index.yml public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations/{conversation_id}/messages/{message_id}: parameters: @@ -264,3 +264,31 @@ public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversat $ref: ./teams/update.yml delete: $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 diff --git a/swagger/swagger.json b/swagger/swagger.json index 60ab58b48..8ad079bd0 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -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": { @@ -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": { "type": "object", "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": { "type": "object", "properties": { @@ -3643,6 +3855,15 @@ "required": true, "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": { "in": "path", "name": "inbox_identifier", @@ -3684,7 +3905,8 @@ "Messages", "Integrations", "Profile", - "Teams" + "Teams", + "Custom Filter" ] }, {