twilio.ts•3.97 kB
import { BaseApiClient } from "../../core/base-api.js";
import { loadConfig } from "../../core/config.js";
import { ToolRegistration } from "../../core/types.js";
class TwilioClient extends BaseApiClient {
private readonly accountSid: string;
private readonly authToken: string;
private readonly authHeader: string;
constructor(accountSid: string, authToken: string) {
super("https://api.twilio.com/2010-04-01");
this.accountSid = accountSid;
this.authToken = authToken;
this.authHeader = Buffer.from(`${accountSid}:${authToken}`).toString("base64");
}
sendSms(to: string, from: string, body: string) {
const form = new URLSearchParams({ To: to, From: from, Body: body });
return this.request(`/Accounts/${this.accountSid}/Messages.json`, {
method: "POST",
headers: { Authorization: `Basic ${this.authHeader}`, "content-type": "application/x-www-form-urlencoded" },
body: form as any,
});
}
makeCall(to: string, from: string, twimlUrl: string) {
const form = new URLSearchParams({ To: to, From: from, Url: twimlUrl });
return this.request(`/Accounts/${this.accountSid}/Calls.json`, {
method: "POST",
headers: { Authorization: `Basic ${this.authHeader}`, "content-type": "application/x-www-form-urlencoded" },
body: form as any,
});
}
getMessageHistory(fromDate?: string) {
return this.request(`/Accounts/${this.accountSid}/Messages.json`, {
headers: { Authorization: `Basic ${this.authHeader}` },
query: fromDate ? { DateSent: fromDate } : undefined,
});
}
}
export function registerTwilio(): ToolRegistration {
const cfg = loadConfig();
const client = new TwilioClient(cfg.twilioAccountSid || "", cfg.twilioAuthToken || "");
return {
tools: [
{
name: "send_sms",
description: "Send an SMS via Twilio",
inputSchema: {
type: "object",
properties: { to: { type: "string" }, from: { type: "string" }, body: { type: "string" } },
required: ["to", "from", "body"],
},
},
{
name: "make_call",
description: "Make a phone call via Twilio with a TwiML URL",
inputSchema: {
type: "object",
properties: { to: { type: "string" }, from: { type: "string" }, twiml_url: { type: "string" } },
required: ["to", "from", "twiml_url"],
},
},
{
name: "get_message_history",
description: "List message history optionally since a date",
inputSchema: {
type: "object",
properties: { from_date: { type: "string" } },
},
},
],
handlers: {
async send_sms(args: Record<string, unknown>) {
if (!cfg.twilioAccountSid || !cfg.twilioAuthToken) throw new Error("TWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKEN are not configured");
const to = String(args.to || "");
const from = String(args.from || "");
const body = String(args.body || "");
if (!to || !from || !body) throw new Error("to, from, body are required");
return client.sendSms(to, from, body);
},
async make_call(args: Record<string, unknown>) {
if (!cfg.twilioAccountSid || !cfg.twilioAuthToken) throw new Error("TWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKEN are not configured");
const to = String(args.to || "");
const from = String(args.from || "");
const twimlUrl = String(args.twiml_url || "");
if (!to || !from || !twimlUrl) throw new Error("to, from, twiml_url are required");
return client.makeCall(to, from, twimlUrl);
},
async get_message_history(args: Record<string, unknown>) {
if (!cfg.twilioAccountSid || !cfg.twilioAuthToken) throw new Error("TWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKEN are not configured");
const fromDate = args.from_date ? String(args.from_date) : undefined;
return client.getMessageHistory(fromDate);
},
},
};
}