Jelajahi Sumber

Add discord support to english bot.

Oleksandr Korniienko 3 tahun lalu
induk
melakukan
cd76e34cd0

+ 3 - 1
community-contributions/joystream-scoring-period-bot/package.json

@@ -13,10 +13,12 @@
         "pm2ru": "tsc && pm2 start dist/bot-ru.js -n bot-ru"
     },
     "dependencies": {
+        "@joystream/types": "^0.16.1",
         "@types/express": "^4.17.13",
         "@types/node": "^16.4.2",
         "axios": "^0.21.1",
         "cors": "^2.8.5",
+        "discord.js": "^13.1.0",
         "dotenv": "^10.0.0",
         "express": "^4.17.1",
         "fs": "^0.0.1-security",
@@ -32,4 +34,4 @@
         "@types/node-telegram-bot-api": "^0.51.4",
         "ts-node": "^10.1.0"
     }
-}
+}

+ 105 - 50
community-contributions/joystream-scoring-period-bot/src/bot-en.ts

@@ -2,19 +2,7 @@ import TelegramBot, { SendMessageOptions } from "node-telegram-bot-api";
 import * as dotenv from "dotenv";
 import axios from "axios";
 import moment from "moment";
-
-dotenv.config();
-
-const tgApiKey = process.env.TG_API_KEY_EN || "";
-const bot = new TelegramBot(tgApiKey, { polling: true });
-moment.locale("en");
-
-const loadScoringPeriodData = async () => {
-  const url =
-    "https://raw.githubusercontent.com/Joystream/founding-members/main/data/fm-info.json";
-  const { data } = await axios.get(url);
-  return data.scoringPeriodsFull;
-};
+import { Client, Intents, Options } from "discord.js";
 
 interface ScoringPeriodData {
   currentScoringPeriod: {
@@ -34,17 +22,61 @@ interface ScoringPeriodData {
   };
 }
 
+dotenv.config();
+
+const tgApiKey = process.env.TG_API_KEY_EN || "";
+const bot = new TelegramBot(tgApiKey, { polling: true });
+const discordToken = process.env.DISCORD_TOKEN || "";
+const clientOptions = Options.createDefault();
+clientOptions.intents = [
+  Intents.FLAGS.GUILDS,
+  Intents.FLAGS.GUILD_MESSAGES,
+  Intents.FLAGS.DIRECT_MESSAGES,
+];
+const client = new Client(clientOptions);
+
 let nextSyncDate = moment();
 let scoringData = {} as ScoringPeriodData;
 let lastGradedPeriod = null as number | null;
 const messageDeletionTimeout = 30000; // 30 seconds
 
-bot.on("message", async (msg: TelegramBot.Message) => {
-  if (nextSyncDate.isBefore(moment())) {
-    scoringData = await loadScoringPeriodData();
-    lastGradedPeriod = scoringData.lastPeriod.scoringPeriodId;
-    nextSyncDate = moment.parseZone(scoringData.currentScoringPeriod.ends);
+client.login(discordToken);
+client.on("ready", async () => {
+  if (!client.user) return;
+  console.log(`Logged in to discord as ${client.user.tag}!`);
+});
+
+moment.locale("en");
+
+const loadScoringPeriodData = async () => {
+  const url =
+    "https://raw.githubusercontent.com/Joystream/founding-members/main/data/fm-info.json";
+  const { data } = await axios.get(url);
+  return data.scoringPeriodsFull;
+};
+
+client.on("message", async (message) => {
+  await reloadScoringData();
+  if (message.content === "!scoring") {
+    const leaderboardLink = `\nCheck scores here: https://t.me/JoystreamLeaderboardBot\nSubmit your report here: https://www.joystream.org/founding-members/form`;
+    const submitReportLink = "submit your report";
+    const messageContent = generateScoringPeriodMessage(
+      message.author.username,
+      submitReportLink,
+      leaderboardLink
+    );
+    message.channel.send({content: messageContent}).then( msg => {
+      msg.suppressEmbeds(true)
+      message.delete()
+      setTimeout(() => {
+        msg.delete()  
+      }, messageDeletionTimeout)
+    });
   }
+});
+
+bot.on("message", async (msg: TelegramBot.Message) => {
+  await reloadScoringData();
   if (msg && msg.from) {
     console.log(msg.chat);
     const chatId = msg.chat.id;
@@ -53,41 +85,19 @@ bot.on("message", async (msg: TelegramBot.Message) => {
     }`.trim();
 
     const userParsed = `[${username}](tg://user?id=${msg.from.id})`;
-    const leaderboardLink = `[Check scores](https://t.me/JoystreamLeaderboardBot)`;
-    const options: SendMessageOptions = { parse_mode: "Markdown", disable_web_page_preview: true };
+    const leaderboardLink = ` - [Check scores](https://t.me/JoystreamLeaderboardBot)`;
+    const options: SendMessageOptions = {
+      parse_mode: "Markdown",
+      disable_web_page_preview: true,
+    };
 
     if (msg.text?.startsWith("/scoring")) {
-      const startDate = moment.parseZone(
-        scoringData.currentScoringPeriod.started
+      const submitReportLink = "[submit your report](https://www.joystream.org/founding-members/form)";
+      const messageContent = generateScoringPeriodMessage(
+        userParsed,
+        submitReportLink,
+        leaderboardLink
       );
-      const endDate = moment.parseZone(scoringData.currentScoringPeriod.ends);
-      const duration = moment.duration(endDate.diff(moment()));
-      const daysDuration = duration.asDays().toFixed();
-      let dayText = "days";
-      if (daysDuration === "1") {
-        dayText = "day";
-      }
-      const daysLeft = `***${duration
-        .asDays()
-        .toFixed()} ${dayText} on ${endDate.format(
-        "dddd DD MMM"
-      )} at ${endDate.format("HH:mm")}***`;
-      const deadline = endDate.add(5, "d").format("dddd DD MMM HH:mm");
-      const prevDeadline = startDate.add(5, "d").format("dddd DD MMM HH:mm");
-      const hello = `Hello ${userParsed}!\n`;
-      const currentPeriodId = scoringData.currentScoringPeriod.scoringPeriodId;
-      const prevPeriodId = scoringData.currentScoringPeriod.scoringPeriodId - 1;
-      const currentScoring = `The current scoring period ***#${currentPeriodId}*** ends in ${daysLeft}\n`;
-      const currentDeadline = `Please make sure to [submit your report](https://www.joystream.org/founding-members/form) for period ***#${currentPeriodId}*** before the deadline ***${deadline}***\n`;
-      const isLastScoringClosed = endDate
-        .add(5, "d")
-        .subtract(2, "w")
-        .isAfter(moment());
-      const previousPeriodDeadline = isLastScoringClosed
-        ? `Reports for the previous period ***#${prevPeriodId}*** are closed\n`
-        : `Reports for the previous period ***#${prevPeriodId}*** can be submitted before ***${prevDeadline}***\n`;
-      const latestGradedPeriod = `Latest graded period - ***#${lastGradedPeriod}*** - ${leaderboardLink}`;
-      const messageContent = `${hello}${currentScoring}${currentDeadline}${previousPeriodDeadline}${latestGradedPeriod}`;
       bot.sendMessage(chatId, messageContent, options).then((message) => {
         try {
           bot.deleteMessage(chatId, msg.message_id.toString());
@@ -101,3 +111,48 @@ bot.on("message", async (msg: TelegramBot.Message) => {
     }
   }
 });
+
+const generateScoringPeriodMessage = (
+  userParsed: string,
+  submitReportLink: string,
+  leaderboardLink: string
+) => {
+  const startDate = moment.parseZone(scoringData.currentScoringPeriod.started);
+  const endDate = moment.parseZone(scoringData.currentScoringPeriod.ends);
+  const duration = moment.duration(endDate.diff(moment()));
+  const daysDuration = duration.asDays().toFixed();
+  let dayText = "days";
+  if (daysDuration === "1") {
+    dayText = "day";
+  }
+  const daysLeft = `***${duration
+    .asDays()
+    .toFixed()} ${dayText} on ${endDate.format(
+    "dddd DD MMM"
+  )} at ${endDate.format("HH:mm")}***`;
+  const deadline = endDate.add(5, "d").format("dddd DD MMM HH:mm");
+  const prevDeadline = startDate.add(5, "d").format("dddd DD MMM HH:mm");
+  const hello = `Hello ${userParsed}!\n`;
+  const currentPeriodId = scoringData.currentScoringPeriod.scoringPeriodId;
+  const prevPeriodId = scoringData.currentScoringPeriod.scoringPeriodId - 1;
+  const currentScoring = `The current scoring period ***#${currentPeriodId}*** ends in ${daysLeft}\n`;
+  const currentDeadline = `Please make sure to ${submitReportLink} for period ***#${currentPeriodId}*** before the deadline ***${deadline}***\n`;
+  const isLastScoringClosed = endDate
+    .add(5, "d")
+    .subtract(2, "w")
+    .isAfter(moment());
+  const previousPeriodDeadline = isLastScoringClosed
+    ? `Reports for the previous period ***#${prevPeriodId}*** are closed\n`
+    : `Reports for the previous period ***#${prevPeriodId}*** can be submitted before ***${prevDeadline}***\n`;
+  const latestGradedPeriod = `Latest graded period - ***#${lastGradedPeriod}***${leaderboardLink}`;
+  const messageContent = `${hello}${currentScoring}${currentDeadline}${previousPeriodDeadline}${latestGradedPeriod}`;
+  return messageContent;
+};
+async function reloadScoringData() {
+  if (nextSyncDate.isBefore(moment())) {
+    scoringData = await loadScoringPeriodData();
+    lastGradedPeriod = scoringData.lastPeriod.scoringPeriodId;
+    nextSyncDate = moment.parseZone(scoringData.currentScoringPeriod.ends);
+  }
+}
+

File diff ditekan karena terlalu besar
+ 677 - 6
community-contributions/joystream-scoring-period-bot/yarn.lock


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini