21
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

WordPressお問合せフォームをAPIで【Contact Form 7 REST API】

Last updated at Posted at 2020-02-26

WordPressでお問合せフォーム

お問合せフォームを作る需要はよくあります。
WordPressでお問合せフォームを作るプラグインは色々ありますが、WordPress REST APIをやってきているのでお問合せフォームもなんとかREST APIで実装したい。
調べた所、Contact Form 7はREST APIに対応していましたので、これを使ってみます。
contact form 7

Contact Form 7

Contact Form 7 は複数のコンタクトフォームを管理できてその上フォームとメールの内容を簡単なマークアップで柔軟にカスタマイズしたりもできます。Ajax によるフォーム送信、CAPTCHA、Akismet スパムフィルタリング等々サポートしています。

Contact Form 7でお問合せフォームの作り方はここでは触れません。
ぱぱっと作れる前提でREST APIのことについてのみ触れます。

REST API全般

Contact Form 7はREST APIに対応しているもののドキュメントがありません。
なのでソースコードを読みます。
https://github.com/ohze/wp-contact-form-7/blob/master/includes/rest-api.php
これをざっと見ると、APIでお問合せフォームの取得と、お問合せの投稿ができそうです。

試す

フォームを1つ作った状態で、
/wp-json/contact-form-7/v1/contact-formsGETメソッドでAPIを叩いてみましょう。
そうすると、以下のようなレスポンスが返ってきます。

レスポンス
{
    "code": "wpcf7_forbidden",
    "message": "リクエストしたコンタクトフォームにアクセスする権限がありません。",
    "data": {
        "status": 403
    }
}

Contact Form 7はAPIによって認証が必要みたいです。
なのでそういったものにはアプリケーションパスワードをリクエストヘッダーにいれてAPIを再度叩いてみましょう。

レスポンス
[
    {
        "id": 13,
        "slug": "%e3%82%b3%e3%83%b3%e3%82%bf%e3%82%af%e3%83%88%e3%83%95%e3%82%a9%e3%83%bc%e3%83%a0-1",
        "title": "コンタクトフォーム 1",
        "locale": "ja"
    }
]

なにやらフォームの一覧っぽいものが返ってきました。

  • ドキュメントないからソースコードをみよう
  • Contact Form 7のAPIの一部は認証が必要

この2つを抑えておきましょう。

フォームの取得

/wp-json/contact-form-7/v1/contact-forms/<id>GETメソッドでAPIを叩いてみましょう。(認証が必要です)

