質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

2回答

301閲覧

WixのwebhookをGASで利用したいが、データの形式が特殊でやり方がわからない

yahata

総合スコア2

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

1クリップ

投稿2024/07/01 14:55

編集2024/07/05 05:09

実現したいこと

WixのwebhookをGASで受け取り、受け取ったデータの処理をしたい

前提

wixという店舗運営サイトで、お客様の予約が入るとwebhookが作動してGASのプログラムが実行される仕様を実現させたいです。
実験的に、自分で予約を入れてみると、webhookでGASに送られてきたデータの形式が、JSONではなく変わった形式だと気づきました。この形式のデータから自分の欲しい情報(たとえばstart_date)を抜き出すにはどうすればいいでしょうか?

該当のソースコード

以下のコードでwebhookを受け取り、スプレッドシートに内容を記録しました。

google

1function doPost(e) { 2 if (e == null || e.postData == null || e.postData.contents == null) return; 3 4 var obj = JSON.parse(e.postData.contents); 5 var now = new Date(); 6 var array = []; 7 array.push(now, obj); 8 9 var ss = SpreadsheetApp.getActive(); 10 var sheet = ss.getSheets()[0]; 11 12 sheet.appendRow(array); 13}

スプレッドシートには以下のように表示されます。見たことのない形式なので、どうやって内容を取り出せばいいかわかりません。

