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

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

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

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

Google Apps Script

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

Slack

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

Q&A

解決済

1回答

3878閲覧

スプレッドシートから、担当者を確認してスラックにメンションされるようにしたい

Tnatsu

総合スコア3

Google スプレッドシート

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

Google Apps Script

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

Slack

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

0グッド

0クリップ

投稿2022/11/06 06:36

前提

スプレッドシートの情報を確認してリマインドをスラックに送るように設定しています。

実現したいこと

K列が空白(=未対応)の場合、
毎朝スラックに通知が飛ぶようにしたいです。

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

スラックへのメンションができず、
「@'スラックID'」とそのままの文字で出てしまいます。

※別件で組んでいるGASでは、問題なくスラックIDを拾ってメンションが飛んでいます。

該当のソースコード

function taskRemind() { // シート取得 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート名') // ループ数定義 var firstRow = 3 var lastRow = sheet.getLastRow() for(var i = firstRow; i <= lastRow; i++) { // 各項目取得 var product_no = sheet.getRange('G' + i).getValue() var slname = sheet.getRange('H' + i).getValue()   var taiou =sheet.getRange('I' + i).getValue()   var slid =sheet.getRange('E' + i).getValue() var status = sheet.getRange('K' + i).getValue() const targetRange = sheet.getRange(i, 11); // console.log(targetRange.getA1Notation()); //空白かどうかをisBlankで判断。空白ならif節を実行。そうでないならelseを実行。 if (targetRange.isBlank()) { var postUrl = 'https://hooks.slack.com/services/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' var slackText = "@"+ slname ~~~(続きますが、省略します)

試したこと

別件で組んでいるGASでは、問題なくメンションされているため
原因がわからない状態です。

if(activeCell.getColumn() == 10 && activeCell.getValues() == "通知"){ var newInputRow = activeCell.getRow(); var time = activeSheet.getRange(activeCell.getRow(), 1).getValues(); var product_no = activeSheet.getRange(activeCell.getRow(), 7).getValues(); var slname = activeSheet.getRange(activeCell.getRow(), 8).getValues(); // 送信するSlackのテキスト var slackText = "@"+slname

お手数おかけしますが、
ご確認よろしくお願いいたします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/11/06 06:51

> 実現したいこと:K列が空白(=未対応)の場合、毎朝スラックに通知が飛ぶようにしたいです。 > 発生している問題・エラーメッセージ:スラックへのメンションができず、「@'スラックID'」とそのままの文字で出てしまいます。 記載の「実現したいこと」と「発生している問題」に齟齬があります。 結局「スラックへの通知はできているが、それがメンション扱いにならない」 ということが問題であるという理解でよろしいでしょうか? また、仮にこの場合、通知している部分を含めその他の部分に問題がある可能性が高いので、現状うまく動いていないコードと、正しく動作しているコード、どちらも通知している部分を含めて省略せず「全部」コードを記載してください。 (うまく動いていないコードと正しく動作しているコードが、本当に同じか比較する必要があるので、どちらも省略せず全部記載してください。プライバシーの観点から隠す必要がある部分は、全く同様の動作をするように簡略化したコードか、ダミーの文字列等に置き換えてください) コード記載する場合、コメントの続きに書かれるとインデントが失われて読みにくくなるので、必ず質問文を編集する形で記載してください。 また、前回の質問との絡みで、スプレッドシートからデータがきちんととれていないことが原因である可能性は排除されているという理解でよろしいでしょうか? たとえば、対象となるスラックIDを直接コードに書き込んだ上で、手で実行しても期待する動作にならない、ということを確認されたでしょうか?
guest

回答1

0

ベストアンサー

これで解決するかはわからないのですが、.getValue().getValues()の違いでしょうか?

質問者様の「該当のソースコード」

javascript

1var slname = sheet.getRange('H' + i).getValue()
質問者様の「試したこと」

javascript

1var slname = activeSheet.getRange(activeCell.getRow(), 8).getValues();

どちらかというと.getValues()の方が間違ってそうに見えるんですが…でもそちらの方は正常に動いてるんですよね?

GASからSlackのメンションをつける方法

GASでSlackのメンションをつけるためには、<@メンバーID>と書かないといけないらしいです。

javascript

1// 🚫 ただの文字になってしまうダメな例 2@Cocode 3@ABCDEFGHI 4 5// ✅ 正しいメンション方法 6<@ABCDEFGHI>
SlackメンバーIDの調べ方
  1. IDを調べたいメンバーのアイコンをクリック
  2. [...その他]というアイコンをクリック
  3. 出てきたメニューのなかにある[メンバーIDをコピー]をクリック
  4. ペーストすると、ABCDEFGHIのような文字列がでてくるので、<@ABCDEFGHI>とスプレッドシートに直接書いてしまったらいいと思います。

↓こんな感じ
イメージ説明

おまけのコード

↑のスクショの「Status」の列が空欄の行のみ、Slackで通知を送るようなコードをかきました。
ポイントとしては、GASとの通信回数を減らしているので処理が多少速いはずです。

javascript

1const SLACK_WEBHOOK_URL = '*****Webhook URLをここに入力*****'; 2 3function notifyUncompletedTaskToSlack() { 4 const sheet = SpreadsheetApp.getActiveSheet(); 5 const range = sheet.getRange(2, 1, sheet.getLastRow()-1, sheet.getLastColumn()); 6 const uncompletedTasks = range.getValues().filter(task => task[2].trim() === ''); 7 8 for (const task of uncompletedTasks) { 9 const [slackUserId, todo] = task; 10 let msg = slackUserId + '\n'; 11 msg += todo; 12 13 postSlack_(msg); 14 } 15} 16 17function postSlack_(message) { 18 const params = { 19 'method': 'POST', 20 'contentType': 'application/json', 21 'payload': JSON.stringify({'text': message}) 22 }; 23 24 const responce = UrlFetchApp.fetch(SLACK_WEBHOOK_URL, params); 25 Logger.log(responce); 26}

イメージ説明

C列やD列が何番目か

const uncompletedTasks = range.getValues() ←ここまでで全データが格納された2次元配列を生成しています。

javascript

1[ 2 [ '<@ABCDEFGHI>', 'Clean the bath room', 'done' ], 3 [ '@Cocode', 'Take the garbage out', '' ], 4 [ '<@ABCDEFGHI>', 'Buy bananas', 'done' ], 5 [ '<@ABCDEFGHI>', 'Send email', '' ] 6]

[ '<@ABCDEFGHI>', 'Clean the bath room', 'done' ]を例に見るとインデックス2番目の要素がC列です。
D列が存在する場合はインデックス3番目になるので、task[3]であっています。

私のコードの例の場合、取得してきた全データの中から、C列が空欄なものだけを.filter()で絞っています。

分割代入について

また分割代入という手法を使ってそれぞれの値を一括して変数に代入してやることができます。

例)

javascript

1const data = ['寺テイル', 30, 'male']; 2const [name, age, gender] = data; 3console.log(name); // '寺テイル' 4console.log(age); // 30 5console.log(gender); // 'male' が代入される

こんな感じです!

つまり、

javascript

1// ↓の部分は、 2const [slackUserId, todo] = task; 3 4// ↓例えばこうなってる 5const [slackUserId, todo] = [ '<@ABCDEFGHI>', 'Send email', '' ]; 6console.log(slackUserId); // '<@ABCDEFGHI>' 7console.log(todo); // 'Send email' 8// あまった '' は無視。どこにも代入されていない。

投稿2022/11/06 17:26

編集2022/11/08 09:24
Cocode

総合スコア2314

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

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

Tnatsu

2022/11/07 08:59

>どちらかというと.getValues()の方が間違ってそうに見えるんですが…でもそちらの方は正常に動いてるんですよね? はい、「試したこと」のGASは問題なく動いています。 また、 .getValue()➡.getValues() に変更してみましたが 同じくメンションができなかったです…
Cocode

2022/11/07 09:14 編集

スプレッドシートのスクショを貼っていただくことは可能ですか? 個人情報などはぼかすなり、ダミーの文字に変えていただいて大丈夫です。 こちらで不具合を再現してみたのち、再検討いたします。
Cocode

2022/11/07 17:58

GASからSlackでメンションする方法を更新しました。 「試したこと」のコードがどうして正常にメンション扱いになるのかは、提示されているコードのみでは判断が難しそうです。すみません。
Tnatsu

2022/11/08 08:32

親切にご教示いただきありがとうございます! 上記にて解決し、問題なくメンションされましたm ありがとうございます! また、追加でGASまで記載いただきありがとうございます。 私の勉強不足で大変恐縮ですが、 指定列を今のC列からD列にする際は、 const range = sheet.getRange(2, 1, sheet.getLastRow()-1, sheet.getLastColumn()); const uncompletedTasks = range.getValues().filter(task => task[2].trim() === ''); 上記の、「 task[2]」を「 task[3]」にすればいいでしょうか? 重ねてのご質問となり恐縮ですが、 ご教示いただけますと幸いです。
Cocode

2022/11/08 08:38

解決してよかったです〜! > 上記の、「 task[2]」を「 task[3]」にすればいいでしょうか? おっしゃる通りです!
Cocode

2022/11/08 09:24

解説を追加して回答を更新しました。お役に立てば幸いです。
Tnatsu

2022/11/08 10:43

ご丁寧にありがとうございます! 上記理解することができました! 教わった方法でやってみようと思います。 この度はありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問