feat(form): add submission link webhook placeholder
This commit is contained in:
@@ -15,6 +15,12 @@ import {
|
|||||||
} from "@/lib/submission-intake";
|
} from "@/lib/submission-intake";
|
||||||
import { submissionWebhookMessage } from "@/lib/submission-webhook";
|
import { submissionWebhookMessage } from "@/lib/submission-webhook";
|
||||||
|
|
||||||
|
function getSubmissionResultLink(formId: string, submissionId: string) {
|
||||||
|
const baseUrl = process.env.BASE_URL || process.env.NEXTAUTH_URL;
|
||||||
|
if (!baseUrl) return `/admin/form/${formId}/result/${submissionId}`;
|
||||||
|
return new URL(`/admin/form/${formId}/result/${submissionId}`, baseUrl).toString();
|
||||||
|
}
|
||||||
|
|
||||||
export async function submitForm(
|
export async function submitForm(
|
||||||
formId: string,
|
formId: string,
|
||||||
answersList: FormAnswerPayload[],
|
answersList: FormAnswerPayload[],
|
||||||
@@ -171,11 +177,13 @@ export async function submitForm(
|
|||||||
|
|
||||||
if (form.discordWebhookUrl) {
|
if (form.discordWebhookUrl) {
|
||||||
try {
|
try {
|
||||||
|
const submissionLink = getSubmissionResultLink(formId, result.submissionId);
|
||||||
const message = submissionWebhookMessage({
|
const message = submissionWebhookMessage({
|
||||||
template: templateToUse,
|
template: templateToUse,
|
||||||
isUpdate: result.isUpdate,
|
isUpdate: result.isUpdate,
|
||||||
userName: session.user.name,
|
userName: session.user.name,
|
||||||
discordId,
|
discordId,
|
||||||
|
submissionLink,
|
||||||
questions: questionsList,
|
questions: questionsList,
|
||||||
answers: normalizedAnswers,
|
answers: normalizedAnswers,
|
||||||
oldAnswersByQuestionId: result.oldAnswersDict,
|
oldAnswersByQuestionId: result.oldAnswersDict,
|
||||||
|
|||||||
@@ -336,10 +336,10 @@ export default function FormExtraClient({ form }: FormExtraClientProps) {
|
|||||||
className="min-h-24"
|
className="min-h-24"
|
||||||
/>
|
/>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
Use <code>{`{1}`}</code>, <code>{`{2}`}</code> to insert answers according to question order, and <code>{`{username}`}</code>, <code>{`{displayname}`}</code>, <code>{`{id}`}</code> for user info.
|
Use <code>{`{1}`}</code>, <code>{`{2}`}</code> to insert answers according to question order, <code>{`{link}`}</code> for the admin result link, and <code>{`{username}`}</code>, <code>{`{displayname}`}</code>, <code>{`{id}`}</code> for user info.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{["username", "displayname", "id", "1", "2"].map((variable) => (
|
{["username", "displayname", "id", "link", "1", "2"].map((variable) => (
|
||||||
<Button
|
<Button
|
||||||
key={variable}
|
key={variable}
|
||||||
type="button"
|
type="button"
|
||||||
@@ -368,10 +368,10 @@ export default function FormExtraClient({ form }: FormExtraClientProps) {
|
|||||||
className="min-h-24"
|
className="min-h-24"
|
||||||
/>
|
/>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
Used when a user updates their existing submission. Use <code>{`{1}`}</code>, <code>{`{2}`}</code> for answers, <code>{`{update}`}</code> to show what was changed, and <code>{`{username}`}</code>, <code>{`{displayname}`}</code>, <code>{`{id}`}</code> for user info.
|
Used when a user updates their existing submission. Use <code>{`{1}`}</code>, <code>{`{2}`}</code> for answers, <code>{`{update}`}</code> to show what was changed, <code>{`{link}`}</code> for the admin result link, and <code>{`{username}`}</code>, <code>{`{displayname}`}</code>, <code>{`{id}`}</code> for user info.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{["username", "displayname", "id", "update", "1", "2"].map((variable) => (
|
{["username", "displayname", "id", "link", "update", "1", "2"].map((variable) => (
|
||||||
<Button
|
<Button
|
||||||
key={variable}
|
key={variable}
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ export function previewWebhookTemplate(
|
|||||||
const key = variable.toLowerCase();
|
const key = variable.toLowerCase();
|
||||||
if (key === "username" || key === "displayname") return "Example User";
|
if (key === "username" || key === "displayname") return "Example User";
|
||||||
if (key === "id") return "123456789";
|
if (key === "id") return "123456789";
|
||||||
|
if (key === "link") {
|
||||||
|
return "https://erika.sudloh.com/admin/form/example-form/result/example-submission";
|
||||||
|
}
|
||||||
if (key === "update") return "Question 1: Previous answer → Example answer";
|
if (key === "update") return "Question 1: Previous answer → Example answer";
|
||||||
if (/^\d+$/.test(key)) return `Example answer ${key}`;
|
if (/^\d+$/.test(key)) return `Example answer ${key}`;
|
||||||
return `{${variable}}`;
|
return `{${variable}}`;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ test("uses an image URL for image-only placeholders", () => {
|
|||||||
isUpdate: false,
|
isUpdate: false,
|
||||||
userName: "Gunshiz",
|
userName: "Gunshiz",
|
||||||
discordId: "123",
|
discordId: "123",
|
||||||
|
submissionLink: "https://erika.sudloh.com/admin/form/form-1/result/submission-1",
|
||||||
questions,
|
questions,
|
||||||
answers: [{
|
answers: [{
|
||||||
questionId: "name",
|
questionId: "name",
|
||||||
@@ -48,12 +49,26 @@ test("uses the configured template", () => {
|
|||||||
isUpdate: false,
|
isUpdate: false,
|
||||||
userName: "Gunshiz",
|
userName: "Gunshiz",
|
||||||
discordId: "123",
|
discordId: "123",
|
||||||
|
submissionLink: "https://erika.sudloh.com/admin/form/form-1/result/submission-1",
|
||||||
questions,
|
questions,
|
||||||
answers,
|
answers,
|
||||||
oldAnswersByQuestionId: {},
|
oldAnswersByQuestionId: {},
|
||||||
})).toBe("New answer: Erika by Gunshiz (123)");
|
})).toBe("New answer: Erika by Gunshiz (123)");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("uses a submission result link placeholder", () => {
|
||||||
|
expect(submissionWebhookMessage({
|
||||||
|
template: "Review: {link}",
|
||||||
|
isUpdate: false,
|
||||||
|
userName: "Gunshiz",
|
||||||
|
discordId: "123",
|
||||||
|
submissionLink: "https://erika.sudloh.com/admin/form/form-1/result/submission-1",
|
||||||
|
questions,
|
||||||
|
answers,
|
||||||
|
oldAnswersByQuestionId: {},
|
||||||
|
})).toBe("Review: https://erika.sudloh.com/admin/form/form-1/result/submission-1");
|
||||||
|
});
|
||||||
|
|
||||||
describe("default templates", () => {
|
describe("default templates", () => {
|
||||||
test("sends a new-submission message when its template is blank", () => {
|
test("sends a new-submission message when its template is blank", () => {
|
||||||
expect(submissionWebhookMessage({
|
expect(submissionWebhookMessage({
|
||||||
@@ -61,6 +76,7 @@ describe("default templates", () => {
|
|||||||
isUpdate: false,
|
isUpdate: false,
|
||||||
userName: "Gunshiz",
|
userName: "Gunshiz",
|
||||||
discordId: "123",
|
discordId: "123",
|
||||||
|
submissionLink: "https://erika.sudloh.com/admin/form/form-1/result/submission-1",
|
||||||
questions,
|
questions,
|
||||||
answers,
|
answers,
|
||||||
oldAnswersByQuestionId: {},
|
oldAnswersByQuestionId: {},
|
||||||
@@ -73,6 +89,7 @@ describe("default templates", () => {
|
|||||||
isUpdate: true,
|
isUpdate: true,
|
||||||
userName: "Gunshiz",
|
userName: "Gunshiz",
|
||||||
discordId: "123",
|
discordId: "123",
|
||||||
|
submissionLink: "https://erika.sudloh.com/admin/form/form-1/result/submission-1",
|
||||||
questions,
|
questions,
|
||||||
answers,
|
answers,
|
||||||
oldAnswersByQuestionId: { name: "Old name" },
|
oldAnswersByQuestionId: { name: "Old name" },
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ type SubmissionWebhookMessageOptions = {
|
|||||||
isUpdate: boolean;
|
isUpdate: boolean;
|
||||||
userName: string | null | undefined;
|
userName: string | null | undefined;
|
||||||
discordId: string;
|
discordId: string;
|
||||||
|
submissionLink: string;
|
||||||
questions: SubmissionQuestion[];
|
questions: SubmissionQuestion[];
|
||||||
answers: NormalizedSubmissionAnswer[];
|
answers: NormalizedSubmissionAnswer[];
|
||||||
oldAnswersByQuestionId: OldAnswersByQuestionId;
|
oldAnswersByQuestionId: OldAnswersByQuestionId;
|
||||||
@@ -24,6 +25,7 @@ export function submissionWebhookMessage({
|
|||||||
isUpdate,
|
isUpdate,
|
||||||
userName,
|
userName,
|
||||||
discordId,
|
discordId,
|
||||||
|
submissionLink,
|
||||||
questions,
|
questions,
|
||||||
answers,
|
answers,
|
||||||
oldAnswersByQuestionId,
|
oldAnswersByQuestionId,
|
||||||
@@ -43,6 +45,9 @@ export function submissionWebhookMessage({
|
|||||||
if (key === "id") {
|
if (key === "id") {
|
||||||
return discordId;
|
return discordId;
|
||||||
}
|
}
|
||||||
|
if (key === "link") {
|
||||||
|
return submissionLink;
|
||||||
|
}
|
||||||
if (key === "update") {
|
if (key === "update") {
|
||||||
return updatesText;
|
return updatesText;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user