レスポンス
{
    "id": 13,
    "slug": "%e3%82%b3%e3%83%b3%e3%82%bf%e3%82%af%e3%83%88%e3%83%95%e3%82%a9%e3%83%bc%e3%83%a0-1",
    "title": "コンタクトフォーム 1",
    "locale": "ja",
    "properties": {
        "form": "<label> お名前 (必須)\n    [text* your-name] </label>\n\n<label> メールアドレス (必須)\n    [email* your-email] </label>\n\n<label> 題名\n    [text your-subject] </label>\n\n<label> メッセージ本文\n    [textarea your-message] </label>\n\n[submit \"送信\"]",
        "mail": {
            "subject": "test \"[your-subject]\"",
            "sender": "test <xxx@example.co.jp>",
            "body": "差出人: [your-name] <[your-email]>\n題名: [your-subject]\n\nメッセージ本文:\n[your-message]\n\n-- \nこのメールは test (http://localhost:8000) のお問い合わせフォームから送信されました",
            "recipient": "xxx@example.co.jp,
            "additional_headers": "Reply-To: [your-email]",
            "attachments": "",
            "use_html": 0,
            "exclude_blank": 0
        },
        "mail_2": {
            "active": false,
            "subject": "test \"[your-subject]\"",
            "sender": "test <xxx@example.co.jp>",
            "body": "メッセージ本文:\n[your-message]\n\n-- \nこのメールは test (http://localhost:8000) のお問い合わせフォームから送信されました",
            "recipient": "[your-email]",
            "additional_headers": "Reply-To: xxx@example.co.jp",
            "attachments": "",
            "use_html": 0,
            "exclude_blank": 0
        },
        "messages": {
            "mail_sent_ok": "ありがとうございます。メッセージは送信されました。",
            "mail_sent_ng": "メッセージの送信に失敗しました。後でまたお試しください。",
            "validation_error": "入力内容に問題があります。確認して再度お試しください。",
            "spam": "メッセージの送信に失敗しました。後でまたお試しください。",
            "accept_terms": "メッセージを送信する前に承諾確認が必要です。",
            "invalid_required": "必須項目に入力してください。",
            "invalid_too_long": "入力されたテキストが長すぎます。",
            "invalid_too_short": "入力されたテキストが短すぎます。",
            "invalid_date": "日付の形式が正しくありません。",
            "date_too_early": "選択された日付は早すぎます。",
            "date_too_late": "選択された日付は遅すぎます。",
            "upload_failed": "ファイルのアップロード時に不明なエラーが発生しました。",
            "upload_file_type_invalid": "この形式のファイルはアップロードできません。",
            "upload_file_too_large": "ファイルが大きすぎます。",
            "upload_failed_php_error": "ファイルのアップロード中にエラーが発生しました。",
            "invalid_number": "数値の形式に間違いがあります。",
            "number_too_small": "入力された数値が小さすぎます。",
            "number_too_large": "数値が最大許容値を超えています。",
            "quiz_answer_not_correct": "クイズの答えが正しくありません。",
            "captcha_not_match": "入力されたコードが正しくありません。",
            "invalid_email": "入力されたメールアドレスに間違いがあります。",
            "invalid_url": "URL に間違いがあります。",
            "invalid_tel": "電話番号に間違いがあります。"
        },
        "additional_settings": null
    }
}

かなり色々なのが返ってきますが、properties.formのhtmlを埋め込みつつ、[text* your-name]とかは独自でパースしてinputタグにしてやる必要がありそうです。
ただこのAPIは認証が必要です。
なのでアプリケーションパスワードを発行してそれをエンドユーザーが使うAPIで利用する必要があります。
エンドユーザー側が扱うAPIを想定しているので、認証に必要な文字列がバレてしまうのでこれを使われるとWordPressの投稿もエンドユーザーからされてしまうことになり大変危険です。
Contact Form 7だけ利用できる権限のユーザを作ればと思いましたが、「購読者」の権限ではContact Form 7のAPIは利用できませんでした。
ソースをいじればいけそうですが、htmlのパースもしないといけないことを考えるとContact Form 7で作ったフォームと完全連動してフロントに埋め込むのは少々骨が折れそうです。

お問合せ投稿

ここでの投稿はエンドユーザーがお問合せフォームにデータを入れて登録することを指します。
/wp-json/contact-form-7/v1/contact-forms/<id>/feedbackPOSTメソッドでAPIを叩きます。
このAPIは認証がいりません。
バリデーションを通らないとエラーが返ります。

レスポンス
{
    "into": "#",
    "status": "validation_failed",
    "message": "入力内容に問題があります。確認して再度お試しください。",
    "invalidFields": [
        {
            "into": "span.wpcf7-form-control-wrap.your-email",
            "message": "必須項目に入力してください。",
            "idref": null
        }
    ]
}

また、content-typeをmultipart/form-dataにしてあげる必要があります。
バリデーションが通ると以下のようなレスポンスが返ります。

レスポンス
{
    "into": "#",
    "status": "mail_sent",
    "message": "ありがとうございます。メッセージは送信されました。"
}

dockerなどでメールの設定をしていない場合以下のようなメッセージが返ってきます。

レスポンス
{
    "into": "#",
    "status": "mail_failed",
    "message": "メッセージの送信に失敗しました。後でまたお試しください。"
}

これを回避するには、Contact Form 7のその他の設定で

skip_mail: on

としてやるとOKです。
(※設定については https://contactform7.com/ja/additional-settings/ を参照)

まとめ

Contact Form 7 REST APIでお問合せが出来ることを確認しました。
管理画面で作ったフォームをAPIで取得してフロントに埋め込むのは少々大変そうです。
ここも機会があればチャレンジしてみようと思います。

21
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?