form-to-inbox
v2.1.0
Published
Convex form submissions with email notifications via Inbound
Maintainers
Readme
form-to-inbox
Drop-in form submissions with email notifications for Convex apps.
Installation
npm install form-to-inboxQuick Start (3 steps)
1. Add the schema
In convex/schema.ts:
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
formSubmissions: defineTable({
formType: v.string(),
name: v.optional(v.string()),
email: v.optional(v.string()),
phone: v.optional(v.string()),
address: v.optional(v.string()),
city: v.optional(v.string()),
subject: v.optional(v.string()),
message: v.optional(v.string()),
customFields: v.optional(v.array(v.object({ key: v.string(), value: v.string() }))),
to: v.string(),
from: v.string(),
status: v.string(),
createdAt: v.number(),
notes: v.optional(v.string()),
})
.index("by_formType", ["formType"])
.index("by_status", ["status"])
.index("by_createdAt", ["createdAt"]),
});2. Create your forms file
In convex/forms.ts:
import { mutation, query, internalAction } from "./_generated/server";
import { createFormFunctions } from "form-to-inbox";
const forms = createFormFunctions({ mutation, query, internalAction });
export const submitForm = forms.submitForm;
export const getAllSubmissions = forms.getAllSubmissions;
export const getSubmissionsByType = forms.getSubmissionsByType;
export const getNewSubmissions = forms.getNewSubmissions;
export const updateStatus = forms.updateStatus;
export const sendNotification = forms.sendNotification;3. Use in your React app
import { useMutation } from "convex/react";
import { api } from "../convex/_generated/api";
function ContactForm() {
const submitForm = useMutation(api.forms.submitForm);
const handleSubmit = async (data) => {
await submitForm({
formType: "Contact",
name: data.name,
email: data.email,
message: data.message,
to: "[email protected]",
from: "[email protected]",
});
};
}That's it! Your forms are now stored in Convex.
Email Notifications
To send email notifications when forms are submitted, set INBOUND_API_KEY in your Convex dashboard and update your submitForm:
import { mutation, query, internalAction } from "./_generated/server";
import { internal } from "./_generated/api";
import { createFormFunctions } from "form-to-inbox";
const forms = createFormFunctions({ mutation, query, internalAction });
// Custom submitForm that also sends email
export const submitForm = mutation({
args: forms.submitForm.args,
handler: async (ctx, args) => {
const id = await forms.submitForm.handler(ctx, args);
await ctx.scheduler.runAfter(0, internal.forms.sendNotification, { payload: args });
return id;
},
});
// Re-export the rest
export const getAllSubmissions = forms.getAllSubmissions;
export const getSubmissionsByType = forms.getSubmissionsByType;
export const getNewSubmissions = forms.getNewSubmissions;
export const updateStatus = forms.updateStatus;
export const sendNotification = forms.sendNotification;Form Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| formType | string | Yes | Form identifier ("Contact", "Quote", etc.) |
| name | string | No | Submitter's name |
| email | string | No | Submitter's email |
| phone | string | No | Submitter's phone |
| address | string | No | Street address |
| city | string | No | City |
| subject | string | No | Subject line |
| message | string | No | Main message |
| customFields | array | No | Extra { key, value } pairs |
| to | string | Yes | Email recipient |
| from | string | Yes | Email sender (verify with Inbound) |
Custom Fields
await submitForm({
formType: "Lead",
name: "Jane Doe",
customFields: [
{ key: "Source", value: "Google Ads" },
{ key: "Budget", value: "$5,000" },
],
to: "[email protected]",
from: "[email protected]",
});Functions Provided
| Function | Description |
|----------|-------------|
| submitForm | Store a form submission |
| getAllSubmissions | Get all submissions (newest first) |
| getSubmissionsByType | Filter by form type |
| getNewSubmissions | Get unprocessed submissions |
| updateStatus | Update status and notes |
| sendNotification | Send email (internal action) |
License
MIT
