diff --git a/src/notifiers/telegram/constants.ts b/src/notifiers/telegram/constants.ts index 4596e99..8833580 100644 --- a/src/notifiers/telegram/constants.ts +++ b/src/notifiers/telegram/constants.ts @@ -4,19 +4,16 @@ export const TELEGRAM_FOLLOWERS_TEMPLATE = ` {} {} `.trim(); - export const TELEGRAM_UNFOLLOWERS_TEMPLATE = ` *❌ {} {}* {} {} `.trim(); - export const TELEGRAM_RENAMES_TEMPLATE = ` *✏️ {} {}* {} {} `.trim(); - export const TELEGRAM_LOG_COUNT = 25; diff --git a/src/notifiers/telegram/index.ts b/src/notifiers/telegram/index.ts index 8da2237..e04a584 100644 --- a/src/notifiers/telegram/index.ts +++ b/src/notifiers/telegram/index.ts @@ -1,33 +1,21 @@ import pluralize from "pluralize"; -import { capitalCase } from "change-case"; import { BaseNotifier } from "@notifiers/base"; -import { - TELEGRAM_FOLLOWERS_TEMPLATE, - TELEGRAM_LOG_COUNT, - TELEGRAM_RENAMES_TEMPLATE, - TELEGRAM_UNFOLLOWERS_TEMPLATE, -} from "@notifiers/telegram/constants"; import { BaseNotifierOption, NotifyPair } from "@notifiers/type"; +import { TELEGRAM_LOG_COUNT } from "@notifiers/telegram/constants"; +import { NotifyResponse, TelegramNotificationData, TokenResponse } from "@notifiers/telegram/types"; import { Fetcher } from "@utils/fetcher"; import { groupNotifies } from "@utils/groupNotifies"; import { Logger } from "@utils/logger"; import { HttpError } from "@utils/httpError"; +import { generateNotificationTargets } from "@notifiers/telegram/utils"; export interface TelegramNotifierOptions extends BaseNotifierOption { token: string; url?: string; } -interface TokenResponse { - token: string; - expires: number; -} -interface NotifyResponse { - success: boolean; -} - export class TelegramNotifier extends BaseNotifier<"Telegram"> { private readonly fetcher = new Fetcher(); private currentToken: string | null = null; @@ -41,37 +29,29 @@ export class TelegramNotifier extends BaseNotifier<"Telegram"> { } public async notify(logs: NotifyPair[]): Promise { const { follow, unfollow, rename } = groupNotifies(logs); - const targets: [NotifyPair[], number, string, string][] = [ - [follow.slice(0, TELEGRAM_LOG_COUNT), follow.length, "new follower", TELEGRAM_FOLLOWERS_TEMPLATE], - [unfollow.slice(0, TELEGRAM_LOG_COUNT), unfollow.length, "unfollower", TELEGRAM_UNFOLLOWERS_TEMPLATE], - [rename.slice(0, TELEGRAM_LOG_COUNT), rename.length, "rename", TELEGRAM_RENAMES_TEMPLATE], - ]; + const targets = generateNotificationTargets({ + unfollowers: unfollow, + followers: follow, + renames: rename, + }); - const resultMessages: string[] = []; - for (const [target, count, word, template] of targets) { - if (target.length <= 0) { + const notifyData: Partial = {}; + for (const { fieldName, countFieldName, count, word, template, pairs } of targets) { + if (count <= 0) { continue; } - const message = Logger.format( + notifyData[countFieldName] = count; + notifyData[fieldName] = Logger.format( template, count, pluralize(word, count), - target.map(this.formatNotify).join("\n"), + pairs.map(this.formatNotify).join("\n"), count > TELEGRAM_LOG_COUNT ? `_... and ${count - TELEGRAM_LOG_COUNT} more_` : "", ).trim(); - - resultMessages.push(message); } - if (resultMessages.length > 0) { - const titleItems = targets.map(([, count, word]) => { - return count > 0 ? `${count} ${pluralize(capitalCase(word), count)}\n` : ""; - }); - const title = Logger.format("_**🦜 Cage Report**_\n\n{}{}{}", ...titleItems).trim(); - - await this.pushNotify([title, ...resultMessages]); - } + await this.pushNotify(notifyData); } private getEndpoint(path: string) { @@ -92,7 +72,9 @@ export class TelegramNotifier extends BaseNotifier<"Telegram"> { return token; } - private async pushNotify(content: string[]) { + private async pushNotify(content: TelegramNotificationData) { + console.log(content); + while (true) { try { await this.fetcher.fetchJson({ @@ -104,7 +86,7 @@ export class TelegramNotifier extends BaseNotifier<"Telegram"> { }, data: { token: this.options.token, - content, + ...content, }, retryCount: 5, retryDelay: 0, diff --git a/src/notifiers/telegram/types.ts b/src/notifiers/telegram/types.ts new file mode 100644 index 0000000..b3f3db3 --- /dev/null +++ b/src/notifiers/telegram/types.ts @@ -0,0 +1,28 @@ +import { SelectOnly } from "@utils/types"; +import { NotifyPair } from "@notifiers/type"; + +export interface TelegramNotificationData { + followers?: string; + unfollowers?: string; + renames?: string; + followerCount?: number; + unfollowerCount?: number; + renameCount?: number; +} + +export interface TokenResponse { + token: string; + expires: number; +} +export interface NotifyResponse { + success: boolean; +} + +export interface NotificationTarget { + fieldName: keyof SelectOnly; + countFieldName: keyof SelectOnly; + word: string; + template: string; + count: number; + pairs: NotifyPair[]; +} diff --git a/src/notifiers/telegram/utils.ts b/src/notifiers/telegram/utils.ts new file mode 100644 index 0000000..cf461ee --- /dev/null +++ b/src/notifiers/telegram/utils.ts @@ -0,0 +1,40 @@ +import { SelectOnly } from "@utils/types"; +import { NotificationTarget, TelegramNotificationData } from "@notifiers/telegram/types"; +import { NotifyPair } from "@notifiers/type"; +import { + TELEGRAM_FOLLOWERS_TEMPLATE, + TELEGRAM_LOG_COUNT, + TELEGRAM_RENAMES_TEMPLATE, + TELEGRAM_UNFOLLOWERS_TEMPLATE, +} from "@notifiers/telegram/constants"; + +export function generateNotificationTargets( + pairs: Record, NotifyPair[]>, +): NotificationTarget[] { + return [ + { + fieldName: "followers", + countFieldName: "followerCount", + word: "new follower", + template: TELEGRAM_FOLLOWERS_TEMPLATE, + pairs: pairs.followers.slice(0, TELEGRAM_LOG_COUNT), + count: pairs.followers.length, + }, + { + fieldName: "unfollowers", + countFieldName: "unfollowerCount", + word: "unfollower", + template: TELEGRAM_UNFOLLOWERS_TEMPLATE, + pairs: pairs.unfollowers.slice(0, TELEGRAM_LOG_COUNT), + count: pairs.unfollowers.length, + }, + { + fieldName: "renames", + countFieldName: "renameCount", + word: "rename", + template: TELEGRAM_RENAMES_TEMPLATE, + pairs: pairs.renames.slice(0, TELEGRAM_LOG_COUNT), + count: pairs.renames.length, + }, + ]; +} diff --git a/src/utils/types.ts b/src/utils/types.ts index 488d359..4992fa6 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -1,5 +1,9 @@ import { Logger } from "@utils/logger"; +export type SelectOnly = { + [Key in keyof Required as Required[Key] extends Type ? Key : never]: Record[Key]; +}; + export type TypeMap = { [TKey in T["type"]]: TKey extends T["type"] ? Extract : never; }; @@ -18,7 +22,6 @@ export type Nullable = T | null | undefined; export interface Serializable { serialize(): Record; } - export interface Hydratable { hydrate(data: Record): void; }