🚀 ニフティ’s Notion

8-ex. GAS(発展)

ex. Slackワークフローから送信された内容をSlackに投稿する。

作るもの
  • 📄 2-ex. Slack(発展) で作成したスプレッドシートに以下のApps Scriptを作成する。
    • スプレッドシートが変更されたら、その内容と今日の運勢をSlackに投稿する。
    • スプレッドシートの内容をそのまま表示するのはワークフロー単体でもできるので、大吉~凶までのランダムな運勢も表示する。

(1) スプレッドシートにバインドされたスクリプトを作成
  • 📄 2-ex. Slack(発展) で作成したスプレッドシートを開く。
  • メニューから「拡張機能 > Apps Script」を選択。
    image block
  • 以下のソースコードをスクリプトエディタに張り付ける。
    function myFunction() {
      // バインド先のシートを取得(バインドされたスクリプトのみ使用可能なメソッド)。
      // ref. https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app?hl=ja#getActiveSheet()
      // ref. https://developers.google.com/apps-script/guides/bound?hl=ja#special_methods
      const sheet = SpreadsheetApp.getActiveSheet();
    
      // 最後の行の位置を取得
      // ref. https://developers.google.com/apps-script/reference/spreadsheet/sheet?hl=ja#getlastrow
      const lastRow = sheet.getLastRow();
      // 最後の列の位置を取得
      // ref. https://developers.google.com/apps-script/reference/spreadsheet/sheet?hl=ja#getlastcolumn
      const lastColumn = sheet.getLastColumn();
      // 最後の行の範囲を取得
      // ref. https://developers.google.com/apps-script/reference/spreadsheet/sheet?hl=ja#getrangerow,-column,-numrows,-numcolumns
      const range = sheet.getRange(lastRow, 1, 1, lastColumn);
      // 最後の行の値の矩形グリッド(2次元配列)を取得
      // ref. https://developers.google.com/apps-script/reference/spreadsheet/range?hl=ja#getvalues
      const value = range.getValues()[0];
    
      // 今日の運勢を取得
      const kujiList = ['大吉', '吉', '中吉', '小吉', '凶'];
      const kuji = kujiList[Math.floor(Math.random() * kujiList.length)];
    
      // Slackに投稿するメッセージの作成
      const name = value[0];
      const workplace = value[2];
      const todo = value[3];
      const message = `*【${name}】*
    *勤務場所 : *
    ${workplace}
    *やること : *
    ${todo}
    *今日の運勢 : *
    ${kuji}`;
    
      // Slackに投稿
      postMessage(message);
    }
    
    function postMessage(message){
      const data = {
        'text': message
      };
      const options = {
        'method' : 'post',
        'contentType': 'application/json',
        'payload' : JSON.stringify(data)
      };
      // Incoming WebhookのURLを指定
      const url = "<作成したIncoming Webhook>";
      // Incoming WebhookをPOSTで叩き、Slackにメッセージを投稿する。
      // ref. https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app?hl=ja#fetchurl,-params
      UrlFetchApp.fetch(url, options);
    }
    
    function createSpreadsheetChangeTrigger() {
      // 現在アクティブなスプレッドシートを取得
      // ref. https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app?hl=ja#getactive
      const ss = SpreadsheetApp.getActive();
    	// スプレッドシートを編集したときにmyFunctionを実行するトリガーを追加する。
      // ref. https://developers.google.com/apps-script/guides/triggers/installable?hl=ja#managing_triggers_programmatically
      // ref. https://developers.google.com/apps-script/reference/script/script-app?hl=ja#newtriggerfunctionname
      ScriptApp.newTrigger('myFunction')
          .forSpreadsheet(ss)
          .onChange()
          .create();
    }
  • 変数 url の値を作成したIncoming WebhookのURLに書き換える。
  • 実行ボタンを押す。実行時に権限の承認が必要なので承認する。
  • 実行すると、 📄 2-ex. Slack(発展) にてSlackワークフローから送信した内容が、Slackチャンネルに投稿される。
    image block
    image block
    image block
(2) Slackワークフローを送信すると、Slack投稿されるようにする。
  • createSpreadsheetChangeTrigger を実行する関数に選択し、実行する。権限を要求される場合は承認する。
    image block
  • 左のメニュー「トリガー」で新しくトリガーが作成されていることが確認できる。
    image block
  • 🚫 Post not found で作成したSlackワークフローから回答を送信すると、
    回答内容と今日の運勢がSlackチャンネルに通知される。
    image block
    image block

さらに時間が余った人向け

