🌱

strapiでお問い合わせをつくってみる

2021/05/13に公開約10,500字

strapiでお問い合わせのバックエンドをつくります。
ベースには下記strapiのプロジェクトを使用していますが特にこれである必要はありません。

https://zenn.dev/mseto/articles/strapi-starter-blog

お問い合わせ用コンテンツタイプ追加

お問い合わせ内容を登録するコンテンツタイプを追加します。
strapi管理画面のメニューから"Content-Types Builder"をクリックします。
"Content-Types Builder"をクリック

"コンテンツタイプ"の"Create new collection type"をクリックします。
"コンテンツタイプ"の"Create new collection type"をクリック

"Display name"にcontactと入力し、"高度な設定"をクリックします。
"Display name"に*contact*と入力し、"高度な設定"をクリック

"Draft/publish system"で"OFF"を選択し、"続ける"をクリックします。
"Draft/publish system"で"OFF"を選択し、"続ける"をクリック

"Text"をクリックします。
"Text"をクリック

"Name"にnameと入力し、"Type"には"Short text"を選択し、"高度な設定"をクリックします。
"Name"に*name*と入力し、"Type"には"Short text"を選択し、"高度な設定"をクリック

"必須フィールド"にチェックを入れ、"Add another field"をクリック。
"必須フィールド"にチェックを入れ、"Add another field"をクリック

同様に下記設定でフィールドを追加します。

Field Type Name Type 必須フィールド 内容
Text name Short Text お問い合わせユーザ名
Email email お問い合わせユーザのメールアドレス
Text title Short Text お問い合わせ件名
Text message Long Text お問い合わせ内容
UID contactId お問い合わせ番号

Contact

フィールドを追加したら、"保存"をクリックします。

お問い合わせメールテンプレート用コンテンツタイプ追加

strapiの管理画面からメール内容の編集ができるようにコンテンツタイプ追加します。

strapiの管理画面の"設定"に"Email Templates"があるのですが、"Reset password"と"Email address confirmation"のみ利用可能になっており、追加する方法がわからなかったので、今回はコンテンツタイプに追加していきます。

お問い合わせ用コンテンツタイプ追加と同様に"Content-Types Builder"から"Create new collection type"を選択し、"Display name"にmailTemplateと入力して、"高度な設定"で"Draft/publish system"を"OFF"に設定します。

各フィールドは下記のように設定し保存します。

Field Type Name Type 必須フィールド 内容
Text name Short Text テンプレート管理用の名前
Text subject Short Text メールタイトル
Text text Long Text テキストメール本文
Text html Long Text HTMLメール本文
Text to Short Text 送信先メールアドレス
Text from Short Text 送信元メールアドレス
Text replyTo Short Text 返信先メールアドレス

mailTemplate

お問い合わせメールテンプレート登録

mailTemplateに管理者用とユーザ用のテンプレートを登録します。

strapiのメニューの"コレクションタイプ"から"MailTemplates"をクリックします。
"MailTemplates"をクリック

"MailTemplatesを追加"をクリックし、"Create an entry"ページにいきます。

管理者用メールテンプレート登録

まず管理者用のテンプレートを登録します。登録内容は下記になります。

フィールド 設定値
Name お問い合わせ(管理者用)
Subject お問い合わせがあります。
To 管理者<admin@example.com>
From
ReplyTo
Text
下記内容でお問い合わせがあります。

お問い合わせ番号: <%= contact.contactId %>
お名前: <%= contact.name %>
お問い合わせ件名: <%= contact.title %>
お問い合わせ内容:
<%= contact.message %>
Html
<h1>下記内容でお問い合わせがあります。</h1>
<table border="0">
  <tr>
    <th align="left">
      お問い合わせ番号:
    </th>
    <td>
      <%= contact.contactId %>
    </td>
  </tr>
  <tr>
    <th align="left">
      お名前:
    </th>
    <td>
      <%= contact.name %>
    </td>
  </tr>
  <tr>
    <th align="left">
      お問い合わせ件名:
    </th>
    <td>
      <%= contact.title %>
    </td>
  </tr>
  <tr>
    <th align="left">
      お問い合わせ内容:
    </th>
    <td>
      <%= contact.message %>
    </td>
  </tr>
</table>

お問い合わせ(管理者用)

テンプレート変数

<%= contact.contactId %>や<%= contact.name %>はメール送信時に変換されるテンプレート変数です。
ここでは下記を設定しました。

テンプレート変数 内容
<%= contact.contactId %> お問い合わせ番号
<%= contact.name %> お問い合わせユーザ名
<%= contact.title %> お問い合わせ件名
<%= contact.message %> お問い合わせ内容

ユーザ用メールテンプレート登録

次にユーザ用のテンプレートを登録します。登録内容は下記になります。

フィールド 設定値
Name お問い合わせ(ユーザ用)
Subject <%= contact.name %> 様 お問い合わせありがとうございます。
To
From 管理者<admin@example.com>
ReplyTo 管理者<admin@example.com>
Text
下記内容でお問い合わせを受け付けました。

お問い合わせ番号: <%= contact.contactId %>
お名前: <%= contact.name %>
お問い合わせ件名: <%= contact.title %>
お問い合わせ内容:
<%= contact.message %>
Html
<h1>下記内容でお問い合わせを受け付けました。</h1>
<table border="0">
  <tr>
    <th align="left">
      お問い合わせ番号:
    </th>
    <td>
      <%= contact.contactId %>
    </td>
  </tr>
  <tr>
    <th align="left">
      お名前:
    </th>
    <td>
      <%= contact.name %>
    </td>
  </tr>
  <tr>
    <th align="left">
      お問い合わせ件名:
    </th>
    <td>
      <%= contact.title %>
    </td>
  </tr>
  <tr>
    <th align="left">
      お問い合わせ内容:
    </th>
    <td>
      <%= contact.message %>
    </td>
  </tr>
