Browse Source

Remove forum posting from automatic aggregator

ghorsington 3 years ago
parent
commit
d84e4bf612
2 changed files with 25 additions and 159 deletions
  1. 15 149
      bot/src/plugins/news_aggregator.ts
  2. 10 10
      bot/src/xenforo.ts

+ 15 - 149
bot/src/plugins/news_aggregator.ts

@@ -1,36 +1,28 @@
 import TurndownService from "turndown";
 import interval from "interval-promise";
-import { client, FORUMS_DOMAIN } from "../client";
+import { client } from "../client";
 import sha1 from "sha1";
 import * as path from "path";
 import * as fs from "fs";
 import { HTML2BBCode } from "html2bbcode";
-import { Dict } from "../util";
 import { IAggregator, NewsPostItem } from "./aggregators/aggregator";
-import { TextChannel, Message, Channel, ReactionCollector, MessageReaction, User, MessageEmbed } from "discord.js";
-import { getRepository, IsNull, Not } from "typeorm";
+import { TextChannel, Message, MessageEmbed } from "discord.js";
+import { getRepository, } from "typeorm";
 import { KnownChannel } from "@shared/db/entity/KnownChannel";
 import { AggroNewsItem } from "@shared/db/entity/AggroNewsItem";
-import { v3beta1 } from "@google-cloud/translate";
 import { logger } from "src/logging";
 import { Plugin } from "src/model/plugin";
-const { TranslationServiceClient } = v3beta1;
+import { assertOk, tryDo } from "src/util";
 
 const UPDATE_INTERVAL = process.env.NODE_ENV == "dev" ? 60 : 5;
-const MAX_PREVIEW_LENGTH = 300;
 const AGGREGATOR_MANAGER_CHANNEL = "aggregatorManager";
