【GAS】#3 NewsAPI.orgからデータを取得し、Slackへ通知する

1. 概要

News API to Slack

本記事では「API連携」による通知について解説します。

2. SlackからWebHook URLを取得

2-1. Slackから「Add apps」をクリック

2-2. 「Incoming WebHooks」を検索し、「Add」ボタンをクリック

2-3. 「Add to Slack」をクリック

2-4. 「通知するチャンネルを選択」し、「Add Incoming WebHooks integration」ボタンをクリック後、「WebHook URL」(*6-3)を取得

  • 「https://hooks.slack.com/services/~」

3. NewsAPIとは

3-1. APIを通して世界中のニュースを取得する事ができるサービス

3-2. 「API Key」を取得する必要がある

  • 登録は無料だが、ビジネス以上で使う場合は有料となる
  • 「Get API Key」

3-3. 現在選択できるカテゴリは下記となる

  • business
  • entertainment
  • general
  • health
  • science
  • sports
  • technology

https://newsapi.org/docs/endpoints/top-headlines

4. サンプルコード

4-1. ファイル構成(GitHubで管理

  • notification/slack/newsapi_to_slack.gs
    • メインコード
  • notification/slack/gas_properties.gsheet
    • 「WebHook URL」を含め、コード内に書かない方が良いデータ(ID、PASSWORD、KEY等)をプロパティとして保存

4-2. スプレッドシートIDの取得

4-3. GAS Editorの開け方

※「+新規」をクリック

4-4. コード & 解説

※複数のプログラムよりプロパティファイルを共有する為、敢えてスタンドアロン型(*6-2)を採用する

// SlackのWebHook URLが記載されているスプレッドシートのID
const bookId = '1j2z-S●●●●●●●●●●●●●●●●●●●●●●●●●●●●cQk';
// Slackへ通知する際の名前
const username = 'Notification';

// Mainメソッド
// NewsAPI.orgからデータを取得し、Slackへ通知
const notifySlack = () => {
  // 対象日を取得
  const from = formatDt(new Date(), false);
  // カテゴリを取得
  const categories = getValueOfProperty('F4');

  categories.split(',').map((category) => {
    fetchAndSend(from, category);
  });
}

// カテゴリ毎にニュースの取得やSlackへ通知
const fetchAndSend = (from, category) => {
  const news = fetchNews(from, category);

  if (news.status != 'ok') {
    return;
  }

  let newsInfo = [];

  news.articles.forEach((article) => {
    newsInfo.push(`【タイトル】${article.title}\n【日時】${formatDt(new Date(article.publishedAt), true)}\n【URL】${article.url}\n【IMAGE】${article.urlToImage}`);
  });
  sendToSlack(newsInfo);
}

// NewsAPI.orgからデータを取得
const fetchNews = (from, category) => {
  // データを取得するターゲットとなるURLをパラメータ付きで取得
  const targetUrl = getTargetUrl(from, category);
  // APIの呼び出し(データ取得)
  const data = UrlFetchApp.fetch(targetUrl).getContentText();
  return JSON.parse(data);
}

// 指定のスプレッドシートに記載されているプロパティの値を取得
const getValueOfProperty = (cell) => {
  const sheet = SpreadsheetApp.openById(bookId).getSheetByName('Properties');
  return sheet.getRange(cell).getValue();
}

// NewsAPI.orgにリクエストするURL
const getTargetUrl = (from, category) => {
  // API Keyを取得
  const apiKey = getValueOfProperty('E4');
  // ソートキーを取得
  const sortBy = getValueOfProperty('G4');
  // フェッチするデータ数を取得
  const pageSize = getValueOfProperty('H4');
  const params = `?country=jp&sortBy=${sortBy}&pageSize=${pageSize}&apiKey=${apiKey}&from=${from}&category=${category}`;
  return `https://newsapi.org/v2/top-headlines${params}`;
}

// 日時を読みやすく整形
const formatDt = (dt, isIncludedTime) => {
  if (isIncludedTime == true) {
      return `${dt.getFullYear()}/${dt.getMonth() + 1}/${dt.getDate()} ${dt.getHours()}:${dt.getMinutes()}:${dt.getSeconds()}`;
  } else {
      return `${dt.getFullYear()}-${dt.getMonth() + 1}-${dt.getDate()}`;
  }
}

// 配列に格納されている分を回しながら、Slackへ通知
const sendToSlack = (msgs) => {
  const webhookUrl = getValueOfProperty('C4');

  msgs.forEach((msg) => {
    // 通知する内容
    const param = {
      'username': username,
      'text': msg
    };
    // paramをJSON文字列に変換
    const payload = JSON.stringify(param);
    // APIを叩くにあたってどのような仕様で通信を行うか、どのような情報を送るかを指定
    const options = {
      'method': 'post',
      'headers': {
        'Content-Type': 'application/json'
      },
      'payload': payload
    };
    // APIの呼び出し(ここで実際に通知される)
    UrlFetchApp.fetch(webhookUrl, options);
  });
}

5. 実行結果例

6. 参考

6-1. GAS(Google Apps Script)とは

6-2. 2種類の方式

6-3. Webhookとは

6-4. 「UrlFetchApp.fetch()」について

関連記事

  1. 【GAS】#7 GoogleForms入力からスプレッドシートへ記載と…

  2. 【GAS】#4 OCRにて画像からテキストを起こし、Lineへ通知する…

  3. 【GAS】#5 LINE(リッチメニュー)とスプレッドシートを利用し、…

  4. 【GAS】#11 Twitterの話題を検索し、スプレッドシートに記載…

  5. 【GAS】#1 Gmailに届いた新着メールをSlackに通知する

  6. 【GAS】#10 ウェブアプリのフォーム入力からスプレッドシートへ記載…