|  | @@ -1,6 +1,6 @@
 | 
	
		
			
				|  |  |  import TurndownService, { Options } from "turndown";
 | 
	
		
			
				|  |  |  import interval from "interval-promise";
 | 
	
		
			
				|  |  | -import { client, forumClient, FORUMS_DOMAIN } from "../client";
 | 
	
		
			
				|  |  | +import { client, FORUMS_DOMAIN, BotClient } from "../client";
 | 
	
		
			
				|  |  |  import sha1 from "sha1";
 | 
	
		
			
				|  |  |  import * as path from "path";
 | 
	
		
			
				|  |  |  import * as fs from "fs";
 | 
	
	
		
			
				|  | @@ -25,7 +25,7 @@ const FORUMS_NEWS_ID = 49;
 | 
	
		
			
				|  |  |  export class NewsAggregator {
 | 
	
		
			
				|  |  |      tlClient = new TranslationServiceClient();
 | 
	
		
			
				|  |  |      aggregators: IAggregator[] = [];
 | 
	
		
			
				|  |  | -    aggregateChannelID: string = null;
 | 
	
		
			
				|  |  | +    aggregateChannelID?: string;
 | 
	
		
			
				|  |  |      bbCodeParser = new HTML2BBCode();
 | 
	
		
			
				|  |  |      turndown = new TurndownService();
 | 
	
		
			
				|  |  |      reactionCollectors: Dict<ReactionCollector> = {};
 | 
	
	
		
			
				|  | @@ -38,7 +38,7 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |          this.turndown.addRule("link", {
 | 
	
		
			
				|  |  |              filter: (node: HTMLElement, opts: Options) => node.nodeName === "A" && node.getAttribute("href") != null,
 | 
	
		
			
				|  |  | -            replacement: (content: string, node: HTMLElement) => node.getAttribute("href")
 | 
	
		
			
				|  |  | +            replacement: (content: string, node: Node) => (node instanceof HTMLElement ? node.getAttribute("href") : null) ?? ""
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -56,8 +56,8 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |              for (let item of itemSet) {
 | 
	
		
			
				|  |  |                  let itemObj = {
 | 
	
		
			
				|  |  |                      ...item,
 | 
	
		
			
				|  |  | -                    cacheMessageId: null,
 | 
	
		
			
				|  |  | -                    postedMessageId: null
 | 
	
		
			
				|  |  | +                    cacheMessageId: undefined,
 | 
	
		
			
				|  |  | +                    postedMessageId: undefined
 | 
	
		
			
				|  |  |                  } as NewsPostItem;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  itemObj.hash = sha1(itemObj.contents);
 | 
	
	
		
			
				|  | @@ -75,9 +75,12 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      async addNewsItem(item: NewsPostItem) {
 | 
	
		
			
				|  |  | +        if (!this.aggregateChannelID)
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          let repo = getRepository(AggroNewsItem);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        let ch = client.channels.resolve(this.aggregateChannelID);
 | 
	
		
			
				|  |  | +        let ch = client.bot.channels.resolve(this.aggregateChannelID);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (!(ch instanceof TextChannel))
 | 
	
		
			
				|  |  |              return;
 | 
	
	
		
			
				|  | @@ -89,7 +92,7 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (newsItem) {
 | 
	
		
			
				|  |  |              if (process.env.IGNORE_CHANGED_NEWS === "TRUE") {
 | 
	
		
			
				|  |  | -                newsItem.hash = item.hash;
 | 
	
		
			
				|  |  | +                newsItem.hash = item.hash ?? "";
 | 
	
		
			
				|  |  |                  await repo.save(newsItem);
 | 
	
		
			
				|  |  |                  return;
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -97,7 +100,7 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |              // No changes, skip
 | 
	
		
			
				|  |  |              if (newsItem.hash == item.hash)
 | 
	
		
			
				|  |  |                  return;
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | +            else if(newsItem.editMessageId)
 | 
	
		
			
				|  |  |                  await this.deleteCacheMessage(newsItem.editMessageId);
 | 
	
		
			
				|  |  |              isNew = false;
 | 
	
		
			
				|  |  |          } else {
 | 
	
	
		
			
				|  | @@ -108,7 +111,7 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |              });
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (item.needsTranslation)
 | 
	
		
			
				|  |  | +        if (item.needsTranslation && process.env.GOOGLE_APP_ID)
 | 
	
		
			
				|  |  |              try {
 | 
	
		
			
				|  |  |                  let request = {
 | 
	
		
			
				|  |  |                      parent: this.tlClient.locationPath(process.env.GOOGLE_APP_ID, "global"),
 | 
	
	
		
			
				|  | @@ -119,9 +122,12 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |                  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  let [res] = await this.tlClient.translateText(request);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                item.title = res.translations[0].translatedText
 | 
	
		
			
				|  |  | -                item.contents = res.translations[1].translatedText;
 | 
	
		
			
				|  |  | +                let [translatedTitle, translatedContents] = res.translations ?? [undefined, undefined];
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +                if (translatedTitle?.translatedText && translatedContents?.translatedText) {
 | 
	
		
			
				|  |  | +                    item.title = translatedTitle.translatedText;
 | 
	
		
			
				|  |  | +                    item.contents = translatedContents.translatedText;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              } catch (err) {
 | 
	
		
			
				|  |  |                  console.log(`Failed to translate because ${err}`);
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -129,10 +135,10 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |          item.contents = this.bbCodeParser.feed(item.contents).toString();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (!newsItem.forumsEditPostId) {
 | 
	
		
			
				|  |  | -            let createResponse = await forumClient.createThread(FORUMS_STAGING_ID, item.title, item.contents);
 | 
	
		
			
				|  |  | +            let createResponse = await client.forum.createThread(FORUMS_STAGING_ID, item.title, item.contents);
 | 
	
		
			
				|  |  |              newsItem.forumsEditPostId = createResponse.thread.thread_id;
 | 
	
		
			
				|  |  | -        } else {
 | 
	
		
			
				|  |  | -            await forumClient.postReply(newsItem.forumsNewsPostId, item.contents);
 | 
	
		
			
				|  |  | +        } else if(newsItem.forumsNewsPostId){
 | 
	
		
			
				|  |  | +            await client.forum.postReply(newsItem.forumsNewsPostId, item.contents);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -164,7 +170,7 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      isVerifyReaction(reaction: MessageReaction, user: User) {
 | 
	
		
			
				|  |  | -        return (reaction.emoji.name == "✅" || reaction.emoji.name == "❌") && !user.bot && user.id != client.user.id;
 | 
	
		
			
				|  |  | +        return (reaction.emoji.name == "✅" || reaction.emoji.name == "❌") && !user.bot && user.id != client.botUser.id;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      collectReaction = async (reaction: MessageReaction, collector: Collector<string, MessageReaction>) => {
 | 
	
	
		
			
				|  | @@ -175,32 +181,41 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |          delete this.reactionCollectors[m.id];
 | 
	
		
			
				|  |  |          let post = this.verifyMessageIdToPost[m.id];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        if(!post.forumsEditPostId) {
 | 
	
		
			
				|  |  | +            throw new Error("No forum edit post found!");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          if (reaction.emoji.name == "✅") {
 | 
	
		
			
				|  |  | -            let res = await forumClient.getThread(post.forumsEditPostId);
 | 
	
		
			
				|  |  | -            let forumPost = await forumClient.getPost(res.thread.first_post_id);
 | 
	
		
			
				|  |  | +            let res = await client.forum.getThread(post.forumsEditPostId);
 | 
	
		
			
				|  |  | +            let forumPost = await client.forum.getPost(res.thread.first_post_id);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              if (!post.forumsNewsPostId) {
 | 
	
		
			
				|  |  | -                let newThread = await forumClient.createThread(FORUMS_NEWS_ID, res.thread.title, forumPost.message);
 | 
	
		
			
				|  |  | +                let newThread = await client.forum.createThread(FORUMS_NEWS_ID, res.thread.title, forumPost.message);
 | 
	
		
			
				|  |  |                  post.forumsNewsPostId = newThread.thread.thread_id;
 | 
	
		
			
				|  |  |              } else {
 | 
	
		
			
				|  |  | -                let curThread = await forumClient.editThread(post.forumsNewsPostId, {
 | 
	
		
			
				|  |  | +                let curThread = await client.forum.editThread(post.forumsNewsPostId, {
 | 
	
		
			
				|  |  |                      title: res.thread.title
 | 
	
		
			
				|  |  |                  });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                await forumClient.editPost(curThread.thread.first_post_id, {
 | 
	
		
			
				|  |  | +                await client.forum.editPost(curThread.thread.first_post_id, {
 | 
	
		
			
				|  |  |                      message: forumPost.message
 | 
	
		
			
				|  |  |                  });
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        await forumClient.deleteThread(post.forumsEditPostId);
 | 
	
		
			
				|  |  | -        await repo.update({ newsId: post.newsId, feedName: post.feedName }, { editMessageId: null, forumsEditPostId: null, forumsNewsPostId: post.forumsNewsPostId });
 | 
	
		
			
				|  |  | +        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) {
 | 
	
		
			
				|  |  | -        let ch = client.channels.resolve(this.aggregateChannelID);
 | 
	
		
			
				|  |  | +        if(!this.aggregateChannelID)
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        let ch = client.bot.channels.resolve(this.aggregateChannelID);
 | 
	
		
			
				|  |  |          if (!(ch instanceof TextChannel))
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -244,7 +259,12 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      async initPendingReactors() {
 | 
	
		
			
				|  |  | -        let verifyChannel = client.channels.resolve(this.aggregateChannelID);
 | 
	
		
			
				|  |  | +        if(!this.aggregateChannelID)
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let verifyChannel = client.bot.channels.resolve(this.aggregateChannelID);
 | 
	
		
			
				|  |  | +        if(!verifyChannel)
 | 
	
		
			
				|  |  | +            throw new Error("Couldn't find verify channel!");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          let repo = getRepository(AggroNewsItem);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -253,10 +273,10 @@ export class NewsAggregator {
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          for (let msg of pendingVerifyMessages) {
 | 
	
		
			
				|  |  | -            let m = await this.tryFetchMessage(verifyChannel, msg.editMessageId);
 | 
	
		
			
				|  |  | +            let m = await this.tryFetchMessage(verifyChannel, msg.editMessageId!);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              if (!m) {
 | 
	
		
			
				|  |  | -                await repo.update({ feedName: msg.feedName, newsId: msg.newsId }, { editMessageId: null });
 | 
	
		
			
				|  |  | +                await repo.update({ feedName: msg.feedName, newsId: msg.newsId }, { editMessageId: undefined });
 | 
	
		
			
				|  |  |                  continue;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 |