Answer the inbox from the panel, with templates

A reply starts from a template filled in the language the person wrote in,
is sent by the application when it has a mailer that delivers or handed to
the replier's mail program otherwise, and is recorded on the submission.
The same is available through the API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 10:45:47 +02:00
parent 697d333ad4
commit 76d022053b
27 changed files with 1096 additions and 0 deletions

View File

@@ -4143,6 +4143,89 @@ paths:
slug: { type: object, additionalProperties: { type: string } }
"403": { $ref: "#/components/responses/Forbidden" }
/v1/applications/{application}/replies:
get:
tags: [Applications]
summary: Replies given to an application
description: Newest first.
parameters:
- name: application
in: path
required: true
schema: { type: integer }
responses:
"200":
description: The replies
content:
application/json:
schema:
type: object
properties:
data:
type: array
items: { $ref: "#/components/schemas/ApplicationReply" }
"403": { $ref: "#/components/responses/Forbidden" }
/v1/applications/{application}/reply:
post:
tags: [Applications]
summary: Reply to an application
description: |
`subject` and `body`, or a `template_id` to fill whichever is left out
— in the language the person wrote in. Sent by this application when
it has a mailer that delivers; otherwise recorded, and the answer
carries a `mailto` link to send it by hand. Moves a new application to
`contacted`.
parameters:
- name: application
in: path
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
template_id: { type: integer, nullable: true }
subject: { type: string, maxLength: 255 }
body: { type: string }
responses:
"201":
description: Reply recorded
content:
application/json:
schema:
type: object
properties:
data:
allOf:
- $ref: "#/components/schemas/ApplicationReply"
- type: object
properties:
mailto: { type: string, nullable: true }
"403": { $ref: "#/components/responses/Forbidden" }
"422": { $ref: "#/components/responses/ValidationError" }
/v1/reply-templates:
get:
tags: [Applications]
summary: Reply templates
description: Every template, in every language. Managed in the panel.
responses:
"200":
description: The templates
content:
application/json:
schema:
type: object
properties:
data:
type: array
items: { $ref: "#/components/schemas/ReplyTemplate" }
"403": { $ref: "#/components/responses/Forbidden" }
/v1/media:
get:
tags: [Media]
@@ -6067,6 +6150,29 @@ components:
links: { $ref: "#/components/schemas/PaginationLinks" }
meta: { $ref: "#/components/schemas/PaginationMeta" }
ApplicationReply:
type: object
properties:
id: { type: integer }
subject: { type: string }
body: { type: string }
channel: { type: string, enum: [mail, mailto], description: "`mail` when sent from here; `mailto` when handed to the replier's mail program." }
author:
type: object
properties:
id: { type: integer, nullable: true }
name: { type: string, nullable: true }
created_at: { type: string, format: date-time }
ReplyTemplate:
type: object
properties:
id: { type: integer }
name: { type: string }
kind: { type: string, nullable: true, enum: [contribute, request] }
subject: { type: object, additionalProperties: { type: string }, description: "Language → text. `{name}`, `{subject}` and `{sender}` are filled in." }
body: { type: object, additionalProperties: { type: string } }
MediaFor:
type: string
enum: [pages, technologies, projects, members, clients, testimonials]