# Introductie Wesender is een transactionele e-mail API voor Nederlandse developers. Verstuur e-mails via een REST API of SMTP-relay, gehost in Europese datacenters. ## Wat is Wesender? Wesender is het Nederlandse alternatief voor Resend, Postmark en SendGrid. Je verbindt je eigen domein, configureert SPF, DKIM en DMARC via DNS en verstuurt daarna e-mails via REST of SMTP. - Data in Europese datacenters - Betalen via iDEAL, Wero of automatische incasso, geen creditcard nodig - Realtime bezorgstatistieken per domein - Webhooks voor bezorging, bounces en klachten ## Hoe werkt het? 1. Domein toevoegen: voeg je verzenddomein toe in het dashboard en configureer de DNS-records (SPF, DKIM, DMARC). 2. API-key aanmaken: genereer een API-key en sla deze veilig op. 3. E-mails versturen: stuur een POST-request naar `https://api.wesender.nl/emails`. ## Vereisten - Een domein waarvan je de DNS-records kunt beheren - Een gratis account op wesender.nl (3.000 e-mails per maand, geen creditcard nodig) --- # Quickstart Van nul tot je eerste verzonden e-mail in minder dan vijf minuten. ## Stap 1: Account aanmaken Maak een gratis account aan op wesender.nl. De eerste 3.000 e-mails per maand zijn gratis, geen creditcard nodig. ## Stap 2: Verzenddomein toevoegen Ga naar Domeinen in het dashboard en voeg het (sub)domein toe. Je krijgt drie DNS-records terug: SPF, DKIM en DMARC. ## Stap 3: DNS-records instellen Stel de DNS-records in via je domeinregistrar en wacht op verificatie (maximaal 15 minuten). ## Stap 4: API-key aanmaken Ga naar API-sleutels in het dashboard en maak een sleutel aan. Sla hem op als omgevingsvariabele: `WS_API_KEY`. ## Stap 5: Eerste e-mail versturen ### cURL ```bash curl -X POST https://api.wesender.nl/emails \ -H "Authorization: Bearer $WS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "from": "noreply@joudomein.nl", "to": ["jij@voorbeeld.nl"], "subject": "Hallo van Wesender", "html": "

Het werkt!

Je eerste mail via Wesender.

" }' ``` ### Node.js ```bash npm install @wesender/node ``` ```typescript import { Wesender } from "@wesender/node" const ws = new Wesender(process.env.WS_API_KEY!) const { id } = await ws.emails.send({ from: "noreply@joudomein.nl", to: ["jij@voorbeeld.nl"], subject: "Hallo van Wesender", html: "

Het werkt!

Je eerste mail via Wesender.

", }) console.log("Verstuurd:", id) ``` ### Respons ```json { "id": "em_01hwxxxxxxxxxxxxxx", "object": "email" } ``` --- # Domein instellen Voordat je e-mails kunt versturen moet je een afzenderdomein toevoegen en DNS-records instellen. Wesender verifieert de records automatisch zodra ze zijn gepropageerd. ## Stap 1: Domein toevoegen Ga naar Domeinen in het dashboard en voeg het (sub)domein toe. Gebruik bij voorkeur een subdomein zoals `mail.joudomein.nl`. ## Stap 2: DNS-records instellen ### SPF-record ``` Type: TXT Naam: mail.joudomein.nl Waarde: v=spf1 include:spf.wesender.nl ~all ``` Als je al een SPF-record hebt, voeg dan `include:spf.wesender.nl` toe aan het bestaande record. ### DKIM-record ``` Type: TXT Naam: postal-wesender._domainkey.mail.joudomein.nl Waarde: v=DKIM1; k=rsa; p= ``` De exacte sleutelwaarde vind je in het dashboard. ### DMARC-record ``` Type: TXT Naam: _dmarc.mail.joudomein.nl Waarde: v=DMARC1; p=quarantine; rua=mailto:dmarc@wesender.nl ``` ### Return Path NS-record ``` Type: NS Naam: psrp.mail.joudomein.nl Waarde: ns1.wesender.nl ``` ## Stap 3: Verificatie afwachten Wesender controleert de records elke minuut. Propagatie duurt doorgaans 5 tot 15 minuten, soms langer afhankelijk van je DNS-provider. --- # API-overzicht De Wesender REST API is bereikbaar op `https://api.wesender.nl`. ## Authenticatie Stuur een Bearer-token mee in de `Authorization`-header: ``` Authorization: Bearer ws_live_... ``` API-sleutels maak je aan in het Wesender-dashboard onder API-sleutels. ## Eindpunten | Methode | Pad | Beschrijving | |---------|-------------------|------------------------------| | POST | /emails | E-mail versturen | | POST | /emails/batch | Tot 50 e-mails in een aanroep| | GET | /domains | Domeinen ophalen | | POST | /domains | Domein toevoegen | | DELETE | /domains/:id | Domein verwijderen | ## Foutcodes - 400: Ongeldige invoer - 401: Ongeldig of ontbrekend token - 422: Van-domein niet geverifieerd of niet compliant (SPF/DKIM/DMARC) - 429: Rate limit bereikt - 500: Interne serverfout --- # E-mail versturen **POST** `https://api.wesender.nl/emails` Verstuur een transactionele e-mail. Het `from`-domein moet geverifieerd zijn in het dashboard. ## Verzoekbody | Veld | Type | Verplicht | Beschrijving | |--------------|-----------------|-----------|---------------------------------------------------| | from | string | Ja | Afzenderadres, bijv. `"Naam "` | | to | string of array | Ja | Ontvanger(s) | | subject | string | Ja | Onderwerpregel | | html | string | Nee* | HTML-inhoud | | text | string | Nee* | Platte tekstinhoud | | cc | string of array | Nee | CC-ontvangers | | bcc | string of array | Nee | BCC-ontvangers | | reply_to | string of array | Nee | Reply-to adres | | attachments | array | Nee | Bijlagen als Base64 | | headers | object | Nee | Aangepaste e-mailheaders | | tags | object | Nee | Metadata-labels voor filtering | *Minstens een van `html` of `text` is verplicht. ## Bijlagen ```json { "attachments": [ { "filename": "factuur.pdf", "content": "", "content_type": "application/pdf" } ] } ``` ## Voorbeelden ### cURL ```bash curl -X POST https://api.wesender.nl/emails \ -H "Authorization: Bearer $WS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "from": "noreply@joudomein.nl", "to": ["klant@voorbeeld.nl"], "subject": "Je bestelling is verzonden", "html": "

Op weg!

", "tags": { "flow": "checkout" } }' ``` ### Node.js ```typescript import { Wesender } from "@wesender/node" const ws = new Wesender(process.env.WS_API_KEY!) const { id } = await ws.emails.send({ from: "noreply@joudomein.nl", to: ["klant@voorbeeld.nl"], subject: "Je bestelling is verzonden", html: "

Op weg!

", tags: { flow: "checkout" }, }) ``` ## Respons ```json HTTP/1.1 201 Created { "id": "em_01hwxxxxxxxxxxxxxx", "object": "email" } ``` ## Fout: domein niet geverifieerd ```json HTTP/1.1 422 Unprocessable Entity { "error": "unprocessable_entity", "message": "from-domein is niet geverifieerd of niet compliant (SPF/DKIM/DMARC)" } ``` --- # Batch versturen **POST** `https://api.wesender.nl/emails/batch` Stuur tot 50 e-mails in een aanroep. Elke e-mail wordt onafhankelijk verwerkt: een fout in een bericht laat de rest ongemoeid. ## Verzoekbody Array van e-mailobjecten, elk met dezelfde velden als `POST /emails`. ## Voorbeeld ### cURL ```bash curl -X POST https://api.wesender.nl/emails/batch \ -H "Authorization: Bearer $WS_API_KEY" \ -H "Content-Type: application/json" \ -d '[ { "from": "noreply@joudomein.nl", "to": ["alice@voorbeeld.nl"], "subject": "Wekelijks rapport", "html": "

Hoi Alice.

" }, { "from": "noreply@joudomein.nl", "to": ["bob@voorbeeld.nl"], "subject": "Wekelijks rapport", "html": "

Hoi Bob.

" } ]' ``` ### Node.js ```typescript const results = await ws.emails.sendBatch([ { from: "noreply@joudomein.nl", to: ["alice@voorbeeld.nl"], subject: "Rapport", html: "

Hoi Alice.

" }, { from: "noreply@joudomein.nl", to: ["bob@voorbeeld.nl"], subject: "Rapport", html: "

Hoi Bob.

" }, ]) // results[0].id, results[1].id ``` ## Respons ```json HTTP/1.1 201 Created [ { "id": "em_01hwaaaaaaaaaa", "object": "email" }, { "id": "em_01hwbbbbbbbbbb", "object": "email" } ] ``` --- # Bijlagen Stuur bestanden mee via het `attachments`-veld in de verzoekbody van `POST /emails`. ## Velden per bijlage | Veld | Type | Verplicht | Beschrijving | |--------------|--------|-----------|-------------------------------------| | filename | string | Ja | Bestandsnaam inclusief extensie | | content | string | Ja | Bestandsinhoud als Base64-string | | content_type | string | Nee | MIME-type, bijv. `application/pdf` | ## Voorbeeld ```typescript import { readFileSync } from "fs" await ws.emails.send({ from: "noreply@joudomein.nl", to: ["klant@voorbeeld.nl"], subject: "Je factuur", html: "

Zie bijlage.

", attachments: [{ filename: "factuur-2026-01.pdf", content: readFileSync("./factuur.pdf").toString("base64"), content_type: "application/pdf", }], }) ``` ## Ondersteunde bestandstypen Elk MIME-type wordt ondersteund: PDF, afbeeldingen (PNG, JPEG, GIF), CSV, DOCX, ZIP en andere. --- # Domeinen Beheer je verzenderdomeinen via de REST API. ## Domeinen ophalen **GET** `https://api.wesender.nl/domains` ```bash curl https://api.wesender.nl/domains \ -H "Authorization: Bearer $WS_API_KEY" ``` Respons: array van domeinobjecten met `id`, `name`, `status` en `records`. ## Domein toevoegen **POST** `https://api.wesender.nl/domains` ```json { "name": "mail.joudomein.nl" } ``` Respons: domeinobject inclusief de te configureren DNS-records. ## Domein verwijderen **DELETE** `https://api.wesender.nl/domains/:id` ```bash curl -X DELETE https://api.wesender.nl/domains/dom_01hwxxxxxxxxxx \ -H "Authorization: Bearer $WS_API_KEY" ``` ## Domeinstatussen - `pending`: DNS-records nog niet geverifieerd - `active`: alle records geverifieerd, klaar voor verzending - `failed`: verificatie mislukt --- # Node.js / TypeScript SDK Officiële SDK met volledige TypeScript-types en async/await. Werkt met Node.js 18+, Bun en Deno. GitHub: https://github.com/wesender/wesender-node ## Installatie ```bash npm install @wesender/wesender-node # of bun add @wesender/wesender-node ``` ## Initialisatie ```typescript import { Wesender } from "@wesender/wesender-node" export const ws = new Wesender(process.env.WS_API_KEY!) ``` ## E-mail versturen ```typescript const { id, status } = await ws.emails.send({ from: "noreply@joudomein.nl", to: "klant@voorbeeld.nl", subject: "Welkom!", html: "

Bedankt voor je registratie.

", }) // id: "em_01hw...", status: "queued" ``` ## Meerdere ontvangers en CC ```typescript await ws.emails.send({ from: "noreply@joudomein.nl", to: ["a@voorbeeld.nl", "b@voorbeeld.nl"], cc: ["manager@bedrijf.nl"], bcc: ["audit@bedrijf.nl"], subject: "Maandelijks rapport", html: "

Zie bijlage.

", }) ``` ## Batch versturen ```typescript const results = await ws.emails.sendBatch([ { from: "noreply@joudomein.nl", to: "a@voorbeeld.nl", subject: "Rapport", html: "

Hoi A.

" }, { from: "noreply@joudomein.nl", to: "b@voorbeeld.nl", subject: "Rapport", html: "

Hoi B.

" }, ]) ``` --- # Python SDK Officiële Python SDK voor Wesender. ## Installatie ```bash pip install wesender ``` ## Gebruik ```python import os from wesender import Wesender ws = Wesender(os.environ["WS_API_KEY"]) response = ws.emails.send({ "from": "noreply@joudomein.nl", "to": ["klant@voorbeeld.nl"], "subject": "Welkom!", "html": "

Bedankt voor je registratie.

", }) print(response.id) ``` ## Batch versturen ```python results = ws.emails.send_batch([ {"from": "noreply@joudomein.nl", "to": ["a@voorbeeld.nl"], "subject": "Rapport", "html": "

Hoi A.

"}, {"from": "noreply@joudomein.nl", "to": ["b@voorbeeld.nl"], "subject": "Rapport", "html": "

Hoi B.

"}, ]) ``` --- # PHP SDK Officiële PHP SDK voor Wesender. ## Installatie ```bash composer require wesender/wesender-php ``` ## Gebruik ```php emails->send([ 'from' => 'noreply@joudomein.nl', 'to' => ['klant@voorbeeld.nl'], 'subject' => 'Welkom!', 'html' => '

Bedankt voor je registratie.

', ]); echo $response->id; ``` --- # Go SDK Officieel Go-pakket voor Wesender. ## Installatie ```bash go get github.com/wesender/wesender-go ``` ## Gebruik ```go package main import ( "context" "os" "github.com/wesender/wesender-go" ) func main() { ws := wesender.New(os.Getenv("WS_API_KEY")) resp, err := ws.Emails.Send(context.Background(), wesender.SendEmailParams{ From: "noreply@joudomein.nl", To: []string{"klant@voorbeeld.nl"}, Subject: "Welkom!", HTML: "

Bedankt.

", }) if err != nil { panic(err) } _ = resp.ID } ``` --- # Ruby SDK Officieel Ruby-gem voor Wesender. ## Installatie ```bash gem install wesender ``` ## Gebruik ```ruby require "wesender" ws = Wesender::Client.new(ENV["WS_API_KEY"]) response = ws.emails.send( from: "noreply@joudomein.nl", to: ["klant@voorbeeld.nl"], subject: "Welkom!", html: "

Bedankt voor je registratie.

" ) puts response.id ``` --- # Rust SDK Officieel Rust-crate voor Wesender. ## Installatie ```toml [dependencies] wesender = "1" ``` ## Gebruik ```rust use wesender::{Wesender, SendEmailParams}; #[tokio::main] async fn main() { let ws = Wesender::new(std::env::var("WS_API_KEY").unwrap()); let resp = ws.emails().send(SendEmailParams { from: "noreply@joudomein.nl".into(), to: vec!["klant@voorbeeld.nl".into()], subject: "Welkom!".into(), html: Some("

Bedankt.

".into()), ..Default::default() }).await.unwrap(); println!("{}", resp.id); } ``` --- # Java SDK Officieel Java-pakket voor Wesender. ## Installatie ### Maven ```xml nl.wesender wesender-java 1.0.0 ``` ### Gradle ```groovy implementation 'nl.wesender:wesender-java:1.0.0' ``` ## Gebruik ```java import nl.wesender.Wesender; import nl.wesender.params.SendEmailParams; Wesender ws = new Wesender(System.getenv("WS_API_KEY")); SendEmailParams params = SendEmailParams.builder() .from("noreply@joudomein.nl") .to(List.of("klant@voorbeeld.nl")) .subject("Welkom!") .html("

Bedankt.

") .build(); String id = ws.emails().send(params).getId(); ``` --- # .NET / C# SDK Officieel .NET-pakket voor Wesender. ## Installatie ```bash dotnet add package Wesender ``` ## Gebruik ```csharp using Wesender; var ws = new WesenderClient(Environment.GetEnvironmentVariable("WS_API_KEY")!); var response = await ws.Emails.SendAsync(new SendEmailParams { From = "noreply@joudomein.nl", To = new[] { "klant@voorbeeld.nl" }, Subject = "Welkom!", Html = "

Bedankt voor je registratie.

", }); Console.WriteLine(response.Id); ``` --- # Elixir SDK Officieel Elixir-pakket voor Wesender. ## Installatie ```elixir # mix.exs def deps do [ {:wesender, "~> 1.0"} ] end ``` ## Gebruik ```elixir {:ok, %{id: id}} = Wesender.Emails.send(%{ from: "noreply@joudomein.nl", to: ["klant@voorbeeld.nl"], subject: "Welkom!", html: "

Bedankt voor je registratie.

" }) IO.puts(id) ``` --- # SMTP-relay Naast de REST API ondersteunt Wesender ook SMTP. Gebruik dit als je een bestaande applicatie hebt die via SMTP verstuurt. ## Instellingen | Instelling | Waarde | |----------------|--------------------------------------------| | Server | smtp.wesender.nl | | Poort | 587 (STARTTLS, aanbevolen) of 465 (SSL/TLS)| | Gebruikersnaam | Jouw geverifieerde afzenderadres | | Wachtwoord | Jouw API-key (ws_live_...) | | Beveiliging | STARTTLS of SSL/TLS | ## Nodemailer (Node.js) ```javascript import nodemailer from "nodemailer" const transporter = nodemailer.createTransport({ host: "smtp.wesender.nl", port: 587, secure: false, auth: { user: "noreply@joudomein.nl", pass: process.env.WS_API_KEY, }, }) await transporter.sendMail({ from: "noreply@joudomein.nl", to: "klant@voorbeeld.nl", subject: "Welkom!", html: "

Bedankt voor je aanmelding.

