Mailchimp 是什么
Mailchimp 是一个广泛使用的营销自动化平台,主要用于电子邮件营销。它帮助企业和个人管理他们的电子邮件列表,创建邮件活动,以及自动化邮件发送流程。Mailchimp 提供了多种工具来跟踪电子邮件活动的效果,如打开率、点击率等。
源码:https://github.com/Jessie-jzn/Jessie-Blog.dev
网站:https://www.jessieontheroad.com/
Mailchimp 的功能
- 电子邮件营销: 创建和发送邮件活动,设计专业的邮件模板。
- 受众管理: 管理和细分电子邮件列表(受众),从而实现精准营销。
- 自动化: 设置自动邮件活动,比如欢迎邮件、生日邮件等。
- 分析与报告: 提供邮件活动的详细报告,帮助用户了解邮件的表现并优化策略。
- 整合与扩展: 可以与许多其他平台(如 Shopify、WordPress、Salesforce 等)整合。
免费计划
Mailchimp 提供一个免费的计划,适合刚开始进行电子邮件营销的个人和小型企业。免费计划包含以下内容:
- 受众人数: 最多 500 个联系人。
- 月度邮件: 每月最多发送 1,000 封电子邮件。
- 基础模板: 访问邮件设计工具和一些基础模板。
- 报告与分析: 获取基础的报告与分析功能。
- 单步自动化: 设置一些简单的自动化邮件。
Mailchimp API
Mailchimp 提供了一个 API,可以让开发者在他们的应用程序或网站中集成 Mailchimp 的功能。通过 Mailchimp API,可以:
- 管理受众列表: 添加、更新或删除联系人。
- 创建和管理活动: 创建新的邮件活动并发送邮件。
- 跟踪邮件活动: 获取邮件活动的统计数据,如打开率和点击率。
免费的 Mailchimp API 功能
即使使用免费的 Mailchimp 计划,仍然可以访问 Mailchimp 的 API,不过 API 调用会受到一定的限制。以下是一些免费的 API 功能:
- 管理受众列表: 可以使用 API 添加、更新或删除联系人。
- 创建和管理邮件活动: 可以通过 API 创建和发送邮件活动。
- 获取邮件活动的报告: 使用 API 获取活动的统计数据。
相关限制
尽管 Mailchimp 的 API 是免费的,但它的使用也会受到一些限制,特别是在免费计划中。常见的限制包括:
- 调用频率限制: 每个 API 密钥都有一定的调用限制。通常为每小时 10 次或 10 次/分钟。
- 功能限制: 免费计划中一些高级功能可能无法通过 API 访问,或有特定限制。
如何使用 Mailchimp
1.创建 Mailchimp 账户和受众列表
- 创建账户: Mailchimp
- 创建受众列表: 进入 Mailchimp 后台,导航到 “Audience” 部分,创建或选择一个现有的受众列表。
2. 获取 Mailchimp API Key 和 Audience ID
- API Key: 进入 Mailchimp 后台,点击右上角的头像 -> “Account” -> “Extras” -> “API keys”,创建一个新的 API Key 并复制它。
- Audience ID: 在 Mailchimp 中找到您想要添加订阅者的受众列表,点击 “Manage Audience” -> “Settings” -> “Audience name and defaults”。在该页面的底部,您可以找到 “Audience ID”。
3.简单的示例
通过 Mailchimp API 添加新订阅者:
curl -X POST 'https://<dc>.api.mailchimp.com/3.0/lists/<list_id>/members/' \\
--user "anystring:<API_KEY>" \\
-H 'Content-Type: application/json' \\
-d '{
"email_address": "newemail@example.com",
"status": "subscribed"
}'
<dc>
是的数据中心标识符,通常为的 API Key 的后缀部分(如 us10)。<list_id>
是受众列表的 ID。
通过 Mailchimp API,可以将这些功能集成到自己的应用程序中,增强电子邮件营销的自动化和效率。
在Next项目中集成Mailchimp
步骤1:封装订阅邮件函数
lib/mailchimp.ts
// lib/mailchimp.ts
interface SubscribeToMailchimpApiParams {
email: string;
first_name?: string;
last_name?: string;
}
interface SubscribeToNewsletterResponse {
success: boolean;
message: string;
}
/**
* 订阅邮件 - 服务端接口
* @param {SubscribeToMailchimpApiParams} params
* @returns {Promise<Response | undefined>}
*/
export async function subscribeToMailchimpApi({
email,
first_name = "",
last_name = "",
}: SubscribeToMailchimpApiParams): Promise<Response | undefined> {
const API_KEY = process.env.MAILCHIMP_API_KEY;
const AUDIENCE_ID = process.env.MAILCHIMP_AUDIENCE_ID;
const SERVER_PREFIX = process.env.MAILCHIMP_SERVER_PREFIX;
const url = `https://${SERVER_PREFIX}.api.mailchimp.com/3.0/lists/${AUDIENCE_ID}/members`;
if (!email || !AUDIENCE_ID || !API_KEY) {
console.error("Missing required fields: email, listId, or apiKey.");
return undefined;
}
const data = {
email_address: email,
status: "subscribed",
merge_fields: {
FNAME: first_name,
LNAME: last_name,
},
};
try {
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `apikey ${API_KEY}`,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error(`Mailchimp API error: ${response.statusText}`);
}
return response;
} catch (error) {
console.error("Error subscribing to Mailchimp:", error);
return undefined;
}
}
/**
* 客户端接口
* @param {string} email
* @param {string} [firstName]
* @param {string} [lastName]
* @returns {Promise<SubscribeToNewsletterResponse>}
*/
export async function subscribeToNewsletter(
email: string,
firstName: string = "",
lastName: string = ""
): Promise<SubscribeToNewsletterResponse> {
try {
const response = await fetch("/api/subscribe", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
first_name: firstName,
last_name: lastName,
}),
});
if (!response.ok) {
throw new Error(`Subscription failed: ${response.statusText}`);
}
const data = await response.json();
return { success: data.status, message: data.message };
} catch (error) {
console.error("Error subscribing to newsletter:", error);
return {
success: false,
message: "Subscription failed. Please try again.",
};
}
}
步骤2:创建一个 API 路由
在 pages/api/subscribe.js
创建一个 API 路由,用于处理订阅请求。
import type { NextApiRequest, NextApiResponse } from "next";
import { subscribeToMailchimpApi } from "@/lib/mailchimp";
interface ApiResponse {
status: "success" | "error";
message: string;
error?: string;
}
/**
* 接受邮件订阅
* @param {NextApiRequest} req
* @param {NextApiResponse<ApiResponse>} res
*/
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<ApiResponse>
) {
if (req.method === "POST") {
const { email, firstName = "", lastName = "" } = req.body;
if (!email) {
return res
.status(400)
.json({ status: "error", message: "Email is required." });
}
try {
console.log("Request received:", { email, firstName, lastName });
const response = await subscribeToMailchimpApi({
email,
first_name: firstName,
last_name: lastName,
});
if (!response) {
console.error("No response from Mailchimp API");
throw new Error("Mailchimp API returned undefined response.");
}
// 解析 response body 并获取详细的错误信息
const responseData = await response.json();
if (!response.ok) {
console.error("Mailchimp API error response:", responseData); // 打印详细的错误信息
res.status(400).json({
status: "error",
message: "Subscription failed!",
error: responseData.detail || "Unknown error",
});
return;
}
res
.status(200)
.json({ status: "success", message: "Subscription successful!" });
} catch (error) {
console.error("Error in handler:", error);
res.status(500).json({
status: "error",
message: "Subscription failed!",
error: (error as Error).message,
});
}
} else {
res.status(405).json({ status: "error", message: "Method not allowed" });
}
}
步骤3: 创建订阅表单
创建一个 React 组件,用于输入用户的 email 并提交表单。
"use client";
import React, { useEffect, useRef, useState } from "react";
import Link from "next/link";
import SiteConfig from "../site.config";
import { subscribeToNewsletter } from "@/lib/mailchimp";
import SocialContactIcon from "./SocialContactIcon";
import { useTranslation } from "next-i18next";
const Footer: React.FC = () => {
const { t } = useTranslation("common");
const formRef = useRef<HTMLFormElement>(null);
const emailRef = useRef<HTMLInputElement>(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const [message, setMessage] = useState<string | null>(null);
const handleSubscribe = async (event: any) => {
event.preventDefault(); // 阻止页面刷新
if (emailRef.current) {
const email = emailRef.current.value;
if (email) {
try {
const response = await subscribeToNewsletter(email);
console.log("Subscription succeeded:", response);
// 在此处添加成功订阅后的操作
if (response.success) {
setMessage(t("subscriptionSuccess")); // 设置成功消息
emailRef.current.value = ""; // 清空输入框
} else {
setMessage(response.message);
}
} catch (error) {
console.error("Subscription failed:", error);
// 在此处添加订阅失败后的操作
setMessage(t("subscriptionFailed")); // 设置失败消息
} finally {
setIsSubmitting(false); // 重新启用按钮
}
} else {
setMessage(t("emailRequired")); // 设置提示消息
}
}
};
useEffect(() => {
const form = formRef.current;
form?.addEventListener("submit", handleSubscribe);
return () => {
form?.removeEventListener("submit", handleSubscribe);
};
}, []);
return (
<div className=" box-border flex flex-col pt-8 items-center w-full border-t border-[#E8E8EA] dark:border-zinc-900 dark:bg-zinc-800">
<div className="flex flex-wrap justify-between w-full pb-8">
<div className="flex flex-col">
<form className="rounded-2xl" ref={formRef}>
<div className="mt-6 flex">
<input
type="email"
ref={emailRef}
placeholder="Email address"
disabled={isSubmitting} // 输入框禁用
className="min-w-0 flex-auto appearance-none rounded-md border border-zinc-900/10 bg-white px-3 py-[calc(theme(spacing.2)-1px)] shadow-md shadow-zinc-800/5 placeholder:text-zinc-400 focus:border-teal-500 focus:outline-none focus:ring-4 focus:ring-teal-500/10 sm:text-sm dark:border-zinc-700 dark:bg-zinc-700/[0.15] dark:text-zinc-200 dark:placeholder:text-zinc-500 dark:focus:border-teal-400 dark:focus:ring-teal-400/10"
/>
<button
className="inline-flex items-center gap-2 justify-center rounded-md py-2 px-3 text-sm outline-offset-2 transition active:transition-none bg-zinc-800 font-semibold text-zinc-100 hover:bg-zinc-700 active:bg-zinc-800 active:text-zinc-100/70 dark:bg-zinc-700 dark:hover:bg-zinc-600 dark:active:bg-zinc-700 dark:active:text-zinc-100/70 ml-4 flex-none"
type="submit"
>
{isSubmitting ? (
<span className="loader"></span> // 显示加载指示器
) : (
t("subscribe")
)}
</button>
</div>
</form>
{message && (
<p className="mt-4 text-sm text-zinc-600 dark:text-zinc-400">
{message}
</p>
)}
</div>
</div>
</div>
);
};
export default Footer;
步骤4:部署项目
最后,将项目部署到 Vercel 或其他平台,确保环境变量中设置了 MAILCHIMP_API_KEY
和 MAILCHIMP_AUDIENCE_ID
, Next.js 网站就会具备一个基于 Mailchimp 的订阅功能
结论
Mailchimp 是一个强大的工具,可以帮助管理电子邮件营销,并且它提供了免费的计划和 API,适合刚起步的小企业和个人用户。虽然有一些限制,但对于初学者来说,Mailchimp 的免费计划提供了足够的功能来建立并管理邮件订阅列表。