{ data={ bookings_page_url=https://xxxxxxxxxxxxxx.wixsite.com/my-site-1/booking-calendar/サービス名, online_conference_enabled=false, staff_member_name=山田, approval_service=false, booking_contact_first_name=鈴木, order_id=xxxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx, contact={ emails=[Ljava.lang.Object;@xxxxxxx, name={last=鈴木}, address={ subdivisions=[Ljava.lang.Object;@xxxxxx, addressLine=千代田区千代田1-1, formattedAddress=千代田区千代田1-1 }, addresses=[Ljava.lang.Object;@xxxxxxxx, phone=000000000000, email=xxxxxxx@xxxxxx.com, phones=[Ljava.lang.Object;@xxxxxxxx, locale=ja }, booking_contact_phone=000000000000, notify_participants=true, booking_id=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx, ics={ downloadUrl=https://www.wix.com/bookings/automations/v2/ics/xxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxx, fileName=session.ics }, custom_form_fields=[Ljava.lang.Object;@xxxxxxxx, service_type=APPOINTMENT, service_name=サービス名, business_name=店舗名, booking_creation_date=2024-06-30T16:51:59.326+09:00, end_date=2024-06-30T20:00:00.000+09:00, context={ activationId=xxxxxxxx-xxxxxxxx-xxxx-xxxxxxxxxx, metaSiteId=xxxxxxxx-xxxxx-xxxxx-xxxxx-xxxxxxxxxxxxxx }, contact_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx, service_id=xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx, location=大阪府, service_url=https://xxxxxxxxxxxxxxx.wixsite.com/my-site-1/service-page/サービス名, time_zone_override=Asia/Tokyo, number_of_participants=1.0, start_date=2024-06-30T19:00:00.000+09:00, _context={ trigger={key=wix_bookings-sessions_booked}, app={id=xxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxx}, activation={id=xxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxx}, action={id=xxxxxxx-xxxxx-xxxx-xxxxx-xxxxxxxxxxxxxx}, configuration={id=xxxxxxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxxxxxxxx} } } }

試したこと

上記の、webhookで得られた内容を別のスプレッドシートに転記し、それをJSONのように処理しようとしましたが、

google

1function myFunction() { 2 var ss = SpreadsheetApp.getActive(); 3 var sheet = ss.getSheets()[0]; 4 var range = sheet.getRange("A1"); 5 var value = range.getValue(); 6 value = JSON.parse(value); 7 console.log(value.data.start_date); 8}

このようなエラーメッセージが出ます

SyntaxError: Expected property name or '}' in JSON at position 1

補足情報(FW/ツールのバージョンなど)

wixのサイトにあったペイロードの説明は以下の通りです。

pricing_plan 販売プラン remaining_amount_due.value 残額 remaining_amount_due.currency 通貨 booking_creation_date 予約作成日: staff_member_name スタッフ名 online_conference_enabled ビデオ会議が有効にされた order_id 受注 ID business_name ビジネス名 booking_contact_phone Booking contact phone start_date 開始日 location 場所 bookings_page_url 予約ページの URL custom_policy_description カスタムポリシーの説明文 service_image_url サービス画像の URL price.value 金額 price.currency 通貨 custom_price カスタム料金 service_url サービスの URL notify_participants 参加者に通知 staff_member_message スタッフのメッセージ approval_service サービスの承認 service_name サービスタイトル booking_id 予約 ID custom_form_fields カスタムフォーム項目 end_date 終了日 booking_contact_last_name Booking contact last name service_type サービスの種類 currency 通貨 number_of_participants 予約者の人数 contact_id 連絡先 ID service_id サービス ID business_phone 電話番号 online_conference_url ビデオ会議のURL ics.fileName ファイル名 ics.downloadUrl ダウンロード URL online_conference_password ビデオ会議のパスワード business_email ビジネス用メールアドレス online_conference_description ビデオ会議の説明文 booking_contact_first_name Booking contact first name contact.name.last Contact last name contact.name.first Contact first name contact.email Contact email contact.locale Contact locale contact.company Contact company contact.birthdate Contact birthdate contact.address.city Contact city contact.address.addressLine Contact address line 1 contact.address.formattedAddress Contact full address contact.address.country Contact country contact.address.postalCode Contact postal code contact.address.addressLine2 Contact address line 2 contact.address.subdivision Contact address subdivision contact.jobTitle Contact job title contact.phone Contact phone

追記

wix側で、ペイロードの構造をシンプルにしました。しかし、やはりなぜかJSONの要素を取得することができません。

google

1function doPost(e) { 2 try{ 3 if (e == null || e.postData == null || e.postData.contents == null) return; 4 5 var params = JSON.stringify(e.postData.contents); 6 console.log(params); 7 8 // JSON文字列をオブジェクトに変換 9 let jsonObject; 10 try { 11 jsonObject = JSON.parse(params); 12 console.log('JSON parsed successfully:', jsonObject); 13 } catch (e) { 14 console.error('Failed to parse JSON:', e); 15 } 16 17 // jsonObject自体を確認 18 console.log('jsonObject:', jsonObject); 19 20 // dataプロパティが存在するか確認 21 if (jsonObject && jsonObject.data) { 22 // staff_member_nameを取得 23 const staffMemberName = jsonObject.data.staff_member_name; 24 console.log('Staff Member Name:', staffMemberName); 25 } else { 26 console.error('data property is undefined'); 27 } 28 29 return ContentService.createTextOutput("Received and processed webhook data."); 30 }catch(error){ 31 Logger.log("Error: " + error.message); 32 return ContentService.createTextOutput("Error processing webhook data."); 33 } 34}

ログは以下の通りです。

"{\"data\":{\"staff_member_name\":\"山田 \"}}" JSON parsed successfully: {"data":{"staff_member_name":"山田 "}} jsonObject: {"data":{"staff_member_name":"山田 "}} data property is undefined

さらにやってみたこと

山田の右に謎の空白があったので、削除してみましたが、それでもやはりdataプロパティは見つからないようです。

function doPost(e) { try{ if (e == null || e.postData == null || e.postData.contents == null) return; var params = JSON.stringify(e.postData.contents); params = params.replace( " ", "" ); console.log(params); params = params.substring(1); // JSON文字列をオブジェクトに変換 let jsonObject; try { jsonObject = JSON.parse(params); console.log('JSON parsed successfully:', jsonObject); } catch (e) { console.error('Failed to parse JSON:', e); } // jsonObject自体を確認 console.log('jsonObject:', jsonObject); // dataプロパティが存在するか確認 if (jsonObject && jsonObject.data) { // staff_member_nameを取得 const staffMemberName = jsonObject.data.staff_member_name; console.log('Staff Member Name:', staffMemberName); // 出力: サニ } else { console.error('data property is undefined'); } return ContentService.createTextOutput("Received and processed webhook data."); }catch(error){ Logger.log("Error: " + error.message); return ContentService.createTextOutput("Error processing webhook data."); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

最初のJSON.stringify をなくしたら、スタッフ名などの取得ができるようになり、問題が解決しました。

function doPost(e) { try { if (e == null || e.postData == null || e.postData.contents == null) return; // JSON.stringifyを削除 var params = e.postData.contents; console.log(params); // JSON文字列をオブジェクトに変換 let jsonObject; try { jsonObject = JSON.parse(params); console.log('JSON parsed successfully:', jsonObject); } catch (e) { console.error('Failed to parse JSON:', e); } // jsonObject自体を確認 console.log('jsonObject:', jsonObject); // dataプロパティが存在するか確認 if (jsonObject && jsonObject.data) { // staff_member_nameを取得 const staffMemberName = jsonObject.data.staff_member_name; console.log('Staff Member Name:', staffMemberName); } else { console.error('data property is undefined'); } return ContentService.createTextOutput("Received and processed webhook data."); } catch (error) { Logger.log("Error: " + error.message); return ContentService.createTextOutput("Error processing webhook data."); }

投稿2024/07/05 05:45

yahata

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

環境がないので確認できていないのですが、
JSON.parse(e.postData.getDataAsString()); とかで受け取れませんか?

【Google Apps ScriptのdoPostでJSONなパラメータのPOSTリクエストを受ける #GoogleAppsScript - Qiita】
https://qiita.com/shirakiya/items/db22de49f00710478cfc#JSONパラメータを受けparseする


【About Webhooks】
https://dev.wix.com/docs/build-apps/develop-your-app/api-integrations/events-and-webhooks/about-webhooks

Event data is sent as a JSON web token (JWT) in the body of the webhook request.

投稿2024/07/01 18:19

kei344

総合スコア69574

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yahata

2024/07/02 10:45

ありがとうございます。 ``` JSON.parse(e.postData.getDataAsString()); ``` で試したところ、質問したのと同じ形式のデータが得られました。 ”Event data is sent as a JSON web token”とwebhookの説明にありますが、私が得たデータは本当にJSONなのでしょうか? JSONはキーと値がダブルクォーテーションで囲まれていますが、このデータにはそれがありません。また、JSONはキーと値がコロンで繫がっていますが、このデータはイコールでつながっています。このようなデータはどう処理すればいいのでしょうか。
kei344

2024/07/02 18:24

e.postData.type e.postData.contents.data.staff_member_name 上記はアクセス可能ですか? >このようなデータはどう処理すればいいのでしょうか。 文字列として扱えるなら無理やり処理していけば扱える可能性がありますが、「データ内容の確認の仕方を間違えている」可能性や「受け取り方を間違えている」可能性を考えるのが先だとは思います。
yahata

2024/07/03 10:31

ご対応ありがとうございます。e.postData.type は application/json e.postData.contents.data.staff_member_name は  "Error: Cannot read properties of undefined (reading 'staff_member_name')" となりました。一応、後者の該当のコードも記してておきます。 function doPost(e) { try{ if (e == null || e.postData == null || e.postData.contents == null) return; var obj = JSON.parse(e.postData.contents.data.staff_member_name); Logger.log(obj); return ContentService.createTextOutput("Received and processed webhook data."); }catch(error){ Logger.log("Error: " + error.message); return ContentService.createTextOutput("Error processing webhook data."); } }
kei344

2024/07/03 12:40

ログの表示については下記のような記事があり、 > console.log では定義した通りで出力されました. > 一方で,Logger.log は:(コロン)が = になり,要素の並びが実行ごと変化します. という記述があります。 【【GAS】ログ出力はなぜLogger.log?console.logとの違いを紹介 - テックパンプ】 https://tellingbook.com/wp-content/uploads/2022/07/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2022-07-10-14.33.13.png また、sheet.appendRow(e.postData.contents); 部分でappendRowに渡すのは配列です。e.postData.contentsは文字列だしもし JSON.parse(e.postData.contents)としてもオブジェクトなので、期待した表示にならないと思われます。 sheet.appendRow([e.postData.contents]); // ← これで変わりませんか 【Class Sheet  |  Apps Script  |  Google for Developers】 https://developers.google.com/apps-script/reference/spreadsheet/sheet?hl=ja#appendrowrowcontents
yahata

2024/07/04 12:35

ご対応ありがとうがおざいます。 ・console.logを試したら、まともなJSONの形式になりました!ありがとうございます。しかし、まだこのJSONから情報を得るのにてこずっています。 ・最初の質問で書いたコードは、エディタ上でコードを書き換えたものの、デプロイをしていなかったので、書き換える前のコードが実行されていました。そのため、質問に即したものではありませんでした。すみません。確かに、最初の質問で書いたコードではうまくスプレッドシートに記載されません。実際に実行していた正しいコードを追記に記載します。 ・doPost関数をwebhookから実行すると、通常はログを見ることができないので仕方なくスプレッドシートに書き出していました。しかし、Google Cloud Platformでログを確認する方法を始めたので、スプレッドシートに書き出す必要がなくなりました。 (こちらを参考にしました https://www.hidetoshl.com/gas-gcp/)
kei344

2024/07/04 13:09

[再送] sheet.appendRow([e.postData.contents]); // ← これで変わりませんか 更新されたコードで array.push(now, obj); としていますが、obj はオブジェクトなので文字列ではありません。ただシートに記録したいだけならparseせずに入れましょう。
yahata

2024/07/05 05:45

最初のJSON.stringify をなくしたら、スタッフ名などの取得ができるようになり、問題が解決しました。しかしここまで来るにはkei344様の助言なくしては不可能でした。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問