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

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

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

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

Google Apps Script

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

Slack

Slackは、Tiny Speckという企業からリリースされたコミュニケーションツールです。GoogleDriveやGitHubなど、さまざまな外部サービスと連携することができます。

Q&A

解決済

1回答

2635閲覧

【GAS】指定の文字列が入力(手動入力ではない)されたら、Slack通知を飛ばしたい。

kenta_kenta

総合スコア19

Google スプレッドシート

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

Google Apps Script

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

Slack

Slackは、Tiny Speckという企業からリリースされたコミュニケーションツールです。GoogleDriveやGitHubなど、さまざまな外部サービスと連携することができます。

0グッド

1クリップ

投稿2021/12/24 05:23

編集2022/01/06 06:19

前提・実現したいこと

GASで指定列に指定文字列が入力(手動入力ではない)されたら、Slack通知を飛ばすGASを作成したい。

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

下記に貼り付けたコードを作成しましたが、Slack通知が飛びません。
調べてみると、スクリプト等で自動で入力される場合は、トリガーの「編集時」には当てはまらないということがわかりました。
ただ調べてみても、その問題の解決方法がよくわからず質問させていただきました。

該当のソースコード

GAS

1//送付エラーのタイムスタンプ/件名/本文/メールIDをスプレッドシートに吐き出す 2 3function getGmailToSS() { 4const ss = SpreadsheetApp.getActiveSpreadsheet(); 5const sheet = ss.getSheetByName('errordata_gmail'); 6 7const searchlabel = '"送付エラー"'; 8 9const threads = GmailApp.search('label:(' + searchlabel + ') -label:処理済み'); 10 11const msgIdArray = sheet.getRange("D:D").getValues().filter(String).flat(); 12let lastRow = msgIdArray.length + 1; 13 14for(const n in threads){ 15 const thread = threads[n]; 16 const msgs = thread.getMessages(); 17 msgs 18 19for(m in msgs){ 20 const msg = msgs[m]; 21 const id = msg.getId(); 22 23 if(msgIdArray.includes(id)) continue; //IDがD列に既に存在する場合はスルー 24 25 26 const msgData = [[msg.getDate(),msg.getSubject(),msg.getPlainBody(),id]]; 27 sheet.getRange(lastRow,1,1,4).setValues(msgData); //まとめて書き込み 28 29 lastRow++ 30 } 31 32 33const label = GmailApp.getUserLabelByName('処理済み'); 34 thread.addLabel(label); 35 } 36 37 38 // スプレッドシートから必要なデータを読み取り、スラックに投稿する。 39 const staffErrorEmail = sh.getRange(writeRow, 5).getValue(); //5=E列(送付エラーアドレス) 40 const staffName = sh.getRange(writeRow, 6).getValue(); //6=F列(スタッフ名) 41 const temphireId = sh.getRange(writeRow, 7).getValue(); //7=G列(ID) 42 const slackId = sh.getRange(writeRow, 9).getValue(); //9=I列(SlackID) 43 44 const message = slackId + '\n' + staffName + '\n' + staffErrorEmail + temphireId; 45 postToSlack(message); 46 47} 48 49 50function postToSlack(message){ 51 const postToMDS = "通知先のWebhooksURL"; // 52 53 const jsonData = 54 { 55 "text" : message, 56 }; 57 58 const payload = JSON.stringify(jsonData); 59 60 const options = 61 { 62 "method" : "post", 63 "contentType" : "application/json", 64 "payload" : payload, 65 }; 66 67 // リクエスト 68 UrlFetchApp.fetch(postToMDS, options); 69} 70

補足情報

トリガー設定

関数:getActiveCell
デプロイ時に実行:Head
イベントソース:スプレッドシートから
イベント種類:編集時

GASのif文で条件にしているスプレッドシートのJ列には下記関数を入れております。
=ARRAYFORMULA(IF(I3:I="","","SlackID生成済み"))

スプレッドシートのI列には<@SlackID>が表示されるようにしています。

Slack通知させるプログラムをつくるのも初めての経験で、
自分が把握していないミスもあるかもしれませんが、何卒よろしくお願いいたします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/12/24 11:30

J列に入っている関数は「I列に文字(SlackID)が入力されていたら、J列の同じ行に「SlackID生成済み」と表示する」という式のようですが、 I列への文字入力は手動なのでしょうか?それとも手動以外の入力方法によるものなのでしょうか?
kenta_kenta

2021/12/25 13:50

I列の文字も手動以外の入力方法によるものです。
guest

回答1

0

ベストアンサー

