💰

Stripe WebhookとGASでStripeのイベントを受信し、購入者に自動でメールを送る

2022/02/22に公開
17

Stripeで商品が買われたときに手動でメールでご案内するのが面倒...自動化したい!

Stripeには、商品購入後に領収書メールを自動送信する機能があります。
しかし、その内容をカスタマイズすることはできません。

自分の商品が購入されたときに、
お客さんに自動返信メールで「お礼」と、「商品の案内」を送りたい!
手動でいちいちメールを送るのは嫌だ!
というわけで、作ってみました。

試す場合は自己責任でお願いいたします。

完成イメージはこちら
https://twitter.com/hedgehog_noodl/status/1495793876791177223

欲しい機能

  • Stripeから商品を購入してくれた人に自動でお礼メールを送る
  • メールの内容は商品ごとに出し分ける

使ったもの

  • Stripe Webhook
  • Stripe API
  • GAS/スプレッドシート
  • Gmail

さっそく作ってみる

Stripeの設定

  1. Stripe右上の「テスト環境」をONにする ※開発が完了したら本番に戻し、APIキーの書き換えを行ってください。
  2. 「開発者」をクリック。APIやWebhookのメニューが表示されます。
  3. 左メニューAPIをクリックし、API Keyを確認
  4. 左メニューWebhookをクリックし、「+エンドポイントを追加」する
  • エンドポイント URL: GASで作ったウェブアプリのURLを入力
  • リッスンするイベントの選択: checkout.session.completed (購入完了のイベント)

スプレッドシート/GAS側の準備

欲しい機能の一つである「メールの内容は商品ごとに出し分ける」を実現するため、
出し分けるテキストの内容をスプレッドシートで管理することにしました。
流れは以下になります。

  1. 購入されたStripeの商品名を取得
  2. 同じ商品名のセルがあるかスプレッドシート内を検索
  3. 隣の列の文章(メールに入れたい文章)を取得
  4. メール送信

では商品名と商品ごとのメールテキストデータを作っていきましょう。
新規スプレッドシートを作成し、
1列目に商品名(Stripeの商品名と完全に一致させること)、
2列目にメールテキストを入れてください。

データが完成したら、

  1. スプレッドシートのメニューからGASのエディタを立ち上げる
  2. 下記コードをコピペ
  3. APIキーやメールアドレス(Gmailアドレス)を書き換える
  4. デプロイ
  5. WEBアプリのURLをコピーし、StripeのWebhook エンドポイントを追加に入力。

function doPost(e) {
  
  //Stripeのイベント
  const jsonString = e.postData.getDataAsString();
  const data = JSON.parse(jsonString);
  const customerMail = data.data.object.customer_details.email;

  const APIKEY = '【あなたのStripe APIキー】';
  const SET = {
   headers: {
     Authorization: 'Basic ' + Utilities.base64Encode(APIKEY)
   },
   muteHttpExceptions: true,
   method: 'GET'
   }

   const response = UrlFetchApp.fetch("https://api.stripe.com/v1/checkout/sessions/"+ data.data.object.id + "/line_items",SET
);
  const responseData = JSON.parse(response);
  const itemName = responseData.data[0]['description'];
  console.log(itemName);

  //スプレッドシート
    var spread = SpreadsheetApp.getActiveSpreadsheet() ;
    var sheet = spread.getSheets()[0] ;
    var textFinder = sheet.createTextFinder(itemName);
    var range= textFinder.findAll(); 
    var row = range[range.length - 1].getRow();
    var itemIntro = sheet.getRange(row,2).getValue();
    Logger.log(itemIntro) ;

  // 購入者に送る自動返信メールの情報
    var sendToAddress ="【あなたのメールアドレス】";
    var subject = itemName +'をご購入いただきありがとうございます';
    var option = {};
    option.from = sendToAddress;

  // 自動返信メール本文
  var body = 
    'この度は'+itemName +'をご購入いただき、誠にありがとうございました。' +
    '\n' +
    itemIntro+
    '\n' +
    '不明点などございましたら、公式LINEよりお問い合わせください。\n' + 
    '\n' +
    '─────────────────────────\n' +
    '署名 \n' +
    '─────────────────────────\n' +
    '\n';

    // メール送信
    GmailApp.sendEmail(customerMail,subject,body,option); //自動返信メール
    GmailApp.sendEmail(sendToAddress,subject,body,option); //自分にも同じ内容を送信

}

これで、商品を購入したとき、商品ごとに異なる内容の自動返信メールを送れるようになりました!

Discussion

teruoteruo

当記事参考にして、自動決済メール実装できました!ありがとうございます。

