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

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

新規登録して質問してみよう
ただいま回答率
85.31%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

Q&A

解決済

1回答

405閲覧

スプシの変更内容を一定期間毎にDiscordへ通知したい

SatouSio

総合スコア1

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

0グッド

0クリップ

投稿2023/08/30 06:13

実現したいこと

GAS(JS)初心者です。
以下サイト記載の構文をコピペにて実行したのですが、デバッグ時に幾つかの型がundefinedとなり通らない。

前提

件名記載要件を満たしそうなサイトが以下にあったので、こちらのソースコードをコピペ。
7行目にて当該エラー発生。

https://qiita.com/daijin/items/5de520af98702f15f432

発生している問題・エラーメッセージ

TypeError: Cannot read properties of undefined (reading 'source') recordToProperty @ task.gs:7

該当のソースコード

task.gs

1//////////////////////////////////////////////////////////////////////////////// 2// 編集時に発行されるイベント 3//////////////////////////////////////////////////////////////////////////////// 4function recordToProperty(e) { 5 // 変更されたのが指定したシートの場合のみ有効 6 // ★★★編集を監視したいシート名に置き換える 7 if (e.source.getSheetName() != 'シート1') { 8 return; 9 } 10 11 // 変更時刻 12 const time = new Date().getTime(); 13 14 // メッセージに変更された範囲、新しい値を入れる 15 const message = [e.range.getA1Notation(), e.value]; 16 17 // 変更があったことをスクリプトプロパティに追加。keyは変更時刻 18 const script_property = PropertiesService.getScriptProperties(); 19 script_property.setProperty(time, JSON.stringify(message)); 20} 21 22//////////////////////////////////////////////////////////////////////////////// 23// 定期実行されるイベント 24//////////////////////////////////////////////////////////////////////////////// 25function notifyToDiscord(e) { 26 // スクリプトプロパティの変更をチェック。 27 const script_property = PropertiesService.getScriptProperties(); 28 const properties = script_property.getProperties(); 29 const array = Object.entries(properties); 30 31 // スクリプトプロパティに1件もなければ、この期間に変更なしと見なす。 32 if (array.length == 0) { 33 return; 34 } 35 36 // プロパティがあったので変更あり。Webhookを送信する。 37 const WEBHOOK_URL = 'https://discord.com/api/webhooks/xxxxxx/xxxxxx'; // ★★★DiscordのWebhook URL 38 39 // メッセージを作成 40 let message_body = 'シートに変更があったよ!!\n'; 41 let embeds = { 42 fields: [], 43 }; 44 45 array.forEach((prop) => { 46 const key = prop[0]; // time 47 const val = JSON.parse(prop[1]); // message 48 embeds.fields.push({ 49 name: 'セル: ' + val[0], 50 value: '変更後の内容: ' + val[1], 51 }); 52 }); 53 54 const payload = { 55 'username': /* ★★★投稿時のユーザー名。指定しない(デフォのままで良い)場合は、行ごと削除する */, 56 'content': message_body, 57 'tts': false, 58 'embeds': [embeds], 59 } 60 61 const param = { 62 'method': 'POST', 63 'headers': { 64 'Content-type': 'application/json' 65 }, 66 'payload': JSON.stringify(payload) 67 } 68 UrlFetchApp.fetch(WEBHOOK_URL, param); 69 70 // 送信成功後、プロパティを全削除 71 script_property.deleteAllProperties(); 72} 73

試したこと

if (e.source.getSheetName() != 'シート1') { return; }

を削るなどでの動作確認。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

codemaker

2023/08/30 06:48

> 件名記載要件を満たしそうなサイトが以下にあったので、こちらのソースコードをコピペ。 ということですので、 そのサイトの説明をよく読んでみることをお勧めします。 動作確認 1.スプレッドシートを編集する 2.notifyToDiscord 関数を手動で「実行」する これでDiscordの指定したチャンネルへBotの書き込みが投稿されれば :ok: 。 実行すべきはrecordToPropertyではないですよね。
YellowGreen

2023/08/30 07:40 編集

GAS(JavaScript)初心者ということなので、ご説明を加えておきます。 お示しのサイトの説明どおりトリガーを設定しているのであれば、 recordToPropertyは、 スプレッドシートのシート1を編集すると、 Googleサーバーのそのスクリプト用の格納領域(スクリプトプロパティ)に 編集した日時をキーとして[編集したセル名, 編集後のセルの値]の配列を保存します。 このスクリプトは、セルを編集したら起動するようにトリガー設定してあり、 編集された値に基づいて処理を行うスクリプトなので、 エディタからは実行しても編集された値がない(undefined)のでエラーになります。 notifyToDiscordの方は、時間指定で起動するトリガーを設定してあるので、 定期的にGoogleサーバーのスクリプトプロパティを読み込んで、 保存されたものがあるならその値に基づき投稿し、 投稿後はスクリプトプロパティを削除します。 なので、動作確認をしたいならば、 スプレッドシートを編集してrecordPropertyに編集内容をサーバーに保存させてから notifyToDiscordを手動で(エディタから)実行して保存した編集内容を取得して 投稿しているかどうかを確認することで動作確認できるということです。 recordToPropertyの方は、 トリガーでの実行を前提としているので、 エディタからはデバッグ実行もできませんから、 console.logなどで適宜変数の値をログに表示するようにして、 シートの編集後にエディタの実行数のペインからログを確認するようになります。 YAmaGNZ様のご提案のようにテスト用の関数の方を実行するときは、 次のように書き換えてみるとエラーが出ないと思います。 function Test_recordToProperty() { //A1セルを編集したときのテスト。A1は★のところを書き換えて適当なセルに設定 let sheet = SpreadsheetApp.openById('XXXXXX').getSheets()[0];//XXXXXXを書換える(左端のシートを取得) let range = sheet.getRange('A1');//★ let value = range.getValue(); let e = { source: sheet, range: range, value: value } recordToProperty(e); } ※ いろいろ書いているうちに解決されたのですね。良かったです。
guest

回答1

0

ベストアンサー

デバッグ時ということはエディタで実行されているのだと思います。
エディタで実行する場合は関数の引数は設定されません。
なので、function recordToProperty(e)eの中身がnullになります。

引数がある関数をテストで実行したい場合はテスト用の関数を作成し、そこから呼ぶようにしてください。

Javascript

1function recordToProperty(e) { 2 // 変更されたのが指定したシートの場合のみ有効 3 // ★★★編集を監視したいシート名に置き換える 4 if (e.source.getSheetName() != 'シート1') { 5 return; 6 } 7} 8 9function Test_recordToProperty() { 10 // 本当の引数がどのようなものなのか知りませんが、実行できるように適当に作成しました。 11 // 本来の引数になるように作成してください。 12 let sheet = SpreadsheetApp.openById('XXXXXX').getSheets()[0]; 13 let e = {source:sheet} 14 recordToProperty(e); 15}

投稿2023/08/30 06:45

YAmaGNZ

総合スコア10557

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

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

SatouSio

2023/08/30 07:21

ご回答ありがとうございます。 解決いたしました!
YAmaGNZ

2023/08/30 07:31

recordToProperty関数に関してはスプレッドシート内だけで完結するものなので実際に実行させてもいいのではないかとは思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問