見出し画像

Noteの通知をDiscordに送る方法

Noteに記事が追加されると自動でDiscordに通知を送りたいと思いました。
備忘録として作成しましたので、所々端折っています


流れ

  1. NoteのRSSを取得

  2. GASでRSSフィードする

  3. Discordに通知を送る

1NoteのRSSを取得

RSSとは
Rich Site Summary
でサイトの配信の情報のフォーマットです
こちらを使って通知を受け取ります

まず、通知したいクリエイターのページにいきます
Finなら以下です
https://note.com/fin_agetech 

そして、メニューボタンを押します
すると、RSSの項目があるのでクリックします

上記のXMLのリンクをコピーします
finの場合は以下でした
https://note.com/fin_agetech/rss 
おそらく以下のフォーマットになるようです
https://note.com/<creater-name>/rss 

2GASでRSSフィードする

GASでRSSをフィードします。
そのためまずDiscordで通知を送りたいチャンネルのWebhookのURLを取得します

次に、Google SpreadSheetを新規作成します
シート名をfeeds, articlesとします
feedsには、任意のタグ名と1.NoteのRSSを取得で取得したRSSのURLをペーストします


そして拡張機能よりGASを選択します
コードは以下のものコピペします
WEBHOOK_URLはDiscordで取得したwebhookのものと取り替えます

const WEBHOOK_URL = "https://discord.com/api/webhooks/.......";

/**
 * スプレッドシートから指定されたシート名のデータを取得
 */
function getSheetData(sheetName, range) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  if (!sheet) throw new Error(`Sheet ${sheetName} not found`);
  return sheet.getRange(range).getValues();
}

/**
 * フィード定義を取得
 */
function getFeeds() {
  const values = getSheetData('feeds', 'A1:B');
  return values.map(([name, link]) => ({ name, link }));
}

/**
 * RSSフィードから記事を取得し、処理する
 */
function getArticles() {
  const feeds = getFeeds();
  feeds.forEach(processFeed);
}

/**
 * 各フィードの記事を処理する
 */
function processFeed(feed) {
  const xml = UrlFetchApp.fetch(feed.link).getContentText();
  const document = XmlService.parse(xml);
  const items = document.getRootElement().getChild('channel').getChildren('item');

  // 逆順に処理
  items.reverse().forEach(item => processItem(feed, item));
}

/**
 * 各アイテム(記事)を処理する
 */
function processItem(feed, item) {
  const title = item.getChild('title').getText();
  const link = item.getChild('link').getValue();
  const pubDate = Utilities.formatDate(new Date(item.getChild('pubDate').getValue()), "JST", "yyyy-MM-dd'T'HH:mm:ssXXX");

  if (isNewArticle(link)) {
    postToChannel(feed.name, title, link);
    saveArticle(feed.name, title, link, pubDate);
  }
}

/**
 * 記事が新しいものかどうかを確認
 */
function isNewArticle(link) {
  const articles = getSheetData('articles', 'C1:C');
  return !articles.flat().includes(link);
}

/**
 * 記事をスプレッドシートに保存
 */
function saveArticle(name, title, link, pubDate) {
  const articlesSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('articles');
  articlesSheet.appendRow([name, title, link, pubDate]);
}

/**
 * チャンネルに通知を投稿する
 */
function postToChannel(name, title, link) {
  
  const message = {
    "content": '`' + name + '`\n' + '**' + title + '**' + '\n' + link
  };
  
  const param = {
    "method": "POST",
    "headers": { 'Content-type': "application/json" },
    "payload": JSON.stringify(message)
  };
  
  UrlFetchApp.fetch(WEBHOOK_URL, param);
}

3Discordに通知を送る

getArticlesを実行します
成功するとDidcordにこれまでnoteの記事が送信されます

そして時間をトリガーにして定期実行させました

余談
GASには実行時間の上限があるようです
適切に時間は指定した方がいいみたいです(当たり前)

参考

https://note.com/taatn0te/n/nacada2f4dfd2 

この記事が気に入ったらサポートをしてみませんか?