🎯

resend-integration

🎯Skill

from b-open-io/prompts

VibeIndex|
What it does

resend-integration skill from b-open-io/prompts

πŸ“¦

Part of

b-open-io/prompts(27 items)

resend-integration

Installation

Install PluginInstall plugin from marketplace
/plugin install bopen-tools@b-open-io
Add MarketplaceAdd marketplace to Claude Code
/plugin marketplace add b-open-io/claude-plugins
Install PluginInstall plugin from marketplace
/plugin install claude-peacock@b-open-io
πŸ“– Extracted from docs: b-open-io/prompts
9Installs
6
-
Last UpdatedJan 24, 2026

Skill Details

SKILL.md

Set up Resend email integration with newsletters, contact forms, and booking systems. Use when implementing email functionality with Resend Audiences, segments, topics, webhooks, and multi-domain accounts.

Overview

# Resend Integration

Complete guide for integrating Resend email services into Next.js applications with proper Audiences setup.

When to Use

  • Setting up newsletter signups
  • Adding contact form email notifications
  • Implementing booking/calendar email confirmations
  • Configuring email forwarding via webhooks
  • Managing multi-domain Resend accounts

Resend Audiences Architecture

Resend has ONE audience per account. Use these features to organize:

| Feature | Purpose | Visibility |

|---------|---------|------------|

| Contacts | Individual subscribers | - |

| Properties | Custom data fields (domain, source, company) | Internal |

| Segments | Internal groupings for targeting | Internal |

| Topics | User-facing email preferences | User can manage |

| Broadcasts | Campaign sending with auto-unsubscribe | - |

Multi-Domain Strategy

For accounts with multiple domains, tag contacts with properties:

```typescript

await resend.contacts.create({

email,

properties: {

domain: "example.com", // Which project

source: "newsletter", // How they signed up

},

segments: [{ id: SEGMENT_ID }],

topics: [{ id: TOPIC_ID, subscription: "opt_in" }],

});

```

Implementation

1. Shared Utility (`lib/resend.ts`)

```typescript

import { Resend } from "resend";

export const resend = new Resend(process.env.RESEND_API_KEY);

const SEGMENT_NEWSLETTER = process.env.RESEND_SEGMENT_NEWSLETTER;

const SEGMENT_LEADS = process.env.RESEND_SEGMENT_LEADS;

const TOPIC_NEWSLETTER = process.env.RESEND_TOPIC_NEWSLETTER;

type ContactSource = "newsletter" | "booking" | "contact";

interface CreateContactOptions {

email: string;

firstName?: string;

lastName?: string;

company?: string;

source: ContactSource;

subscribeToNewsletter?: boolean;

}

export async function createContact({

email,

firstName,

lastName,

company,

source,

subscribeToNewsletter = false,

}: CreateContactOptions) {

const segments: { id: string }[] = [];

if (source === "newsletter" && SEGMENT_NEWSLETTER) {

segments.push({ id: SEGMENT_NEWSLETTER });

} else if ((source === "booking" || source === "contact") && SEGMENT_LEADS) {

segments.push({ id: SEGMENT_LEADS });

}

const topics: { id: string; subscription: "opt_in" | "opt_out" }[] = [];

if (subscribeToNewsletter && TOPIC_NEWSLETTER) {

topics.push({ id: TOPIC_NEWSLETTER, subscription: "opt_in" });

}

const properties: Record = {

domain: "YOUR_DOMAIN.com", // Replace with actual domain

source,

};

if (company) properties.company = company;

const { data, error } = await resend.contacts.create({

email,

firstName: firstName || undefined,

lastName: lastName || undefined,

unsubscribed: false,

...(Object.keys(properties).length > 0 && { properties }),

...(segments.length > 0 && { segments }),

...(topics.length > 0 && { topics }),

});

if (error?.message?.includes("already exists")) {

return { exists: true, error: null };

}

return { data, exists: false, error };

}

export async function contactExists(email: string): Promise {

try {

const { data } = await resend.contacts.get({ email });

return !!data;

} catch {

return false;

}

}

```

2. Newsletter Route (`/api/newsletter`)

