Integraties

E-mail versturen vanuit Mistral AI

Mistral Function Calling in TypeScript — stuur e-mail via Wesender vanuit een Europees AI-model.

Agent-framework TypeScript Webhooks

Vereisten

  • Node.js 20+ en TypeScript
  • Wesender-account met API-sleutel
  • npm install @mistralai/mistralai @wesender/node
  • Omgevingsvariabelen: WESENDER_API_KEY en MISTRAL_API_KEY

Stap 1: Installeer de Mistral SDK en Wesender

Voeg de officiële Mistral TypeScript SDK en de Wesender Node SDK toe aan je project.

npm install @mistralai/mistralai @wesender/node

Stap 2: Definieer send_email als Mistral-tool

Mistral Function Calling gebruikt een JSON-schema vergelijkbaar met OpenAI. Definieer de tool met naam, beschrijving en parameterspecificatie.

const tools = [
  {
    type: "function" as const,
    function: {
      name: "send_email",
      description: "Verstuur een e-mail via Wesender",
      parameters: {
        type: "object",
        properties: {
          to:      { type: "string", description: "E-mailadres van de ontvanger" },
          subject: { type: "string", description: "Onderwerpregel van de e-mail" },
          html:    { type: "string", description: "HTML-inhoud van de e-mail"   },
        },
        required: ["to", "subject", "html"],
      },
    },
  },
]

Stap 3: Voer de tool uit via Wesender

Verwerk de tool call die Mistral teruggeeft en stuur het resultaat terug als tool-bericht in de conversatie.

import { Wesender } from "@wesender/node"

const emailClient = new Wesender(process.env.WESENDER_API_KEY!)

async function executeTool(name: string, args: Record<string, string>) {
  if (name === "send_email") {
    const result = await emailClient.emails.send({
      from:    "noreply@jouwdomein.nl",
      to:      args.to,
      subject: args.subject,
      html:    args.html,
    })
    return JSON.stringify({ success: true, id: result.id })
  }
  throw new Error(`Onbekende tool: ${name}`)
}

Stap 4: Bouw de agent-lus

Stuur het bericht naar Mistral, verwerk eventuele tool calls en herhaal totdat Mistral een definitief antwoord geeft.

import Mistral from "@mistralai/mistralai"

const mistral = new Mistral({ apiKey: process.env.MISTRAL_API_KEY! })

const messages: any[] = [
  { role: "user", content: "Stuur een welkomstmail naar jan@voorbeeld.nl." },
]

let response = await mistral.chat.complete({
  model: "mistral-large-latest",
  messages,
  tools,
  toolChoice: "auto",
})

while (response.choices?.[0].finishReason === "tool_calls") {
  const toolCalls = response.choices[0].message.toolCalls!
  messages.push(response.choices[0].message)
  for (const call of toolCalls) {
    const args = JSON.parse(call.function.arguments as string)
    const output = await executeTool(call.function.name, args)
    messages.push({ role: "tool", toolCallId: call.id, content: output })
  }
  response = await mistral.chat.complete({ model: "mistral-large-latest", messages, tools })
}

console.log(response.choices?.[0].message.content)

Volledig voorbeeld

Hier is de volledige implementatie in mistral-email-agent.ts:

import Mistral from "@mistralai/mistralai"
import { Wesender } from "@wesender/node"

const mistral = new Mistral({ apiKey: process.env.MISTRAL_API_KEY! })
const emailClient = new Wesender(process.env.WESENDER_API_KEY!)

const tools = [{
  type: "function" as const,
  function: {
    name: "send_email",
    description: "Verstuur een e-mail via Wesender",
    parameters: {
      type: "object",
      properties: {
        to:      { type: "string" },
        subject: { type: "string" },
        html:    { type: "string" },
      },
      required: ["to", "subject", "html"],
    },
  },
}]

async function runAgent(userMessage: string) {
  const messages: any[] = [{ role: "user", content: userMessage }]

  let response = await mistral.chat.complete({
    model: "mistral-large-latest",
    messages,
    tools,
    toolChoice: "auto",
  })

  while (response.choices?.[0].finishReason === "tool_calls") {
    const toolCalls = response.choices[0].message.toolCalls!
    messages.push(response.choices[0].message)
    for (const call of toolCalls) {
      const args = JSON.parse(call.function.arguments as string)
      const result = await emailClient.emails.send({
        from:    "noreply@jouwdomein.nl",
        to:      args.to,
        subject: args.subject,
        html:    args.html,
      })
      messages.push({
        role: "tool",
        toolCallId: call.id,
        content: JSON.stringify({ success: true, id: result.id }),
      })
    }
    response = await mistral.chat.complete({ model: "mistral-large-latest", messages, tools })
  }

  return response.choices?.[0].message.content
}

console.log(await runAgent(
  "Stuur een welkomstmail naar jan@voorbeeld.nl met als onderwerp 'Welkom'."
))

Bezorgstatussen via webhooks

Mistral AI kan bezorg-, bounce- en klachtsignalen ontvangen via webhooks. Configureer een webhook-endpoint in je Mistral AI-workflow dat POST-verzoeken van Wesender accepteert. Zie Webhooks instellen voor de volledige configuratiestappen en het payload-formaat.

Veelgestelde vragen

Welke Mistral-modellen ondersteunen function calling?

Mistral Large, Mistral Medium en Mistral Small ondersteunen allen function calling. Voor productie raden we mistral-large-latest aan vanwege de hogere nauwkeurigheid bij tool-selectie.

Zijn Mistral-inferentie en Wesender-data beide Europees?

Mistral verwerkt inferentie op servers in Europa. Wesender verwerkt e-mailbezorging in Europese datacenters. Je AI-workflow blijft volledig binnen de EER.

Hoe verwerk ik meerdere parallelle tool calls?

Mistral kan meerdere tool calls in één response teruggeven. Gebruik Promise.all om alle calls gelijktijdig te verwerken: await Promise.all(toolCalls.map(call => executeTool(...))). Voeg alle resultaten als tool-berichten toe vóór de volgende request.

Volgende stappen