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

2018-11-07

前言

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

auphone.net subscription form

用 MailChimp 做免費仔

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

事前準備

  • 一個 MailChimp 帳戶
  • 一張 Contact List
  • 一條 MailChimp API Key
  • 一點 Node.js 的知識
  • 一部伺服器(我的是 Raspberry Pi 3)

取得 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": "[email protected]"
}

伺服器端請求

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

{
  "body": {
    "email_address": "[email protected]",
    "status": "subscribed"
  }
}

DEMO

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