Block Kit
  • インタラクティブなUI(良い感じの見た目のSlackメッセージ)を構築するSlackアプリ用のフレームワーク
    image block
  • JSONで記述する。
    ↑の投稿のJSON
    {
    	"blocks": [
    		{
    			"type": "section",
    			"text": {
    				"type": "mrkdwn",
    				"text": "Hello, Assistant to the Regional Manager Dwight! *Michael Scott* wants to know where you'd like to take the Paper Company investors to dinner tonight.\n\n *Please select a restaurant:*"
    			}
    		},
    		{
    			"type": "divider"
    		},
    		{
    			"type": "section",
    			"text": {
    				"type": "mrkdwn",
    				"text": "*Farmhouse Thai Cuisine*\n:star::star::star::star: 1528 reviews\n They do have some vegan options, like the roti and curry, plus they have a ton of salad stuff and noodles can be ordered without meat!! They have something for everyone here"
    			},
    			"accessory": {
    				"type": "image",
    				"image_url": "https://s3-media3.fl.yelpcdn.com/bphoto/c7ed05m9lC2EmA3Aruue7A/o.jpg",
    				"alt_text": "alt text for image"
    			}
    		},
    		{
    			"type": "section",
    			"text": {
    				"type": "mrkdwn",
    				"text": "*Kin Khao*\n:star::star::star::star: 1638 reviews\n The sticky rice also goes wonderfully with the caramelized pork belly, which is absolutely melt-in-your-mouth and so soft."
    			},
    			"accessory": {
    				"type": "image",
    				"image_url": "https://s3-media2.fl.yelpcdn.com/bphoto/korel-1YjNtFtJlMTaC26A/o.jpg",
    				"alt_text": "alt text for image"
    			}
    		},
    		{
    			"type": "section",
    			"text": {
    				"type": "mrkdwn",
    				"text": "*Ler Ros*\n:star::star::star::star: 2082 reviews\n I would really recommend the  Yum Koh Moo Yang - Spicy lime dressing and roasted quick marinated pork shoulder, basil leaves, chili & rice powder."
    			},
    			"accessory": {
    				"type": "image",
    				"image_url": "https://s3-media2.fl.yelpcdn.com/bphoto/DawwNigKJ2ckPeDeDM7jAg/o.jpg",
    				"alt_text": "alt text for image"
    			}
    		},
    		{
    			"type": "divider"
    		},
    		{
    			"type": "actions",
    			"elements": [
    				{
    					"type": "button",
    					"text": {
    						"type": "plain_text",
    						"text": "Farmhouse",
    						"emoji": true
    					},
    					"value": "click_me_123"
    				},
    				{
    					"type": "button",
    					"text": {
    						"type": "plain_text",
    						"text": "Kin Khao",
    						"emoji": true
    					},
    					"value": "click_me_123",
    					"url": "https://google.com"
    				},
    				{
    					"type": "button",
    					"text": {
    						"type": "plain_text",
    						"text": "Ler Ros",
    						"emoji": true
    					},
    					"value": "click_me_123",
    					"url": "https://google.com"
    				}
    			]
    		}
    	]
    }
  • Block Kit Builderを使うことで、簡単に作ることができる。
おまけ演習
  • Block Kit Builderで作った見た目のメッセージをIncoming WebhookでSlackに投稿する。
  • Block Kitで自由に見た目を作る。
    image block
  • 右上のSend to Slackボタンを押すと、自分のアカウントでチャンネルに投稿できる。
    image block
    image block
書き換え例
function myFunction() {
  // バインド先のシートを取得(バインドされたスクリプトのみ使用可能なメソッド)。
  // ref. https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app?hl=ja#getActiveSheet()
  // ref. https://developers.google.com/apps-script/guides/bound?hl=ja#special_methods
  const sheet = SpreadsheetApp.getActiveSheet();

  // 最後の行の位置を取得
  // ref. https://developers.google.com/apps-script/reference/spreadsheet/sheet?hl=ja#getlastrow
  const lastRow = sheet.getLastRow();
  // 最後の列の位置を取得
  // ref. https://developers.google.com/apps-script/reference/spreadsheet/sheet?hl=ja#getlastcolumn
  const lastColumn = sheet.getLastColumn();
  // 最後の行の範囲を取得
  // ref. https://developers.google.com/apps-script/reference/spreadsheet/sheet?hl=ja#getrangerow,-column,-numrows,-numcolumns
  const range = sheet.getRange(lastRow, 1, 1, lastColumn);
  // 最後の行の値の矩形グリッド(2次元配列)を取得
  // ref. https://developers.google.com/apps-script/reference/spreadsheet/range?hl=ja#getvalues
  const value = range.getValues()[0];

  // 今日の運勢を取得
  const kujiList = ['大吉', '吉', '中吉', '小吉', '凶'];
  const kuji = kujiList[Math.floor(Math.random() * kujiList.length)];

  // Slackに投稿するメッセージの作成
  const name = value[0];
  const workplace = value[2];
  const todo = value[3];
  const data = {
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": name,
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*勤務地*\n" + workplace
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*やること*\n" + todo
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*今日の運勢*\n" + kuji
        }
      }
    ]
  };

  // Slackに投稿
  postMessage(data);
}

function postMessage(data){
  const options = {
    'method' : 'post',
    'contentType': 'application/json',
    'payload' : JSON.stringify(data)
  };
  // Incoming WebhookのURLを指定
  const url = "<作成したIncoming Webhook>";
  // Incoming WebhookをPOSTで叩き、Slackにメッセージを投稿する。
  // ref. https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app?hl=ja#fetchurl,-params
  UrlFetchApp.fetch(url, options);
}

function createSpreadsheetChangeTrigger() {
  // 現在アクティブなスプレッドシートを取得
  // ref. https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app?hl=ja#getactive
  const ss = SpreadsheetApp.getActive();
	// スプレッドシートを編集したときにmyFunctionを実行するトリガーを追加する。
  // ref. https://developers.google.com/apps-script/guides/triggers/installable?hl=ja#managing_triggers_programmatically
  // ref. https://developers.google.com/apps-script/reference/script/script-app?hl=ja#newtriggerfunctionname
  ScriptApp.newTrigger('myFunction')
      .forSpreadsheet(ss)
      .onChange()
      .create();
}
  • Slackワークフローから回答を送信すると、回答内容と今日の運勢が #alrt_emtg_productivity2023 に通知される。
    image block
    image block