249 lines
8.1 KiB
Go
249 lines
8.1 KiB
Go
package v1
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
"github.com/gochat/gochat/internal/repository"
|
|
"github.com/gochat/gochat/pkg/response"
|
|
)
|
|
|
|
// PlatformAgentBotHandler handles Platform API agent bot endpoints (AccessToken auth).
|
|
// Reference: Chatwoot Platform::Api::V1::AgentBotsController — AccessToken authenticated
|
|
//
|
|
// Distinct from account-level AgentBotHandler: this uses AccessToken authentication
|
|
// + Permissible system for resource-level access control.
|
|
// Platform-level bots (account_id == nil) and account-scoped bots are both accessible.
|
|
type PlatformAgentBotHandler struct {
|
|
agentBotRepo *repository.AgentBotRepo
|
|
permissibleRepo *repository.PermissibleRepo
|
|
}
|
|
|
|
// NewPlatformAgentBotHandler creates a new PlatformAgentBot handler.
|
|
func NewPlatformAgentBotHandler(
|
|
agentBotRepo *repository.AgentBotRepo,
|
|
permissibleRepo *repository.PermissibleRepo,
|
|
) *PlatformAgentBotHandler {
|
|
return &PlatformAgentBotHandler{
|
|
agentBotRepo: agentBotRepo,
|
|
permissibleRepo: permissibleRepo,
|
|
}
|
|
}
|
|
|
|
// List returns all agent bots the PlatformApp has permissible access to.
|
|
// GET /platform/api/v1/agent_bots
|
|
// Reference: Chatwoot Platform::Api::V1::AgentBotsController#index
|
|
func (h *PlatformAgentBotHandler) List(c *gin.Context) {
|
|
platformAppID := getPlatformAppID(c)
|
|
|
|
permissibles, err := h.permissibleRepo.FindByPlatformAppID(c.Request.Context(), platformAppID)
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, err.Error())
|
|
return
|
|
}
|
|
|
|
var bots []model.AgentBot
|
|
for _, perm := range permissibles {
|
|
if perm.PermissibleType == model.PermissibleTypeAgentBot {
|
|
bot, err := h.agentBotRepo.FindByID(c.Request.Context(), perm.PermissibleID)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
bots = append(bots, *bot)
|
|
}
|
|
}
|
|
|
|
response.OK(c, bots)
|
|
}
|
|
|
|
// Show retrieves an agent bot by ID.
|
|
// GET /platform/api/v1/agent_bots/:id
|
|
// Reference: Chatwoot Platform::Api::V1::AgentBotsController#show
|
|
// Requires: Permissible verification
|
|
func (h *PlatformAgentBotHandler) Show(c *gin.Context) {
|
|
botID, err := parseUintParam(c, "id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid bot ID")
|
|
return
|
|
}
|
|
|
|
platformAppID := getPlatformAppID(c)
|
|
|
|
// Verify Permissible access
|
|
perm, err := h.permissibleRepo.FindByPlatformAppAndResource(c.Request.Context(), platformAppID, model.PermissibleTypeAgentBot, botID)
|
|
if err != nil || perm == nil {
|
|
response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "non permissible resource")
|
|
return
|
|
}
|
|
|
|
bot, err := h.agentBotRepo.FindByID(c.Request.Context(), botID)
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusNotFound, response.ErrNotFound, "agent bot not found")
|
|
return
|
|
}
|
|
|
|
response.OK(c, bot)
|
|
}
|
|
|
|
// Create creates a new agent bot and auto-creates Permissible record.
|
|
// POST /platform/api/v1/agent_bots
|
|
// Reference: Chatwoot Platform::Api::V1::AgentBotsController#create
|
|
// Auto-permissible: PlatformApp automatically gets access to the created bot.
|
|
func (h *PlatformAgentBotHandler) Create(c *gin.Context) {
|
|
platformAppID := getPlatformAppID(c)
|
|
|
|
var req struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Description string `json:"description,omitempty"`
|
|
AvatarURL string `json:"avatar_url,omitempty"`
|
|
AccountID *uint `json:"account_id,omitempty"`
|
|
Config model.AgentBot `json:"config,omitempty"` // Embedded struct for bot config
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
bot := &model.AgentBot{
|
|
AccountID: req.AccountID,
|
|
Name: req.Name,
|
|
Description: req.Description,
|
|
AvatarURL: req.AvatarURL,
|
|
}
|
|
|
|
if err := h.agentBotRepo.Create(c.Request.Context(), bot); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, err.Error())
|
|
return
|
|
}
|
|
|
|
// Auto-create Permissible
|
|
perm := &model.Permissible{
|
|
PlatformAppID: platformAppID,
|
|
PermissibleType: model.PermissibleTypeAgentBot,
|
|
PermissibleID: bot.ID,
|
|
}
|
|
if err := h.permissibleRepo.Create(c.Request.Context(), perm); err != nil {
|
|
// Non-critical
|
|
}
|
|
|
|
response.Created(c, bot)
|
|
}
|
|
|
|
// Update updates an agent bot.
|
|
// PUT /platform/api/v1/agent_bots/:id
|
|
// Reference: Chatwoot Platform::Api::V1::AgentBotsController#update
|
|
// Requires: Permissible verification
|
|
func (h *PlatformAgentBotHandler) Update(c *gin.Context) {
|
|
botID, err := parseUintParam(c, "id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid bot ID")
|
|
return
|
|
}
|
|
|
|
platformAppID := getPlatformAppID(c)
|
|
|
|
// Verify Permissible access
|
|
perm, err := h.permissibleRepo.FindByPlatformAppAndResource(c.Request.Context(), platformAppID, model.PermissibleTypeAgentBot, botID)
|
|
if err != nil || perm == nil {
|
|
response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "non permissible resource")
|
|
return
|
|
}
|
|
|
|
bot, err := h.agentBotRepo.FindByID(c.Request.Context(), botID)
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusNotFound, response.ErrNotFound, "agent bot not found")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Name string `json:"name,omitempty"`
|
|
Description string `json:"description,omitempty"`
|
|
AvatarURL string `json:"avatar_url,omitempty"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
if req.Name != "" {
|
|
bot.Name = req.Name
|
|
}
|
|
if req.Description != "" {
|
|
bot.Description = req.Description
|
|
}
|
|
if req.AvatarURL != "" {
|
|
bot.AvatarURL = req.AvatarURL
|
|
}
|
|
|
|
if err := h.agentBotRepo.Update(c.Request.Context(), bot); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, err.Error())
|
|
return
|
|
}
|
|
|
|
response.OK(c, bot)
|
|
}
|
|
|
|
// Destroy deletes an agent bot.
|
|
// DELETE /platform/api/v1/agent_bots/:id
|
|
// Reference: Chatwoot Platform::Api::V1::AgentBotsController#destroy
|
|
// Requires: Permissible verification
|
|
func (h *PlatformAgentBotHandler) Destroy(c *gin.Context) {
|
|
botID, err := parseUintParam(c, "id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid bot ID")
|
|
return
|
|
}
|
|
|
|
platformAppID := getPlatformAppID(c)
|
|
|
|
// Verify Permissible access
|
|
perm, err := h.permissibleRepo.FindByPlatformAppAndResource(c.Request.Context(), platformAppID, model.PermissibleTypeAgentBot, botID)
|
|
if err != nil || perm == nil {
|
|
response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "non permissible resource")
|
|
return
|
|
}
|
|
|
|
if err := h.agentBotRepo.Delete(c.Request.Context(), botID); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, err.Error())
|
|
return
|
|
}
|
|
|
|
response.NoContent(c)
|
|
}
|
|
|
|
// DeleteAvatar removes the avatar of an agent bot.
|
|
// POST /platform/api/v1/agent_bots/:id/delete_avatar
|
|
// Reference: Chatwoot Platform::Api::V1::AgentBotsController#delete_avatar
|
|
// Requires: Permissible verification
|
|
func (h *PlatformAgentBotHandler) DeleteAvatar(c *gin.Context) {
|
|
botID, err := parseUintParam(c, "id")
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid bot ID")
|
|
return
|
|
}
|
|
|
|
platformAppID := getPlatformAppID(c)
|
|
|
|
// Verify Permissible access
|
|
perm, err := h.permissibleRepo.FindByPlatformAppAndResource(c.Request.Context(), platformAppID, model.PermissibleTypeAgentBot, botID)
|
|
if err != nil || perm == nil {
|
|
response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "non permissible resource")
|
|
return
|
|
}
|
|
|
|
bot, err := h.agentBotRepo.FindByID(c.Request.Context(), botID)
|
|
if err != nil {
|
|
response.AbortWithStatusError(c, http.StatusNotFound, response.ErrNotFound, "agent bot not found")
|
|
return
|
|
}
|
|
|
|
bot.AvatarURL = ""
|
|
if err := h.agentBotRepo.Update(c.Request.Context(), bot); err != nil {
|
|
response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, err.Error())
|
|
return
|
|
}
|
|
|
|
response.OK(c, bot)
|
|
} |