見出し画像

SlackにGASを使ってグラフを自動投稿をする方法

最近 ハマっているマンガは「デッドマウント・デスプレイ」と「魔術師クノンは見えている」です。プロダクトマネージャーで大切なことは、すべてサメ映画が教えてくれるのかもしれない。

この記事は REALITY Advent Calendar 2023 の12日目となります。

プロダクトマネージャーは様々なKPIを追いますよね。クエリを書いて個々に出したり、重要な指標はDashboardをつくったりもすると思います。特に関わる人が増えてくると、ひと手間加えてグラフにしたりもすると思います。
・毎回クエリを書きたくない!
・Slackでbotのように毎朝教えてほしい!
・グラフとかでわかりやすく伝えたい!
そんなあなたにおすすめな方法を紹介します。


この記事でできること

実際の数値、地域は虚構です。地域は僕が旅行したことがある地域から選びました。

こんな感じで、指定した時刻にSlackへBigQueryの結果を元にグラフにして投稿してくれます。
PMの代わりに!!!素敵!

全体像

「クエリの集計結果をスプレッドシートにして、スプレッドシート上でグラフを作って、その画像をSlackに投稿する」を、GASさんにやってもらう。

今回試したのは、主に下半分。GASとやらに作業を代行してもらう。という文です。
まずは 比較的PMなら出来そうな GASさんを抜きにした、上の部分から順番に説明します。

1.BigQueryとスプレッドシートの連携

上記の記事の [1.BigQueryとスプレッドシートの連携] と同じ内容なので簡易的に説明しますが…
1.日付毎に XX が集計されるクエリを書く
2.スプレッドシートの「データコネクタ」にクエリをいれる

こんな成果物がスプレッドシート上に現れればokです。※繰り返しますが、数値は適当に入れてます。実際とは異なります。

2.スプレッドシートからグラフをつくる

人間がやる場合は…ここは 「グラフの作成」を押すくらいです。

3.GASを使って色々動かす

さて、いよいよGAS(Google Apps Script)さんに、作業をしてもらうときがきました。
ざっくり言うと、これまでの 1~2 を人間の代わりにやってもらう必要があります。

大事なのは、「何をやってほしいか?」を明文化することです。
もし上記の1~2を、誰かに依頼する時 どう説明するか?

人間相手でも、この依頼はどうかと思う内容ですね。

ちゃんとテキストにすると…

  1. このスプレッドシートのURLを開いてください

  2. 開いたら「データの更新」を押してください

  3. スプレッドシートの「タブ1」を開いてください

  4. A1からF30の数値を見てください

  5. 下記の指示に従って、グラフにしてください

    1. グラフは「積み上げ棒グラフ」にしてください

    2. 行1を見出しに

    3. 列Aは日数なので横軸に

    4. A2からF30を値にしてください

  6. 出来たグラフを画像にして、XXX のSlackチャンネルに投稿してください

  7. この作業は、毎朝 9時30分に実施してください

こんな感じかと思います。
これらを、GASにしっかり依頼する必要があるわけです。


まず、この Apps Script というのを開きます。
このコードを書く場所に、上記の依頼を書いていきます。
function main() {

  // スプレッドシート xxxxxxx を開く
  let spreadsheet = SpreadsheetApp.openById('スプレッドシートのIDを記載する箇所');


  // スプレッドシート コネクテッドシートを更新する  
  SpreadsheetApp.enableBigQueryExecution();
  spreadsheet.getDataSources()[0].refreshAllLinkedDataSourceObjects();
  spreadsheet.getDataSources()[0].waitForAllDataExecutionsCompletion(300);


  // スプレッドシート xxxxxxx の シート1 を開く
  let sheet = spreadsheet.getSheets()[0];

  // A1セルからラベルを取得
  let labelsRange = sheet.getRange('A1:F1');
  let labels = labelsRange.getValues()[0];

  // 新しいグラフを作成する
  let chartBuilder = sheet.newChart()
      .setChartType(Charts.ChartType.COMBO) // BarStacked  が 積層横棒タイプ らしい
      .setOption('isStacked', 'true') 
      .addRange(sheet.getRange('A2:A32')) // 月初~月末
      .addRange(sheet.getRange('B2:B32')) // 月初~月末 1地域目
      .addRange(sheet.getRange('C2:C32')) // 月初~月末 2地域目
      .addRange(sheet.getRange('D2:D32')) // 月初~月末 3地域目
      .addRange(sheet.getRange('E2:E32')) // 月初~月末 4地域目
      .addRange(sheet.getRange('F2:F32')) // 月初~月末 5地域目
      .setOption('legend.position', 'top') // 凡例を画像の上部に配置
      .setOption('vAxis.format', '#,###') // 数値形式を指定(カンマ区切り)
      .setOption('title','世界各国の今月の いいねをグラフにする') // グラフタイトル
      .setOption('series', [
        { labelInLegend: labels[0], type: 'bars' },
        { labelInLegend: labels[1], type: 'bars' },
        { labelInLegend: labels[2], type: 'bars' },
        { labelInLegend: labels[3], type: 'bars' },
        { labelInLegend: labels[4], type: 'bars' },
        ])
      .setPosition(5, 5, 0, 0); 

  // グラフを指定したslackに投稿してください
    var url = "https://slack.com/api/files.upload";
    var postData = {
        'as_user': true,
        'channels': 'xxxxxxxxx', //SlackのチャンネルIDをいれる
        'token': "xxxxxxxx",  //Slackのトークンをいれる
        'file' : chartBuilder.build().getAs('image/png'),
    };
    var options = {
        "method": "POST",
        "payload": postData
    };
    UrlFetchApp.fetch(url, options);
}

こんな感じのコードを書きます。
先程の 1~6がそれぞれ書いてあります。

7.この作業は、毎朝 9時30分に実施してください

Apps Script の トリガーから定期実行などを決めます


3.自動で投稿される!

わーい!

4.余談

最近、AIの進化がすごいですよねー
今回のコードとかも、結構AIさんに助けてもらいました。
この記事の途中で、こんな頼み方はだめですね!と書きましたが…

もしかしたら、数年後には ふわっとした依頼でもAIが実現してくれるのかもしれない…そう思うくらいには、実際にAIの理解度が高いな、と感じました。
いくつか例を書こうと思います。

Q.棒グラフごとに、凡例を追加したいです
A.Google Apps Scriptを使用して、棒グラフごとに凡例を追加するには、データシリーズごとに凡例情報を設定する必要があります。以下は、棒グラフごとに凡例を追加するコードの例です。
Q.生成された画像内における、縦棒グラフの描画エリアの横幅を0.8倍にしたいです
A.生成された画像内における縦棒グラフの描画エリアの横幅を0.8倍にするには、Google Apps Scriptのチャートオプションを使用して、チャートの描画エリアの横幅を調整する必要があります。以下は、その方法の一例です。

それまでに聞いた内容、伝えた内容を加味して教えてくれるの…本当にすごいですね。

5.明日のアドベントカレンダーは?

明日は・・・なんと!!!ぜひチェックしてください!