</table>

お問い合わせ(ユーザ用)

メールテンプレートのIDを確認

登録後、"Id"を確認します。
"Id"を確認

お問い合わせ用コンテンツタイプの権限設定

一般ユーザからお問い合わせができるように権限を設定します。
strapiのメニューから"設定"をクリックし、"ロールと権限"をクリックします。
"設定"をクリックし、"ロールと権限"をクリック

"ロールの一覧"から"Public"をクリックします。
"ロールの一覧"から"Public"をクリック

"CONTACT"の"create"にチェックを入れて"Save"をクリックし、保存します。
"CONTACT"の"create"にチェックを入れて"Save"をクリック

strapi-provider-email-nodemailerをインストール

strapiではデフォルトのメール送信にsendmailが使われていますが、使用しているnode.jsのDockerイメージにはインストールされていないので、ここではstrapi-provider-email-nodemailerをインストールしてSMTPを使ってメールを送信します。

https://www.npmjs.com/package/strapi-provider-email-nodemailer

strapiではメールプロバイダを変えることでsendmail、SMTPだけでなくSendGridmailgunAmazon SESなど様々なメール送信サービスを使用することができます。

使用できるプロバイダ一覧は下記になります。

https://www.npmjs.com/search?q=strapi-provider-email-&ranking=popularity

下記コマンドでstrapi-provider-email-nodemailerをインストールします。

$ yarn add strapi-provider-email-nodemailer

strapi-provider-email-nodemailerの設定

開発環境用にconfig/env/development/plugins.jsにstrapi-provider-email-nodemailerの設定を記述します。
config/env/development/plugins.jsがない場合は作成します。

config/env/development/plugins.js
module.exports = ({ env }) => ({
  email: {
    provider: 'nodemailer',
    providerOptions: {
      host: env('SMTP_HOST'),
      port: env('SMTP_PORT'),
      auth: {
        user: env('SMTP_USERNAME'),
        pass: env('SMTP_PASSWORD'),
      },
    },
    settings: {
      defaultFrom: 'hello@example.com',
      defaultReplyTo: 'hello@example.com',
    },
  },
});

defaultFromにはデフォルトで使用される送信元メールアドレス、defaultReplyToにはデフォルトで使用される返信先メールアドレスを設定します。

.envにSMTPサーバーの設定を記述します。

.env
SMTP_HOST=SMTPサーバー
SMTP_PORT=SMTPサーバーのポート
SMTP_USERNAME=メールユーザ名
SMTP_PASSWORD=メールユーザパスワード

コントローラーをカスタマイズしてメールを送信を追加する

Contactの新規作成時にお問い合わせメールが送信されるようにコントローラーを下記のようにカスタマイズします。

api/contact/controllers/contact.js
'use strict';

const { sanitizeEntity } = require('strapi-utils');
const { v4: uuidv4 } = require('uuid');
const _ = require('lodash');

/**
 * Read the documentation (https://strapi.io/documentation/developer-docs/latest/development/backend-customization.html#core-controllers)
 * to customize this controller
 */

module.exports = {

  async create(ctx) {

    // contactIdを追加してDBに保存
    const contactId = uuidv4();
    const contact = await strapi.services.contact.create({...ctx.request.body, contactId: contactId});

    // 管理者用メール送信
    const toAdminTemplate = await strapi.query('mail-template').findOne({ id: 1 });
    await strapi.plugins.email.services.email.sendTemplatedEmail(
      // 送信先に管理者のメールアドレスを設定
      {
        to: toAdminTemplate.to,
      },
      // メールテンプレートを設定
      toAdminTemplate,
      // テンプレート変数を設定
      {
        contact: _.pick(contact, ['name', 'email', 'title', 'message', 'contactId']),
      }
    );

    // ユーザ用メール送信
    const toUserTemplate = await strapi.query('mail-template').findOne({ id: 2 });
    await strapi.plugins.email.services.email.sendTemplatedEmail(
      // 送信先にユーザ、送信元と返信先に管理者のメールアドレスをそれぞれ設定
      {
        to: contact.email,
        from: toUserTemplate.from,
        replyTo: toUserTemplate.replyTo,
      },
      // メールテンプレートを設定
      toUserTemplate,
      // テンプレート変数を設定
      {
        contact: _.pick(contact, ['name', 'email', 'title', 'message', 'contactId']),
      }
    );

    return sanitizeEntity(contact, { model: strapi.models.contact });
  },
};

確認したメールテンプレートのIDをそれぞれ設定しています。

メールが送信されるか確認する

以前に紹介したVSCodeの拡張機能Thunder Clientを使用して動作確認します。

https://zenn.dev/mseto/articles/vscode-thunder-client

テスト用のGraphqlを設定します。

Body > Graphql
mutation {
  createContact(input:  {
    data:{
      name: "ユーザ名",
      email: "test@example.com",
      title: "お問い合わせテスト",
      message: "お問い合わせ内容",
    }
  }){
    contact {
      name
      contactId
      title
      email
      message
    }
  }
}

テスト

正常に結果が戻り、メールが送信されていれば成功です。
テスト結果

まとめ

strapiはもともとの機能が充実している上、カスタマイズもしやすいと思いました。

Discussion

ログインするとコメントできます