1点、当記事の手順+α で実施した作業があったので連携しておきます。
(Stripeのログが401エラー吐いていたので、その解消手順です)

【Google Apps Scriptの承認エラー 401の対処方法】
https://www.teijitaisya.com/gas-approval-error/#index_id1

tttttt

このページ50回くらい見ました。ありがとうございます。
もう1点自分がはまったところもメモで書かしてください。

gasを、サーバー(webアプリ)にして、webhookを利用するときの注意点
① gasのコードはデプロイしないと使えないよ(自分みたいな初心者は気をつけてよ)
②デプロイするときのアクセスできるユーザの欄は全員にするよ
③ 次にデプロイ管理をクリックして、いま作ったアプリのバージョンを最新のものに変えるよ <- マジでハマるよ

参考
https://gr8developer.blogspot.com/2019/07/google-apps-scriptgaswebhook.html

xnxn888xnxn888

APIとメールのみ変更して実装いたしました。
ストライプ側でエラーは特にないのですが、メールの送受信がされない状態です。
送受信がされない原因などは何か考えられる部分などございますでしょうか?

はりねずみ麺はりねずみ麺

コメント&お試しいただきありがとうございます!
GASのほうでエラーなにかでてますか?
tttさんのコメント内容も参考になりそうです。

xnxn888xnxn888

ご返信ありがとうございます!
tttさんの内容も試したのですが、なぜかメールが機能しない状態でした...
以下エラーがGASの方では出ております。

TypeError: Cannot read properties of undefined (reading 'postData')
doPost @ コード.gs:4

はりねずみ麺はりねずみ麺

ありがとうございます!
こちらはおそらく、GASのRun▶ボタンで実行した時のエラーかと思われ、正常です。

e.postDataはStripeで商品が買われたときのイベントで、
GASのRun▶ボタンを押してもデータがないためにエラーとなります。

実際にStripeで商品を購入したときに、どうなるか試してみてください。
(見当違いでしたら申し訳ありません!)

xnxn888xnxn888

そこのエラーは正常とのことで承知いたしました。
ただテストページにて商品を購入した際にメールの返信が来ない状況でした...
APIキーも公開キーと非公開キーどちらも試して、履歴を見るとストライプ上では正常に機能しているみたいです。

はりねずみ麺はりねずみ麺

ありがとうございます。
Stripeで購入時に、GASの方でなにかエラーが出ていますか?
出ている場合、同じ内容でしょうか。

xnxn888xnxn888


エラーはこちらの場所が確認で問題ないでしょうか?
一応このページではエラー処理になっているようです!

tscontscon

記事大変参考になりました!ありがとうございます!

素人質問で申し訳ないのですが、下記ステップ、何故「data.data」と連続するのでしょうか?

const customerMail = data.data.object.customer_details.email;

このように連続して記述すること動くことは自分の環境でも確認済なのですが・・
JSONに理解が疎く、理由や参考になる記事等あれば教えていただけますと幸いです。

tscontscon

すみません、改めてStripeのリクエスト情報を見て理解しました。失礼しました!

やっくんやっくん

はりねずみ麺様。
大変有益な記事をありがとうございます!
このような仕組みを導入できたら大変便利だなと思い、
ネットを漁っていたところ、
こちらの記事を見つけ、藁にもすがる思いで設定を進めております。

Stripe側で401エラーが発生しましたが、
コメント欄のteruoさんのコメントによって無事解決、
また、tttさんのコメントにも助けられました。

Stripeのテスト環境にて動作確認を何度か行ってみたところ、
Stripe側ではエラーはありませんが、
GASの「実行数」→「ステータス」を見ると
失敗しましたと表示され、メールが届かない状態です。

麺様がコメント欄にてupいただいていた、
以下のページも拝見いたしましたが、トリガーを設定していないため、エラー表示箇所がない状態でした
https://auto-worker.com/blog/?p=3731

しかしながら、GASの「実行数」
→ 失敗した行の右側「3点」
→「Cloudのエラー」より以下のエラーが表示されておりますが
何が原因がお分かりになりますでしょうか?

大変お手数おかけ致しますが
ご返信いただけましたら幸いです。

どうぞよろしくお願いいたします

やっくんやっくん

こちら、いろいろ試行錯誤した結果、
GASに入力するStripeのAPIキーを
「公開可能キー」ではなく、「シークレットキー」にすることで解決しました!

メール届いた時には震え上がりました笑
ありがとうございました🙇‍♂️

はりねずみ麺はりねずみ麺

わわ、みなさんコメント気が付かずに申し訳ありません!
(そして、みなさん自力で解決...!✨️)