", }) ``` ## PHPMailer ```php isSMTP(); $mail->Host = 'smtp.wesender.nl'; $mail->SMTPAuth = true; $mail->Username = 'noreply@joudomein.nl'; $mail->Password = getenv('WS_API_KEY'); $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; ``` ## Compatibel met Laravel (Mail), Django (EMAIL_HOST), WordPress (WP Mail SMTP), Nodemailer, PHPMailer, Postfix en vrijwel elk ander systeem dat SMTP ondersteunt. --- # Webhooks Ontvang realtime HTTP POST-verzoeken bij e-mailactiviteit. ## Webhook aanmaken ```bash curl -X POST https://api.wesender.nl/webhooks \ -H "Authorization: Bearer $WS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://joudomein.nl/webhooks/wesender", "events": ["email.delivered", "email.bounced", "email.opened", "email.clicked", "email.failed"] }' ``` ## Beschikbare events | Event | Wanneer | |-----------------|------------------------------------------| | email.delivered | Bezorgd in de inbox van de ontvanger | | email.bounced | Permanent geweigerd (hard bounce) | | email.opened | Ontvanger heeft de e-mail geopend | | email.clicked | Ontvanger heeft een link geklikt | | email.failed | Tijdelijk leveringsprobleem | ## Payloads ### email.delivered ```json { "type": "email.delivered", "created_at": "2026-06-13T09:19:31Z", "data": { "id": "av276ywjkg15k2ku9j1xgrqe", "from": "noreply@joudomein.nl", "to": ["klant@voorbeeld.nl"], "subject": "Je bestelling is verzonden" } } ``` ### email.bounced ```json { "type": "email.bounced", "created_at": "2026-06-13T09:21:07Z", "data": { "id": "av276ywjkg15k2ku9j1xgrqe", "to": ["ongeldig@voorbeeld.nl"], "bounce_type": "hard", "bounce_message": "550 5.1.1 The email account does not exist" } } ``` ### email.clicked ```json { "type": "email.clicked", "created_at": "2026-06-13T09:26:01Z", "data": { "id": "av276ywjkg15k2ku9j1xgrqe", "click_url": "https://joudomein.nl/bestellingen/12345" } } ``` ## Verifieer de handtekening Elke payload bevat een HMAC-handtekening in de `X-Wesender-Signature`-header. Verifieer die om te bevestigen dat het verzoek van Wesender afkomstig is. --- # CLI Stuur e-mails en beheer je account vanuit de terminal. ## Installatie ```bash npm install -g @wesender/wesender-cli ``` ## Configuratie ```bash # API-key instellen wesender config set-key ws_live_... # Standaard afzender instellen wesender config set-from noreply@mail.joudomein.nl # Verbinding controleren wesender doctor ``` ## E-mail versturen ```bash wesender send \ --to klant@bedrijf.nl \ --subject "Welkom bij ons platform" \ --html "

Welkom!

" # Met expliciete afzender wesender send \ --from "Wesender " \ --to klant@bedrijf.nl \ --subject "Welkom" \ --html "

Bedankt voor je registratie.

" # JSON-output voor scripts wesender send --to x@y.nl --subject "Test" --html "

x

" --json ``` ## Domeinen beheren ```bash # Alle domeinen bekijken wesender domains list # Nieuw domein toevoegen wesender domains add mail.joudomein.nl # DNS-status controleren wesender domains verify mail.joudomein.nl ``` ## Logs ```bash # Laatste 50 e-mails wesender logs # Live streamen wesender logs --follow # Filteren op status wesender logs --status bounced --limit 100 ``` ## Authenticatie via omgevingsvariabele ```bash export WS_API_KEY=ws_live_... wesender send --to x@y.nl --subject "Test" --html "

x

" ``` --- # Model Context Protocol + WeSender > Bouw een MCP-server die je AI-model rechtstreeks e-mails laat versturen via Wesender. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/mcp ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel (WESENDER_API_KEY) - Node.js 18 of nieuwer - Een MCP-client zoals Claude Desktop of een eigen implementatie ## Integratiestappen ### Stap 1: Installeer de benodigde packages Maak een nieuw Node.js-project aan en installeer de MCP SDK en de Wesender Node.js SDK. ### Stap 2: Definieer de send_email tool Registreer een ListTools-handler die jouw MCP-client vertelt welke tools beschikbaar zijn. De send_email tool accepteert from, to, subject en html. ### Stap 3: Verwerk de tool-aanroep De CallTool-handler ontvangt de argumenten van het AI-model en roept de Wesender API aan. Fouten worden teruggegeven zodat het model ze kan verwerken. ### Stap 4: Start de server en koppel aan je MCP-client Verbind de server met een StdioServerTransport en voeg hem toe aan de configuratie van je MCP-client. ## Volledig voorbeeld (src/index.ts) ```typescript import { Server } from "@modelcontextprotocol/sdk/server/index.js" import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js" import { Wesender } from "@wesender/node" const emailClient = new Wesender(process.env.WESENDER_API_KEY!) const server = new Server( { name: "wesender-mcp", version: "1.0.0" }, { capabilities: { tools: {} } } ) server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: "send_email", description: "Verstuur een transactionele e-mail via Wesender", inputSchema: { type: "object" as const, properties: { from: { type: "string", description: "Afzenderadres op je geverifieerde domein" }, to: { type: "string", description: "Ontvanger-e-mailadres" }, subject: { type: "string", description: "Onderwerpregel" }, html: { type: "string", description: "HTML-inhoud van het bericht" }, }, required: ["from", "to", "subject", "html"], }, }, ], })) server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name !== "send_email") { return { isError: true, content: [{ type: "text" as const, text: "Onbekend tool: " + request.params.name }], } } const { from, to, subject, html } = request.params.arguments as Record try { const result = await emailClient.emails.send({ from, to, subject, html }) return { content: [{ type: "text" as const, text: "E-mail verstuurd, id: " + result.id }], } } catch (err) { return { isError: true, content: [{ type: "text" as const, text: "Verzending mislukt: " + String(err) }], } } }) const transport = new StdioServerTransport() await server.connect(transport) ``` ## Veelgestelde vragen **Is dit een officiele Wesender MCP-server?** Nee, dit is een referentie-implementatie die laat zien hoe je de Wesender REST API omhult met het Model Context Protocol. Je kunt hem direct gebruiken of aanpassen aan je eigen situatie. **Welke MCP-clients werken met deze server?** Elke MCP-client die het Model Context Protocol ondersteunt, waaronder Claude Desktop, Cursor en zelfgebouwde clients via de officiiele MCP SDK. Voeg de serverconfiguratie toe aan het JSON-configuratiebestand van je client. **Kan ik meerdere tools toevoegen, zoals een tool om e-mailstatus op te vragen?** Ja. Voeg extra items toe aan de tools-array in de ListTools-handler en verwerk ze in de CallTool-handler. De Wesender API biedt ook endpoints voor berichtstatus en berichtgeschiedenis. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/mcp - Marketingpagina: https://wesender.nl/ai/integraties/mcp - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # LangChain + WeSender > Voeg Wesender toe als LangChain-tool zodat je agent e-mails kan versturen als onderdeel van een keten of graph. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/langchain ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel (WESENDER_API_KEY) - Node.js 18 of nieuwer - LangChain 0.3 of nieuwer (npm: @langchain/core, @langchain/openai) ## Integratiestappen ### Stap 1: Installeer de benodigde packages Installeer LangChain, de Wesender SDK en Zod voor schema-validatie. ### Stap 2: Definieer de Wesender-tool Gebruik de tool()-functie uit @langchain/core/tools om een gestructureerde tool te maken. Het Zod-schema beschrijft de parameters die de LLM kan invullen. ### Stap 3: Koppel de tool aan een agent Geef de tool mee aan een LangChain-agent. De agent beslist zelf wanneer hij de tool aanroept op basis van de conversatie. ## Volledig voorbeeld (agent.ts) ```typescript import { tool } from "@langchain/core/tools" import { createOpenAIFunctionsAgent, AgentExecutor } from "langchain/agents" import { ChatOpenAI } from "@langchain/openai" import { ChatPromptTemplate } from "@langchain/core/prompts" import { z } from "zod" import { Wesender } from "@wesender/node" const emailClient = new Wesender(process.env.WESENDER_API_KEY!) // Wesender als gestructureerde LangChain-tool const sendEmailTool = tool( async ({ from, to, subject, html }) => { try { await emailClient.emails.send({ from, to, subject, html }) return "E-mail verstuurd naar " + to } catch (err) { return "Verzending mislukt: " + String(err) } }, { name: "send_email", description: "Verstuur een transactionele e-mail via Wesender", schema: z.object({ from: z.string().describe("Afzenderadres op je geverifieerde domein"), to: z.string().describe("Ontvanger-e-mailadres"), subject: z.string().describe("Onderwerpregel"), html: z.string().describe("HTML-inhoud van het bericht"), }), } ) // Agent met de tool const llm = new ChatOpenAI({ model: "gpt-4o", temperature: 0 }) const prompt = ChatPromptTemplate.fromMessages([ ["system", "Je bent een behulpzame assistent. Gebruik send_email om e-mails te versturen."], ["human", "{input}"], ["placeholder", "{agent_scratchpad}"], ]) const agent = await createOpenAIFunctionsAgent({ llm, tools: [sendEmailTool], prompt }) const executor = new AgentExecutor({ agent, tools: [sendEmailTool], verbose: false }) const result = await executor.invoke({ input: process.argv[2] ?? "Stuur een testmail naar test@jouwdomein.nl" }) console.log(result.output) ``` ## Veelgestelde vragen **Werkt dit ook met LangGraph?** Ja. Je kunt sendEmailTool direct doorgeven als tool in een LangGraph-graph. Voeg hem toe aan de tools-lijst van een ToolNode en bind hem aan je LLM via llm.bindTools([sendEmailTool]). **Kan ik ook een Python-versie gebruiken?** Ja. Installeer langchain en wesender via pip. Maak een StructuredTool met from_function() en een Pydantic-model als args_schema. De Wesender Python SDK gebruikt wesender.Client(api_key=...).emails.send(...). **Hoe voorkom ik dat de agent twee keer dezelfde mail verstuurt?** LangChain biedt geen ingebouwde idempotentie. Voeg een controle toe in de tool-handler: sla een hash van (to, subject, tijdstip) op in een database en sla de verzending over als de hash al bestaat. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/langchain - Marketingpagina: https://wesender.nl/ai/integraties/langchain - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # OpenAI function calling + WeSender > Definieer Wesender als OpenAI-tool zodat GPT-4o zelf besluit wanneer en naar wie er gemaild wordt. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/openai-function-calling ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel (WESENDER_API_KEY) - OpenAI API-sleutel (OPENAI_API_KEY) - Node.js 18 of nieuwer ## Integratiestappen ### Stap 1: Installeer de packages Installeer de OpenAI SDK en de Wesender SDK. ### 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. ### 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. ### 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. ## Volledig voorbeeld (agent.ts) ```typescript 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 { 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 { 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) ``` ## 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. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/openai-function-calling - Marketingpagina: https://wesender.nl/ai/integraties/openai-function-calling - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Vercel AI SDK + WeSender > Voeg e-mail toe als tool in een generateText- of streamText-flow met de Vercel AI SDK. **Categorie:** multi | **URL:** https://docs.wesender.nl/docs/integraties/vercel-ai-sdk ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel (WESENDER_API_KEY) - Node.js 18 of nieuwer - Vercel AI SDK 4 of nieuwer (npm: ai, @ai-sdk/openai) ## Integratiestappen ### Stap 1: Installeer de packages Installeer de Vercel AI SDK, een modelprovider en de Wesender SDK. ### Stap 2: Definieer de send_email tool Gebruik de tool()-functie uit de ai-package. Het Zod-schema valideert de parameters die het model aanlevert en TypeScript weet automatisch wat de typen zijn in de execute-functie. ### Stap 3: Gebruik de tool in generateText Geef de tool mee aan generateText. Zet maxSteps hoger dan 1 zodat het model meerdere tool-aanroepen mag doen voordat het antwoordt. ## Volledig voorbeeld (agent.ts) ```typescript import { generateText, tool } from "ai" import { openai } from "@ai-sdk/openai" import { z } from "zod" import { Wesender } from "@wesender/node" const emailClient = new Wesender(process.env.WESENDER_API_KEY!) // Tool-definitie const sendEmailTool = tool({ description: "Verstuur een transactionele e-mail via Wesender", parameters: z.object({ to: z.string().describe("Ontvanger-e-mailadres"), subject: z.string().describe("Onderwerpregel"), html: z.string().describe("HTML-inhoud van het bericht"), }), execute: async ({ to, subject, html }) => { try { const result = await emailClient.emails.send({ from: "agent@jouwdomein.nl", to, subject, html, }) return { verstuurd: true, id: result.id } } catch (err) { return { verstuurd: false, fout: String(err) } } }, }) // Agent-run const { text, steps } = await generateText({ model: openai("gpt-4o"), system: "Je bent een behulpzame assistent. Gebruik send_email om e-mails te versturen.", prompt: process.argv[2] ?? "Stuur een testmail naar test@jouwdomein.nl", tools: { send_email: sendEmailTool }, maxSteps: 5, }) console.log(text) for (const step of steps) { if (step.toolCalls.length > 0) { console.log("Tool-aanroepen:", step.toolCalls) } } ``` ## Veelgestelde vragen **Werkt dit ook met streamText voor streaming-responses?** Ja. Vervang generateText door streamText en gebruik dezelfde tools-parameter. Tool-aanroepen worden ook gestreamd zodra het model ze aanroept. Het execute-resultaat is beschikbaar via de toolResults-stream. **Kan ik andere modelproviders gebruiken, zoals Anthropic of Google?** Ja. De Vercel AI SDK is modelprovider-onafhankelijk. Vervang openai('gpt-4o') door anthropic('claude-sonnet-4-5') of google('gemini-2.0-flash'). De tool-definitie en Wesender-aanroep blijven ongewijzigd. **Hoe koppel ik bezorgingsevents terug naar mijn flow?** Stel een webhook-endpoint in via het Wesender-dashboard. Wesender stuurt een POST naar dat endpoint bij elk bezorgingsevent (bezorgd, bounced, klacht). Je kunt de bezorgstatus opslaan en later ophalen als input voor een volgende stap in de flow. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/vercel-ai-sdk - Marketingpagina: https://wesender.nl/ai/integraties/vercel-ai-sdk - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # n8n + WeSender > Stuur e-mails vanuit n8n-workflows via de Wesender REST API, zonder code, met een HTTP Request-node. **Categorie:** workflow | **URL:** https://docs.wesender.nl/docs/integraties/n8n ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel (WESENDER_API_KEY) - n8n Cloud of zelfgehoste n8n instantie ## Integratiestappen ### Stap 1: Stel de API-credential in n8n in Ga naar Settings > Credentials in n8n. Maak een nieuwe 'Header Auth' credential aan met de naam 'Wesender API'. Zet de Header Name op 'Authorization' en de Value op 'Bearer JOUW_API_SLEUTEL'. ### Stap 2: Voeg een HTTP Request-node toe Voeg een HTTP Request-node toe aan je workflow. Kies 'POST' als methode en vul de Wesender API-URL in. Koppel de Wesender API-credential. ### Stap 3: Stel de body in met dynamische velden Gebruik n8n-expressies om waarden uit vorige nodes te gebruiken. Zo stuur je gepersonaliseerde e-mails op basis van data uit je workflow. ### Stap 4: Verwerk bezorgingsevents via een Webhook-node Voeg een Webhook-node toe in n8n en stel het endpoint in als Wesender-webhook in het dashboard. n8n ontvangt dan een POST bij elk bezorgingsevent. ## Volledig voorbeeld (wesender-n8n-flow.json) ```json { "name": "Wesender e-mail workflow", "nodes": [ { "name": "Trigger", "type": "n8n-nodes-base.manualTrigger", "position": [240, 300] }, { "name": "Stel data in", "type": "n8n-nodes-base.set", "position": [460, 300], "parameters": { "values": { "string": [ { "name": "email", "value": "ontvanger@jouwdomein.nl" }, { "name": "titel", "value": "Update van je workflow" }, { "name": "inhoud", "value": "De pijplijn is afgerond." } ] } } }, { "name": "Verstuur via Wesender", "type": "n8n-nodes-base.httpRequest", "position": [680, 300], "parameters": { "method": "POST", "url": "https://api.wesender.nl/v1/emails", "authentication": "predefinedCredentialType", "nodeCredentialType": "httpHeaderAuth", "jsonBody": true, "body": { "from": "workflow@jouwdomein.nl", "to": "={{ $json.email }}", "subject": "={{ $json.titel }}", "html": "=

{{ $json.inhoud }}

