✉️

Shopify Admin API と Next.js の API Route を用いてメールマガジン登録APIを作る

2022/03/04に公開

ECサイトの運営にメールマガジンへの動線は必要不可欠です。(今だとはLINEでもいいとは思いますが)
Shopify にはデフォルトでメールマガジン機能がついており、メールマガジンの登録機能もついているため普通に使うぶんには困ることはありません。

しかし、昨今の流行りのヘッドレスなテーマを作成する場合には一つ工夫が必要になります。

Shopify の Storefront API の Customer 作成 API だと、Customer を作成するのにメールの他にパスワードが必要となり、この API を用いると会員登録用のユーザーは作成できてもメールマガジンのみのユーザーを作成することはできません。

Storefront のドキュメント
https://shopify.dev/api/storefront/2022-01/mutations/customerCreate

ここでどうしたもんかと API をにらめっこしていたら Shopify Admin API の場合だとパスワードが必須ではないことに気付き、必要なもののみ投げてみたところメールマガジン登録のみのユーザーを作成することができたので共有します。

Admin API のドキュメント
https://shopify.dev/api/admin-graphql/2022-01/mutations/customerCreate

コード

サンプルコードのため依存をなくすためにベタで書いていますが、 graphql-request で書いたり、 graphql-codegen を用いてコードを自動生成したりするとスマートになります。

下のコードを配置する前に、Admin API の顧客管理を、読み取りおよび書き込みにする必要があります。

import { NextApiRequest, NextApiResponse } from 'next'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const body = JSON.parse(req.body) as {
    email: string
  }

  const headers = {
    Authorization:
      'Basic ' +
      Buffer.from(
        process.env.SHOPIFY_ADMIN_API_KEY +
          ':' +
          process.env.SHOPIFY_ADMIN_API_PASS
      ).toString('base64'),
    'X-Shopify-Storefront-Access-Token':
      process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN,
    'Content-Type': 'application/json',
    Accept: 'application/json',
    'Access-Control-Allow-Origin': '*',
  } as any

  const query = `
    mutation customerCreate($input: CustomerInput!) {
      customerCreate(input: $input) {
        userErrors { 
          field 
          message 
        }
        customer {
          id
          email
          acceptsMarketing
        }
      }
    }
  `

  const r = await fetch(
    process.env.NEXT_PUBLIC_SHOPIFY_ADMIN_GRAPHQL_API_URL as string,
    {
      method: 'POST',
      headers,
      body: JSON.stringify({
        query,
        variables: {
          input: {
            email: body.email,
            acceptsMarketing: true,
          },
        },
      }),
    }
  )

  const json = await r.json()

  res.statusCode = 200
  res.setHeader('Content-Type', 'application/json')
  res.end(JSON.stringify(json))
}

環境変数は書き換えてください。

エラーがあった場合、 userErrors にメールがすでに登録されているなどのエラーが返ってきますのでよしなにフロントで対応してください。

今回は Next.js の API Routes を使いましたが、Admin APIも絡んでいるのでもっとセキュアにしたい場合は Lambda などを用いて Next.js から外したりしたほうがいいかと思います。

Discussion