```typescript

import { NextResponse } from "next/server";

import { resend, createContact, contactExists } from "@/lib/resend";

export async function POST(request: Request) {

const { email } = await request.json();

if (!email) {

return NextResponse.json({ error: "Email is required" }, { status: 400 });

}

// Duplicate check

if (await contactExists(email)) {

return NextResponse.json(

{ error: "already_subscribed", message: "You're already subscribed!" },

{ status: 409 },

);

}

const { error } = await createContact({

email,

source: "newsletter",

subscribeToNewsletter: true,

});

if (error) {

// Return actual error, not generic 500

const message = typeof error === "object" && "message" in error

? (error as { message: string }).message

: "Failed to subscribe";

const statusCode = typeof error === "object" && "statusCode" in error

? (error as { statusCode: number }).statusCode

: 500;

return NextResponse.json({ error: message }, { status: statusCode });

}

// Send welcome email

await resend.emails.send({

from: "Company ",

to: [email],

subject: "Welcome to our Newsletter",

html:

Thanks for subscribing!

...,

});

return NextResponse.json({ success: true });

}

```

3. Frontend Duplicate Handling

```typescript

const response = await fetch("/api/newsletter", {

method: "POST",

headers: { "Content-Type": "application/json" },

body: JSON.stringify({ email }),

});

const data = await response.json();

if (response.status === 409) {

toast.info("You're already subscribed!");

return;

}

if (!response.ok) {

throw new Error(data.error);

}

toast.success("Thanks for subscribing!");

```

4. Booking/Contact Form (Create Lead)

Add contact creation without blocking the main flow:

```typescript

// In booking or contact form API route

createContact({

email,

firstName,

lastName,

company,

source: "booking", // or "contact"

}).catch((err) => console.error("Failed to create contact:", err));

```

5. Inbound Email Forwarding

For receiving emails via subdomain (e.g., mail.example.com):

Webhook handler (/api/webhooks/resend):

```typescript

case "email.received":

const forwardTo = process.env.EMAIL_FORWARD_TO?.split(",").map(e => e.trim());

if (!forwardTo?.length) return;

await resend.emails.send({

from: "Forwarded ",

to: forwardTo,

replyTo: event.data.from,

subject: [Fwd] ${event.data.subject},

html: `

From: ${event.data.from}

To: ${event.data.to?.join(", ")}


${event.data.html || event.data.text}

`,

attachments: event.data.attachments,

});

break;

```

Environment Variables

```bash

# Required

RESEND_API_KEY=re_xxxxx

# Optional - for Audiences integration

RESEND_SEGMENT_NEWSLETTER=seg_xxxxx

RESEND_SEGMENT_LEADS=seg_xxxxx

RESEND_TOPIC_NEWSLETTER=top_xxxxx

# Optional - for email forwarding

EMAIL_FORWARD_TO=email1@example.com,email2@example.com

```

Resend Dashboard Setup

IMPORTANT: Create these in the dashboard BEFORE deploying code that uses them.

Create Properties

Properties must exist before the API can use them.

  1. Go to Audiences β†’ Properties tab
  2. Create these properties:

- domain (text) - For multi-domain account filtering

- source (text) - How contact signed up (newsletter, booking, contact)

- company (text) - Optional company name

Create Segments

  1. Go to Audiences β†’ Segments
  2. Create "project-newsletter" segment
  3. Create "project-leads" segment
  4. Copy IDs to env vars

Create Topics

  1. Go to Audiences β†’ Topics
  2. Create topic (e.g., "Project Newsletter")
  3. Defaults to: Opt-in (subscribers must explicitly opt in)
  4. Visibility: Public (visible on preference page) or Private
  5. Copy ID to env var

Email Receiving (Subdomain)

To receive emails without conflicting with existing email (e.g., Google Workspace):

  1. DNS: Add MX record for subdomain

- Name: mail

- Content: inbound-smtp.us-east-1.amazonaws.com

- Priority: 10

  1. Resend: Enable receiving for mail.yourdomain.com
  1. Webhook: Point to your /api/webhooks/resend endpoint

Broadcasts

Use Resend dashboard for sending newsletters:

  1. Go to Broadcasts β†’ Create
  2. Select segment to target
  3. Use personalization: {{{FIRST_NAME|there}}}
  4. Include unsubscribe: {{{RESEND_UNSUBSCRIBE_URL}}}
  5. Send or schedule

Common Patterns

Sender Addresses

Use consistent from addresses:

  • noreply@domain.com - Automated notifications
  • contact@domain.com - Contact form
  • booking@domain.com - Calendar invites
  • forwarded@domain.com - Forwarded inbound emails

Team Notifications

Send internal notifications to a subdomain address that forwards:

```typescript

to: ["info@mail.domain.com"] // Forwards via webhook

```