Chore: APIs for agent bots (#676)

Co-authored-by: Pranav Raj Sreepuram <pranavrajs@gmail.com>
This commit is contained in:
Sojan Jose 2020-04-07 10:41:18 +05:30 committed by GitHub
parent 4feca1d88d
commit 1cfa756d49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 277 additions and 3 deletions

View file

@ -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

View 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

View file

@ -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?

View file

@ -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

View file

@ -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]

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View 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

View 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

View 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

View file

@ -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:

View file

@ -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": [
{ {