mirror of
https://github.com/warmbly/warmbly.git
synced 2026-08-19 16:01:16 +00:00
232 lines
5.5 KiB
Go
232 lines
5.5 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/warmbly/warmbly/internal/api/middleware"
|
|
"github.com/warmbly/warmbly/internal/errx"
|
|
"github.com/warmbly/warmbly/internal/models"
|
|
)
|
|
|
|
// ListTemplates lists all reply templates for the organization, optionally
|
|
// filtered by `?q=` against name and subject.
|
|
// GET /templates
|
|
func (h *Handler) ListTemplates(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.Handle(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
|
|
var q models.ListReplyTemplatesQuery
|
|
_ = c.ShouldBindQuery(&q)
|
|
|
|
templates, xerr := h.TemplateService.List(c.Request.Context(), *orgID, q.Search)
|
|
if xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, models.ReplyTemplatesResult{Data: templates})
|
|
}
|
|
|
|
// CreateTemplate creates a new reply template
|
|
// POST /templates
|
|
func (h *Handler) CreateTemplate(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.Handle(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
|
|
userID, err := middleware.GetUserUUID(c)
|
|
if err != nil {
|
|
errx.Handle(c, errx.ErrUser)
|
|
return
|
|
}
|
|
|
|
var data models.CreateReplyTemplate
|
|
if err := c.ShouldBindJSON(&data); err != nil {
|
|
errx.Handle(c, errx.ErrInvalid)
|
|
return
|
|
}
|
|
|
|
tmpl, xerr := h.TemplateService.Create(c.Request.Context(), *orgID, userID, &data)
|
|
if xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, tmpl)
|
|
}
|
|
|
|
// GetTemplate retrieves a reply template by ID
|
|
// GET /templates/:id
|
|
func (h *Handler) GetTemplate(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.Handle(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
|
|
templateID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
errx.Handle(c, errx.ErrUuid)
|
|
return
|
|
}
|
|
|
|
tmpl, xerr := h.TemplateService.GetByID(c.Request.Context(), *orgID, templateID)
|
|
if xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, tmpl)
|
|
}
|
|
|
|
// UpdateTemplate updates a reply template
|
|
// PATCH /templates/:id
|
|
func (h *Handler) UpdateTemplate(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.Handle(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
|
|
templateID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
errx.Handle(c, errx.ErrUuid)
|
|
return
|
|
}
|
|
|
|
var data models.UpdateReplyTemplate
|
|
if err := c.ShouldBindJSON(&data); err != nil {
|
|
errx.Handle(c, errx.ErrInvalid)
|
|
return
|
|
}
|
|
|
|
tmpl, xerr := h.TemplateService.Update(c.Request.Context(), *orgID, templateID, &data)
|
|
if xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, tmpl)
|
|
}
|
|
|
|
// DeleteTemplate deletes a reply template
|
|
// DELETE /templates/:id
|
|
func (h *Handler) DeleteTemplate(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.Handle(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
|
|
templateID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
errx.Handle(c, errx.ErrUuid)
|
|
return
|
|
}
|
|
|
|
if xerr := h.TemplateService.Delete(c.Request.Context(), *orgID, templateID); xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
c.Status(http.StatusNoContent)
|
|
}
|
|
|
|
// DuplicateTemplate clones a template, appending " (copy)" to the name
|
|
// and placing it at the end of the org's list.
|
|
// POST /templates/:id/duplicate
|
|
func (h *Handler) DuplicateTemplate(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.Handle(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
|
|
userID, err := middleware.GetUserUUID(c)
|
|
if err != nil {
|
|
errx.Handle(c, errx.ErrUser)
|
|
return
|
|
}
|
|
|
|
templateID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
errx.Handle(c, errx.ErrUuid)
|
|
return
|
|
}
|
|
|
|
tmpl, xerr := h.TemplateService.Duplicate(c.Request.Context(), *orgID, userID, templateID)
|
|
if xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, tmpl)
|
|
}
|
|
|
|
// ReorderTemplates reassigns positions across the org's templates so they
|
|
// line up with the order in the request body.
|
|
// PATCH /templates/reorder
|
|
func (h *Handler) ReorderTemplates(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.Handle(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
|
|
var data models.ReorderReplyTemplates
|
|
if err := c.ShouldBindJSON(&data); err != nil {
|
|
errx.Handle(c, errx.ErrInvalid)
|
|
return
|
|
}
|
|
|
|
if xerr := h.TemplateService.Reorder(c.Request.Context(), *orgID, data.IDs); xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
templates, xerr := h.TemplateService.List(c.Request.Context(), *orgID, "")
|
|
if xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, models.ReplyTemplatesResult{Data: templates})
|
|
}
|
|
|
|
// RenderTemplate expands {{.Key}} placeholders in subject + body fields
|
|
// using a caller-supplied variable map. Used by Unibox to preview a reply
|
|
// before scheduling the send.
|
|
// POST /templates/:id/render
|
|
func (h *Handler) RenderTemplate(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.Handle(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
|
|
templateID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
errx.Handle(c, errx.ErrUuid)
|
|
return
|
|
}
|
|
|
|
var data models.RenderReplyTemplateRequest
|
|
// Body is optional: missing/empty body just renders all placeholders empty.
|
|
_ = c.ShouldBindJSON(&data)
|
|
|
|
rendered, xerr := h.TemplateService.Render(c.Request.Context(), *orgID, templateID, data.Variables)
|
|
if xerr != nil {
|
|
errx.Handle(c, xerr)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, rendered)
|
|
}
|