@robinpath/sendgrid
Advanced tools
| import type { ModuleAdapter } from "@robinpath/core"; | ||
| declare const SendgridModule: ModuleAdapter; | ||
| export default SendgridModule; | ||
| export { SendgridModule }; | ||
| export { SendgridFunctions, SendgridFunctionMetadata, SendgridModuleMetadata, SendgridCredentialTypes, } from "./sendgrid.js"; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AASrD,QAAA,MAAM,cAAc,EAAE,aAQrB,CAAC;AAEF,eAAe,cAAc,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,eAAe,CAAC"} |
| import { SendgridFunctions, SendgridFunctionMetadata, SendgridModuleMetadata, SendgridCredentialTypes, configureSendgrid, } from "./sendgrid.js"; | ||
| const SendgridModule = { | ||
| name: "sendgrid", | ||
| functions: SendgridFunctions, | ||
| functionMetadata: SendgridFunctionMetadata, | ||
| moduleMetadata: SendgridModuleMetadata, | ||
| credentialTypes: SendgridCredentialTypes, | ||
| configure: configureSendgrid, | ||
| global: false, | ||
| }; | ||
| export default SendgridModule; | ||
| export { SendgridModule }; | ||
| export { SendgridFunctions, SendgridFunctionMetadata, SendgridModuleMetadata, SendgridCredentialTypes, } from "./sendgrid.js"; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,MAAM,cAAc,GAAkB;IACpC,IAAI,EAAE,UAAU;IAChB,SAAS,EAAE,iBAAiB;IAC5B,gBAAgB,EAAE,wBAAwB;IAC1C,cAAc,EAAE,sBAAsB;IACtC,eAAe,EAAE,uBAAuB;IACxC,SAAS,EAAE,iBAAiB;IAC5B,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,eAAe,cAAc,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,eAAe,CAAC"} |
| /** | ||
| * RobinPath SendGrid Module (Node port) | ||
| * | ||
| * Twilio SendGrid integration: transactional email (Mail Send v3), | ||
| * dynamic templates, marketing contacts and lists, stats. Mirror of | ||
| * packages/php/sendgrid/src/index.php for the WordPress plugin; shares | ||
| * the same credential contract, metadata shape, and error taxonomy so | ||
| * the visual editor can render both identically. | ||
| * | ||
| * Authentication uses the RobinPath credential vault. Every handler | ||
| * takes a credential slug as its first argument. The host registers a | ||
| * CredentialStore on the runtime and this module resolves the API key | ||
| * at call time via the injected ModuleHost. | ||
| * | ||
| * Credential type declared by this module: | ||
| * - sendgrid : { api_key } → Bearer auth with a SendGrid API key | ||
| */ | ||
| import type { BuiltinHandler, CredentialTypeSchema, FunctionMetadata, ModuleHost, ModuleMetadata } from "@robinpath/core"; | ||
| export declare function configureSendgrid(h: ModuleHost): void; | ||
| export declare const SendgridFunctions: Record<string, BuiltinHandler>; | ||
| export declare const SendgridCredentialTypes: CredentialTypeSchema[]; | ||
| export declare const SendgridFunctionMetadata: Record<string, FunctionMetadata>; | ||
| export declare const SendgridModuleMetadata: ModuleMetadata; | ||
| //# sourceMappingURL=sendgrid.d.ts.map |
| {"version":3,"file":"sendgrid.d.ts","sourceRoot":"","sources":["../src/sendgrid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,cAAc,EAEf,MAAM,iBAAiB,CAAC;AAezB,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAErD;AAkeD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAU5D,CAAC;AAIF,eAAO,MAAM,uBAAuB,EAAE,oBAAoB,EAkBzD,CAAC;AA2CF,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA8UrE,CAAC;AAIF,eAAO,MAAM,sBAAsB,EAAE,cAuCpC,CAAC"} |
+809
| /** | ||
| * RobinPath SendGrid Module (Node port) | ||
| * | ||
| * Twilio SendGrid integration: transactional email (Mail Send v3), | ||
| * dynamic templates, marketing contacts and lists, stats. Mirror of | ||
| * packages/php/sendgrid/src/index.php for the WordPress plugin; shares | ||
| * the same credential contract, metadata shape, and error taxonomy so | ||
| * the visual editor can render both identically. | ||
| * | ||
| * Authentication uses the RobinPath credential vault. Every handler | ||
| * takes a credential slug as its first argument. The host registers a | ||
| * CredentialStore on the runtime and this module resolves the API key | ||
| * at call time via the injected ModuleHost. | ||
| * | ||
| * Credential type declared by this module: | ||
| * - sendgrid : { api_key } → Bearer auth with a SendGrid API key | ||
| */ | ||
| // ── Module-local state (populated by configure hook) ──────────────────── | ||
| const state = {}; | ||
| function host() { | ||
| if (!state.host) { | ||
| throw new Error("SendGrid module not initialized. Pass the adapter to rp.installModule() so its configure() hook runs first."); | ||
| } | ||
| return state.host; | ||
| } | ||
| export function configureSendgrid(h) { | ||
| state.host = h; | ||
| } | ||
| // ── Constants ────────────────────────────────────────────────────────── | ||
| const API_BASE = "https://api.sendgrid.com/v3/"; | ||
| const CREDENTIAL_TYPE = "sendgrid"; | ||
| function errorReturn(error, code, extra = {}) { | ||
| return { error, code, ...extra }; | ||
| } | ||
| // ── Credential resolver (mirrors PHP resolveApiKey) ──────────────────── | ||
| async function resolveApiKey(credentialSlug) { | ||
| if (!credentialSlug) { | ||
| return errorReturn("Credential slug is required.", "credential_not_found"); | ||
| } | ||
| let fields; | ||
| try { | ||
| fields = await host().credentials.get(credentialSlug); | ||
| } | ||
| catch (e) { | ||
| return errorReturn(e instanceof Error ? e.message : String(e), "credential_not_found"); | ||
| } | ||
| if (!fields) { | ||
| return errorReturn(`Credential '${credentialSlug}' not found.`, "credential_not_found"); | ||
| } | ||
| const apiKey = String(fields.api_key ?? ""); | ||
| if (!apiKey) { | ||
| return errorReturn("Credential has no `api_key` field.", "api_key_missing"); | ||
| } | ||
| return { apiKey }; | ||
| } | ||
| // ── HTTP helper (normalized envelope, never throws for API errors) ───── | ||
| async function http(apiKey, method, pathAndQuery, body) { | ||
| const headers = { | ||
| Authorization: `Bearer ${apiKey}`, | ||
| }; | ||
| if (body !== undefined && body !== null) { | ||
| headers["Content-Type"] = "application/json"; | ||
| } | ||
| const init = { method, headers }; | ||
| if (body !== undefined && body !== null) { | ||
| init.body = JSON.stringify(body); | ||
| } | ||
| let response; | ||
| try { | ||
| response = await fetch(`${API_BASE}${pathAndQuery.replace(/^\/+/, "")}`, init); | ||
| } | ||
| catch (e) { | ||
| return errorReturn(e instanceof Error ? e.message : String(e), "transport"); | ||
| } | ||
| const raw = await response.text(); | ||
| let decoded; | ||
| try { | ||
| decoded = raw ? JSON.parse(raw) : null; | ||
| } | ||
| catch { | ||
| decoded = { raw }; | ||
| } | ||
| if (response.status >= 200 && response.status < 300) { | ||
| // 202 / 204: no body → treat as ok; otherwise return decoded body. | ||
| if (response.status === 202 || response.status === 204) { | ||
| if (decoded && typeof decoded === "object") | ||
| return decoded; | ||
| return { ok: true }; | ||
| } | ||
| if (decoded && typeof decoded === "object") | ||
| return decoded; | ||
| return { raw }; | ||
| } | ||
| const decodedObj = (decoded && typeof decoded === "object") | ||
| ? decoded | ||
| : {}; | ||
| const errors = decodedObj.errors; | ||
| let message = `SendGrid returned HTTP ${response.status}.`; | ||
| if (Array.isArray(errors) && errors.length > 0) { | ||
| const first = errors[0]; | ||
| if (first && typeof first === "object" && "message" in first) { | ||
| message = String(first.message); | ||
| } | ||
| } | ||
| const code = response.status === 429 ? "rate_limited" : "sendgrid_error"; | ||
| return errorReturn(message, code, { | ||
| status: response.status, | ||
| sendgrid_error: decodedObj, | ||
| }); | ||
| } | ||
| // ── Mail body builders (mirror PHP buildMailBody / normalizeEmail) ───── | ||
| function isPlainObject(v) { | ||
| return !!v && typeof v === "object" && !Array.isArray(v); | ||
| } | ||
| function normalizeEmail(value) { | ||
| if (isPlainObject(value)) { | ||
| const out = {}; | ||
| const email = value.email !== undefined ? String(value.email) : ""; | ||
| if (email !== "") | ||
| out.email = email; | ||
| if (value.name !== undefined && value.name !== null && String(value.name) !== "") { | ||
| out.name = String(value.name); | ||
| } | ||
| return out; | ||
| } | ||
| return { email: String(value ?? "") }; | ||
| } | ||
| function normalizeEmailList(value) { | ||
| if (!Array.isArray(value)) { | ||
| if (isPlainObject(value) && "email" in value) { | ||
| return [normalizeEmail(value)]; | ||
| } | ||
| return [normalizeEmail(value)]; | ||
| } | ||
| return value.map((v) => normalizeEmail(v)); | ||
| } | ||
| function buildMailBody(fields) { | ||
| // Required validation. | ||
| if (!fields.to || !fields.from) { | ||
| return errorReturn("`to` and `from` are required.", "validation_failed"); | ||
| } | ||
| if (!fields.template_id && | ||
| !fields.subject && | ||
| !fields.html && | ||
| !fields.text) { | ||
| return errorReturn("Provide either `template_id` or `subject` + `html`/`text`.", "validation_failed"); | ||
| } | ||
| const personalization = { | ||
| to: normalizeEmailList(fields.to), | ||
| }; | ||
| if (fields.cc !== undefined) { | ||
| personalization.cc = normalizeEmailList(fields.cc); | ||
| } | ||
| if (fields.bcc !== undefined) { | ||
| personalization.bcc = normalizeEmailList(fields.bcc); | ||
| } | ||
| if (fields.subject !== undefined) { | ||
| personalization.subject = String(fields.subject); | ||
| } | ||
| if (fields.dynamic_template_data !== undefined) { | ||
| personalization.dynamic_template_data = fields.dynamic_template_data; | ||
| } | ||
| if (fields.custom_args !== undefined) { | ||
| personalization.custom_args = fields.custom_args; | ||
| } | ||
| if (fields.send_at !== undefined) { | ||
| personalization.send_at = Number(fields.send_at) | 0; | ||
| } | ||
| const body = { | ||
| personalizations: [personalization], | ||
| from: normalizeEmail(fields.from), | ||
| }; | ||
| if (fields.reply_to !== undefined) { | ||
| body.reply_to = normalizeEmail(fields.reply_to); | ||
| } | ||
| if (fields.subject !== undefined) { | ||
| body.subject = String(fields.subject); | ||
| } | ||
| // Content — plain + html. | ||
| const content = []; | ||
| if (fields.text !== undefined) { | ||
| content.push({ type: "text/plain", value: String(fields.text) }); | ||
| } | ||
| if (fields.html !== undefined) { | ||
| content.push({ type: "text/html", value: String(fields.html) }); | ||
| } | ||
| if (content.length > 0) { | ||
| body.content = content; | ||
| } | ||
| const passthroughKeys = [ | ||
| "template_id", | ||
| "attachments", | ||
| "categories", | ||
| "send_at", | ||
| "asm", | ||
| "tracking_settings", | ||
| "mail_settings", | ||
| "headers", | ||
| "batch_id", | ||
| ]; | ||
| for (const key of passthroughKeys) { | ||
| if (fields[key] !== undefined) { | ||
| body[key] = fields[key]; | ||
| } | ||
| } | ||
| return body; | ||
| } | ||
| // ── Mail send caller ─────────────────────────────────────────────────── | ||
| async function callMailSend(credentialSlug, body) { | ||
| const resolved = await resolveApiKey(credentialSlug); | ||
| if ("error" in resolved) | ||
| return resolved; | ||
| const headers = { | ||
| Authorization: `Bearer ${resolved.apiKey}`, | ||
| "Content-Type": "application/json", | ||
| }; | ||
| let response; | ||
| try { | ||
| response = await fetch(`${API_BASE}mail/send`, { | ||
| method: "POST", | ||
| headers, | ||
| body: JSON.stringify(body), | ||
| }); | ||
| } | ||
| catch (e) { | ||
| return { | ||
| ok: false, | ||
| error: e instanceof Error ? e.message : String(e), | ||
| code: "transport", | ||
| }; | ||
| } | ||
| const status = response.status; | ||
| if (status >= 200 && status < 300) { | ||
| const messageId = response.headers.get("x-message-id") ?? | ||
| response.headers.get("X-Message-Id") ?? | ||
| ""; | ||
| return { | ||
| ok: true, | ||
| status, | ||
| message_id: messageId, | ||
| }; | ||
| } | ||
| const raw = await response.text(); | ||
| let decoded; | ||
| try { | ||
| decoded = raw ? JSON.parse(raw) : null; | ||
| } | ||
| catch { | ||
| decoded = { raw }; | ||
| } | ||
| const decodedObj = (decoded && typeof decoded === "object") | ||
| ? decoded | ||
| : {}; | ||
| const errors = decodedObj.errors; | ||
| let message = `SendGrid returned HTTP ${status}.`; | ||
| if (Array.isArray(errors) && errors.length > 0) { | ||
| const first = errors[0]; | ||
| if (first && typeof first === "object" && "message" in first) { | ||
| message = String(first.message); | ||
| } | ||
| } | ||
| const code = status === 429 ? "rate_limited" : "sendgrid_error"; | ||
| return { | ||
| error: message, | ||
| code, | ||
| status, | ||
| sendgrid_error: decodedObj, | ||
| }; | ||
| } | ||
| // ── Generic JSON caller (wraps http + credential resolution) ─────────── | ||
| async function callJson(credentialSlug, method, path, body) { | ||
| const resolved = await resolveApiKey(credentialSlug); | ||
| if ("error" in resolved) | ||
| return resolved; | ||
| return http(resolved.apiKey, method, path, body); | ||
| } | ||
| // ── Handlers ─────────────────────────────────────────────────────────── | ||
| const sendEmail = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const fields = (isPlainObject(args[1]) ? args[1] : {}); | ||
| const body = buildMailBody(fields); | ||
| if ("error" in body) | ||
| return body; | ||
| return (await callMailSend(cred, body)); | ||
| }; | ||
| const sendTemplate = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const fields = (isPlainObject(args[1]) ? args[1] : {}); | ||
| if (!fields.template_id) { | ||
| return errorReturn("`template_id` is required.", "validation_failed"); | ||
| } | ||
| const body = buildMailBody(fields); | ||
| if ("error" in body) | ||
| return body; | ||
| return (await callMailSend(cred, body)); | ||
| }; | ||
| const addContact = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const fields = (isPlainObject(args[1]) ? args[1] : {}); | ||
| const listIds = Array.isArray(args[2]) ? args[2] : []; | ||
| if (!fields.email) { | ||
| return errorReturn("`email` is required.", "validation_failed"); | ||
| } | ||
| const body = { contacts: [fields] }; | ||
| if (listIds.length > 0) { | ||
| body.list_ids = listIds; | ||
| } | ||
| return (await callJson(cred, "PUT", "marketing/contacts", body)); | ||
| }; | ||
| const removeContact = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const ids = args[1]; | ||
| const idsCsv = Array.isArray(ids) | ||
| ? ids.map((v) => String(v)).join(",") | ||
| : String(ids ?? ""); | ||
| if (idsCsv === "") { | ||
| return errorReturn("Contact IDs required.", "validation_failed"); | ||
| } | ||
| return (await callJson(cred, "DELETE", `marketing/contacts?ids=${encodeURIComponent(idsCsv)}`)); | ||
| }; | ||
| const listContacts = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const opts = (isPlainObject(args[1]) ? args[1] : {}); | ||
| const params = new URLSearchParams(); | ||
| if (opts.page_size !== undefined) { | ||
| params.set("page_size", String(Number(opts.page_size) | 0)); | ||
| } | ||
| if (opts.page_token !== undefined) { | ||
| params.set("page_token", String(opts.page_token)); | ||
| } | ||
| let path = "marketing/contacts"; | ||
| const qs = params.toString(); | ||
| if (qs) | ||
| path += `?${qs}`; | ||
| return (await callJson(cred, "GET", path)); | ||
| }; | ||
| const createList = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const name = String(args[1] ?? ""); | ||
| if (name === "") { | ||
| return errorReturn("List name is required.", "validation_failed"); | ||
| } | ||
| return (await callJson(cred, "POST", "marketing/lists", { name })); | ||
| }; | ||
| const addToList = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const listId = String(args[1] ?? ""); | ||
| const contacts = Array.isArray(args[2]) ? args[2] : []; | ||
| if (listId === "") { | ||
| return errorReturn("List ID required.", "validation_failed"); | ||
| } | ||
| if (contacts.length === 0) { | ||
| return errorReturn("At least one contact is required.", "validation_failed"); | ||
| } | ||
| return (await callJson(cred, "PUT", "marketing/contacts", { | ||
| list_ids: [listId], | ||
| contacts, | ||
| })); | ||
| }; | ||
| const removeFromList = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const listId = String(args[1] ?? ""); | ||
| const contactIds = args[2]; | ||
| if (listId === "") { | ||
| return errorReturn("List ID required.", "validation_failed"); | ||
| } | ||
| const idsCsv = Array.isArray(contactIds) | ||
| ? contactIds.map((v) => String(v)).join(",") | ||
| : String(contactIds ?? ""); | ||
| if (idsCsv === "") { | ||
| return errorReturn("Contact IDs required.", "validation_failed"); | ||
| } | ||
| return (await callJson(cred, "DELETE", `marketing/lists/${listId}/contacts?contact_ids=${encodeURIComponent(idsCsv)}`)); | ||
| }; | ||
| const getStats = async (args) => { | ||
| const cred = String(args[0] ?? ""); | ||
| const opts = (isPlainObject(args[1]) ? args[1] : {}); | ||
| if (!opts.start_date) { | ||
| return errorReturn("`start_date` is required (YYYY-MM-DD).", "validation_failed"); | ||
| } | ||
| const params = new URLSearchParams(); | ||
| if (opts.start_date !== undefined && opts.start_date !== "") { | ||
| params.set("start_date", String(opts.start_date)); | ||
| } | ||
| if (opts.end_date !== undefined && opts.end_date !== "") { | ||
| params.set("end_date", String(opts.end_date)); | ||
| } | ||
| if (opts.aggregated_by !== undefined && opts.aggregated_by !== "") { | ||
| params.set("aggregated_by", String(opts.aggregated_by)); | ||
| } | ||
| if (Array.isArray(opts.categories) && opts.categories.length > 0) { | ||
| params.set("categories", opts.categories.map((v) => String(v)).join(",")); | ||
| } | ||
| return (await callJson(cred, "GET", `stats?${params.toString()}`)); | ||
| }; | ||
| // ── Exports: functions map ───────────────────────────────────────────── | ||
| export const SendgridFunctions = { | ||
| sendEmail, | ||
| sendTemplate, | ||
| addContact, | ||
| removeContact, | ||
| listContacts, | ||
| createList, | ||
| addToList, | ||
| removeFromList, | ||
| getStats, | ||
| }; | ||
| // ── Exports: credential types ────────────────────────────────────────── | ||
| export const SendgridCredentialTypes = [ | ||
| { | ||
| slug: CREDENTIAL_TYPE, | ||
| title: "SendGrid", | ||
| icon: "mail", | ||
| fields: [ | ||
| { | ||
| name: "api_key", | ||
| title: "API Key", | ||
| type: "password", | ||
| required: true, | ||
| placeholder: "SG.…", | ||
| description: "Create one at app.sendgrid.com → Settings → API Keys. Needs at least Mail Send + Marketing scopes.", | ||
| pattern: "^SG\\.", | ||
| }, | ||
| ], | ||
| }, | ||
| ]; | ||
| // ── Shared parameter metadata ────────────────────────────────────────── | ||
| const credentialParam = { | ||
| name: "credential", | ||
| title: "Credential", | ||
| description: "Slug of a saved `sendgrid` credential.", | ||
| dataType: "string", | ||
| formInputType: "resource", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "my_sendgrid", | ||
| resource: { | ||
| type: "credential", | ||
| listFn: "credential.list", | ||
| modes: ["list", "expression"], | ||
| searchable: true, | ||
| filter: { type: CREDENTIAL_TYPE }, | ||
| }, | ||
| }; | ||
| const listIdParam = { | ||
| name: "listId", | ||
| title: "List", | ||
| description: "SendGrid List ID (UUID).", | ||
| dataType: "string", | ||
| formInputType: "resource", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "abc123-…", | ||
| }; | ||
| const commonErrors = { | ||
| credential_not_found: "No credential with that slug exists in the vault.", | ||
| api_key_missing: "The credential exists but has no `api_key` field.", | ||
| transport: "Network failure calling api.sendgrid.com.", | ||
| sendgrid_error: "SendGrid returned an error — see `sendgrid_error.errors`.", | ||
| rate_limited: "SendGrid rate limited the request.", | ||
| }; | ||
| // ── Exports: function metadata ───────────────────────────────────────── | ||
| export const SendgridFunctionMetadata = { | ||
| // ── Send ────────────────────────────────────────────────── | ||
| sendEmail: { | ||
| title: "Send email", | ||
| summary: "Send a transactional email via the Mail Send v3 API", | ||
| description: "Calls `/mail/send`. Sends an email immediately. For high-volume marketing, use `sendTemplate` with a saved dynamic template instead.", | ||
| group: "send", | ||
| action: "write", | ||
| icon: "send", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call", "sends_email"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "email", "send", "transactional"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "fields", | ||
| title: "Fields", | ||
| description: "Email fields. Required: `to`, `from`, `subject`, and one of `text`/`html`. Common shape:\n to : 'a@b.com' OR ['a@b.com','c@d.com'] OR [{email,name},…]\n from : 'sender@b.com' OR {email, name}\n reply_to : 'reply@b.com' OR {email, name}\n subject : string\n text : plain-text body\n html : HTML body\n cc, bcc : same shapes as `to`\n attachments : [{content (base64), type, filename, disposition?}]\n categories : ['signup','newsletter'] — for stats grouping\n custom_args : {…} — appears in webhook events\n send_at : Unix timestamp to schedule\n asm : { group_id, groups_to_display? } — unsubscribe groups\n tracking_settings : { click_tracking: {enable:true}, open_tracking: {enable:true} }", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 8, | ||
| placeholder: '{\n "to": "customer@example.com",\n "from": "hello@yourbrand.com",\n "subject": "Welcome",\n "html": "<p>Thanks for signing up!</p>"\n}', | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "{ ok: bool, status: int, message_id?: string } — message_id from the X-Message-Id header.", | ||
| errors: commonErrors, | ||
| examples: [ | ||
| { | ||
| title: "Welcome email", | ||
| code: 'sendgrid.sendEmail "my_sendgrid" {\n to: {{ user.email }},\n from: "hello@brand.com",\n subject: "Welcome to Brand",\n html: "<h1>Hi {{ user.name }}</h1><p>Glad you\'re here.</p>"\n}', | ||
| }, | ||
| ], | ||
| example: 'sendgrid.sendEmail "my_sendgrid" {to:"a@b", from:"x@y", subject:"hi", text:"hello"}', | ||
| }, | ||
| sendTemplate: { | ||
| title: "Send dynamic template", | ||
| summary: "Send via a saved SendGrid dynamic template with substitutions", | ||
| description: "Same as `sendEmail` but adds `template_id` and `dynamic_template_data`. Designs live in SendGrid; you supply the data and recipient.", | ||
| group: "send", | ||
| action: "write", | ||
| icon: "mail-plus", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call", "sends_email"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "template", "dynamic"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "fields", | ||
| title: "Fields", | ||
| description: "Required keys:\n to : recipient (same shapes as sendEmail)\n from : sender\n template_id : 'd-…'\n dynamic_template_data: {…} — substitutions referenced in the template\n\nOptional: subject (overrides template), reply_to, cc, bcc, attachments, categories, send_at, asm, tracking_settings.", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 8, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| errors: commonErrors, | ||
| example: 'sendgrid.sendTemplate "my_sendgrid" {to:"a@b", from:"x@y", template_id:"d-…", dynamic_template_data:{name:"Ada"}}', | ||
| }, | ||
| // ── Contacts ────────────────────────────────────────────── | ||
| addContact: { | ||
| title: "Add or update contact", | ||
| summary: "Upsert a marketing contact (and optionally subscribe to lists)", | ||
| description: "Calls `PUT /marketing/contacts`. Asynchronous — returns a `job_id`. The contact is matched by email address.", | ||
| group: "contacts", | ||
| action: "write", | ||
| icon: "user-plus", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "contact", "marketing"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "fields", | ||
| title: "Fields", | ||
| description: "Recognized keys:\n email : required\n first_name, last_name, alternate_emails, address_line_1/2, city, state_province_region, country, postal_code, phone_number\n custom_fields : { id_a1b2: 'value', … }", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 6, | ||
| }, | ||
| { | ||
| name: "listIds", | ||
| title: "List IDs", | ||
| description: "Optional list IDs to also subscribe the contact to.", | ||
| dataType: "array", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 3, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "{ job_id: string }", | ||
| errors: commonErrors, | ||
| examples: [ | ||
| { | ||
| title: "Subscribe form submitter", | ||
| code: 'sendgrid.addContact "my_sendgrid" {email: {{ form.email }}, first_name: {{ form.name }}} ["abc-list-id"]', | ||
| }, | ||
| ], | ||
| example: 'sendgrid.addContact "my_sendgrid" {email:"a@b.com"}', | ||
| }, | ||
| removeContact: { | ||
| title: "Delete contacts", | ||
| summary: "Remove one or more contacts entirely", | ||
| description: "Calls `DELETE /marketing/contacts?ids=…`. Permanent. To remove from a list without deleting the contact, use `removeFromList`.", | ||
| group: "contacts", | ||
| action: "delete", | ||
| icon: "trash-2", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "contact", "delete"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "contactIds", | ||
| title: "Contact IDs", | ||
| description: "Comma-separated string OR array of contact IDs.", | ||
| dataType: "any", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 3, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| errors: commonErrors, | ||
| example: 'sendgrid.removeContact "my_sendgrid" ["abc","def"]', | ||
| }, | ||
| listContacts: { | ||
| title: "List contacts", | ||
| summary: "List marketing contacts (paginated)", | ||
| description: "Calls `GET /marketing/contacts`. Returns up to 50 contacts per page.", | ||
| group: "contacts", | ||
| action: "query", | ||
| icon: "list", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "contact", "list"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n page_size : default 50, max 50\n page_token: pagination cursor", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: false, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 3, | ||
| advanced: true, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "{ result: [], _metadata: { next: …, prev: … } }", | ||
| errors: commonErrors, | ||
| example: 'sendgrid.listContacts "my_sendgrid"', | ||
| }, | ||
| // ── Lists ───────────────────────────────────────────────── | ||
| createList: { | ||
| title: "Create list", | ||
| summary: "Create a new marketing list", | ||
| description: "Calls `POST /marketing/lists`.", | ||
| group: "lists", | ||
| action: "write", | ||
| icon: "folder-plus", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: false, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "list", "audience"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "name", | ||
| title: "Name", | ||
| description: "List name (max 100 chars).", | ||
| dataType: "string", | ||
| formInputType: "text", | ||
| required: true, | ||
| allowExpression: true, | ||
| placeholder: "Newsletter subscribers", | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| returnDescription: "{ id, name, contact_count }", | ||
| errors: commonErrors, | ||
| example: 'sendgrid.createList "my_sendgrid" "Newsletter"', | ||
| }, | ||
| addToList: { | ||
| title: "Add contacts to list", | ||
| summary: "Subscribe one or more contact emails to a list", | ||
| description: "Calls `PUT /marketing/contacts` with `list_ids: [listId]`. Async — returns a `job_id`.", | ||
| group: "lists", | ||
| action: "write", | ||
| icon: "user-plus", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "list", "subscribe"], | ||
| parameters: [ | ||
| credentialParam, | ||
| listIdParam, | ||
| { | ||
| name: "contacts", | ||
| title: "Contacts", | ||
| description: "Array of `{email, first_name?, last_name?}` objects. The contact is upserted.", | ||
| dataType: "array", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 5, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| errors: commonErrors, | ||
| example: 'sendgrid.addToList "my_sendgrid" "list-uuid" [{email:"a@b.com"}]', | ||
| }, | ||
| removeFromList: { | ||
| title: "Remove from list", | ||
| summary: "Unsubscribe contacts from a list (without deleting them)", | ||
| description: "Calls `DELETE /marketing/lists/{listId}/contacts?contact_ids=…`. Contacts remain in your account; just removed from this list.", | ||
| group: "lists", | ||
| action: "delete", | ||
| icon: "user-minus", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "list", "unsubscribe"], | ||
| parameters: [ | ||
| credentialParam, | ||
| listIdParam, | ||
| { | ||
| name: "contactIds", | ||
| title: "Contact IDs", | ||
| description: "Comma-separated string OR array of contact IDs.", | ||
| dataType: "any", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 3, | ||
| }, | ||
| ], | ||
| returnType: "object", | ||
| errors: commonErrors, | ||
| example: 'sendgrid.removeFromList "my_sendgrid" "list-uuid" ["contact-id"]', | ||
| }, | ||
| // ── Reports ─────────────────────────────────────────────── | ||
| getStats: { | ||
| title: "Get email stats", | ||
| summary: "Aggregated delivery stats over a date range", | ||
| description: "Calls `GET /stats`. Returns daily breakdown of opens, clicks, bounces, etc.", | ||
| group: "reports", | ||
| action: "read", | ||
| icon: "bar-chart-3", | ||
| capability: "manage_options", | ||
| sideEffects: ["makes_http_call"], | ||
| idempotent: true, | ||
| since: "1.0.0", | ||
| tags: ["sendgrid", "stats", "reports"], | ||
| parameters: [ | ||
| credentialParam, | ||
| { | ||
| name: "options", | ||
| title: "Options", | ||
| description: "Recognized keys:\n start_date : YYYY-MM-DD (required)\n end_date : YYYY-MM-DD\n aggregated_by : 'day' (default) | 'week' | 'month'\n categories : array of categories to filter", | ||
| dataType: "object", | ||
| formInputType: "json", | ||
| required: true, | ||
| allowExpression: true, | ||
| language: "json", | ||
| rows: 4, | ||
| }, | ||
| ], | ||
| returnType: "array", | ||
| returnDescription: "Array of `{ date, stats: [{metrics: {…}}] }` entries.", | ||
| errors: commonErrors, | ||
| example: 'sendgrid.getStats "my_sendgrid" {start_date:"2026-04-01"}', | ||
| }, | ||
| }; | ||
| // ── Exports: module metadata ─────────────────────────────────────────── | ||
| export const SendgridModuleMetadata = { | ||
| slug: "sendgrid", | ||
| title: "SendGrid", | ||
| summary: "Transactional email (Mail Send v3) + marketing contacts, lists, templates, stats", | ||
| description: "Use SendGrid when `wp_mail` isn't enough — high deliverability, click tracking, dynamic templates, dedicated IPs.\n\nFor transactional sends, use `sendEmail` (raw HTML/text) or `sendTemplate` (SendGrid dynamic template with substitutions). For newsletters, use `addContact` + lists. `getStats` returns delivery/open/click metrics.", | ||
| category: "marketing", | ||
| icon: "icon.svg", | ||
| color: "#1A82E2", | ||
| version: "0.2.0", | ||
| docsUrl: "https://docs.robinpath.com/modules/sendgrid", | ||
| status: "stable", | ||
| requires: [], | ||
| minNodeVersion: "18.0.0", | ||
| credentialsType: CREDENTIAL_TYPE, | ||
| operationGroups: { | ||
| send: { | ||
| title: "Send", | ||
| description: "Transactional email + dynamic templates.", | ||
| order: 1, | ||
| }, | ||
| contacts: { | ||
| title: "Contacts", | ||
| description: "Marketing contacts CRUD.", | ||
| order: 2, | ||
| }, | ||
| lists: { | ||
| title: "Lists", | ||
| description: "Audience segmentation.", | ||
| order: 3, | ||
| }, | ||
| reports: { | ||
| title: "Reports", | ||
| description: "Aggregated stats.", | ||
| order: 4, | ||
| }, | ||
| }, | ||
| methods: Object.keys(SendgridFunctions), | ||
| }; | ||
| //# sourceMappingURL=sendgrid.js.map |
| {"version":3,"file":"sendgrid.js","sourceRoot":"","sources":["../src/sendgrid.ts"],"names":[],"mappings":"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"} |
+19
-8
| { | ||
| "name": "@robinpath/sendgrid", | ||
| "version": "0.1.1", | ||
| "version": "0.3.0", | ||
| "publishConfig": { | ||
@@ -23,12 +23,17 @@ "access": "public" | ||
| "peerDependencies": { | ||
| "@robinpath/core": ">=0.20.0" | ||
| "@robinpath/core": ">=0.40.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@robinpath/core": "^0.30.1", | ||
| "@robinpath/core": "^0.40.0", | ||
| "typescript": "^5.6.0" | ||
| }, | ||
| "description": "SendGrid module for RobinPath.", | ||
| "description": "SendGrid transactional email + marketing — send mail, dynamic templates, contact + list management, stats. Uses the encrypted credential vault for API keys.", | ||
| "keywords": [ | ||
| "sendgrid", | ||
| "email marketing" | ||
| "email marketing", | ||
| "email", | ||
| "transactional", | ||
| "marketing", | ||
| "newsletter", | ||
| "smtp" | ||
| ], | ||
@@ -38,7 +43,13 @@ "license": "MIT", | ||
| "category": "email-marketing", | ||
| "type": "integration", | ||
| "auth": "api-key", | ||
| "type": "module", | ||
| "auth": "credential-vault", | ||
| "functionCount": 20, | ||
| "baseUrl": "https://api.sendgrid.com/v3" | ||
| "baseUrl": "https://api.sendgrid.com/v3", | ||
| "language": "nodejs", | ||
| "platforms": [ | ||
| "cloud", | ||
| "cli", | ||
| "desktop" | ||
| ] | ||
| } | ||
| } |
+1
-1
@@ -22,3 +22,3 @@ # @robinpath/sendgrid | ||
| ```bash | ||
| npm install @robinpath/sendgrid | ||
| robinpath add @robinpath/sendgrid | ||
| ``` | ||
@@ -25,0 +25,0 @@ |
AI-detected possible typosquat
Supply chain riskAI has identified this package as a potential typosquat of a more popular package. This suggests that the package may be intentionally mimicking another package's name, description, or other metadata.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Network access
Supply chain riskThis module accesses the network.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
64063
1093.2%10
400%853
Infinity%2
100%4
100%