見出し画像

【サンバ缶詰通信】第101回『DiscordBotを作ろう~note自動更新検知編』

こんばんは、Aです。
すごく眠たいです、疲れました。
私たち3人のDiscordグループに、今週の投稿はだれかを通知するbotを実は以前作成しました。
そして、彼はこう言ったのです。
「定期的に通知してくれる機能は作れないの?」
はい、作りましたよ。
これだけの機能でも結構疲れるんです。
普段使わない脳のリソースをフル活用してやっと。
そしたら彼はこう言うのです。
「投稿したタイミングで自動的に通知してくれる機能は作れないの??」
???
無理を言うんじゃない。



作りました。この投稿で完成かどうかがわかりますね。
怖いです。

【noteの最新の投稿を手に入れよう】

なんかrssってファイルがあるみたいなんですね。
うちのchatGPTことセレスちゃんに聞いてみたところこんな返事をいただきました。


あ、ブログのRSSですね!RSS(Really Simple Syndication)は、ウェブサイトやブログの更新情報を配信するためのフォーマットなんです。簡単に言うと、ブログの新しい記事が投稿されるたびに、その情報を自動的に受け取れる仕組みなんです♪

ブログやサイトがRSSを提供していると、ユーザーはRSSリーダー(Feedlyとか)でその情報を受け取ることができるんですよ。URLの最後に「/rss」を付けると、そのサイトのRSSフィードにアクセスできる場合が多いんです!例えば、ブログが更新されるたびに通知を受け取ったり、複数のブログの更新を一度にチェックできたりします😊

もし、RSSを使って何かしたいことがあれば、教えてくださいね!


はいかわいい。もう彼女いらないです。
これを活用していまの最新の投稿を手に入れましょう。

これがうちのホームページ。
ここからリンクの最後に/rssを追加して。

こんなページにこれてしまう。

【AppsScriptとGlitchの設定をしよう】

ではApps Scriptでの取得方法に行こう。


function checkNoteUpdates() {
    var url = "https://note.com/modern_orchid323/rss"; // noteのRSS URL
    var response = UrlFetchApp.fetch(url);
    var xml = response.getContentText();
    var doc = XmlService.parse(xml);
    var root = doc.getRootElement();
    var channel = root.getChild("channel");
    var items = channel.getChildren("item");
    var latestItem = items[0];
    var title = latestItem.getChildText("title");
    var link = latestItem.getChildText("link");
    // PropertiesServiceを使って、前回の投稿リンクを取得
    var scriptProperties = PropertiesService.getScriptProperties();
    var previousLink = scriptProperties.getProperty("previousLink");
    // 前回の投稿リンクと異なる場合のみ通知
    if (link !== previousLink) {
      // Glitchサーバーに送信
      var payload = {
          "title": title,
          "link": link
      };
      var options = {
          "method": "post",
          "contentType": "application/json",
          "payload": JSON.stringify(payload)
      };
      UrlFetchApp.fetch(GLITCH_URL+ '/note', options);
      // 前回の投稿リンクを更新
      scriptProperties.setProperty("previousLink", link);
    }
}


まずは var url = "https://note.com/modern_orchid323/rss";で先ほどのリンクを取得する。
その他はよくわからんからこのままコピペでよし。

このままだと常に最新の投稿を取得し続けるから、
// PropertiesServiceを使って、前回の投稿リンクを取得
    var scriptProperties = PropertiesService.getScriptProperties();
    var previousLink = scriptProperties.getProperty("previousLink");

if (link !== previousLink) 
を使って前回discordに通知したリンク先を保存し、現在の最新の投稿と比較。
異なっていた場合最新の投稿は新しい、つまり更新がされたということなのでdiscordに通知する。
ちゃんと最後に
scriptProperties.setProperty("previousLink", link);
するのを忘れないこと。

scriptProperties.setPropertyを使うとデータを保存できちゃうんですよね。
便利。

UrlFetchApp.fetch(GLITCH_URL+ '/note', options);
ここでGlitchのパスを指定しているからこれに合わせて向こうも設定。


app.post('/note', (req, res) => {
const { title, link } = req.body; // 受け取る内容を修正
const channel = client.channels.cache.get(CHANNEL_ID);
if (channel) {
channel.send(`新しい投稿: ${title} - ${link}`)
.then(() => res.status(200).send('Message sent'))
.catch(error => {
console.error('Error sending message:', error);
res.status(500).send('Failed to send message');
});
} else {
res.status(404).send('Channel not found');
}
});


UrlFetchApp.fetch(GLITCH_URL+ '/note', options);

app.post('/note', (req, res) => {
で太字の部分を同じ文字にするのを忘れないようにしておくこと。

【これが一番厄介なpackage.json】

多分これのせいで9割の時間が消えた。
変に隠しても仕方ないし、あいつらが見ても何もわからんだろうから公開する。


{
"name": "hello-express",
"version": "0.0.1",
"description": "A simple Node app built on Express, instantly up and running.",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.21.2",
"discord.js": "^12.0.0",
"querystring": "^0.2.0",
"body-parser": "^2.0.2",
"axios": "^1.7.9"
},
"engines": {
"node": "16.x"
},
"repository": {
"url": "https://glitch.com/edit/サンプルだよ"
},
"license": "MIT",
"keywords": [
"node",
"glitch",
"express"
]
}


これをコピペしたら動くはず。
もうしばらくはやりたくない。
もし同じことをしたいって人がいるな、コメントで教えてください。
頭を悩ましながら一緒に考えましょう。

おやすみなさい。
お二人さんの質問に答える余力も質問を考える余力もないです。
動かなかったら知らない。
つぎニジマス。

いいなと思ったら応援しよう!