" }, "options": { "response": { "response": { "responseFormat": "json" } } } }, "credentials": { "httpHeaderAuth": { "name": "Wesender API" } } } ] } ``` ## Veelgestelde vragen **Kan ik ook HTML-templates met n8n-variabelen gebruiken?** Ja. Bouw de HTML-inhoud op in een Code-node of Function-node vóór de HTTP Request-node. Gebruik n8n-expressies (={{ }}) om waarden dynamisch in te vullen. Geef de ingevulde HTML door als de html-parameter in de body. **Hoe verwerk ik bounces in mijn n8n-flow?** Voeg een Webhook-node toe als ontvangstpunt voor Wesender-events. Stel het webhook-URL in als delivery-webhook in het Wesender-dashboard. Gebruik een IF-node om events met type 'bounced' of 'complained' door te sturen naar een aparte tak in je workflow. **Werkt dit ook met n8n Cloud?** Ja. De HTTP Request-node en Webhook-node zijn beschikbaar in zowel n8n Cloud als zelfgehoste instanties. De enige vereiste is dat het Wesender-webhook-endpoint bereikbaar is vanuit het internet, wat bij n8n Cloud standaard het geval is. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/n8n - Marketingpagina: https://wesender.nl/ai/integraties/n8n - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Anthropic Claude + WeSender > Gebruik Claude's tool use om e-mails te sturen vanuit een AI-agent zonder tussenkomst van de gebruiker. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/anthropic ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel van Wesender (WESENDER_API_KEY) - Anthropic API-sleutel (ANTHROPIC_API_KEY) - Node.js 18 of nieuwer ## Integratiestappen ### Stap 1: Installeer de benodigde packages Maak een nieuw Node.js-project aan en installeer de Anthropic SDK en de Wesender Node.js SDK. ### Stap 2: Definieer de send_email-tool Maak een tool-definitie aan. Claude gebruikt het JSON-schema om te begrijpen welke parameters hij moet meegeven bij het versturen van een e-mail. ### Stap 3: Roep Claude aan en verwerk de tool Stuur een gebruikersbericht naar Claude. Als Claude de send_email-tool aanroept, haal je de parameters op en stuur je de e-mail via Wesender. ## Volledig voorbeeld (claude-tool-use.ts) ```typescript import Anthropic from "@anthropic-ai/sdk" import { WesenderClient } from "@wesender/node" const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }) const wesender = new WesenderClient({ apiKey: process.env.WESENDER_API_KEY }) const tools: Anthropic.Tool[] = [ { name: "send_email", description: "Verstuur een transactionele e-mail via Wesender", input_schema: { type: "object", properties: { to: { type: "string", description: "E-mailadres van de ontvanger" }, subject: { type: "string", description: "Onderwerp van de e-mail" }, html: { type: "string", description: "HTML-inhoud van de e-mail" }, }, required: ["to", "subject", "html"], }, }, ] async function runEmailAgent(userMessage: string) { const response = await client.messages.create({ model: "claude-opus-4-8", max_tokens: 1024, tools, messages: [{ role: "user", content: userMessage }], }) for (const block of response.content) { if (block.type === "tool_use" && block.name === "send_email") { const { to, subject, html } = block.input as { to: string; subject: string; html: string } await wesender.emails.send({ from: "noreply@jouwdomein.nl", to, subject, html }) console.log("E-mail verzonden naar", to) } } } runEmailAgent("Stuur een bevestigingsmail naar maria@voorbeeld.nl") ``` ## Veelgestelde vragen **Kan ik meerdere e-mails in een gesprek sturen?** Ja. Voeg het tool_result-blok toe aan de berichten en stuur een vervolgrequest naar Claude. Zolang je de conversation history bijhoudt, kan Claude meerdere keren send_email aanroepen binnen hetzelfde gesprek. **Welk Claude-model moet ik gebruiken?** claude-opus-4-8 biedt de sterkste redenering voor complexe instructies. Voor hogere snelheid bij lagere kosten kun je claude-haiku-4-5-20251001 gebruiken. Beide ondersteunen tool use volledig. **Hoe voorkom ik dat Claude onbedoeld e-mails verstuurt?** Bouw een bevestigingsstap in: verwerk de tool_use-blokken niet automatisch, maar toon de parameters eerst aan de gebruiker. Wacht op goedkeuring voordat je de Wesender API aanroept. Zo blijft de mens in de loop. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/anthropic - Marketingpagina: https://wesender.nl/ai/integraties/anthropic - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Claude Agent SDK + WeSender > Bouw een volwaardige AI-agent met de Claude Agent SDK die zelfstandig e-mails verstuurt als onderdeel van een meerstappenproces. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/claude-agent-sdk ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel van Wesender (WESENDER_API_KEY) - Anthropic API-sleutel (ANTHROPIC_API_KEY) - Node.js 20 of nieuwer ## Integratiestappen ### Stap 1: Installeer de Claude Agent SDK Installeer de officiële Claude Agent SDK en de Wesender Node.js SDK in je project. ### Stap 2: Definieer de e-mail-tool Maak een tool-object dat de agent kan gebruiken om e-mails te versturen. De SDK herkent het automatisch als uitvoerbare actie. ### Stap 3: Start de agent met een doel Maak een agent-instantie en geef hem de tools mee. De agent verwerkt de instructie zelfstandig en roept de e-mail-tool aan wanneer dat nodig is. ## Volledig voorbeeld (claude-agent-email.ts) ```typescript import { Agent, tool } from "@anthropic-ai/claude-code" import { WesenderClient } from "@wesender/node" const wesender = new WesenderClient({ apiKey: process.env.WESENDER_API_KEY }) const sendEmailTool = tool({ name: "send_email", description: "Verstuur een transactionele e-mail via Wesender", parameters: { to: { type: "string" as const, description: "Ontvanger e-mailadres" }, subject: { type: "string" as const, description: "Onderwerp" }, html: { type: "string" as const, description: "HTML-inhoud" }, }, execute: async ({ to, subject, html }: { to: string; subject: string; html: string }) => { await wesender.emails.send({ from: "noreply@jouwdomein.nl", to, subject, html }) return { success: true, recipient: to } }, }) const agent = new Agent({ model: "claude-opus-4-8", tools: [sendEmailTool], }) const result = await agent.run( "Verstuur een welkomstmail aan anna@voorbeeld.nl en bas@voorbeeld.nl" ) console.log("Agent klaar:", result.summary) ``` ## Veelgestelde vragen **Wat is het verschil tussen de Claude Agent SDK en gewone tool use?** Bij gewone tool use verwerk je de cyclus handmatig: user message, tool call, tool result, response. De Agent SDK beheert deze cyclus automatisch. De agent kan meerdere tools aanroepen in een keten zonder dat je elke stap hoeft te orchestreren. **Kan de agent meerdere e-mails in een taak versturen?** Ja. De agent kan send_email meerdere keren aanroepen als de instructie daarom vraagt. Je kunt ook een limiet instellen op het aantal tool-aanroepen om onverwacht hoge verzendvolumes te voorkomen. **Hoe log ik wat de agent heeft gedaan?** De Agent SDK retourneert een gedetailleerde trace van alle stappen, inclusief de tool-aanroepen en de resultaten. Sla deze trace op in je eigen logging-systeem voor audits en debugging. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/claude-agent-sdk - Marketingpagina: https://wesender.nl/ai/integraties/claude-agent-sdk - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # LangGraph + WeSender > Modelleer je e-mailworkflow als een toestandsgraph en laat AI-nodes zelfstandig beslissingen nemen over wanneer en wat er verstuurd wordt. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/langgraph ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel van Wesender (WESENDER_API_KEY) - OpenAI of Anthropic API-sleutel - Python 3.11 of nieuwer ## Integratiestappen ### Stap 1: Installeer de benodigde packages Installeer LangGraph, LangChain en de requests-bibliotheek voor de Wesender REST API. ### Stap 2: Definieer de toestand en de graph-nodes Maak een TypedDict voor de graph-toestand. Elke node is een Python-functie die de toestand leest, verwerkt en bijgewerkt teruggeeft. ### Stap 3: Bouw en compileer de graph Voeg de nodes toe, stel de edges in en compileer de graph tot een uitvoerbare agent. Roep de graph aan met een beginstand. ## Volledig voorbeeld (langgraph_email.py) ```python import os, requests from typing import TypedDict from langgraph.graph import StateGraph, END from langchain_openai import ChatOpenAI class EmailState(TypedDict): recipient: str subject: str body: str sent: bool def compose_email(state: EmailState) -> EmailState: llm = ChatOpenAI(model="gpt-4o-mini") reply = llm.invoke( f"Schrijf een welkomstmail voor {state['recipient']}. Reageer alleen met de HTML-inhoud." ) return { **state, "body": reply.content } def send_email(state: EmailState) -> EmailState: requests.post( "https://api.wesender.nl/v1/emails", headers={ "Authorization": f"Bearer {os.environ['WESENDER_API_KEY']}" }, json={ "from": "noreply@jouwdomein.nl", "to": state["recipient"], "subject": state["subject"], "html": state["body"], }, ).raise_for_status() return { **state, "sent": True } graph = StateGraph(EmailState) graph.add_node("compose", compose_email) graph.add_node("send", send_email) graph.set_entry_point("compose") graph.add_edge("compose", "send") graph.add_edge("send", END) app = graph.compile() result = app.invoke({ "recipient": "lisa@voorbeeld.nl", "subject": "Welkom bij ons platform", "body": "", "sent": False, }) print("Verstuurd:", result["sent"]) ``` ## Veelgestelde vragen **Kan ik conditionele edges gebruiken om te beslissen of een e-mail wordt verstuurd?** Ja. LangGraph ondersteunt conditionele edges via add_conditional_edges. Je kunt een routeringsfunctie schrijven die de toestand beoordeelt en beslist of de e-mail wordt verstuurd of dat de flow naar een andere node gaat. **Hoe voeg ik menselijke goedkeuring toe aan de graph?** Gebruik LangGraph's interrupt-mechanisme. Voeg interrupt_before=['send'] toe bij het compileren van de graph. De uitvoering pauzeert dan voor de send-node zodat een mens de e-mail kan controleren voordat hij wordt verstuurd. **Kan ik de graph persistent maken over meerdere aanroepen?** Ja. LangGraph ondersteunt checkpointing via SqliteSaver of PostgresSaver. Zo bewaar je de toestand tussen aanroepen en kan de agent doorgaan waar hij gebleven was, ook na een herstart. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/langgraph - Marketingpagina: https://wesender.nl/ai/integraties/langgraph - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # CrewAI + WeSender > Laat een team van AI-agents samenwerken: een schrijver stelt de mail op, een reviewer keurt hem goed en een verzender stuurt hem via Wesender. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/crewai ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel van Wesender (WESENDER_API_KEY) - OpenAI API-sleutel (OPENAI_API_KEY) - Python 3.11 of nieuwer ## Integratiestappen ### Stap 1: Installeer CrewAI en dependencies Installeer CrewAI en de requests-bibliotheek voor de Wesender REST API. ### Stap 2: Maak de Wesender-tool Definieer een CrewAI-tool die de Wesender API aanroept. Agents kunnen deze tool gebruiken als ze een e-mail willen versturen. ### Stap 3: Definieer de agents en taken Maak een schrijver-agent en een verzender-agent. Elke agent krijgt een rol en een taak. De crew voert de taken sequentieel uit. ## Volledig voorbeeld (crewai_email.py) ```python import os, requests from crewai import Agent, Task, Crew from crewai.tools import tool @tool("send_email") def send_email(to: str, subject: str, html: str) -> str: """Verstuur een e-mail via Wesender. Geef to, subject en html mee.""" requests.post( "https://api.wesender.nl/v1/emails", headers={ "Authorization": f"Bearer {os.environ['WESENDER_API_KEY']}" }, json={ "from": "noreply@jouwdomein.nl", "to": to, "subject": subject, "html": html }, ).raise_for_status() return f"E-mail verstuurd naar {to}" schrijver = Agent( role="E-mailschrijver", goal="Schrijf een professionele welkomstmail in HTML", backstory="Jij bent een copywriter gespecialiseerd in transactionele e-mails.", verbose=True, ) verzender = Agent( role="E-mailverzender", goal="Verstuur de mail via Wesender", backstory="Jij zorgt dat e-mails correct worden verstuurd via de Wesender API.", tools=[send_email], verbose=True, ) schrijf_taak = Task( description="Schrijf een HTML-welkomstmail voor {ontvanger}. Geef alleen de HTML terug.", expected_output="Volledige HTML-e-mail als string", agent=schrijver, ) verstuur_taak = Task( description="Verstuur de HTML-mail naar {ontvanger} met onderwerp 'Welkom bij ons platform'.", expected_output="Bevestiging dat de e-mail verstuurd is", agent=verzender, context=[schrijf_taak], ) crew = Crew(agents=[schrijver, verzender], tasks=[schrijf_taak, verstuur_taak]) result = crew.kickoff(inputs={ "ontvanger": "kees@voorbeeld.nl" }) print(result) ``` ## Veelgestelde vragen **Kan ik een reviewstap toevoegen voor het versturen?** Ja. Voeg een reviewer-agent toe tussen de schrijver en de verzender. Geef de reviewer-taak de schrijftaak als context. De reviewer past de HTML aan als dat nodig is, waarna de verzender de definitieve versie doorstuurt. **Hoe gebruik ik een ander taalmodel per agent?** Geef elke agent zijn eigen llm-parameter mee: Agent(llm=ChatOpenAI(model='gpt-4o'), ...). Je kunt de schrijver op een krachtig model zetten en de verzender op een sneller model, omdat die agent weinig generatieve intelligentie nodig heeft. **Wat kost het om CrewAI met OpenAI te gebruiken?** Kosten hangen af van het model en het aantal tokens. Gebruik gpt-4o-mini voor lage kosten tijdens ontwikkeling. Schakel over naar gpt-4o voor productie als de kwaliteit dat vereist. De Wesender API-kosten zijn afhankelijk van je abonnement. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/crewai - Marketingpagina: https://wesender.nl/ai/integraties/crewai - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Make + WeSender > Verbind Make-scenarios met de Wesender API via een HTTP-module en stuur automatisch e-mails vanuit elke trigger, zonder code. **Categorie:** workflow | **URL:** https://docs.wesender.nl/docs/integraties/make ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel van Wesender (WESENDER_API_KEY) - Make-account (gratis of betaald plan) ## Integratiestappen ### Stap 1: Maak een nieuw Make-scenario Log in op make.com, klik op 'Create a new scenario' en voeg een trigger-module toe. Gebruik Webhook, Google Sheets, Airtable of een andere bron die past bij jouw situatie. ### Stap 2: Voeg een HTTP-module toe Klik op het plusje na je trigger, zoek op 'HTTP' en kies 'Make a request'. Vul de URL in, stel de methode in op POST en voeg de Authorization-header toe. ### Stap 3: Stel de request body in Klik op 'Body' en kies 'Raw'. Voer de JSON in en gebruik Make-variabelen ({{1.email}}) om velden dynamisch in te vullen vanuit je trigger. ### Stap 4: Test en activeer het scenario Klik op 'Run once' om het scenario te testen met echte data. Controleer of de e-mail aankomt. Activeer daarna het scenario zodat het automatisch draait bij elke nieuwe trigger. ## Volledig voorbeeld (make-http-module.json) ```json { "url": "https://api.wesender.nl/v1/emails", "method": "POST", "headers": [ { "name": "Authorization", "value": "Bearer {{WESENDER_API_KEY}}" }, { "name": "Content-Type", "value": "application/json" } ], "body": { "from": "noreply@jouwdomein.nl", "to": "{{1.email}}", "subject": "{{1.subject}}", "html": "{{1.html}}" } } ``` ## Veelgestelde vragen **Kan ik HTML-e-mails met Make-variabelen opbouwen?** Ja. Gebruik de Text Aggregator- of String-module om HTML dynamisch op te bouwen vanuit Make-variabelen. Zet het resultaat door als de html-waarde in de HTTP-module. Zo stuur je gepersonaliseerde e-mails op basis van formulierdata of databaserecords. **Hoe verwerk ik bounces terug in Make?** Voeg een Webhook-module toe als triggerpunt en stel de URL in als bezorgwebhook in het Wesender-dashboard. Elke bounce-, klacht- of bezorgingsevent triggert dan je scenario, zodat je de status kunt opslaan in Airtable, Google Sheets of je eigen database. **Hoeveel e-mails kan ik per scenario versturen?** Dat hangt af van je Make-plan (operaties per maand) en je Wesender-abonnement (e-mails per maand). Gebruik de iterator in Make om in bulk te versturen. Houd rekening met rate limits: Wesender accepteert maximaal 100 requests per seconde. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/make - Marketingpagina: https://wesender.nl/ai/integraties/make - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Zapier + WeSender > Verstuur automatisch e-mails via Wesender vanuit duizenden Zapier-apps met de ingebouwde Webhooks-actie. **Categorie:** workflow | **URL:** https://docs.wesender.nl/docs/integraties/zapier ## Vereisten - Wesender-account met geverifieerd verzenddomein - API-sleutel van Wesender (WESENDER_API_KEY) - Zapier-account (Starter-plan of hoger voor Webhooks) ## Integratiestappen ### Stap 1: Maak een nieuw Zap Log in op zapier.com, klik op 'Create Zap' en voeg een trigger toe. Kies een app zoals Google Forms, Typeform, HubSpot of Stripe als startpunt van je automatisering. ### Stap 2: Voeg 'Webhooks by Zapier' toe als actie Klik op het plusje, zoek op 'Webhooks by Zapier' en kies 'POST'. Dit is de actie die de Wesender API aanroept. ### Stap 3: Configureer het webhook-verzoek Vul de URL, headers en de payload in. Gebruik Zapier-velden (zoals Contact Email) om de e-mail dynamisch te personaliseren. ### Stap 4: Test en zet de Zap live Klik op 'Test action' om een testmail te versturen. Controleer of de e-mail aankomt. Schakel de Zap in zodat hij automatisch draait bij elke nieuwe trigger-event. ## Volledig voorbeeld (zapier-webhook-config.json) ```json { "url": "https://api.wesender.nl/v1/emails", "method": "POST", "headers": { "Authorization": "Bearer WESENDER_API_KEY", "Content-Type": "application/json" }, "data": { "from": "noreply@jouwdomein.nl", "to": "{{contact_email}}", "subject": "Bedankt voor je aanmelding", "html": "

Hoi {{contact_first_name}}, welkom!