・特定の数式の計算結果が変更されたことを、変更時・更新時のトリガー(onEditやonChangeで直接検知することはできませんし、その計算結果が変わったセルはアクティブセルにはなりません。
(この例で言えば、I列に何らかの文字が入ったことによりJ列の当該行が「SlackID生成済み」という文字に変化しても、J列自体は、アクティブセルとして扱われません。)

・変更時・更新時のトリガーは、基本的に、スプレッドシートへ直接手動入力する場合以外は検知できません。
ただし、たとえば、GoogleスプレッドシートのAppSheetという機能による書き込みについては、「変更時」トリガーであれば書き込みがあったことを検知し、書き込まれたセルがActiveCellになるということは確認できています。(「編集時」トリガーでは検知不可)
したがって、限られた場面では、スプレッドシートへ直接手動入力する場合以外であっても「変更」トリガーで検知できる可能性はあるかもしれません。

コメントでの質問に対する回答によると、今回I列への文字入力は「手動入力ではない」とのことですが、どのような手段を用いて自動入力しているのかについての詳細が開示されておりませんので、質問者さんの使用状況で「変更時」でも検知できるかどうかはこちらではわかりかねます。

いずれにしても下記コードに直したうえで、トリガーを「編集時」から「変更時」に変更して保存した場合、もしかしたら検知できるかもしれません。

js

1// トリガーは「編集時」から「変更時」に変える。 2function getActiveCell() { 3 const SS = SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシート取得 4 const Sh = SS.getActiveSheet(); // アクティブシート取得 5 if(Sh.getName() != "errordata_gmail"){ //シート名取得  6 return; 7 } 8 const ActiveCell = Sh.getActiveCell(); //アクティブセル取得 9 10 if(ActiveCell.getColumn() == 9 && ActiveCell.getValues() !== ""){ //条件:I列(=9)に何らかの文字が入力されたとき通知 11 const InputRow = ActiveCell.getRow(); //条件一致の行を取得 12 //以下条件一致のセルを取得。取得したい値を変更したい場合は列数を変更。定数は適宜変更。 13 const staffErrorEmail = Sh.getRange(ActiveCell.getRow(), 5).getValues(); //5=E列(送付エラーアドレス) 14 const staffName = Sh.getRange(ActiveCell.getRow(), 6).getValues(); //6=F列(スタッフ名) 15 const temphireId = Sh.getRange(ActiveCell.getRow(), 7).getValues(); //7=G列(ID) 16 const slackId = Sh.getRange(ActiveCell.getRow(), 9).getValues(); //9=I列(SlackID) 17 18 const message = slackId + '\n' + staffName + '\n' + staffErrorEmail + temphireId ; 19 postToSlack(message);

コメントを受けて追記

「GASを使ってD列にメールアドレスを書き込んでいる」とのことなので、
アプローチを変えて、その書き込むGASの方を改造すればよいと思います。
(書き込まれるスプレッドシートの方で書き込まれたことを検知するのではなく、
書き込んでいるGASを使って最終的なSlackの投稿処理まで行う、ということです)

具体的には、書き込み用のGASでD列にメールアドレスを書き込んだ後、続けて数式が入っているセル(E列~I列まで)を読み取ってSlackに投稿する、という流れです。
以下のように、スプレッドシートのA列~D列に書き込む処理の後に、Slack投稿用のコードを継ぎ足してみてはいかがでしょうか

(先頭が「+」となっている行は追加、「-」となっている行は削除)

diff

1//送付エラーのタイムスタンプ/件名/本文/メールIDをスプレッドシートに吐き出す 2 3function getGmailToSS() { 4 const ss = SpreadsheetApp.getActiveSpreadsheet(); 5 const sheet = ss.getSheetByName('errordata_gmail'); 6 7 const searchlabel = '"送付エラー"'; 8 9 const threads = GmailApp.search('label:(' + searchlabel + ') -label:処理済み'); 10 11 const msgIdArray = sheet.getRange("D:D").getValues().filter(String).flat(); 12 let lastRow = msgIdArray.length + 1; 13 14 for (const n in threads) { 15 const thread = threads[n]; 16 const msgs = thread.getMessages(); 17 msgs 18 19 for (m in msgs) { 20 const msg = msgs[m]; 21 const id = msg.getId(); 22 23 if (msgIdArray.includes(id)) continue; //IDがD列に既に存在する場合はスルー 24 25 26 const msgData = [[msg.getDate(), msg.getSubject(), msg.getPlainBody(), id]]; 27 sheet.getRange(lastRow, 1, 1, 4).setValues(msgData); //まとめて書き込み 28 29 30+ // スプレッドシートから必要なデータを読み取り、スラックに投稿する。 31+ const staffErrorEmail = sheet.getRange(lastRow, 5).getValue(); //5=E列(送付エラーアドレス) 32+ const staffName = sheet.getRange(lastRow, 6).getValue(); //6=F列(スタッフ名) 33+ const temphireId = sheet.getRange(lastRow, 7).getValue(); //7=G列(ID) 34+ const slackId = sheet.getRange(lastRow, 9).getValue(); //9=I列(SlackID) 35+ const message = slackId + '\n' + staffName + '\n' + staffErrorEmail + temphireId; 36+ postToSlack(message); 37 38 lastRow++ 39 } 40 41 42 const label = GmailApp.getUserLabelByName('処理済み'); 43 thread.addLabel(label); 44 } 45 46 47- // スプレッドシートから必要なデータを読み取り、スラックに投稿する。 48- const staffErrorEmail = sh.getRange(writeRow, 5).getValue(); //5=E列(送付エラーアドレス) 49- const staffName = sh.getRange(writeRow, 6).getValue(); //6=F列(スタッフ名) 50- const temphireId = sh.getRange(writeRow, 7).getValue(); //7=G列(ID) 51- const slackId = sh.getRange(writeRow, 9).getValue(); //9=I列(SlackID) 52 53- const message = slackId + '\n' + staffName + '\n' + staffErrorEmail + temphireId; 54- postToSlack(message); 55 56} 57 58function postToSlack(message) { 59 ...略... 60}

投稿2021/12/25 21:24

編集2022/01/06 12:59
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kenta_kenta

2021/12/27 08:15 編集

ご回答ありがとうございます。 ・質問に対する回答が不十分で失礼いたしました。 I列のセルについてもスプレッドシートの関数で入力されています。 SlackIDが出力されるようにしてあります。 =ARRAYFORMULA(IF(H3:H="","",iferror("<@"&VLOOKUP(H3:H,'SlackIDが入力されているシート'!$E$1:$G,3,FALSE)&">"))) ・いただいたコードで、トリガーを「編集時」から「変更時」に変更して保存してみましたが、やはりSlack通知は飛びませんでした。 下記質問も拝見しました。Appsheet使ったことがないので少し調べてみましたが、Appsheetで入力する必要があり、上記のI列のセルの関数の機能をAppSheetでもたせることは難しいのでしょうか? https://teratail.com/questions/371662
退会済みユーザー

退会済みユーザー

2021/12/27 12:03 編集

繰り返しになりますが、監視対象が、数式が入っているセルである限り、そのセルの(計算結果の)変化は、どうやっても検知できないと思われます。 したがって数式が参照している大元(この場合I列に入っている数式が参照しているH列  →仮にH列が数式ならばその数式が参照している先・・・以下同じ)を監視する必要があります。 そして、数式が参照している大元がどのようにして(=どのようなツールやアプリ等を用いて)自動入力されているのか、という点をご教示いただけないことには、それがGASで検知可能か不可能かを調べることはできないと思われます。 >Appsheetで入力する必要があり、上記のI列のセルの関数の機能をAppSheetでもたせることは難しいのでしょうか? →前述の通り、「現状、どういう方法で大元のスプレッドシートに自動入力されて、最終的にJ列に"SlackID生成済み"という表示がなされるようになっているのか」に関する情報が全く不明であるため、 現状の機能をAppSheetで置き換えられるかどうかについても、答えようがありません。
kenta_kenta

2021/12/28 05:05

回答ありがとうございます。 理解力不足で失礼いたしました。 数式が参照している大元はD列で、GASでメールIDを自動入力させております。 送付エラーになったメールの内容を出力しているGASになります。
退会済みユーザー

退会済みユーザー

2021/12/28 11:03

追記しました。
kenta_kenta

2022/01/06 06:22 編集

追記ありがとうございます。 D列にはメールアドレスではなく、メールIDをGASで書き込んでおります。 理解力不足で申し訳ないのですが、下記内容を自分のプログラムで実装する際にどうすればよいのかがよくわかりませんでした。 質問文のプログラムを変更しましたので、可能であれば教えていただいてもよろしいでしょうか? // 書き込むメールアドレス const mailAddress = "aa@aaa.com"; // 書き込み先の行番号(ここでは簡便のため固定値(10)にしているが、forループを使っている場合はその変数に読み替えてもよい) const writeRow = 10; // メールアドレスを「writeRow行目、D列」に書き込む sh.getRange(writeRow, 4).setValue(mailAddress); }
退会済みユーザー

退会済みユーザー

2022/01/06 07:00 編集

>D列にはメールアドレスではなく、メールIDをGASで書き込んでおります。 とのことですが、 それでは、その「メールIDを書き込む方のGAS」のコードを、省略せずに質問文に追記していただけないでしょうか?
kenta_kenta

2022/01/06 07:09

返信ありがとうございます。 質問文を修正いたしました。 const msgData = [[msg.getDate(),msg.getSubject(),msg.getPlainBody(),id]]; sheet.getRange(lastRow,1,1,4).setValues(msgData); こちらで書き込みを行っております。
退会済みユーザー

退会済みユーザー

2022/01/06 12:56

後半のコードを修正しました
kenta_kenta

2022/01/07 01:22

ご回答ありがとうございます。 望んでいた形で実装することができました。 何から何までご丁寧に教えていただき大変助かりました。 まずは、記載いただいたコードをしっかり理解するところから勉強させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.43%

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

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

質問する

関連した質問