auphone.net "揼曲"筆記
Written by Human, Not by AI

// Mailchimp API 自架伺服器實現 AJAX 請求 //

前言 #

本來我使用 MailChimp 這類 email marketing 服務是想避免自架伺服器好讓我能省一點錢,可惜它跟大部份公司的做法都是要 redirect 到其他頁面再填寫表格的(以安全性和防 spamming 的角度我是能理解啦),想要一個簡簡單單輸入個 email 就能訂閱的表格其實不太簡單!

auphone.net subscription form

用 MailChimp 做免費仔 #

MailChimp Logo MailChimp 本來就有免費的計劃,而且它的免費用量足夠給一些剛起步的網站,界面用起來也不錯,這裡說一下另一家叫 MailJet 的基本上付合我的要求而且不用設伺服器,但因為界面太糟糕而且各種奇怪設定問題所以決定不採用…

事前準備 #

取得 API Key #

怎樣註冊 MailChimp 我就不說了,Contact List 可以在 Lists 頁面 建立,API Key 可以在 Account 頁面 建立,詳情請看 官方教學

取得 data center 位置和 API root #

取得 API Key 之後我們首先要知道自己帳號的 data center 位置,登入 MailChimp 後看看 URL 的位置最前那段就是 data center

以下例子的 <dc>us18 #

https://us18.admin.mailchimp.com/

所以 API root 就是 #

https://us18.api.mailchimp.com/3.0

取得 List ID #

如果你還沒有 Contact List 請到 這裡 建立一張,然後我們可以用 API 取得 Contact List 的 ID,最簡單的方法是用 curl

$ curl https://<dc>.api.mailchimp.com/3.0/lists --user 'anystring:<api-key>'

<dc><api-key> 修改成你的設定,你會收到一串像這樣的 JSON,當中的 id 就是 List ID,先把它記著我們之後要用到

{
  "lists": [
    {
      "id": "12345abcde",
      "web_id": 12345,
      "name": "auphone.net",
      ...
    }
  ]
}

安裝 Node.js #

如果還沒有 Node.js,建議使用 nvm 安裝

Linux / MacOS 用戶 #

https://github.com/creationix/nvm

Windows 用戶 #

https://github.com/coreybutler/nvm-windows

Nodejs 伺服器原碼 #

先附上原碼,需要整個 project 可以到我的 Github 下載

https://github.com/auphone/simple-mailchimp-api-server

NPM 模組 #

$ npm init
$ npm install express cors body-parser request request-promise
$ touch index.js

index.js 與設定 #

你需要把 index.js 內的 config 改成之前取得的 dc 位置和 api key

const rp = require("request-promise");
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");

// Change to your MailChimp config
const config = {
  dc: "<dc>",
  apiKey: "<your-api-key>",
  listId: "<your-list-id>",
};

// Express
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// API
app.post("/subscribe", (req, res) => {
  const { email } = req.body;
  if (!email) {
    return res.status(422).send("Missing Parameter: email");
  }
  rp({
    method: "POST",
    uri: `https://${config.dc}.api.mailchimp.com/3.0/lists/${config.listId}/members`,
    headers: {
      Authorization: `Basic ${new Buffer(`anystring:${config.apiKey}`).toString(
        "base64"
      )}`,
    },
    body: {
      email_address: email,
      status: "subscribed",
    },
    json: true,
  })
    .then((result) => {
      res.send("OK");
    })
    .catch((err) => {
      res.status(400).send(err);
    });
});

app.listen(config.port || 3000, () => {
  console.log("server started");
});

運行伺服器 #

$ node .

使用方法 #

最簡單是使用 html + 純 js 做 HTTP 請求

index.html #

<!DOCTYPE html>
<html>
  <head>
    <title></title>
  </head>
  <body>
    <form onsubmit="subscribe()">
      <input id="sub-email" type="email" required />
      <button type="submit">Subscribe</button>
    </form>
    <script src="./script.js"></script>
  </body>
</html>

script.js #

function subcribe() {
  const email = document.getElementById("sub-email").value;
  const data = {
    method: "POST",
    headers: {
      "Content-Type": "application/json; charset=utf-8",
    },
    body: JSON.stringify({ email }),
  };
  fetch("http://localhost:3000/subscribe", data).then(() => {
    // Do Something here
  });
  return false;
}

資料補充 #

客戶端的請求 #

整個伺服器就只有一個 POST call,也沒有任何 Auth method,要怎樣使用請自行斟酌

http://localhost:3000/subscribe

這裡我只接收 email 一個 parameter,實際上 MailChimp 有更多的選項

{
  "email": "xxx@example.com"
}

伺服器端請求 #

因為 CORS 的關係不能使用客戶端直接 API 請求,就算可以你也不想公開你的 API Key 吧?回正題,這個伺服器請求會只接把 Email 傳到 MailChimp,而且會自動變為已訂閱的狀態,如有需要請自行更改

{
  "body": {
    "email_address": "xxx@example.com",
    "status": "subscribed"
  }
}

DEMO #

為何不訂閱我的網誌看看?(ゝ ∀・)b