" } } ``` ## Veelgestelde vragen **Kan ik HTML-e-mails opbouwen in Zapier?** Ja. Gebruik een Formatter by Zapier-stap voor de Webhooks-actie om tekstvelden samen te voegen tot een HTML-string. Zo verwerk je dynamische inhoud, zoals de naam en het bestelnummer van een klant, in de HTML. **Hoe verwerk ik bezorgingsstatussen terug in Zapier?** Voeg een Catch Hook-trigger toe aan een apart Zap en stel de URL in als bezorgwebhook in het Wesender-dashboard. Elke bezorging-, bounce- of klachtevent triggert dit Zap, zodat je de status kunt opslaan in Airtable, Google Sheets of je CRM. **Werkt dit ook op het gratis Zapier-plan?** Webhooks by Zapier is alleen beschikbaar op betaalde Zapier-plannen (Starter of hoger). Op het gratis plan kun je Make als alternatief gebruiken: dat biedt webhook-integraties op het gratis plan. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/zapier - Marketingpagina: https://wesender.nl/ai/integraties/zapier - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Pydantic AI + WeSender > Type-veilige Python-agents met automatische validatie — stuur e-mail via Wesender als gevalideerde tool. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/pydantic-ai ## Vereisten - Python 3.11+ geïnstalleerd - Wesender-account met API-sleutel - pip install "pydantic-ai[openai]" wesender - Omgevingsvariabelen: WESENDER_API_KEY en OPENAI_API_KEY ## Integratiestappen ### Stap 1: Installeer Pydantic AI en de Wesender Python SDK Voeg de benodigde packages toe. Pydantic AI ondersteunt meerdere model-providers via een uniforme interface. ### Stap 2: Definieer de send_email-tool met type-annotaties Pydantic AI gebruikt Python-functies met type-annotaties voor automatische validatie van toolparameters. Decoreer de functie met @agent.tool_plain om hem als tool te registreren. ### Stap 3: Roep de agent aan De agent herkent automatisch wanneer send_email moet worden aangeroepen op basis van de gebruikersvraag. Pydantic AI valideert alle parameters vóór uitvoering. ### Stap 4: Verwerk het resultaat De agent geeft het resultaat van de tool terug als string. Sla het e-mail-ID op voor bezorgingscontrole via Wesender-webhooks. ## Volledig voorbeeld (pydantic_ai_email.py) ```python import asyncio import os from pydantic_ai import Agent from wesender import Wesender client = Wesender(api_key=os.environ["WESENDER_API_KEY"]) agent = Agent( model="openai:gpt-4o", system_prompt="Je bent een assistent die e-mails verstuurt via Wesender.", ) @agent.tool_plain async def send_email(to: str, subject: str, html: str) -> str: """Verstuur een e-mail via Wesender.""" result = client.emails.send( from_="noreply@jouwdomein.nl", to=to, subject=subject, html=html, ) return f"E-mail verzonden. ID: {result.id}" async def main(): response = await agent.run( "Stuur een welkomstmail naar jan@voorbeeld.nl " "met als onderwerp 'Welkom bij ons platform' " "en als inhoud een vriendelijke HTML-begroeting." ) print(response.data) if __name__ == "__main__": asyncio.run(main()) ``` ## Veelgestelde vragen **Welke model-providers werken met Pydantic AI?** Pydantic AI ondersteunt OpenAI, Anthropic, Google Gemini, Groq en Mistral via een uniforme interface. Je wisselt van provider door de model-parameter aan te passen, bijv. van 'openai:gpt-4o' naar 'anthropic:claude-sonnet-4-5'. **Hoe valideer ik e-mailadressen vóór het versturen?** Gebruik Pydantic-modellen als toolparameters. Vervang losse string-annotaties door een dataclass met EmailStr uit pydantic[email]. Pydantic AI valideert de invoer automatisch voordat de tool wordt aangeroepen. **Kan ik meerdere e-mails in één agent-run versturen?** Ja. De agent roept send_email herhaaldelijk aan als de instructie dat vereist. Elke aanroep retourneert een uniek e-mail-ID. Je kunt ook een batchfunctie definiëren die een lijst adressen accepteert. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/pydantic-ai - Marketingpagina: https://wesender.nl/ai/integraties/pydantic-ai - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Mastra + WeSender > TypeScript-agentframework met Zod-validatie — definieer send_email als eerste-klasse Mastra-tool. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/mastra ## Vereisten - Node.js 20+ en TypeScript 5+ - Wesender-account met API-sleutel - npm install @mastra/core @wesender/node zod - Omgevingsvariabelen: WESENDER_API_KEY en OPENAI_API_KEY ## Integratiestappen ### Stap 1: Installeer Mastra en de Wesender Node SDK Voeg de benodigde packages toe. Mastra biedt een TypeScript-native interface voor productie-agents. ### Stap 2: Definieer de send_email-tool met Zod-schema Mastra-tools zijn type-safe met Zod-schemadefinities. Parameters worden automatisch gevalideerd voordat de tool wordt uitgevoerd. ### Stap 3: Maak de agent aan Koppel de tool aan een Mastra-agent. De agent bepaalt op basis van de instructie wanneer send_email wordt aangeroepen. ### Stap 4: Voer de agent uit Roep de agent aan met een gebruikersinstructie. Het resultaat bevat het antwoord van de agent plus de tool-aanroepen die zijn uitgevoerd. ## Volledig voorbeeld (mastra-email-agent.ts) ```typescript import { Agent, createTool } from "@mastra/core" import { Wesender } from "@wesender/node" import { z } from "zod" const emailClient = new Wesender(process.env.WESENDER_API_KEY!) const sendEmailTool = createTool({ id: "send_email", description: "Verstuur een e-mail via Wesender", inputSchema: z.object({ to: z.string().email(), subject: z.string(), html: z.string(), }), execute: async ({ context }) => { const result = await emailClient.emails.send({ from: "noreply@jouwdomein.nl", to: context.to, subject: context.subject, html: context.html, }) return { success: true, id: result.id } }, }) const emailAgent = new Agent({ name: "email-agent", instructions: "Je bent een assistent die e-mails verstuurt via Wesender. " + "Gebruik send_email zodra de gebruiker dat vraagt.", model: { provider: "OPEN_AI", name: "gpt-4o", toolChoice: "auto" }, tools: { sendEmailTool }, }) const response = await emailAgent.generate([ { role: "user", content: "Stuur een welkomstmail naar jan@voorbeeld.nl." }, ]) console.log(response.text) ``` ## Veelgestelde vragen **Welke LLM-providers ondersteunt Mastra?** Mastra ondersteunt OpenAI, Anthropic, Google Gemini en andere providers via een gestandaardiseerde interface. Je wisselt van provider door model.provider aan te passen, zonder de toollogica te hoeven wijzigen. **Werkt Mastra met een bestaand Express- of Fastify-project?** Ja. Mastra is framework-agnostisch. Importeer de agent en roep generate() aan vanuit elke Node.js-server of serverless functie, zoals een Next.js API-route of een Hono-endpoint. **Hoe log ik e-mail-ID's voor bezorgingscontrole?** Het tool-resultaat bevat { success: true, id: result.id }. Sla dit op in je eigen database of stuur het terug naar de gebruiker. Combineer met Wesender-webhooks voor realtime bezorgingsstatussen. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/mastra - Marketingpagina: https://wesender.nl/ai/integraties/mastra - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Google Gemini + WeSender > Gemini Function Calling in TypeScript — laat je Gemini-model e-mail versturen via Wesender. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/gemini ## Vereisten - Node.js 20+ en TypeScript - Wesender-account met API-sleutel - npm install @google/generative-ai @wesender/node - Omgevingsvariabelen: WESENDER_API_KEY en GEMINI_API_KEY ## Integratiestappen ### Stap 1: Installeer de Google Generative AI SDK en Wesender Voeg de officiële Google SDK en de Wesender Node SDK toe aan je project. ### Stap 2: Definieer send_email als Gemini-functie Gemini Function Calling gebruikt een JSON-schema om beschikbare functies te beschrijven. Definieer de parameters zodat Gemini weet hoe de functie aan te roepen. ### Stap 3: Voer de function call uit via Wesender Wanneer Gemini een functionCall teruggeeft, voer je de logica uit met de Wesender Node SDK en stuur je het resultaat terug in de conversatie. ### Stap 4: Bouw de conversatielus Stuur berichten naar Gemini, verwerk function calls en herhaal totdat het model een definitief tekstantwoord geeft. ## Volledig voorbeeld (gemini-email-agent.ts) ```typescript import { GoogleGenerativeAI } from "@google/generative-ai" import { Wesender } from "@wesender/node" const emailClient = new Wesender(process.env.WESENDER_API_KEY!) const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!) const model = genAI.getGenerativeModel({ model: "gemini-1.5-pro", tools: [{ functionDeclarations: [{ 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(prompt: string) { const chat = model.startChat() let result = await chat.sendMessage(prompt) while (result.response.functionCalls()?.length) { const call = result.response.functionCalls()![0] const args = call.args as { to: string; subject: string; html: string } const emailResult = await emailClient.emails.send({ from: "noreply@jouwdomein.nl", to: args.to, subject: args.subject, html: args.html, }) result = await chat.sendMessage([{ functionResponse: { name: call.name, response: { success: true, id: emailResult.id }, }, }]) } return result.response.text() } console.log(await runAgent( "Stuur een welkomstmail naar jan@voorbeeld.nl met een vriendelijke begroeting." )) ``` ## Veelgestelde vragen **Welke Gemini-modellen ondersteunen Function Calling?** Gemini 1.5 Pro en Gemini 1.5 Flash ondersteunen beiden Function Calling. Flash is goedkoper en sneller; Pro is beter in complexe redeneringen. Beide werken identiek met de bovenstaande code. **Kan Gemini meerdere functies tegelijk aanroepen?** Ja, Gemini kan parallelle function calls teruggeven. Itereer dan over result.response.functionCalls() volledig en verwerk alle resultaten gelijktijdig met Promise.all voor betere prestaties. **Hoe beperk ik welke functies Gemini mag aanroepen?** Gebruik toolConfig in de modelconfiguratie met mode: 'ANY' en een allowedFunctionNames-lijst. Zo beperk je Gemini tot uitsluitend send_email, ook als je meer functies definieert. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/gemini - Marketingpagina: https://wesender.nl/ai/integraties/gemini - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # LlamaIndex + WeSender > Combineer RAG en e-mailbezorging in één LlamaIndex-agent — verstuur e-mail via Wesender als FunctionTool. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/llamaindex ## Vereisten - Python 3.11+ en pip - Wesender-account met API-sleutel - pip install llama-index wesender openai - Omgevingsvariabelen: WESENDER_API_KEY en OPENAI_API_KEY ## Integratiestappen ### Stap 1: Installeer LlamaIndex en de Wesender Python SDK Voeg de benodigde packages toe. LlamaIndex vereist ook de OpenAI-bibliotheek voor de standaard LLM-backend. ### Stap 2: Definieer send_email als LlamaIndex FunctionTool LlamaIndex-agents gebruiken FunctionTool om Python-functies beschikbaar te maken als tool-aanroepen. De docstring wordt gebruikt als beschrijving voor het LLM. ### Stap 3: Maak een ReActAgent aan met de e-mailtool Combineer de e-mailtool met andere LlamaIndex-tools, zoals een QueryEngine voor documentretrieval. De agent beslist zelf welke tool hij wanneer inzet. ### Stap 4: Roep de agent aan Geef de agent een instructie in natuurlijke taal. De ReActAgent redeneert stap voor stap en roept send_email aan wanneer nodig. ## Volledig voorbeeld (llamaindex_email_agent.py) ```python import os from llama_index.core.tools import FunctionTool from llama_index.core.agent import ReActAgent from llama_index.llms.openai import OpenAI from wesender import Wesender client = Wesender(api_key=os.environ["WESENDER_API_KEY"]) def send_email(to: str, subject: str, html: str) -> str: """ Verstuur een e-mail via Wesender. Args: to: E-mailadres van de ontvanger. subject: Onderwerpregel van de e-mail. html: HTML-inhoud van de e-mail. """ result = client.emails.send( from_="noreply@jouwdomein.nl", to=to, subject=subject, html=html, ) return f"E-mail verzonden. ID: {result.id}" email_tool = FunctionTool.from_defaults(fn=send_email) agent = ReActAgent.from_tools( tools=[email_tool], llm=OpenAI(model="gpt-4o"), verbose=True, ) response = agent.chat( "Stuur een welkomstmail naar jan@voorbeeld.nl " "met onderwerp 'Welkom bij ons platform'." ) print(response.response) ``` ## Veelgestelde vragen **Kan ik de e-mailtool combineren met een documentindex?** Ja. Voeg naast email_tool ook een QueryEngineTool toe die verbonden is met je VectorStoreIndex. De agent kan eerst documenten raadplegen en daarna een samenvatting per e-mail versturen. **Welke LLM-backends ondersteunt LlamaIndex?** LlamaIndex ondersteunt OpenAI, Anthropic, Mistral, HuggingFace en meer via pluggable LLM-integraties. Vervang OpenAI(model=...) door bijv. Anthropic(model='claude-sonnet-4-5') na installatie van llama-index-llms-anthropic. **Hoe gebruik ik de async-variant voor hoge throughput?** Gebruik achat() in plaats van chat() voor asynchroon gebruik: response = await agent.achat(...). Combineer met asyncio.gather() om meerdere agents tegelijk te draaien. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/llamaindex - Marketingpagina: https://wesender.nl/ai/integraties/llamaindex - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Mistral AI + WeSender > Mistral Function Calling in TypeScript — stuur e-mail via Wesender vanuit een Europees AI-model. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/mistral ## 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 ## Integratiestappen ### Stap 1: Installeer de Mistral SDK en Wesender Voeg de officiële Mistral TypeScript SDK en de Wesender Node SDK toe aan je project. ### 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. ### 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. ### Stap 4: Bouw de agent-lus Stuur het bericht naar Mistral, verwerk eventuele tool calls en herhaal totdat Mistral een definitief antwoord geeft. ## Volledig voorbeeld (mistral-email-agent.ts) ```typescript 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'." )) ``` ## 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. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/mistral - Marketingpagina: https://wesender.nl/ai/integraties/mistral - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Dify + WeSender > Bouw AI-workflows zonder code — koppel Wesender als HTTP-actieblok in je Dify-workflow. **Categorie:** workflow | **URL:** https://docs.wesender.nl/docs/integraties/dify ## Vereisten - Dify-account (cloud op dify.ai of self-hosted via Docker) - Wesender-account met API-sleutel - Een bestaande of nieuwe Dify-workflow - Geen programmeerkennis vereist ## Integratiestappen ### Stap 1: Maak een nieuwe Dify-workflow aan Log in op Dify en navigeer naar Studio → Workflow → Nieuw aanmaken. Kies het type Workflow (niet Chatflow). Geef de workflow een naam, bijv. 'Welkomstmail verzenden'. ### Stap 2: Configureer het Start-blok met invoervariabelen Klik op het Start-blok en voeg invoervariabelen toe: to_email (tekst) en naam (tekst). Deze worden ingevuld bij het starten van de workflow. ### Stap 3: Voeg een LLM-blok toe voor de e-mailinhoud Voeg een LLM-blok toe om een gepersonaliseerde e-mailtekst te genereren. Verbind het Start-blok als invoer en gebruik variabelen via Dify-expressies. ### Stap 4: Voeg een HTTP-verzoekblok toe voor Wesender Voeg een HTTP-verzoek-blok toe. Stel methode, URL, headers en body in om de Wesender API aan te roepen. Verwijs naar LLM-output via de Dify-expressie {{#llm.text#}}. ### Stap 5: Sla de API-sleutel op als omgevingsvariabele Navigeer naar Instellingen → Omgevingsvariabelen en voeg WESENDER_API_KEY toe met je Wesender API-sleutel. Verwijs er in het HTTP-blok naar via {{WESENDER_API_KEY}} zodat de sleutel nooit zichtbaar is in de workflow-configuratie. ### Stap 6: Test en publiceer de workflow Klik op Uitvoeren in de workflow-editor, vul testwaarden in voor to_email en naam, en controleer of de e-mail aankomt. Publiceer de workflow: Dify genereert een API-eindpunt waarmee je de workflow vanuit externe systemen kunt triggeren. ## Volledig voorbeeld (dify-workflow-config.json) ```json { "workflow_name": "Welkomstmail verzenden", "nodes": [ { "type": "start", "variables": [ { "key": "to_email", "type": "string", "label": "Ontvanger e-mailadres" }, { "key": "naam", "type": "string", "label": "Naam ontvanger" } ] }, { "type": "llm", "model": "gpt-4o", "system_prompt": "Je bent een assistent die welkomstmails schrijft in HTML.", "user_prompt": "Schrijf een welkomstmail in HTML voor {{#start.naam#}}." }, { "type": "http_request", "method": "POST", "url": "https://api.wesender.nl/v1/emails", "headers": { "Authorization": "Bearer {{WESENDER_API_KEY}}", "Content-Type": "application/json" }, "body": { "from": "noreply@jouwdomein.nl", "to": "{{#start.to_email#}}", "subject": "Welkom bij ons platform", "html": "{{#llm.text#}}" } } ] } ``` ## Veelgestelde vragen **Kan ik Dify self-hosten voor volledige datacontrole?** Ja. Dify is open-source en kan via Docker worden gehost op je eigen server. Combineer dit met de Wesender API voor een volledig Europese, self-hosted AI-e-mailoplossing. **Hoe trigger ik de workflow vanuit een extern systeem?** Na publicatie genereert Dify een API-eindpunt. Stuur een POST-verzoek naar dit eindpunt met je inputs als JSON-body en de Dify API-key als Bearer-token. Zo koppel je de workflow aan je CRM, webshop of andere systemen. **Kan ik bezorgingsstatussen terugkrijgen in Dify?** Voeg een tweede HTTP-blok toe om een Wesender-webhook te registreren, of gebruik een externe integratie zoals Make of Zapier om bezorgingsevents te ontvangen en terug te koppelen aan een Dify-workflow via de Run API. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/dify - Marketingpagina: https://wesender.nl/ai/integraties/dify - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # OpenAI Agents SDK + WeSender > De officiële OpenAI Agents SDK met ingebouwde tool-lus — voeg send_email toe en de agent mailt zelfstandig. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/openai-agents-sdk ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - OPENAI_API_KEY ingesteld als omgevingsvariabele - Node.js 18 of nieuwer - npm install @openai/agents @wesender/node zod ## Integratiestappen ### Stap 1: Installeer de pakketten Voeg de OpenAI Agents SDK, de WeSender Node SDK en Zod toe aan je project. ### Stap 2: Definieer de e-mailtool Maak send_email aan als een Agents SDK-tool met een Zod-schema. De execute-functie verstuurt de mail via WeSender en geeft het e-mail-ID terug. ### Stap 3: Maak de agent aan en start hem Maak een agent met de e-mailtool en start hem via run(). De SDK handelt de tool-lus automatisch af: aanroepen, uitvoeren, doorgaan. ## Volledig voorbeeld (src/agent.ts) ```typescript import { Agent, run, tool } from "@openai/agents" import { z } from "zod" import { Wesender } from "@wesender/node" const emailClient = new Wesender(process.env.WESENDER_API_KEY!) const sendEmail = tool({ name: "send_email", description: "Verstuur een transactionele e-mail via WeSender", parameters: z.object({ to: z.string(), subject: z.string(), html: z.string(), }), execute: async ({ to, subject, html }) => { const result = await emailClient.emails.send({ from: "agent@jouwdomein.nl", to, subject, html, }) return "E-mail verstuurd, id: " + result.id }, }) const agent = new Agent({ name: "Mailagent", instructions: "Je verstuurt transactionele e-mails namens de gebruiker.", tools: [sendEmail], }) const result = await run(agent, "Mail een welkomstbericht naar nieuwe@klant.nl") console.log(result.finalOutput) ``` ## Veelgestelde vragen **Kan de agent meerdere tools combineren?** Ja. Voeg extra tools toe aan de tools-array. De agent kiest zelf welke hij nodig heeft op basis van de instructie en de context van het gesprek. **Werkt dit ook met handoffs naar andere agents?** Ja. De Agents SDK ondersteunt handoffs tussen agents. Geef de e-mailtool aan de agent die berichten moet versturen en gebruik handoffs voor de overige taken. **Hoe beperk ik wat de agent mag doen?** Wees specifiek in de instructies en voeg een goedkeuringsstap in voor onomkeerbare acties. Je kunt ook de output van de agent eerst tonen aan de gebruiker voordat je de tool-aanroep uitvoert. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/openai-agents-sdk - Marketingpagina: https://wesender.nl/ai/integraties/openai-agents-sdk - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # OpenAI Responses API + WeSender > De opvolger van de Assistants API — definieer send_email als tool en het model bepaalt wanneer er gemaild wordt. **Categorie:** provider | **URL:** https://docs.wesender.nl/docs/integraties/openai-responses ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - OPENAI_API_KEY ingesteld als omgevingsvariabele - Node.js 18 of nieuwer - npm install openai @wesender/node ## Integratiestappen ### Stap 1: Installeer de pakketten Voeg de officiële OpenAI Node SDK en de WeSender Node SDK toe aan je project. ### Stap 2: Beschrijf de tool als JSON-schema Definieer send_email als een functie-tool met een JSON-schema. De Responses API gebruikt dit schema om te bepalen wanneer en met welke argumenten de tool aangeroepen wordt. ### Stap 3: Roep de Responses API aan Stuur een instructie naar het model. Als het model send_email wil aanroepen, geeft het een function_call-item terug in de output-array. ### Stap 4: Voer de toolaanroep uit Loop door de output en voer elke function_call uit met de WeSender Node SDK. ## Volledig voorbeeld (src/responses.ts) ```typescript import OpenAI from "openai" import { Wesender } from "@wesender/node" const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY! }) const emailClient = new Wesender(process.env.WESENDER_API_KEY!) const tools = [ { type: "function" as const, name: "send_email", description: "Verstuur een transactionele e-mail via WeSender", parameters: { type: "object", properties: { to: { type: "string" }, subject: { type: "string" }, html: { type: "string" }, }, required: ["to", "subject", "html"], additionalProperties: false, }, }, ] async function run(prompt: string) { const response = await openai.responses.create({ model: "gpt-4o", input: prompt, tools, }) for (const item of response.output) { if (item.type === "function_call" && item.name === "send_email") { const args = JSON.parse(item.arguments) const result = await emailClient.emails.send({ from: "assistent@jouwdomein.nl", ...args, }) console.log("E-mail verstuurd, id: " + result.id) } } } run("Mail een welkomstbericht naar nieuwe@klant.nl") ``` ## Veelgestelde vragen **Waarom de Responses API en niet de Assistants API?** OpenAI sluit de Assistants API op 26 augustus 2026. De Responses API is de aanbevolen opvolger voor nieuwe projecten en de plek waar nieuwe modellen als eerste beschikbaar komen. **Moet ik het toolresultaat terugsturen voor een vervolggesprek?** Ja. Stuur het toolresultaat terug in een volgende aanroep via het previous_response_id-veld, zodat het model de context van het gesprek behoudt. **Werkt dit met alle OpenAI-modellen?** Met elk model dat tool calling ondersteunt op de Responses API. OpenAI brengt nieuwe modellen exclusief uit op deze API. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/openai-responses - Marketingpagina: https://wesender.nl/ai/integraties/openai-responses - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Google ADK + WeSender > Bouw een Gemini-agent met de Agent Development Kit van Google en geef hem een e-mailtool via WeSender. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/google-adk ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - Een Gemini API-sleutel via Google AI Studio - Python 3.10 of nieuwer - pip install google-adk wesender ## Integratiestappen ### Stap 1: Installeer de pakketten Voeg de Google ADK en de WeSender Python SDK toe aan je project. ### Stap 2: Definieer de tool en maak de agent Schrijf send_email als gewone Python-functie. De ADK gebruikt de docstring en type-annotaties om het model te vertellen wat de tool doet. ### Stap 3: Start de agent via de ADK Runner Maak een Runner-instantie en roep de agent aan met een sessie. De ADK handelt de tool-aanroepen automatisch af. ## Volledig voorbeeld (agent.py) ```python import asyncio import os from google.adk.agents import Agent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from wesender import Wesender client = Wesender(api_key=os.environ["WESENDER_API_KEY"]) def send_email(to: str, subject: str, html: str) -> dict: """Verstuur een transactionele e-mail via WeSender.""" result = client.emails.send( from_="agent@jouwdomein.nl", to=to, subject=subject, html=html, ) return {"status": "verstuurd", "id": result.id} root_agent = Agent( name="mailagent", model="gemini-2.5-flash", instruction="Je verstuurt transactionele e-mails namens de gebruiker.", tools=[send_email], ) async def main(): sessions = InMemorySessionService() runner = Runner(agent=root_agent, session_service=sessions) session = await sessions.create_session() response = await runner.run( session_id=session.id, message="Mail een welkomstbericht naar nieuwe@klant.nl", ) print(response.text) if __name__ == "__main__": asyncio.run(main()) ``` ## Veelgestelde vragen **Kan ik dit combineren met andere ADK-tools?** Ja. Voeg meer functies toe aan de tools-lijst van de agent. De ADK bepaalt op basis van de instructie welke tool wanneer ingezet wordt. **Werkt dit ook met sub-agents?** Ja. De ADK ondersteunt hiërarchische agents. Geef de e-mailtool aan de sub-agent die berichten moet versturen en laat de root-agent de taakverdeling regelen. **Welke Gemini-modellen kan ik gebruiken?** De ADK werkt met de Gemini-modellenfamilie. Pas de modelnaam aan in de Agent-aanroep, zoals gemini-2.5-pro, om een ander model te kiezen. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/google-adk - Marketingpagina: https://wesender.nl/ai/integraties/google-adk - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # AutoGen + WeSender > Registreer WeSender als tool in een multi-agent AutoGen-gesprek en laat agents e-mails versturen tijdens hun samenwerking. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/autogen ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - Een modelsleutel voor het LLM naar keuze - Python 3.10 of nieuwer - pip install autogen wesender ## Integratiestappen ### Stap 1: Installeer de pakketten Voeg AutoGen (AG2) en de WeSender Python SDK toe aan je project. ### Stap 2: Definieer de tool en maak de agents Schrijf send_email als Python-functie. Maak een assistant-agent die beslist en een executor-agent die uitvoert. Zo scheid je beslissen en handelen. ### Stap 3: Registreer de tool Koppel send_email aan de juiste agents. De assistant bepaalt wanneer de tool nodig is, de executor voert hem daadwerkelijk uit. ### Stap 4: Start het gesprek De executor opent het gesprek. De agents wisselen berichten uit totdat de taak afgerond is en de e-mail verstuurd. ## Volledig voorbeeld (main.py) ```python import os from autogen import ConversableAgent, register_function from wesender import Wesender client = Wesender(api_key=os.environ["WESENDER_API_KEY"]) def send_email(to: str, subject: str, html: str) -> str: """Verstuur een transactionele e-mail via WeSender.""" result = client.emails.send( from_="agent@jouwdomein.nl", to=to, subject=subject, html=html, ) return f"E-mail verstuurd, id: {result.id}" assistant = ConversableAgent( name="assistant", llm_config={"model": "gpt-4o"}, ) executor = ConversableAgent( name="executor", human_input_mode="NEVER", ) register_function( send_email, caller=assistant, executor=executor, description="Verstuur een transactionele e-mail via WeSender", ) executor.initiate_chat( assistant, message="Mail een welkomstbericht naar nieuwe@klant.nl", ) ``` ## Veelgestelde vragen **Welke agent verstuurt de mail?** De executor voert de tool uit nadat de assistant hem heeft aangewezen. Zo scheid je beslissen en uitvoeren, wat de controleerbaarheid van je multi-agent systeem vergroot. **Werkt dit ook met groepsgesprekken?** Ja. Registreer de tool bij de juiste agents in je groepsgesprek. De GroupChatManager stuurt de beurt naar de agent die de e-mail moet versturen. **Kan ik een mens laten goedkeuren?** Ja. Zet human_input_mode op 'ALWAYS' of 'TERMINATE' bij de executor om bevestiging te vragen voordat de tool wordt uitgevoerd. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/autogen - Marketingpagina: https://wesender.nl/ai/integraties/autogen - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Semantic Kernel + WeSender > Voeg WeSender toe als KernelFunction-plugin in je .NET-agent en laat Semantic Kernel de REST API aanroepen. **Categorie:** agent | **URL:** https://docs.wesender.nl/docs/integraties/semantic-kernel ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - WESENDER_API_KEY en een OpenAI- of Azure OpenAI-sleutel - .NET 8 of nieuwer - dotnet add package Microsoft.SemanticKernel ## Integratiestappen ### Stap 1: Installeer het pakket Voeg de Semantic Kernel NuGet toe aan je .NET-project. ### Stap 2: Maak de e-mailplugin Definieer een klasse met een KernelFunction-methode. WeSender heeft geen .NET SDK, dus je roept de REST API aan via HttpClient. ### Stap 3: Registreer de plugin en draai de kernel Bouw de kernel op, voeg de EmailPlugin toe en schakel automatisch function calling in. De kernel roept de plugin zelf aan op het juiste moment. ## Volledig voorbeeld (Program.cs) ```csharp using System.ComponentModel; using System.Net.Http.Json; using Microsoft.SemanticKernel; // Plugin public class EmailPlugin { private static readonly HttpClient http = new(); [KernelFunction("send_email")] [Description("Verstuur een transactionele e-mail via WeSender")] public async Task SendEmailAsync( string to, string subject, string html) { var key = Environment.GetEnvironmentVariable("WESENDER_API_KEY"); var req = new HttpRequestMessage( HttpMethod.Post, "https://api.wesender.nl/v1/emails" ); req.Headers.Add("Authorization", $"Bearer {key}"); req.Content = JsonContent.Create(new { from = "agent@jouwdomein.nl", to, subject, html }); var res = await http.SendAsync(req); res.EnsureSuccessStatusCode(); return "E-mail verstuurd"; } } // Program var builder = Kernel.CreateBuilder() .AddOpenAIChatCompletion( "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY")! ); var kernel = builder.Build(); kernel.Plugins.AddFromType("Email"); var result = await kernel.InvokePromptAsync( "Mail een welkomstbericht naar nieuwe@klant.nl", new KernelArguments(new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(), }) ); Console.WriteLine(result); ``` ## Veelgestelde vragen **Waarom de REST API in plaats van een SDK?** Er is nog geen officiële WeSender .NET SDK. De REST API biedt precies dezelfde functionaliteit en werkt net zo betrouwbaar via HttpClient. **Werkt automatisch function calling?** Ja. Met FunctionChoiceBehavior.Auto() roept de kernel de plugin zelf aan op het juiste moment, zonder dat je de tool-lus handmatig hoeft te beheren. **Kan ik meer functies toevoegen aan de plugin?** Ja. Voeg extra KernelFunction-methoden toe aan de EmailPlugin-klasse. Semantic Kernel herkent ze automatisch via reflectie. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/semantic-kernel - Marketingpagina: https://wesender.nl/ai/integraties/semantic-kernel - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Activepieces + WeSender > Open-source automatisering die je zelf kunt hosten — voeg WeSender toe als HTTP-piece en verstuur e-mails zonder code. **Categorie:** workflow | **URL:** https://docs.wesender.nl/docs/integraties/activepieces ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - Een Activepieces-account of een zelf-gehoste installatie - Geen programmeerkennis vereist ## Integratiestappen ### Stap 1: Maak een flow met een trigger Log in op Activepieces en maak een nieuwe flow aan. Kies de trigger die de e-mail moet veroorzaken, zoals een Webhook- of Schedule-trigger. ### Stap 2: Voeg de HTTP-piece toe Klik op het plusje na je trigger en zoek naar de piece HTTP. Kies de actie Send Request. ### Stap 3: Configureer methode, URL en headers Stel de HTTP-piece in met de WeSender API-gegevens. Voeg je API-sleutel toe in de Authorization-header. ### Stap 4: Stel de body in Voer de JSON-body in met de e-mailgegevens. Gebruik het expressiesysteem van Activepieces om triggervelden zoals het e-mailadres in te voegen. ### Stap 5: Test en activeer de flow Klik op Testen om een testmail te versturen. Controleer of hij aankomt en activeer de flow. ## Volledig voorbeeld (activepieces-config.json) ```json { "piece": "HTTP", "action": "Send Request", "method": "POST", "url": "https://api.wesender.nl/v1/emails", "headers": { "Authorization": "Bearer JOUW_WESENDER_API_KEY", "Content-Type": "application/json" }, "body": { "from": "flow@jouwdomein.nl", "to": "{{trigger.email}}", "subject": "Bedankt voor je aanmelding", "html": "

Hoi {{trigger.naam}}, bedankt voor je aanmelding.

" } } ``` ## Veelgestelde vragen **Heb ik programmeerkennis nodig?** Nee. Je configureert een HTTP-piece via de visuele editor en vult de JSON-body in. Geen code vereist. **Waarom Activepieces in plaats van Make of Zapier?** Activepieces is open-source en zelf te hosten, handig als je alles binnen je eigen EU-infrastructuur wilt houden zonder afhankelijkheid van externe SaaS-providers. **Kan ik per trigger andere ontvangers mailen?** Ja. Gebruik triggervelden in het to-veld van de body, zoals {{trigger.email}}, om dynamisch de ontvanger in te stellen op basis van de binnenkomende data. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/activepieces - Marketingpagina: https://wesender.nl/ai/integraties/activepieces - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Pipedream + WeSender > Voeg WeSender toe als Node-codestap in je Pipedream-workflow en verstuur e-mails vanuit elke trigger. **Categorie:** workflow | **URL:** https://docs.wesender.nl/docs/integraties/pipedream ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - WESENDER_API_KEY opgeslagen als environment variable in Pipedream - Een Pipedream-account ## Integratiestappen ### Stap 1: Sla de API-sleutel op als omgevingsvariabele Navigeer in Pipedream naar Settings > Environment Variables en voeg WESENDER_API_KEY toe. Zo is de sleutel nooit zichtbaar in je workflowcode. ### Stap 2: Maak een workflow met een trigger Maak een nieuwe workflow en kies de trigger die de e-mail moet veroorzaken, zoals een HTTP-trigger of een event van een externe dienst. ### Stap 3: Voeg een Node-codestap toe Klik op het plusje en kies Run Node.js code. Plak de onderstaande stap in de editor en pas de triggervelden aan op je eigen situatie. ### Stap 4: Test en publiceer de workflow Klik op Test om een testmail te versturen. Controleer of het e-mail-ID wordt teruggegeven en publiceer de workflow daarna. ## Volledig voorbeeld (send-email.js) ```javascript import { Wesender } from "@wesender/node" export default defineComponent({ async run({ steps }) { const client = new Wesender(process.env.WESENDER_API_KEY) // Pas dit aan op je triggergegevens const to = steps.trigger.event.email const subject = steps.trigger.event.subject ?? "Bedankt voor je aanmelding" const html = "

Hoi, bedankt voor je aanmelding.

" const result = await client.emails.send({ from: "workflow@jouwdomein.nl", to, subject, html }) return { id: result.id } }, }) ``` ## Veelgestelde vragen **Code of no-code?** Pipedream is low-code. Een korte Node-stap geeft je de meeste controle en flexibiliteit. Wil je geen code schrijven, dan is een HTTP Request-stap ook mogelijk. **Waar sla ik mijn API-sleutel op?** Als environment variable in Pipedream, zodat hij niet zichtbaar is in je workflowcode en niet in versiebeheer terechtkomt. **Kan ik triggervelden gebruiken in de e-mailbody?** Ja. Lees ze uit via steps.trigger.event in je code. Zo verwerk je naam, bestelnummer of andere gegevens van de trigger direct in de e-mail. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/pipedream - Marketingpagina: https://wesender.nl/ai/integraties/pipedream - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # CopilotKit + WeSender > Geef de copilot in je React-app een e-mailactie — de sleutel blijft op de server, de actie in je component. **Categorie:** assistent | **URL:** https://docs.wesender.nl/docs/integraties/copilotkit ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - WESENDER_API_KEY alleen op de server, nooit in de browser - Een React-app met CopilotKit opgezet - npm install @wesender/node ## Integratiestappen ### Stap 1: Maak een server-route voor e-mail Houd je WeSender API-sleutel op de server. Maak een serverroute die de browser aanroept, nooit WeSender rechtstreeks vanuit de client. ### Stap 2: Definieer de copilot-actie Voeg useCopilotAction toe in een component binnen de CopilotKit-provider. De handler roept je eigen serverroute aan, zodat de API-sleutel nooit de browser bereikt. ### Stap 3: Voeg de CopilotKit UI toe aan je app Omsluit je app met een CopilotKitProvider en voeg een CopilotSidebar of CopilotPopup toe zodat gebruikers de copilot kunnen aanspreken. ## Volledig voorbeeld (app/api/send-email/route.ts) ```typescript import { Wesender } from "@wesender/node" const emailClient = new Wesender(process.env.WESENDER_API_KEY!) export async function POST(req: Request) { const { to, subject, html } = await req.json() const result = await emailClient.emails.send({ from: "app@jouwdomein.nl", to, subject, html, }) return Response.json({ id: result.id }) } // Gebruik in je component (binnen CopilotKitProvider): // // import { useCopilotAction } from "@copilotkit/react-core" // // useCopilotAction({ // name: "send_email", // description: "Verstuur een transactionele e-mail via WeSender", // parameters: [ // { name: "to", type: "string" }, // { name: "subject", type: "string" }, // { name: "html", type: "string" }, // ], // handler: async ({ to, subject, html }) => { // const res = await fetch("/api/send-email", { // method: "POST", headers: { "Content-Type": "application/json" }, // body: JSON.stringify({ to, subject, html }), // }) // return "E-mail verstuurd, id: " + (await res.json()).id // }, // }) ``` ## Veelgestelde vragen **Mag mijn API-sleutel in de browser staan?** Nee. Houd de WeSender API-sleutel altijd op de server en laat de browser je eigen serverroute aanroepen. Zo is de sleutel nooit zichtbaar in je frontend-code of de browser-devtools. **Kan de gebruiker de mail eerst bekijken?** Ja. Toon een concept in de copilot met een bevestigingsinteractie en verstuur pas na goedkeuring. CopilotKit ondersteunt dit standaard voor onomkeerbare acties. **Werkt dit met elke React-app?** Ja, zolang je een CopilotKitProvider rond je app hebt en de actie wordt gedefinieerd in een component die daarbinnen valt. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/copilotkit - Marketingpagina: https://wesender.nl/ai/integraties/copilotkit - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Ollama + WeSender > Lokaal model, betrouwbare bezorging — laat Ollama een send_email tool aanroepen en WeSender verstuurt vanuit de EU. **Categorie:** provider | **URL:** https://docs.wesender.nl/docs/integraties/ollama ## Vereisten - WeSender-account met geverifieerd domein en API-sleutel - Ollama lokaal geinstalleerd met een tool-compatibel model (bijv. llama3.1) - Node.js 18 of nieuwer - npm install ollama @wesender/node ## Integratiestappen ### Stap 1: Installeer de pakketten Voeg de Ollama JavaScript-client en de WeSender Node SDK toe aan je project. Zorg dat Ollama lokaal draait en een model heeft geladen. ### Stap 2: Roep het lokale model aan met de tool Stuur een verzoek naar je lokale Ollama-instantie met de tool-definitie. Het model geeft een function_call terug als het send_email wil aanroepen. ### Stap 3: Voer de toolaanroep uit Controleer of het model een function_call heeft teruggegeven en verstuur de e-mail via WeSender. ## Volledig voorbeeld (src/ollama.ts) ```typescript import ollama from "ollama" import { Wesender } from "@wesender/node" const emailClient = new Wesender(process.env.WESENDER_API_KEY!) const response = await ollama.chat({ model: "llama3.1", messages: [{ role: "user", content: "Mail een welkomstbericht naar nieuwe@klant.nl" }], tools: [{ type: "function", function: { name: "send_email", description: "Verstuur een transactionele e-mail via WeSender", parameters: { type: "object", properties: { to: { type: "string" }, subject: { type: "string" }, html: { type: "string" }, }, required: ["to", "subject", "html"], }, }, }], }) const call = response.message.tool_calls?.[0] if (call?.function.name === "send_email") { const { to, subject, html } = call.function.arguments as Record try { const result = await emailClient.emails.send({ from: "assistent@jouwdomein.nl", to, subject, html, }) console.log("E-mail verstuurd, id: " + result.id) } catch (err) { console.error("Fout bij versturen:", err) } } ``` ## Veelgestelde vragen **Welke modellen ondersteunen tool calling?** Modellen die tool calling ondersteunen, zoals Llama 3.1 en nieuwer. Controleer per model in de Ollama-documentatie of tool calling beschikbaar is. **Blijft alles lokaal?** Het model draait op je eigen machine. De e-mail gaat via WeSender, dat verwerkt binnen Europese datacenters. Zo combineer je een volledig lokale AI met betrouwbare bezorging. **Werkt dit ook in Python?** Ja. Ollama heeft ook een Python-client. Gebruik dezelfde opzet met de WeSender Python SDK: client.emails.send(from_=..., to=..., subject=..., html=...). ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/ollama - Marketingpagina: https://wesender.nl/ai/integraties/ollama - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Claude Desktop + WeSender > Koppel de WeSender MCP-server aan Claude Desktop en laat Claude rechtstreeks vanuit je gesprek mailen. **Categorie:** mcp | **URL:** https://docs.wesender.nl/docs/integraties/claude-desktop ## Vereisten - De WeSender MCP-server gebouwd en gecompileerd via de MCP-gids - Claude Desktop geinstalleerd (versie met MCP-ondersteuning) - Je WESENDER_API_KEY bij de hand ## Integratiestappen ### Stap 1: Bouw de MCP-server Volg eerst de MCP-gids om de WeSender MCP-server te bouwen. Je hebt het volledige pad naar de gecompileerde dist/index.js nodig in de volgende stap. ### Stap 2: Open de configuratie van Claude Desktop Open het MCP-configuratiebestand van Claude Desktop. Op macOS vind je het op ~/Library/Application Support/Claude/claude_desktop_config.json, op Windows op %APPDATA%\Claude\claude_desktop_config.json. ### Stap 3: Voeg de WeSender-server toe Voeg het wesender-object toe aan mcpServers en vervang het pad door het volledige pad naar dist/index.js op jouw systeem. ### Stap 4: Herstart Claude Desktop Sluit Claude Desktop volledig af en open het opnieuw. Na de herstart verschijnt send_email als beschikbare tool. Vraag Claude om een mail te sturen en keur de tool-aanroep goed in de bevestigingsdialoog. ## Volledig voorbeeld (claude_desktop_config.json) ```json { "mcpServers": { "wesender": { "command": "node", "args": ["/absoluut/pad/naar/dist/index.js"], "env": { "WESENDER_API_KEY": "ws_jouw_sleutel" } } } } ``` ## Veelgestelde vragen **Moet ik de MCP-server eerst zelf bouwen?** Ja. Volg de MCP-gids om de server te bouwen met npm run build. Deze gids veronderstelt dat dist/index.js al beschikbaar is. **Werkt elke versie van Claude Desktop?** Elke versie die MCP-servers ondersteunt. Controleer in de app of MCP beschikbaar is en houd Claude Desktop bijgewerkt voor de nieuwste ondersteuning. **Kan ik meer tools toevoegen?** Ja. Voeg extra tools toe aan de MCP-server en hercompileer. Na een herstart van Claude Desktop zijn ze beschikbaar in je gesprekken. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/claude-desktop - Marketingpagina: https://wesender.nl/ai/integraties/claude-desktop - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Cursor + WeSender > Koppel de WeSender MCP-server aan Cursor en laat de agent in je editor e-mails versturen zonder de IDE te verlaten. **Categorie:** mcp | **URL:** https://docs.wesender.nl/docs/integraties/cursor ## Vereisten - De WeSender MCP-server gebouwd en gecompileerd via de MCP-gids - Cursor geinstalleerd - Je WESENDER_API_KEY bij de hand ## Integratiestappen ### Stap 1: Bouw de MCP-server Volg eerst de MCP-gids om de WeSender MCP-server te bouwen. Je hebt het volledige pad naar dist/index.js nodig. ### Stap 2: Open de MCP-instellingen van Cursor Open het MCP-configuratiebestand van Cursor. Je kunt de server per project instellen in .cursor/mcp.json of globaal in de Cursor-instellingen via Cursor > Settings > MCP. ### Stap 3: Voeg de WeSender-server toe Voeg het wesender-object toe aan mcpServers en vervang het pad door het volledige pad naar dist/index.js op jouw systeem. ### Stap 4: Gebruik de tool in de agent Herstart Cursor. De agent kan nu send_email aanroepen via MCP. Geef de agent een instructie en keur de aanroep goed wanneer Cursor erom vraagt. ## Volledig voorbeeld (.cursor/mcp.json) ```json { "mcpServers": { "wesender": { "command": "node", "args": ["/absoluut/pad/naar/dist/index.js"], "env": { "WESENDER_API_KEY": "ws_jouw_sleutel" } } } } ``` ## Veelgestelde vragen **Waarvoor gebruik ik dit?** Bijvoorbeeld om een agent in je editor een testrapport, buildresultaat of codereview-samenvatting te laten mailen terwijl je doorwerkt in Cursor. **Moet ik de server eerst bouwen?** Ja. Bouw de MCP-server via de MCP-gids met npm run build. Daarna werkt deze configuratie direct. **Werkt dit ook in andere editors?** Elke editor die MCP ondersteunt werkt op dezelfde manier met deze server. De configuratiestap verschilt per editor, maar de server-code blijft hetzelfde. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/cursor - Marketingpagina: https://wesender.nl/ai/integraties/cursor - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Lovable + WeSender > Prompt een volledige app, voeg e-maillogica toe via WeSender. **Categorie:** builtool | **URL:** https://docs.wesender.nl/docs/integraties/lovable ## Vereisten - Lovable-account met een actief project - WeSender-account met geverifieerd domein - Supabase-project gekoppeld aan je Lovable-app (voor server-side secrets) ## Integratiestappen ### Stap 1: Haal je WeSender API-sleutel op Ga naar app.wesender.nl, open Instellingen > API-sleutels en kopieer de sleutel. Bewaar hem tijdelijk - je voegt hem zo toe als Supabase-secret. ### Stap 2: Sla de sleutel op als Supabase Edge Function Secret Open je Supabase-dashboard, ga naar Project Settings > Edge Functions en voeg WESENDER_API_KEY toe als secret. De sleutel is nu beschikbaar in je Edge Functions zonder dat hij in de frontend-code staat. ### Stap 3: Prompt Lovable om een Edge Function te maken Open Lovable en typ de volgende prompt: Maak een Supabase Edge Function genaamd 'send-email'. De functie stuurt een e-mail via de WeSender REST API (POST https://api.wesender.nl/v1/emails). Gebruik de omgevingsvariabele WESENDER_API_KEY als Bearer-token. De functie accepteert een JSON-body met de velden 'to', 'subject' en 'html'. Geef een JSON-response terug met het e-mail-id of een foutmelding. Lovable genereert de Edge Function, voegt hem toe aan je Supabase-project en schrijft de aanroepcode in de frontend. ### Stap 4: Controleer de gegenereerde code Open de Edge Function in Lovable of Supabase. Controleer dat de Authorization-header de omgevingsvariabele gebruikt (Deno.env.get('WESENDER_API_KEY')) en niet een hardcoded waarde. Het 'from'-adres moet op je geverifieerde domein staan. ### Stap 5: Stuur een testmail via Lovable Prompt Lovable om een testknop toe te voegen die de Edge Function aanroept met een voorbeeldmail. Klik op de knop in de preview, controleer je inbox en bekijk het bezorgrapport in je WeSender-dashboard. ## Volledig voorbeeld (supabase/functions/send-email/index.ts) ```typescript import { serve } from "https://deno.land/std@0.168.0/http/server.ts" serve(async (req) => { if (req.method !== "POST") { return new Response("Method not allowed", { status: 405 }) } const { to, subject, html } = await req.json() const res = await fetch("https://api.wesender.nl/v1/emails", { method: "POST", headers: { "Authorization": `Bearer ${Deno.env.get("WESENDER_API_KEY")}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "noreply@jouwdomein.nl", to, subject, html, }), }) const data = await res.json() return new Response(JSON.stringify(data), { headers: { "Content-Type": "application/json" }, status: res.status, }) }) ``` ## Veelgestelde vragen **Kan ik de API-sleutel direct in de Lovable-frontend gebruiken?** Nee. Elke sleutel in frontend-code is zichtbaar voor bezoekers van je app. Gebruik altijd een server-side omgeving zoals een Supabase Edge Function om de sleutel veilig te bewaren. **Welk from-adres moet ik gebruiken?** Het from-adres moet op een domein staan dat je in het WeSender-dashboard hebt geverifieerd. Gebruik je een ander domein, dan weigert de API de aanvraag. **Lovable geeft een CORS-fout. Wat nu?** Voeg in de Edge Function een 'Access-Control-Allow-Origin'-header toe en vang OPTIONS-verzoeken op. Prompt Lovable: voeg CORS-headers toe aan de send-email Edge Function zodat aanroepen vanuit de browser werken. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/lovable - Marketingpagina: https://wesender.nl/ai/integraties/lovable - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Bolt + WeSender > Bouw en deploy apps vanuit een prompt, met WeSender voor transactionele mail. **Categorie:** builtool | **URL:** https://docs.wesender.nl/docs/integraties/bolt ## Vereisten - Bolt.new-account - WeSender-account met geverifieerd domein - Basiskennis van hoe Bolt server-side routes maakt ## Integratiestappen ### Stap 1: Start een nieuw Bolt-project met server-side logica Open Bolt.new en prompt een app met een server-side API-route. Bolt ondersteunt frameworks zoals Remix en Next.js, die server-side code native ondersteunen. Kies Remix of Next.js voor de beste resultaten met server-side secrets. ### Stap 2: Voeg de WeSender API-sleutel toe als omgevingsvariabele In Bolt kun je omgevingsvariabelen instellen via het .env-venster in de editor. Voeg toe: WESENDER_API_KEY=jouw_sleutel. Bolt gooit de .env niet mee in exports, maar sla de sleutel ook op in je eigen .env.local als je het project lokaal runt. ### Stap 3: Prompt Bolt om een e-mail API-route te maken Typ in Bolt: Maak een POST API-route /api/send-email. De route leest WESENDER_API_KEY uit process.env en stuurt een e-mail via POST https://api.wesender.nl/v1/emails met JSON-body {from, to, subject, html}. Geef het e-mail-id terug als JSON. Bolt schrijft de route in het gekozen framework. ### Stap 4: Koppel de route aan een UI-actie Prompt Bolt om een formulier of knop toe te voegen die de route aanroept: Voeg een knop toe op de homepage die POST /api/send-email aanroept met testdata en het resultaat (e-mail-id of foutmelding) toont in een alert. ### Stap 5: Test en deploy Klik op de knop in de Bolt-preview. Controleer je inbox en het WeSender-dashboard. Gebruik daarna de Bolt deploy-knop om de app live te zetten. Zorg dat de productie-omgeving ook de WESENDER_API_KEY-variabele heeft. ## Volledig voorbeeld (app/routes/api.send-email.ts) ```typescript import type { ActionFunctionArgs } from "@remix-run/node" import { json } from "@remix-run/node" export async function action({ request }: ActionFunctionArgs) { if (request.method !== "POST") { return json({ error: "Method not allowed" }, { status: 405 }) } const { to, subject, html } = await request.json() const res = await fetch("https://api.wesender.nl/v1/emails", { method: "POST", headers: { "Authorization": `Bearer ${process.env.WESENDER_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "noreply@jouwdomein.nl", to, subject, html, }), }) const data = await res.json() return json(data, { status: res.status }) } ``` ## Veelgestelde vragen **Bolt heeft geen .env-ondersteuning in mijn project. Wat nu?** Prompt Bolt om het project te converteren naar een framework met native .env-ondersteuning zoals Remix of Next.js. Die frameworks lezen process.env server-side en sturen omgevingsvariabelen nooit naar de browser. **Kan ik de WeSender Node SDK gebruiken in Bolt?** Ja. Prompt Bolt om @wesender/node te installeren en gebruik dan: import { Wesender } from '@wesender/node'; const client = new Wesender(process.env.WESENDER_API_KEY!); await client.emails.send({...}). Dit geeft typeveiligheid. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/bolt - Marketingpagina: https://wesender.nl/ai/integraties/bolt - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # v0 + WeSender > Genereer React-componenten met Vercel v0, verstuur mail via WeSender. **Categorie:** builtool | **URL:** https://docs.wesender.nl/docs/integraties/v0 ## Vereisten - Vercel-account met toegang tot v0.dev - WeSender-account met geverifieerd domein - Next.js-project (v0 exporteert naar Next.js) ## Integratiestappen ### Stap 1: Genereer een UI-component met v0 Open v0.dev en prompt een component dat een e-mail trigger nodig heeft, bijvoorbeeld een contactformulier of een bestelbevestiging. v0 genereert React-code die je exporteert naar een Next.js-project. ### Stap 2: Exporteer het component naar Next.js Klik op 'Export' in v0 en importeer de code in je lokale Next.js-project of in een Vercel-project. Zorg dat je Next.js 14 of hoger gebruikt zodat Server Actions beschikbaar zijn. ### Stap 3: Voeg een Server Action toe voor e-mailverzending Maak een nieuw bestand app/actions/sendEmail.ts en voeg de Server Action toe. Server Actions draaien server-side, dus de API-sleutel is nooit zichtbaar in de browser. ### Stap 4: Koppel de action aan het v0-component Open het geexporteerde v0-component en voeg de Server Action toe als form action of als onClick-handler. Gebruik 'use server' bovenaan het actiebestand. ### Stap 5: Stel de omgevingsvariabele in en deploy Voeg WESENDER_API_KEY toe aan je .env.local voor lokale ontwikkeling en aan de Vercel Environment Variables voor productie. Deploy via Vercel CLI of de Vercel-dashboard. ## Volledig voorbeeld (app/actions/sendEmail.ts) ```typescript "use server" export async function sendEmail(formData: FormData) { const to = formData.get("email") as string const subject = formData.get("subject") as string const html = formData.get("html") as string const res = await fetch("https://api.wesender.nl/v1/emails", { method: "POST", headers: { "Authorization": `Bearer ${process.env.WESENDER_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "noreply@jouwdomein.nl", to, subject, html, }), }) if (!res.ok) { throw new Error(`WeSender-fout: ${res.statusText}`) } const { id } = await res.json() return { id } } ``` ## Veelgestelde vragen **v0 genereert client-side code. Hoe voorkom ik dat de API-sleutel in de browser komt?** Gebruik altijd een Server Action (bestand begint met 'use server') of een API-route (app/api/send-email/route.ts). v0-componenten zelf zijn client-side React, maar de e-mailverzending moet altijd server-side. **Kan ik de WeSender Node SDK gebruiken in een Server Action?** Ja. Installeer @wesender/node en gebruik: import { Wesender } from '@wesender/node'; const client = new Wesender(process.env.WESENDER_API_KEY!); const result = await client.emails.send({...}); **v0 heeft geen server-side code gegenereerd. Moet ik dat zelf schrijven?** Ja. v0 genereert UI-componenten. De server-side logica voor e-mail schrijf je zelf in een Server Action of API-route. Dat is maar een enkel bestand en volgt exact het patroon in de voorbeeldcode boven. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/v0 - Marketingpagina: https://wesender.nl/ai/integraties/v0 - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Replit + WeSender > Bouw en host apps in de browser, voeg WeSender toe via Replit Secrets. **Categorie:** builtool | **URL:** https://docs.wesender.nl/docs/integraties/replit ## Vereisten - Replit-account - WeSender-account met geverifieerd domein - Basis Node.js of Python kennis ## Integratiestappen ### Stap 1: Maak een nieuw Replit-project aan Open Replit en maak een nieuw project aan. Kies Node.js (Express) of Python (Flask) als template. Beide frameworks ondersteunen server-side code en omgevingsvariabelen via Replit Secrets. ### Stap 2: Sla je WeSender API-sleutel op als Replit Secret Open in je Replit-project het slotje-icoon (Secrets) in het linker menu. Voeg een nieuw secret toe met naam WESENDER_API_KEY en jouw API-sleutel als waarde. Replit injecteert dit automatisch als omgevingsvariabele. ### Stap 3: Installeer de WeSender SDK Open de Shell in Replit en typ: npm install @wesender/node. Voor Python gebruik: pip install wesender. Replit slaat de dependency op in package.json of requirements.txt. ### Stap 4: Voeg een e-mail-endpoint toe Open index.js (of main.py) en voeg een POST-route toe die e-mails verstuurt. Gebruik process.env.WESENDER_API_KEY om de sleutel op te halen. Gebruik nooit een hardcoded sleutel in de code. ### Stap 5: Test de endpoint via de Replit Webview Klik op Run in Replit. Open de Webview en gebruik de ingebouwde console of een tool zoals curl om een POST-verzoek te sturen naar /send-email. Controleer je inbox en het WeSender-dashboard voor bezorgbevestiging. ## Volledig voorbeeld (index.ts) ```typescript import express from "express" import { Wesender } from "@wesender/node" const app = express() const client = new Wesender(process.env.WESENDER_API_KEY!) app.use(express.json()) app.post("/send-email", async (req, res) => { const { to, subject, html } = req.body try { const result = await client.emails.send({ from: "noreply@jouwdomein.nl", to, subject, html, }) res.json({ id: result.id }) } catch (err) { res.status(500).json({ error: (err as Error).message }) } }) app.listen(3000, () => console.log("Server draait op poort 3000")) ``` ## Veelgestelde vragen **Kan ik de API-sleutel ook in de Replit-code zetten?** Nee. Hardcoded sleutels in code zijn zichtbaar voor iedereen die de Repl bekijkt of forkt. Gebruik altijd Replit Secrets zodat de sleutel veilig opgeslagen is en niet mee-geexporteerd wordt. **Mijn Replit-app is gratis en stopt als niemand hem gebruikt. Werkt WeSender dan nog?** WeSender zelf staat altijd aan. Het probleem is dat een slapende Replit-app geen inkomende verzoeken kan verwerken. Gebruik Replit Deployments of een externe cron om de app wakker te houden als je webhooks of geplande mails nodig hebt. **Welke talen ondersteunt WeSender via Replit?** Je kunt de REST API aanroepen vanuit elke taal. WeSender heeft officiele SDK's voor Node.js (@wesender/node) en Python (wesender). Voor andere talen gebruik je een gewone HTTP-aanroep naar https://api.wesender.nl/v1/emails. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/replit - Marketingpagina: https://wesender.nl/ai/integraties/replit - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Claude Code + WeSender > Laat Claude Code de WeSender-integratie schrijven via de MCP-server. **Categorie:** coding-agent | **URL:** https://docs.wesender.nl/docs/integraties/claude-code ## Vereisten - Claude Code geinstalleerd (claude.ai/code of via npm: npm i -g @anthropic-ai/claude-code) - WeSender-account met geverifieerd domein en API-sleutel - Node.js 18 of hoger ## Integratiestappen ### Stap 1: Installeer en configureer Claude Code Installeer Claude Code via de website of terminal: npm install -g @anthropic-ai/claude-code. Voer claude login uit om in te loggen. Claude Code werkt in je terminal als een AI-assistent die bestanden kan lezen, schrijven en commando's kan uitvoeren. ### Stap 2: Koppel de WeSender MCP-server Voeg de WeSender MCP-server toe aan Claude Code zodat de agent direct met je WeSender-account kan werken. Typ in je terminal: claude mcp add wesender-mcp -- npx -y @wesender/mcp Omgevingsvariabele toevoegen: claude mcp add wesender-mcp --env WESENDER_API_KEY=jouw_sleutel -- npx -y @wesender/mcp Claude Code laadt de MCP-server automatisch bij elke sessie. ### Stap 3: Vraag Claude Code om een integratie te schrijven Open een terminal in je projectmap en start Claude Code met claude. Geef dan een opdracht: Voeg WeSender-e-mailverzending toe aan dit project. Maak een TypeScript-functie die een welkomstmail stuurt na registratie. Gebruik de omgevingsvariabele WESENDER_API_KEY en de @wesender/node SDK. Claude Code leest je projectstructuur, schrijft de code en voegt de dependency toe. ### Stap 4: Laat de agent de code testen Vraag Claude Code om de integratie te testen: Schrijf een test voor de sendWelcomeEmail-functie die controleert of de WeSender API correct wordt aangeroepen. Gebruik Vitest of Jest. Claude Code schrijft de test, runt hem en laat je de output zien. ### Stap 5: Controleer de gegenereerde code Open de gegenereerde bestanden en controleer: staat de API-sleutel in process.env? Is het from-adres op een geverifieerd domein? Bevat de code geen hardcoded secrets? Claude Code volgt de WeSender-docs die via de MCP-server beschikbaar zijn, maar een snelle check is altijd verstandig. ## Volledig voorbeeld (.mcp.json (Claude Code MCP-configuratie)) ```bash { "mcpServers": { "wesender": { "command": "npx", "args": ["-y", "@wesender/mcp"], "env": { "WESENDER_API_KEY": "${WESENDER_API_KEY}" } } } } ``` ## Veelgestelde vragen **Hoe weet Claude Code wat WeSender kan?** Via de MCP-server heeft Claude Code toegang tot de WeSender-tools (send_email, list_domains, list_emails, get_email). Bovendien kun je wesender.nl/llms.txt aan het begin van je sessie delen: claude 'Lees https://wesender.nl/llms.txt en gebruik die context voor alle WeSender-vragen.' **Kan ik Claude Code ook zonder MCP-server gebruiken?** Ja. Deel de WeSender-documentatie aan het begin van je sessie en vraag Claude Code om de integratie te schrijven op basis van de REST API of Node SDK. De MCP-server geeft extra context maar is niet verplicht. **Claude Code vraagt om mijn API-sleutel in de code. Wat doe ik?** Zeg dan: gebruik process.env.WESENDER_API_KEY in plaats van een hardcoded waarde. Voeg WESENDER_API_KEY toe aan .env.local en laad hem via dotenv. Claude Code past de code direct aan. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/claude-code - Marketingpagina: https://wesender.nl/ai/integraties/claude-code - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # GitHub Copilot + WeSender > Copilot schrijft WeSender-integratiecode direct in je editor. **Categorie:** coding-agent | **URL:** https://docs.wesender.nl/docs/integraties/github-copilot ## Vereisten - GitHub Copilot-abonnement (Copilot Individual, Business of Enterprise) - VS Code met de GitHub Copilot-extensie of JetBrains IDE - WeSender-account met geverifieerd domein en API-sleutel ## Integratiestappen ### Stap 1: Installeer de Copilot-extensie Open VS Code en installeer de extensie 'GitHub Copilot' en 'GitHub Copilot Chat' vanuit de marketplace. Log in met je GitHub-account. Voor JetBrains installeer je de plugin via Settings > Plugins > GitHub Copilot. ### Stap 2: Open Copilot Agent Mode In VS Code: open de Copilot Chat-sidebar (Ctrl+Alt+I of Cmd+Option+I) en klik op het agentpictogram. In Agent Mode kan Copilot bestanden aanmaken, aanpassen en terminalopdrachten uitvoeren. Selecteer de map van je project als werkruimte. ### Stap 3: Geef de integratievraag aan Copilot @workspace Voeg een e-mailfunctie toe die een welkomstmail verstuurt via de WeSender REST API (POST https://api.wesender.nl/v1/emails). Gebruik process.env.WESENDER_API_KEY als Bearer-token. Maak ook een .env.example-bestand. Copilot leest de projectstructuur, schrijft de functie in de juiste map en maakt het .env.example-bestand aan. ### Stap 4: Voeg .env-instructies toe via Copilot Vraag Copilot: Voeg WESENDER_API_KEY toe aan .env.example en aan .gitignore. Zorg dat de sleutel nooit in de code staat. Copilot voegt de entries toe en past eventueel de bestaande .gitignore aan. ### Stap 5: Test de integratie Vraag Copilot om een test te schrijven: Schrijf een unit test voor de sendEmail-functie met Vitest. Mock de fetch-aanroep en controleer dat de Authorization-header correct is. Run de tests met npm test of via de terminal in de sidebar. ## Volledig voorbeeld (src/lib/email.ts) ```typescript export async function sendEmail(opts: { to: string subject: string html: string }) { const res = await fetch("https://api.wesender.nl/v1/emails", { method: "POST", headers: { "Authorization": `Bearer ${process.env.WESENDER_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "noreply@jouwdomein.nl", ...opts, }), }) if (!res.ok) { throw new Error(`WeSender-fout: ${res.statusText}`) } return res.json() as Promise<{ id: string }> } ``` ## Veelgestelde vragen **Copilot schrijft de API-sleutel direct in de code. Hoe voorkom ik dat?** Geef de instructie mee in je prompt: gebruik altijd process.env.WESENDER_API_KEY en nooit een hardcoded waarde. Voeg toe: als je ooit een hardcoded sleutel ziet, markeer dat als een beveiligingsprobleem. Copilot volgt instructies in de prompt. **Kan Copilot ook de WeSender Node SDK gebruiken in plaats van fetch?** Ja. Prompt: gebruik @wesender/node in plaats van fetch. Copilot installeert de package en schrijft: import { Wesender } from '@wesender/node'; const client = new Wesender(process.env.WESENDER_API_KEY!); await client.emails.send({...}). **Copilot genereert andere code dan ik verwacht. Hoe stuur ik bij?** Geef concrete feedback in de chat: de Authorization-header mist, het from-adres moet op geverifieerd domein staan, of voeg foutafhandeling toe. Copilot past de gegenereerde code aan op basis van je feedback. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/github-copilot - Marketingpagina: https://wesender.nl/ai/integraties/github-copilot - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # OpenAI Codex + WeSender > Codex schrijft en test WeSender-integraties in een geïsoleerde cloud-omgeving. **Categorie:** coding-agent | **URL:** https://docs.wesender.nl/docs/integraties/codex ## Vereisten - OpenAI-account met toegang tot Codex (codex.openai.com) - GitHub-repository voor je project - WeSender-account met geverifieerd domein en API-sleutel ## Integratiestappen ### Stap 1: Open Codex en koppel je repository Ga naar codex.openai.com en log in met je OpenAI-account. Koppel je GitHub-repository via de OAuth-flow. Codex krijgt leestoegang tot je code en kan pull requests aanmaken. ### Stap 2: Voeg de WeSender API-sleutel toe als secret In de Codex-omgeving kun je omgevingsvariabelen instellen voordat een taak start. Voeg WESENDER_API_KEY toe als secret. Codex injecteert de variabele in de sandboxomgeving zodat tests kunnen draaien zonder de sleutel in de code te zetten. ### Stap 3: Geef Codex een taakopdracht Maak een nieuwe taak aan in Codex: Voeg een TypeScript-functie toe aan src/lib/email.ts die een transactionele e-mail verstuurt via de WeSender REST API. Gebruik process.env.WESENDER_API_KEY als Bearer-token. Schrijf ook een Vitest-test die de fetch-aanroep mockt en de Authorization-header controleert. Codex werkt asynchroon: het schrijft de code, runt de tests en maakt een pull request als alles slaagt. ### Stap 4: Review de pull request Als Codex klaar is, ontvang je een GitHub pull request met de gegenereerde code en de testresultaten. Controleer de code op hardcoded waarden, het from-adres en de foutafhandeling. Merge de PR als alles klopt. ### Stap 5: Deploy en stel omgevingsvariabelen in Voeg WESENDER_API_KEY toe aan je productie-omgeving (Vercel, Railway, Render of een andere hostingdienst). De code die Codex heeft geschreven gebruikt process.env, dus je hoeft alleen de variabele in te stellen. ## Volledig voorbeeld (src/lib/email.ts) ```typescript import { Wesender } from "@wesender/node" const client = new Wesender(process.env.WESENDER_API_KEY!) export async function sendTransactionalEmail(opts: { to: string subject: string html: string }): Promise<{ id: string }> { const result = await client.emails.send({ from: "noreply@jouwdomein.nl", to: opts.to, subject: opts.subject, html: opts.html, }) return { id: result.id } } ``` ## Veelgestelde vragen **Codex heeft toegang tot mijn repository. Is dat veilig?** Codex werkt in een geïsoleerde sandboxomgeving en heeft geen toegang tot productiesystemen. Sla secrets op via de Codex secrets-interface, niet in de code. Controleer altijd de gegenereerde pull request voor je merget. **Codex draait de tests maar WeSender-aanroepen mislukken in de sandbox.** Dat klopt. Codex-testen die echte API-aanroepen doen werken niet in de sandbox tenzij je netwerktoegang hebt ingeschakeld. Schrijf unit tests met een gemockte fetch en gebruik integratietests lokaal of in CI met de echte sleutel. **Kan ik Codex ook vragen om een webhook-handler te schrijven?** Ja. Prompt: voeg een POST /webhooks/wesender route toe die WeSender-webhook-events verwerkt. Valideer de handtekening via de X-Wesender-Signature-header. Sla de sleutel op als WESENDER_WEBHOOK_SECRET. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/codex - Marketingpagina: https://wesender.nl/ai/integraties/codex - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Windsurf + WeSender > Windsurf begrijpt de volledige codebase en schrijft WeSender-integraties contextueel. **Categorie:** coding-agent | **URL:** https://docs.wesender.nl/docs/integraties/windsurf ## Vereisten - Windsurf IDE geinstalleerd (windsurf.ai) - WeSender-account met geverifieerd domein en API-sleutel - Een bestaand project dat je wilt uitbreiden met e-maillogica ## Integratiestappen ### Stap 1: Installeer Windsurf en open je project Download Windsurf via windsurf.ai en installeer de IDE. Open je bestaande project via File > Open Folder. Windsurf indexeert de hele codebase zodat Cascade (de ingebouwde AI) context heeft over je projectstructuur, bestaande functies en naamgevingsconventies. ### Stap 2: Stel de omgevingsvariabele in Voeg WESENDER_API_KEY toe aan je .env.local. Als je project al een .env-bestand heeft, zet de sleutel daar. Windsurf leest de projectstructuur maar laat secrets nooit uitlekken naar de Cascade-context. ### Stap 3: Vraag Cascade om de integratie te schrijven Open de Cascade-sidebar (Ctrl+L of Cmd+L) en typ: Voeg een e-mailfunctie toe die WeSender gebruikt. Kijk naar de bestaande functiestructuur in dit project en schrijf de WeSender-integratie op dezelfde manier. Gebruik process.env.WESENDER_API_KEY en de @wesender/node SDK. Cascade analyseert je codebase, volgt de bestaande conventies en schrijft de code consistent met je project. ### Stap 4: Cascade schrijft en past meerdere bestanden aan Cascade kan in een stap meerdere bestanden aanpassen: de e-mailfunctie, een test, de types en eventuele index-bestanden. Bekijk de diff in de Windsurf-editor en keur de wijzigingen goed of stuur Cascade bij via de chat. ### Stap 5: Test via de ingebouwde terminal Open de terminal in Windsurf (Ctrl+backtick) en run: npm test. Als tests slagen, commit je de wijzigingen vanuit de geintegreerde Git-interface. Als er fouten zijn, geef ze terug aan Cascade: los de testfout op de regel X op. ## Volledig voorbeeld (src/services/email.service.ts) ```typescript import { Wesender } from "@wesender/node" export class EmailService { private readonly client: Wesender constructor() { this.client = new Wesender(process.env.WESENDER_API_KEY!) } async sendWelcome(to: string, naam: string): Promise { const result = await this.client.emails.send({ from: "noreply@jouwdomein.nl", to, subject: `Welkom bij onze app, ${naam}!`, html: `

Hoi ${naam}, je account is aangemaakt.

`, }) return result.id } async sendPasswordReset(to: string, resetUrl: string): Promise { const result = await this.client.emails.send({ from: "noreply@jouwdomein.nl", to, subject: "Wachtwoord opnieuw instellen", html: `

Stel je wachtwoord opnieuw in

`, }) return result.id } } ``` ## Veelgestelde vragen **Cascade schrijft code die niet aansluit bij mijn project. Hoe verbeter ik dat?** Windsurf indexeert de codebase, maar geef ook expliciete context mee: kijk naar de class EmailService in src/services/ en schrijf de WeSender-integratie op dezelfde manier. Hoe specifieker je prompt, hoe consistenter de uitvoer. **Kan Cascade ook de WeSender MCP-server gebruiken?** Windsurf ondersteunt MCP-servers. Open Settings > Cascade > MCP en voeg de WeSender MCP-server toe. Cascade kan dan live e-mails sturen en domeinen opvragen terwijl je werkt. **Windsurf heeft mijn .env-bestand gelezen en de sleutel zichtbaar gemaakt.** Windsurf stuurt .env-inhoud niet naar de Cascade-servers. Als je twijfelt, zet de sleutel in .env.local en voeg .env.local toe aan .gitignore. Windsurf respecteert .gitignore bij het indexeren. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/windsurf - Marketingpagina: https://wesender.nl/ai/integraties/windsurf - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Devin + WeSender > Devin is een autonome software-engineer die zelfstandig WeSender-integraties bouwt. **Categorie:** coding-agent | **URL:** https://docs.wesender.nl/docs/integraties/devin ## Vereisten - Devin-account (cognition.ai) - GitHub-repository gekoppeld aan Devin - WeSender-account met geverifieerd domein en API-sleutel ## Integratiestappen ### Stap 1: Koppel je repository aan Devin Log in op app.devin.ai en ga naar Settings > Repositories. Koppel je GitHub-repository via de OAuth-flow. Devin krijgt schrijfrechten om branches aan te maken en pull requests te openen. ### Stap 2: Voeg de WeSender API-sleutel toe als secret Ga naar Settings > Secrets in Devin en voeg WESENDER_API_KEY toe. Devin injecteert de variabele in de werkomgeving zodat de integratie kan worden getest zonder de sleutel in de code te zetten. ### Stap 3: Maak een taak aan voor Devin Klik op New Session en geef de volgende taakomschrijving: Voeg e-mailverzending toe via WeSender aan dit project. Installeer @wesender/node, maak een EmailService-class met methoden sendWelcome en sendPasswordReset, gebruik process.env.WESENDER_API_KEY. Schrijf Vitest-tests, maak een pull request als alles slaagt. Devin start een sessie, leest de codebase, schrijft een plan en voert het stap voor stap uit. ### Stap 4: Volg de sessie live Devin toont in realtime wat het doet: bestanden lezen, code schrijven, tests runnen. Je kunt tussentijds commentaar geven via de chat als Devin bijgestuurd moet worden. Je hoeft niet te wachten totdat het klaar is, je wordt per e-mail of Slack gewaarschuwd. ### Stap 5: Review en merge de pull request Als Devin klaar is, opent het een GitHub pull request met de gegenereerde code, testresultaten en een korte beschrijving. Controleer de code, voeg feedback toe in de PR als nodig en merge als alles correct is. ## Volledig voorbeeld (Devin-taakomschrijving (voorbeeld)) ```markdown ## Taak: WeSender e-mailintegratie Voeg transactionele e-mailverzending toe aan dit project via WeSender. ### Wat je moet doen 1. Installeer @wesender/node als productie-dependency 2. Maak src/services/email.service.ts met: - sendWelcome(to: string, naam: string): Promise - sendPasswordReset(to: string, resetUrl: string): Promise 3. Gebruik process.env.WESENDER_API_KEY (al beschikbaar als secret) 4. from-adres: noreply@jouwdomein.nl 5. Schrijf Vitest unit tests in src/services/email.service.test.ts 6. Voeg WESENDER_API_KEY toe aan .env.example 7. Open een pull request als alle tests slagen ### Niet doen - Geen hardcoded API-sleutels - Geen wijzigingen in bestaande functies tenzij nodig voor de integratie ``` ## Veelgestelde vragen **Devin heeft de verkeerde aanpak gekozen. Hoe stuur ik bij?** Typ feedback in de Devin-sessiechat: gebruik de class-structuur van EmailService in plaats van losse functies, of gebruik de WeSender Node SDK in plaats van fetch. Devin past de aanpak aan en schrijft de code opnieuw. **Hoe lang duurt een Devin-sessie voor een WeSender-integratie?** Een eenvoudige integratie met tests duurt 5 tot 15 minuten. Devin werkt asynchroon, dus je hoeft er niet op te wachten. Je ontvangt een melding als de pull request klaar is. **Kan Devin ook webhooks verwerken?** Ja. Geef in de taakomschrijving mee: voeg ook een POST /webhooks/wesender endpoint toe dat email.delivered en email.bounced events logt. Gebruik WESENDER_WEBHOOK_SECRET om de handtekening te valideren. Devin schrijft ook hiervoor de code en tests. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/devin - Marketingpagina: https://wesender.nl/ai/integraties/devin - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # OpenCode + WeSender > Open-source terminal coding-agent die WeSender integreert vanuit de CLI. **Categorie:** coding-agent | **URL:** https://docs.wesender.nl/docs/integraties/opencode ## Vereisten - OpenCode geinstalleerd (npm install -g opencode-ai of via de GitHub-releases) - WeSender-account met geverifieerd domein en API-sleutel - API-sleutel van je LLM-provider (Anthropic, OpenAI of Google) ## Integratiestappen ### Stap 1: Installeer OpenCode Installeer OpenCode via npm: npm install -g opencode-ai. Of download de binary direct van de GitHub-releasepagina van sst/opencode. Controleer de installatie met: opencode --version. OpenCode draait volledig lokaal en stuurt alleen code naar de LLM-provider die je kiest. ### Stap 2: Configureer je LLM-provider OpenCode ondersteunt Anthropic, OpenAI en Google. Maak een .opencode.json in je projectmap: { "provider": "anthropic", "model": "claude-sonnet-4-5" } Stel de API-sleutel in als omgevingsvariabele: ANTHROPIC_API_KEY=jouw_sleutel. OpenCode leest de sleutel uit de omgeving. ### Stap 3: Start OpenCode in je project Open een terminal in je projectmap en typ: opencode. OpenCode indexeert je codebase en start een interactieve sessie. Je kunt direct opdrachten geven en OpenCode past je bestanden aan. ### Stap 4: Geef de WeSender-opdracht Typ in de OpenCode-sessie: Voeg een TypeScript-functie toe die een e-mail verstuurt via de WeSender REST API. Gebruik process.env.WESENDER_API_KEY als Bearer-token. Sla de functie op in src/lib/email.ts. OpenCode schrijft de functie, voegt hem toe aan de bestaande bestanden en toont de diff. ### Stap 5: Voeg WESENDER_API_KEY toe en test Voeg de sleutel toe aan je .env.local. Vraag OpenCode om een test te schrijven: schrijf een Vitest-test voor de sendEmail-functie in src/lib/email.test.ts. Run de tests met npm test en controleer de uitvoer. ## Volledig voorbeeld (.opencode.json) ```json { "provider": "anthropic", "model": "claude-sonnet-4-5", "context": [ "https://wesender.nl/llms.txt" ] } ``` ## Veelgestelde vragen **OpenCode is open-source. Wordt mijn code naar externe servers gestuurd?** OpenCode stuurt alleen de context (codeblokken en je opdracht) naar de LLM-provider die je instelt, zoals Anthropic of OpenAI. Je kiest zelf welke provider je vertrouwt. De tool zelf draait lokaal en slaat geen data op. **Kan ik de WeSender-documentatie als context meegeven aan OpenCode?** Ja. Voeg in .opencode.json de context-optie toe met wesender.nl/llms.txt. OpenCode laadt de documentatie automatisch bij elke sessie zodat de agent accurate WeSender-code schrijft. **OpenCode ondersteunt mijn project-taal niet. Wat nu?** OpenCode ondersteunt alle populaire talen. Voor Python gebruik je de WeSender Python SDK: pip install wesender, from wesender import Wesender, client = Wesender(os.environ['WESENDER_API_KEY']). Voor andere talen gebruik je de REST API via een gewone HTTP-aanroep. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/opencode - Marketingpagina: https://wesender.nl/ai/integraties/opencode - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Gemini CLI + WeSender > Google Gemini als terminal coding-agent voor WeSender-integraties. **Categorie:** coding-agent | **URL:** https://docs.wesender.nl/docs/integraties/gemini-cli ## Vereisten - Gemini CLI geinstalleerd (npm install -g @google/generative-ai-cli of via de Google AI Studio CLI) - Google-account met toegang tot Gemini API (via Google AI Studio) - WeSender-account met geverifieerd domein en API-sleutel ## Integratiestappen ### Stap 1: Installeer en configureer de Gemini CLI Installeer de Gemini CLI via npm: npm install -g @google/gemini-cli. Of volg de installatie-instructies op de Google AI Studio-pagina. Log in met: gemini auth login. De CLI slaat de sessie op zodat je niet elke keer opnieuw hoeft in te loggen. ### Stap 2: Geef de WeSender-context mee De Gemini CLI ondersteunt het meegeven van context via bestanden of URLs. Voeg de WeSender-documentatie toe aan het begin van je sessie: gemini chat --context wesender.nl/llms.txt Of voeg in de chat handmatig de API-referentie toe: plak de inhoud van wesender.nl/llms.txt als eerste bericht. ### Stap 3: Vraag Gemini om de integratie te schrijven Typ in de Gemini CLI-sessie: Maak een Node.js TypeScript-functie die een e-mail verstuurt via de WeSender REST API (POST https://api.wesender.nl/v1/emails). Gebruik process.env.WESENDER_API_KEY als Bearer-token. Maak ook een .env.example-bestand. Gemini schrijft de functie in de chat. Kopieer de code naar je project of vraag Gemini om de bestanden direct aan te passen. ### Stap 4: Sla de sleutel veilig op Voeg WESENDER_API_KEY toe aan je .env.local. Voeg .env.local toe aan .gitignore als dat nog niet het geval is. Vraag Gemini om dit te controleren: controleer of .env.local in .gitignore staat en voeg hem toe als dat niet zo is. ### Stap 5: Test de integratie Vraag Gemini om een testscript te schrijven: Schrijf een eenvoudig Node.js-script dat de sendEmail-functie aanroept met een testadres en de output logt. Geen testframework nodig, gewoon een ts-node-script. Run met: npx ts-node test-email.ts. Controleer je inbox en het WeSender-dashboard. ## Volledig voorbeeld (src/lib/email.ts) ```typescript export async function sendEmail(opts: { to: string subject: string html: string }): Promise<{ id: string }> { const res = await fetch("https://api.wesender.nl/v1/emails", { method: "POST", headers: { "Authorization": `Bearer ${process.env.WESENDER_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "noreply@jouwdomein.nl", ...opts, }), }) if (!res.ok) { throw new Error(`WeSender-fout: ${res.statusText}`) } return res.json() as Promise<{ id: string }> } ``` ## Veelgestelde vragen **De Gemini CLI past bestanden niet direct aan. Hoe ga ik daarmee om?** De Gemini CLI is primair een chatinterface. Kopieer de gegenereerde code handmatig naar je project, of gebruik Gemini in een IDE-plugin (VS Code heeft een Google Gemini-extensie) die wel directe bestandsaanpassingen ondersteunt. **Gemini schrijft Python-code terwijl ik TypeScript wil. Hoe los ik dat op?** Geef de taal expliciet mee in je prompt: schrijf alleen TypeScript-code. Gebruik de @wesender/node SDK in plaats van fetch. Gemini volgt de instructie en schrijft TypeScript. **Is de Gemini CLI gratis?** Voor persoonlijk gebruik via Google AI Studio is de Gemini CLI gratis met een aanvraaginlimiet. Voor zakelijk gebruik of hogere volumes heb je een betaald Google Cloud-project nodig. De WeSender-integratie werkt in beide gevallen hetzelfde. ## Links - Technische documentatie: https://docs.wesender.nl/docs/integraties/gemini-cli - Marketingpagina: https://wesender.nl/ai/integraties/gemini-cli - API-referentie: https://docs.wesender.nl/docs/api-reference/emails --- # Bouwen met AI: overzicht Wesender heeft native ondersteuning voor AI-toepassingen: een MCP-server, skills voor agent-frameworks en uitgewerkte gidsen voor bouwtools. ## Snelstart voor AI-agents Installeer de MCP-server: ```json { "mcpServers": { "wesender": { "command": "npx", "args": ["-y", "@wesender/mcp"], "env": { "WESENDER_API_KEY": "ws_..." } } } } ``` Of gebruik de REST API direct via een tool-definitie voor je LLM-framework. ## Wat is er beschikbaar? - MCP-server voor Claude, Cursor, Windsurf en andere MCP-clients - Skills voor OpenAI Agents SDK, LangChain, Anthropic, etc. - Docs voor agents via llms.txt en llms-full.txt - Builder-gidsen voor Lovable, Bolt, v0 en Replit --- # Docs voor agents Wesender biedt machine-leesbare documentatie voor AI-agents en taalmodellen. ## Beschikbare bestanden | Bestand | Beschrijving | |-------------------------------------------|-----------------------------------------------| | https://docs.wesender.nl/llms.txt | Gecureerde index van alle documentatie | | https://docs.wesender.nl/llms-full.txt | Volledige documentatie in een enkel bestand | | https://docs.wesender.nl/quickstart.md | Ruwe markdown van een specifieke pagina | ## Elke pagina als markdown Voeg `.md` toe aan een docs-URL om de ruwe markdown te ontvangen: - `https://docs.wesender.nl/quickstart.md` - `https://docs.wesender.nl/api-reference/emails.md` - `https://docs.wesender.nl/sdks/nodejs.md` ## llms.txt Volgt de llmstxt.org-standaard. Bevat een korte index van alle pagina's met beschrijvingen en links naar de .md-varianten. ## llms-full.txt Bevat de volledige inhoud van alle documentatiepagina's achter elkaar, inclusief codevoorbeelden. Gebruik dit bestand als je alle documentatie in een context wil laden. --- # MCP-server Het Model Context Protocol (MCP) is een open protocol dat een LLM tools geeft om namens de gebruiker te handelen. De WeSender MCP-server werkt met Claude Desktop, Cursor, Windsurf, GitHub Copilot en meer. ## Installatie Voeg dit toe aan de MCP-configuratie van je client: ```json { "mcpServers": { "wesender": { "command": "npx", "args": ["-y", "@wesender/mcp"], "env": { "WESENDER_API_KEY": "ws_xxxxxxxx" } } } } ``` ### Claude Code (terminal) ```bash claude mcp add wesender-mcp --env WESENDER_API_KEY=jouw_sleutel -- npx -y @wesender/mcp ``` ### Claude Desktop Open `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) of `%APPDATA%\Claude\claude_desktop_config.json` (Windows) en plak het blok in de `mcpServers`-sectie. ## Beschikbare tools | Tool | Beschrijving | |--------------|--------------------------------------------------------| | send_email | Verstuur een e-mail. Vereist: from, to, subject, html | | list_domains | Geverifieerde domeinen ophalen | | list_emails | Overzicht van verstuurde e-mails (optioneel: limit) | | get_email | Details en bezorgstatus op ID | --- # WeSender-skills Skills zijn kant-en-klare tool-definities voor populaire agent-frameworks. ## Beschikbare bestanden - `https://wesender.nl/skills.json` - Gestructureerde tool-definities (JSON) - `https://wesender.nl/skills.md` - Beschrijvende skill-context voor een LLM (Markdown) ## Inhoud van skills.json Bevat tool-definities voor: - `send_email` - E-mail versturen - `list_domains` - Domeinen ophalen - `list_emails` - Verstuurde e-mails ophalen - `get_email` - E-mail details ophalen ## Gebruik in een agent ```typescript import { Wesender } from "@wesender/node" const tools = [ { type: "function", function: { name: "send_email", description: "Verstuur een e-mail via Wesender", parameters: { type: "object", properties: { to: { type: "string", description: "Ontvanger" }, subject: { type: "string", description: "Onderwerpregel" }, html: { type: "string", description: "HTML-inhoud" }, }, required: ["to", "subject", "html"], }, }, }, ] ``` --- # E-mail best practices voor AI-agents Aanbevelingen voor agents die e-mails versturen via Wesender. ## Authenticatie (SPF, DKIM, DMARC) Configureer alle drie DNS-records voor optimale afleveringsscores: - SPF: geeft aan welke servers namens jouw domein mogen versturen - DKIM: digitale handtekening die de authenticiteit bewijst - DMARC: beleid dat bepaalt wat er met verdachte mail gebeurt Wesender helpt de bezorgbaarheid door alle records automatisch te verifiëren. ## Datalocatie Alle e-maildata wordt verwerkt en opgeslagen in Europese datacenters. E-mailinhoud verlaat de EU nooit. ## Rate limits - Free: 3.000 e-mails per maand - Starter: 25.000 per maand - Pro: 100.000 per maand - Business: 500.000 per maand Agents die boven het limiet gaan ontvangen een 429-respons. Implementeer exponential backoff bij retries. ## Idempotentie Agents die opnieuw uitvoeren na een fout kunnen dezelfde e-mail meerdere keren versturen. Gebruik een idempotentiesleutel: ```typescript const sleutel = createHash("sha256") .update(runId + ontvanger) .digest("hex") if (!verzonden.has(sleutel)) { await ws.emails.send({ ... }) verzonden.add(sleutel) } ``` ## Gebruik van tags Voeg `tags` toe om e-mails te labelen voor filtering in de statistieken: ```typescript await ws.emails.send({ ..., tags: { flow: "agent-checkout", run_id: runId }, }) ``` --- # Lovable Koppel Wesender aan een Lovable-app via een Supabase Edge Function. ## Aanpak Lovable genereert een volledige applicatie op basis van een prompt. Supabase Edge Functions zijn serverless TypeScript-functies die je veilig API-keys kunt opslaan. ## Supabase Edge Function ```typescript // supabase/functions/send-email/index.ts import { serve } from "https://deno.land/std@0.177.0/http/server.ts" serve(async (req: Request) => { const { to, subject, html } = await req.json() const res = await fetch("https://api.wesender.nl/emails", { method: "POST", headers: { "Authorization": `Bearer ${Deno.env.get("WESENDER_API_KEY")}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "noreply@joudomein.nl", to: [to], subject, html, }), }) const data = await res.json() return new Response(JSON.stringify(data), { status: res.status }) }) ``` ## Vanuit Lovable aanroepen ```typescript const { data, error } = await supabase.functions.invoke("send-email", { body: { to: "klant@voorbeeld.nl", subject: "Welkom!", html: "

Hoi!

" }, }) ``` ## API-key opslaan Sla `WESENDER_API_KEY` op als Supabase-secret via het dashboard of de CLI, nooit in de clientcode. --- # Bolt.new Integreer Wesender in een Bolt.new-applicatie via een server-side API-route. ## Aanpak Bolt genereert full-stack webapplicaties. Maak een server-side API-route zodat de API-key nooit in de browser terechtkomt. ## API-route (Remix) ```typescript // app/routes/api.send-email.ts import type { ActionFunctionArgs } from "@remix-run/node" import { json } from "@remix-run/node" export async function action({ request }: ActionFunctionArgs) { const { to, subject, html } = await request.json() const res = await fetch("https://api.wesender.nl/emails", { method: "POST", headers: { "Authorization": `Bearer ${process.env.WESENDER_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "noreply@joudomein.nl", to: [to], subject, html }), }) return json(await res.json(), { status: res.status }) } ``` ## Aanroepen vanuit de client ```typescript await fetch("/api/send-email", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ to: "klant@voorbeeld.nl", subject: "Welkom!", html: "

Hoi!

" }), }) ``` --- # v0 Koppel Wesender aan een v0-gegenereerde Next.js-applicatie via een Server Action. ## Aanpak v0 genereert React-componenten. Voeg een Next.js Server Action toe om e-mails te versturen zonder de API-key in de browser. ## Server Action ```typescript // app/actions/send-email.ts "use server" export async function sendEmail(to: string, subject: string, html: string) { const res = await fetch("https://api.wesender.nl/emails", { method: "POST", headers: { "Authorization": `Bearer ${process.env.WESENDER_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "noreply@joudomein.nl", to: [to], subject, html }), }) if (!res.ok) throw new Error(`Wesender fout: ${res.status}`) return res.json() } ``` ## Gebruik in een component ```tsx "use client" import { sendEmail } from "@/app/actions/send-email" export function ContactForm() { async function handleSubmit(formData: FormData) { await sendEmail( formData.get("email") as string, "Bedankt voor je bericht", "

We nemen spoedig contact op.

" ) } return
{/* velden */}
} ``` ## Omgevingsvariabele Voeg `WESENDER_API_KEY=ws_live_...` toe aan `.env.local`. Vercel leest dit automatisch bij de deployment.