Chore: APIs for agent bots (#676)
Co-authored-by: Pranav Raj Sreepuram <pranavrajs@gmail.com>
This commit is contained in:
parent
4feca1d88d
commit
1cfa756d49
14 changed files with 277 additions and 3 deletions
|
@ -1,6 +1,7 @@
|
||||||
class Api::V1::Accounts::InboxesController < Api::BaseController
|
class Api::V1::Accounts::InboxesController < Api::BaseController
|
||||||
before_action :check_authorization
|
before_action :check_authorization
|
||||||
before_action :fetch_inbox, only: [:destroy, :update]
|
before_action :fetch_inbox, except: [:index]
|
||||||
|
before_action :fetch_agent_bot, only: [:set_agent_bot]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@inboxes = policy_scope(current_account.inboxes)
|
@inboxes = policy_scope(current_account.inboxes)
|
||||||
|
@ -10,6 +11,17 @@ class Api::V1::Accounts::InboxesController < Api::BaseController
|
||||||
@inbox.update(inbox_update_params)
|
@inbox.update(inbox_update_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_agent_bot
|
||||||
|
if @agent_bot
|
||||||
|
agent_bot_inbox = @inbox.agent_bot_inbox || AgentBotInbox.new(inbox: @inbox)
|
||||||
|
agent_bot_inbox.agent_bot = @agent_bot
|
||||||
|
agent_bot_inbox.save!
|
||||||
|
elsif @inbox.agent_bot_inbox.present?
|
||||||
|
@inbox.agent_bot_inbox.destroy!
|
||||||
|
end
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@inbox.destroy
|
@inbox.destroy
|
||||||
head :ok
|
head :ok
|
||||||
|
@ -21,6 +33,10 @@ class Api::V1::Accounts::InboxesController < Api::BaseController
|
||||||
@inbox = current_account.inboxes.find(params[:id])
|
@inbox = current_account.inboxes.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch_agent_bot
|
||||||
|
@agent_bot = AgentBot.find(params[:agent_bot]) if params[:agent_bot]
|
||||||
|
end
|
||||||
|
|
||||||
def check_authorization
|
def check_authorization
|
||||||
authorize(Inbox)
|
authorize(Inbox)
|
||||||
end
|
end
|
||||||
|
|
8
app/controllers/api/v1/agent_bots_controller.rb
Normal file
8
app/controllers/api/v1/agent_bots_controller.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
class Api::V1::AgentBotsController < Api::BaseController
|
||||||
|
skip_before_action :authenticate_user!
|
||||||
|
skip_before_action :check_subscription
|
||||||
|
|
||||||
|
def index
|
||||||
|
render json: AgentBot.all
|
||||||
|
end
|
||||||
|
end
|
|
@ -38,6 +38,7 @@ class Inbox < ApplicationRecord
|
||||||
has_many :messages, through: :conversations
|
has_many :messages, through: :conversations
|
||||||
|
|
||||||
has_one :agent_bot_inbox, dependent: :destroy
|
has_one :agent_bot_inbox, dependent: :destroy
|
||||||
|
has_one :agent_bot, through: :agent_bot_inbox
|
||||||
has_many :webhooks, dependent: :destroy
|
has_many :webhooks, dependent: :destroy
|
||||||
|
|
||||||
after_create :subscribe_webhook, if: :facebook?
|
after_create :subscribe_webhook, if: :facebook?
|
||||||
|
|
|
@ -31,4 +31,8 @@ class InboxPolicy < ApplicationPolicy
|
||||||
def destroy?
|
def destroy?
|
||||||
@user.administrator?
|
@user.administrator?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_agent_bot?
|
||||||
|
@user.administrator?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -65,7 +65,9 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :inboxes, only: [:index, :destroy, :update]
|
resources :inboxes, only: [:index, :destroy, :update] do
|
||||||
|
post :set_agent_bot, on: :member
|
||||||
|
end
|
||||||
resources :inbox_members, only: [:create, :show], param: :inbox_id
|
resources :inbox_members, only: [:create, :show], param: :inbox_id
|
||||||
resources :labels, only: [:index] do
|
resources :labels, only: [:index] do
|
||||||
collection do
|
collection do
|
||||||
|
@ -104,6 +106,8 @@ Rails.application.routes.draw do
|
||||||
|
|
||||||
resource :profile, only: [:show, :update]
|
resource :profile, only: [:show, :update]
|
||||||
|
|
||||||
|
resources :agent_bots, only: [:index]
|
||||||
|
|
||||||
namespace :widget do
|
namespace :widget do
|
||||||
resource :contact, only: [:update]
|
resource :contact, only: [:update]
|
||||||
resources :inbox_members, only: [:index]
|
resources :inbox_members, only: [:index]
|
||||||
|
|
|
@ -138,4 +138,62 @@ RSpec.describe 'Inboxes API', type: :request do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'POST /api/v1/accounts/{account.id}/inboxes/:id/set_agent_bot' do
|
||||||
|
let(:inbox) { create(:inbox, account: account) }
|
||||||
|
let(:agent_bot) { create(:agent_bot) }
|
||||||
|
|
||||||
|
context 'when it is an unauthenticated user' do
|
||||||
|
it 'returns unauthorized' do
|
||||||
|
post "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/set_agent_bot"
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it is an authenticated user' do
|
||||||
|
let(:admin) { create(:user, account: account, role: :administrator) }
|
||||||
|
let(:valid_params) { { agent_bot: agent_bot.id } }
|
||||||
|
|
||||||
|
it 'sets the agent bot' do
|
||||||
|
post "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/set_agent_bot",
|
||||||
|
headers: admin.create_new_auth_token,
|
||||||
|
params: valid_params,
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(inbox.reload.agent_bot.id).to eq agent_bot.id
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'throw error when invalid agent bot id' do
|
||||||
|
post "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/set_agent_bot",
|
||||||
|
headers: admin.create_new_auth_token,
|
||||||
|
params: { agent_bot: 0 },
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:not_found)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'disconnects the agent bot' do
|
||||||
|
post "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/set_agent_bot",
|
||||||
|
headers: admin.create_new_auth_token,
|
||||||
|
params: { agent_bot: nil },
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(inbox.reload.agent_bot).to be_falsey
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'will not update agent bot when its an agent' do
|
||||||
|
agent = create(:user, account: account, role: :agent)
|
||||||
|
|
||||||
|
post "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/set_agent_bot",
|
||||||
|
headers: agent.create_new_auth_token,
|
||||||
|
params: valid_params,
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
17
spec/controllers/api/v1/agent_bots_controller_spec.rb
Normal file
17
spec/controllers/api/v1/agent_bots_controller_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Profile API', type: :request do
|
||||||
|
let!(:agent_bot1) { create(:agent_bot) }
|
||||||
|
let!(:agent_bot2) { create(:agent_bot) }
|
||||||
|
|
||||||
|
describe 'GET /api/v1/agent_bots' do
|
||||||
|
it 'returns all the agent bots in the system' do
|
||||||
|
get '/api/v1/agent_bots',
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(response.body).to include(agent_bot1.name)
|
||||||
|
expect(response.body).to include(agent_bot2.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,7 @@ RSpec.describe InboxPolicy, type: :policy do
|
||||||
let(:agent) { create(:user, account: account) }
|
let(:agent) { create(:user, account: account) }
|
||||||
let(:inbox) { create(:inbox) }
|
let(:inbox) { create(:inbox) }
|
||||||
|
|
||||||
permissions :create?, :destroy? do
|
permissions :create?, :destroy?, :update?, :set_agent_bot? do
|
||||||
context 'when administrator' do
|
context 'when administrator' do
|
||||||
it { expect(inbox_policy).to permit(administrator, inbox) }
|
it { expect(inbox_policy).to permit(administrator, inbox) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,6 +17,8 @@ user:
|
||||||
$ref: ./resource/user.yml
|
$ref: ./resource/user.yml
|
||||||
inbox:
|
inbox:
|
||||||
$ref: ./resource/inbox.yml
|
$ref: ./resource/inbox.yml
|
||||||
|
agent_bot:
|
||||||
|
$ref: ./resource/agent_bot.yml
|
||||||
# RESPONSE
|
# RESPONSE
|
||||||
|
|
||||||
## contact
|
## contact
|
||||||
|
|
14
swagger/definitions/resource/agent_bot.yml
Normal file
14
swagger/definitions/resource/agent_bot.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: number
|
||||||
|
description: ID of the agent bot
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
description: The description about the agent bot
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: The name of the agent bot
|
||||||
|
outgoing_url:
|
||||||
|
type: string
|
||||||
|
description: The webhook URL for the bot
|
17
swagger/paths/agent_bots/index.yml
Normal file
17
swagger/paths/agent_bots/index.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- AgentBot
|
||||||
|
operationId: listAgentBots
|
||||||
|
summary: List all agentbots
|
||||||
|
description: List all available agentbots for the current installation
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
schema:
|
||||||
|
type: Array
|
||||||
|
description: 'List of agent bots'
|
||||||
|
$ref: '#/definitions/agent_bot'
|
||||||
|
404:
|
||||||
|
description: Inbox not found, Agent bot not found
|
||||||
|
403:
|
||||||
|
description: Access denied
|
29
swagger/paths/inboxes/set_agent_bot.yml
Normal file
29
swagger/paths/inboxes/set_agent_bot.yml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Inbox
|
||||||
|
operationId: updateAgentBot
|
||||||
|
summary: Add or remove agent bot
|
||||||
|
description: To add an agent bot pass agent_bot id, to remove agent bot from an inbox pass null
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
type: number
|
||||||
|
description: ID of the inbox
|
||||||
|
required: true
|
||||||
|
- name: data
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
agent_bot:
|
||||||
|
type: number
|
||||||
|
required: true
|
||||||
|
description: 'Agent bot ID'
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: Success
|
||||||
|
404:
|
||||||
|
description: Inbox not found, Agent bot not found
|
||||||
|
403:
|
||||||
|
description: Access denied
|
|
@ -9,6 +9,12 @@
|
||||||
$ref: ./inboxes/index.yml
|
$ref: ./inboxes/index.yml
|
||||||
/accounts/{account_id}/inboxes/{id}:
|
/accounts/{account_id}/inboxes/{id}:
|
||||||
$ref: ./inboxes/update.yml
|
$ref: ./inboxes/update.yml
|
||||||
|
/accounts/{account_id}/inboxes/{id}/set_agent_bot:
|
||||||
|
$ref: ./inboxes/update.yml
|
||||||
|
|
||||||
|
/agent_bots:
|
||||||
|
$ref: ./agent_bots/index.yml
|
||||||
|
|
||||||
|
|
||||||
# Conversations
|
# Conversations
|
||||||
/accounts/{account_id}/conversations:
|
/accounts/{account_id}/conversations:
|
||||||
|
|
|
@ -200,6 +200,83 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/accounts/{account_id}/inboxes/{id}/set_agent_bot": {
|
||||||
|
"patch": {
|
||||||
|
"tags": [
|
||||||
|
"Inbox"
|
||||||
|
],
|
||||||
|
"operationId": "updateInbox",
|
||||||
|
"summary": "Update Inbox",
|
||||||
|
"description": "Add avatar and disable auto assignment for an inbox",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"type": "number",
|
||||||
|
"description": "ID of the inbox",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "data",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enable_auto_assignment": {
|
||||||
|
"type": "boolean",
|
||||||
|
"required": true,
|
||||||
|
"description": "Enable Auto Assignment"
|
||||||
|
},
|
||||||
|
"avatar": {
|
||||||
|
"type": "file",
|
||||||
|
"required": false,
|
||||||
|
"description": "Image file for avatar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/inbox"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Inbox not found"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Access denied"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/agent_bots": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"AgentBot"
|
||||||
|
],
|
||||||
|
"operationId": "listAgentBots",
|
||||||
|
"summary": "List all agentbots",
|
||||||
|
"description": "List all available agentbots for the current installation",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/agent_bot"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Inbox not found, Agent bot not found"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Access denied"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/accounts/{account_id}/conversations": {
|
"/accounts/{account_id}/conversations": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
@ -942,6 +1019,27 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"agent_bot": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "ID of the agent bot"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The description about the agent bot"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of the agent bot"
|
||||||
|
},
|
||||||
|
"outgoing_url": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The webhook URL for the bot"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"extended_contact": {
|
"extended_contact": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue