E-mail versturen vanuit OpenAI function calling
Definieer Wesender als OpenAI-tool zodat GPT-4o zelf besluit wanneer en naar wie er gemaild wordt.
Vereisten
- Wesender-account met geverifieerd verzenddomein
- API-sleutel (WESENDER_API_KEY)
- OpenAI API-sleutel (OPENAI_API_KEY)
- Node.js 18 of nieuwer
Stap 1: Installeer de packages
Installeer de OpenAI SDK en de Wesender SDK.
npm install openai @wesender/node Stap 2: Definieer het tool-schema
Beschrijf de send_email-functie als een OpenAI-tool. Het model gebruikt de description en parameters om te beslissen wanneer en hoe het de tool aanroept.
import OpenAI from "openai"
const tools: OpenAI.Chat.ChatCompletionTool[] = [
{
type: "function",
function: {
name: "send_email",
description: "Verstuur een e-mail via Wesender",
parameters: {
type: "object",
properties: {
to: { type: "string", description: "Ontvanger-e-mailadres" },
subject: { type: "string", description: "Onderwerpregel" },
html: { type: "string", description: "HTML-inhoud van het bericht" },
},
required: ["to", "subject", "html"],
},
},
},
] Stap 3: Schrijf de tool-handler
Verwerk de tool-aanroep en stuur de e-mail via Wesender. Het resultaat geef je terug als tool-bericht zodat het model de uitkomst kent.
import { Wesender } from "@wesender/node"
const emailClient = new Wesender(process.env.WESENDER_API_KEY!)
async function handleToolCall(
toolCallId: string,
args: { to: string; subject: string; html: string }
): Promise<OpenAI.Chat.ChatCompletionToolMessageParam> {
try {
await emailClient.emails.send({
from: "agent@jouwdomein.nl",
to: args.to,
subject: args.subject,
html: args.html,
})
return { role: "tool", tool_call_id: toolCallId, content: "E-mail verstuurd" }
} catch (err) {
return { role: "tool", tool_call_id: toolCallId, content: "Fout: " + String(err) }
}
} Stap 4: Bouw de agent-loop
Roep het model aan in een loop totdat het stopt met tool-aanroepen. Dit patroon werkt met alle modellen die de tools-parameter ondersteunen.
const openai = new OpenAI()
async function runAgent(userPrompt: string): Promise<string> {
const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
{ role: "user", content: userPrompt },
]
while (true) {
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages,
tools,
tool_choice: "auto",
})
const choice = response.choices[0]
messages.push(choice.message)
if (choice.finish_reason === "stop") return choice.message.content ?? ""
for (const call of choice.message.tool_calls ?? []) {
if (call.function.name === "send_email") {
const args = JSON.parse(call.function.arguments)
messages.push(await handleToolCall(call.id, args))
}
}
}
} Volledig voorbeeld
Hier is de volledige implementatie in agent.ts:
import OpenAI from "openai"
import { Wesender } from "@wesender/node"
const openai = new OpenAI()
const emailClient = new Wesender(process.env.WESENDER_API_KEY!)
// Tool-schema
const tools: OpenAI.Chat.ChatCompletionTool[] = [
{
type: "function",
function: {
name: "send_email",
description: "Verstuur een transactionele e-mail via Wesender",
parameters: {
type: "object",
properties: {
to: { type: "string", description: "Ontvanger-e-mailadres" },
subject: { type: "string", description: "Onderwerpregel" },
html: { type: "string", description: "HTML-inhoud van het bericht" },
},
required: ["to", "subject", "html"],
},
},
},
]
// Tool-handler
async function handleToolCall(
toolCallId: string,
name: string,
rawArgs: string
): Promise<OpenAI.Chat.ChatCompletionToolMessageParam> {
if (name !== "send_email") {
return { role: "tool", tool_call_id: toolCallId, content: "Onbekend tool" }
}
try {
const args = JSON.parse(rawArgs) as { to: string; subject: string; html: string }
await emailClient.emails.send({
from: "agent@jouwdomein.nl",
to: args.to,
subject: args.subject,
html: args.html,
})
return { role: "tool", tool_call_id: toolCallId, content: "E-mail verstuurd" }
} catch (err) {
return { role: "tool", tool_call_id: toolCallId, content: "Fout: " + String(err) }
}
}
// Agent-loop
async function runAgent(userPrompt: string): Promise<string> {
const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
{ role: "user", content: userPrompt },
]
while (true) {
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages,
tools,
tool_choice: "auto",
})
const choice = response.choices[0]
messages.push(choice.message)
if (choice.finish_reason === "stop") return choice.message.content ?? ""
for (const call of choice.message.tool_calls ?? []) {
messages.push(await handleToolCall(call.id, call.function.name, call.function.arguments))
}
}
}
// Voorbeeld
const output = await runAgent("Stuur een welkomstmail naar jan@jouwdomein.nl")
console.log(output) Bezorgstatussen via webhooks
OpenAI function calling kan bezorg-, bounce- en klachtsignalen ontvangen via webhooks. Configureer een webhook-endpoint in je OpenAI function calling-workflow dat POST-verzoeken van Wesender accepteert. Zie Webhooks instellen voor de volledige configuratiestappen en het payload-formaat.
Veelgestelde vragen
Werkt dit ook met Anthropic Claude-modellen?
Ja, maar dan gebruik je de Anthropic SDK in plaats van openai. Het patroon is vergelijkbaar: definieer tools als JSON-schema, verwerk tool_use-blokken in de response en stuur tool_result-blokken terug. De Wesender-handler blijft hetzelfde.
Hoe beperk ik wat het model mag mailen?
Voeg validatie toe in de handler vóór de emailClient.emails.send()-aanroep. Controleer het ontvangeradres op een toegestane lijst, filter onderwerpen of begrens het HTML-formaat. Het model heeft geen directe toegang tot de API, alleen via jouw handler.
Kan ik bijlagen meesturen via function calling?
Ja. Voeg een attachments-parameter toe aan het tool-schema en verwerk die in de handler. Geef bijlagen base64-gecodeerd mee in de attachments-array van de Wesender API-aanroep.