← back to Dw Install Docs
canned/send.mjs
61 lines
#!/usr/bin/env node
// Send a canned reply (with its attachments) via George's /api/send-with-attachment.
// Usage: node canned/send.mjs <response-id> <to-email> [account]
// account defaults to "info" (info@designerwallcoverings.com). Only "info" or
// "steve-office" are supported by the George route.
// Auth + endpoint are read from the george MCP env in ~/.claude.json (the same
// credential the mcp__george__ tools use) — no separate secret to manage.
import fs from "node:fs";
import path from "node:path";
const [, , id, to, accountArg] = process.argv;
if (!id || !to) {
console.error("Usage: node canned/send.mjs <response-id> <to-email> [account]");
process.exit(1);
}
const account = accountArg || "info";
const repo = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
// 1. Load the canned response
const store = JSON.parse(fs.readFileSync(path.join(repo, "canned/responses.json"), "utf8"));
const r = store.responses.find((x) => x.id === id);
if (!r) {
console.error(`No canned response "${id}". Available: ${store.responses.map((x) => x.id).join(", ")}`);
process.exit(1);
}
// 2. Read George auth/endpoint from ~/.claude.json mcpServers.george.env
const cfg = JSON.parse(fs.readFileSync(path.join(process.env.HOME, ".claude.json"), "utf8"));
let env = null;
(function walk(o) {
for (const k in o) {
if (k === "mcpServers" && o[k] && o[k].george) { env = o[k].george.env; return; }
if (o[k] && typeof o[k] === "object") walk(o[k]);
if (env) return;
}
})(cfg);
if (!env || !env.GEORGE_BASIC_AUTH) { console.error("No george MCP auth in ~/.claude.json"); process.exit(1); }
const base = (env.GEORGE_URL || "https://kamatera.tail79cb8e.ts.net:9850").replace(/\/$/, "");
const MIME = { ".pdf": "application/pdf", ".doc": "application/msword", ".png": "image/png", ".jpg": "image/jpeg" };
const attachments = (r.attachments || []).map((rel) => {
const p = path.join(repo, rel);
return {
filename: path.basename(rel),
content_base64: fs.readFileSync(p).toString("base64"),
mime_type: MIME[path.extname(rel).toLowerCase()] || "application/octet-stream",
};
});
const headers = { "Content-Type": "application/json", Authorization: "Basic " + env.GEORGE_BASIC_AUTH };
if (env.GEORGE_EXTERNAL_SEND_TOKEN) headers["X-Send-Approval"] = env.GEORGE_EXTERNAL_SEND_TOKEN;
const res = await fetch(base + "/api/send-with-attachment", {
method: "POST",
headers,
body: JSON.stringify({ account, to, subject: r.subject, body: r.body, attachments }),
});
console.log("HTTP", res.status);
console.log(await res.text());
if (!res.ok) process.exit(1);