-const FORUMS_STAGING_ID = 54;
-const FORUMS_NEWS_ID = 49;
 
 @Plugin
 export class NewsAggregator {
-    tlClient = new TranslationServiceClient();
     aggregators: IAggregator[] = [];
     aggregateChannelID?: string;
     bbCodeParser = new HTML2BBCode();
     turndown = new TurndownService();
-    reactionCollectors: Dict<ReactionCollector> = {};
-    verifyMessageIdToPost: Dict<AggroNewsItem> = {};
 
     constructor() {
         this.turndown.addRule("image", {
@@ -68,13 +60,6 @@ export class NewsAggregator {
         }
     }
 
-    clipText(text: string): string {
-        if (text.length <= MAX_PREVIEW_LENGTH)
-            return text;
-
-        return `${text.substring(0, MAX_PREVIEW_LENGTH)}...`;
-    }
-
     async addNewsItem(item: NewsPostItem): Promise<void> {
         if (!this.aggregateChannelID)
             return;
@@ -112,108 +97,24 @@ export class NewsAggregator {
             });
         }
 
-        if (item.needsTranslation && process.env.GOOGLE_APP_ID)
-            try {
-                const request = {
-                    parent: this.tlClient.locationPath(process.env.GOOGLE_APP_ID, "global"),
-                    contents: [item.title, item.contents],
-                    mimeType: "text/html",
-                    sourceLanguageCode: "ja",
-                    targetLanguageCode: "en"
-                };
-
-                const [res] = await this.tlClient.translateText(request);
-                const [translatedTitle, translatedContents] = res.translations ?? [undefined, undefined];
-                
-                if (translatedTitle?.translatedText && translatedContents?.translatedText) {
-                    item.title = translatedTitle.translatedText;
-                    item.contents = translatedContents.translatedText;
-                }
-            } catch (err) {
-                logger.error("Failed to translate news with Google", err);
-            }
-
-        item.contents = this.bbCodeParser.feed(item.contents).toString();
-
-        if (!newsItem.forumsEditPostId) {
-            const createResponse = await client.forum.createThread(FORUMS_STAGING_ID, item.title, item.contents);
-            newsItem.forumsEditPostId = createResponse.thread.thread_id;
-        } else if(newsItem.forumsNewsPostId){
-            await client.forum.postReply(newsItem.forumsNewsPostId, item.contents);
-        }
-
-
-        const msg = await ch.send(new MessageEmbed({
-            title: item.title,
+        const msg = await assertOk(ch.send(new MessageEmbed({
+            title: `${(isNew ? "**[NEW]**" : "**[EDIT]**")} ${item.title}`,
             url: item.link,
             color: item.embedColor,
             timestamp: new Date(),
-            description: `${(isNew ? "**[NEW]**" : "**[EDIT]**")}\n[**Edit on forums**](${FORUMS_DOMAIN}/index.php?threads/.${newsItem.forumsEditPostId}/)`,
             author: {
                 name: item.author
             },
             footer: {
                 text: "NoctBot News Aggregator"
             }
-        })) as Message;
+        }))) as Message;
 
         newsItem.editMessageId = msg.id;
 
-        await msg.react("✅");
-        await msg.react("❌");
-
-        const collector = msg.createReactionCollector(this.isVerifyReaction, { maxEmojis: 1 });
-        collector.on("collect", this.collectorFor(collector));
-        this.reactionCollectors[msg.id] = collector;
-        this.verifyMessageIdToPost[msg.id] = newsItem;
-
         await repo.save(newsItem);
     }
 
-    isVerifyReaction(reaction: MessageReaction, user: User): boolean {
-        return (reaction.emoji.name == "✅" || reaction.emoji.name == "❌") && !user.bot && user.id != client.botUser.id;
-    }
-
-    collectorFor = (collector: ReactionCollector) =>
-        async (reaction: MessageReaction): Promise<void> => {
-            const repo = getRepository(AggroNewsItem);
-
-            const m = reaction.message;
-            collector.stop();
-            delete this.reactionCollectors[m.id];
-            const post = this.verifyMessageIdToPost[m.id];
-
-            if(!post.forumsEditPostId) {
-                throw new Error("No forum edit post found!");
-            }
-
-            if (reaction.emoji.name == "✅") {
-                const res = await client.forum.getThread(post.forumsEditPostId);
-                const forumPost = await client.forum.getPost(res.thread.first_post_id);
-
-                if (!post.forumsNewsPostId) {
-                    const newThread = await client.forum.createThread(FORUMS_NEWS_ID, res.thread.title, forumPost.message);
-                    post.forumsNewsPostId = newThread.thread.thread_id;
-                } else {
-                    const curThread = await client.forum.editThread(post.forumsNewsPostId, {
-                        title: res.thread.title
-                    });
-
-                    await client.forum.editPost(curThread.thread.first_post_id, {
-                        message: forumPost.message
-                    });
-                }
-            }
-
-            await client.forum.deleteThread(post.forumsEditPostId);
-            await repo.update({ newsId: post.newsId, feedName: post.feedName }, { 
-                editMessageId: undefined, 
-                forumsEditPostId: undefined, 
-                forumsNewsPostId: post.forumsNewsPostId });
-            await reaction.message.delete();
-            delete this.verifyMessageIdToPost[m.id];
-        };
-
     async deleteCacheMessage(messageId: string): Promise<void> {
         if(!this.aggregateChannelID)
             return;
@@ -221,20 +122,15 @@ export class NewsAggregator {
         if (!(ch instanceof TextChannel))
             return;
 
-        const msg = await this.tryFetchMessage(ch, messageId);
+        const msg = await tryDo(ch.messages.fetch(messageId));
 
-        if (msg)
-            await msg.delete();
-    }
-
-    async tryFetchMessage(channel: Channel, messageId: string): Promise<Message | null> {
-        try {
-            if (!(channel instanceof TextChannel))
-                return null;
-            return await channel.messages.fetch(messageId);
-        } catch (error) {
-            return null;
-        }
+        if (msg.ok) {
+            const deleteResult = await tryDo(msg.result.delete());
+            if (!deleteResult.ok)
+                logger.error("NewsAggregator: failed to delete message %s: %s", messageId, deleteResult.error);
+        } 
+        else
+            logger.error("NewsAggregator: failed to fetch messate %s: %s", this.aggregateChannelID, msg.error);
     }
 
     initAggregators(): void {
@@ -261,35 +157,6 @@ export class NewsAggregator {
         }
     }
 
-    async initPendingReactors(): Promise<void> {
-        if(!this.aggregateChannelID)
-            return;
-
-        const verifyChannel = client.bot.channels.resolve(this.aggregateChannelID);
-        if(!verifyChannel)
-            throw new Error("Couldn't find verify channel!");
-
-        const repo = getRepository(AggroNewsItem);
-
-        const pendingVerifyMessages = await repo.find({
-            where: { editMessageId: Not(IsNull()) }
-        });
-
-        for (const msg of pendingVerifyMessages) {
-            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-            const m = await this.tryFetchMessage(verifyChannel, msg.editMessageId!);
-
-            if (!m) {
-                await repo.update({ feedName: msg.feedName, newsId: msg.newsId }, { editMessageId: undefined });
-                continue;
-            }
-
-            const collector = m.createReactionCollector(this.isVerifyReaction, { maxEmojis: 1 });
-            collector.on("collect", this.collectorFor(collector));
-            this.reactionCollectors[m.id] = collector;
-            this.verifyMessageIdToPost[m.id] = msg;
-        }
-    }
 
     async start(): Promise<void> {
         const repo = getRepository(KnownChannel);
@@ -303,7 +170,6 @@ export class NewsAggregator {
 
         this.aggregateChannelID = ch.channelId;
 
-        await this.initPendingReactors();
         this.initAggregators();
         interval(this.checkFeeds, UPDATE_INTERVAL * 60 * 1000);
     }

+ 10 - 10
bot/src/xenforo.ts

@@ -1,4 +1,4 @@
-import { Dict, tryDo, isHttpError } from "./util";
+import { Dict, tryDo, isHttpError, assertOk } from "./util";
 import got, { Method } from "got";
 
 export interface RequestError {
@@ -35,41 +35,41 @@ export class XenforoClient {
     }
 
     async getMe(): Promise<User> {
-        const { me }: {me: User} = await this.makeRequest("me/", "get");
+        const { me }: {me: User} = await assertOk(this.makeRequest("me/", "get"));
         return me;
     }
 
     async postReply(thread_id: number, message: string, attachment_key?: string): Promise<void> {
-        return await this.makeRequest("posts/", "post", {
+        return await assertOk(this.makeRequest("posts/", "post", {
             thread_id,
             message,
             attachment_key
-        });
+        }));
     }
 
     async editThread(id: number, opts?: EditThreadOptions): Promise<CreateThreadResponse> {
-        return await this.makeRequest(`threads/${id}`, "post", opts);
+        return await assertOk(this.makeRequest(`threads/${id}`, "post", opts));
     }
 
     async editPost(id: number, opts?: EditPostOptions): Promise<EditPostResponse> {
-        return await this.makeRequest(`posts/${id}`, "post", opts);
+        return await assertOk(this.makeRequest(`posts/${id}`, "post", opts));
     }
 
     async getThread(id: number, opts?: GetThreadOptions): Promise<GetThreadResponse> {
-        return await this.makeRequest(`threads/${id}`, "post", opts);
+        return await assertOk(this.makeRequest(`threads/${id}`, "post", opts));
     }
 
     async deleteThread(id: number, opts?: DeleteThreadOptions): Promise<SuccessResponse> {
-        return await this.makeRequest(`threads/${id}`, "delete", opts);
+        return await assertOk(this.makeRequest(`threads/${id}`, "delete", opts));
     }
 
     async createThread(forumId: number, title: string, message: string, opts?: CreateThreadOptions): Promise<CreateThreadResponse> {
-        return await this.makeRequest("threads/", "post", {
+        return await assertOk(this.makeRequest("threads/", "post", {
             node_id: forumId,
             title: title,
             message: message,
             ...opts
-        });
+        }));
     }
 
     async getPost(id: number): Promise<Post> {