Skip to content

Commit

Permalink
refactor(telegram): now notifier pushes data with new format instead …
Browse files Browse the repository at this point in the history
…of plain text
  • Loading branch information
async3619 committed Dec 12, 2022
1 parent c2863c4 commit b9b49fe
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 41 deletions.
3 changes: 0 additions & 3 deletions src/notifiers/telegram/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
56 changes: 19 additions & 37 deletions src/notifiers/telegram/index.ts
Original file line number Diff line number Diff line change
@@ -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<TelegramNotifier> {
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;
Expand All @@ -41,37 +29,29 @@ export class TelegramNotifier extends BaseNotifier<"Telegram"> {
}
public async notify(logs: NotifyPair[]): Promise<void> {
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<TelegramNotificationData> = {};
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) {
Expand All @@ -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<NotifyResponse>({
Expand All @@ -104,7 +86,7 @@ export class TelegramNotifier extends BaseNotifier<"Telegram"> {
},
data: {
token: this.options.token,
content,
...content,
},
retryCount: 5,
retryDelay: 0,
Expand Down
28 changes: 28 additions & 0 deletions src/notifiers/telegram/types.ts
Original file line number Diff line number Diff line change
@@ -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<TelegramNotificationData, string>;
countFieldName: keyof SelectOnly<TelegramNotificationData, number>;
word: string;
template: string;
count: number;
pairs: NotifyPair[];
}
40 changes: 40 additions & 0 deletions src/notifiers/telegram/utils.ts
Original file line number Diff line number Diff line change
@@ -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<keyof SelectOnly<TelegramNotificationData, string>, 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,
},
];
}
5 changes: 4 additions & 1 deletion src/utils/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Logger } from "@utils/logger";

export type SelectOnly<Record, Type extends Record[keyof Record]> = {
[Key in keyof Required<Record> as Required<Record>[Key] extends Type ? Key : never]: Record[Key];
};

export type TypeMap<T extends { type: string }> = {
[TKey in T["type"]]: TKey extends T["type"] ? Extract<T, { type: TKey }> : never;
};
Expand All @@ -18,7 +22,6 @@ export type Nullable<T> = T | null | undefined;
export interface Serializable {
serialize(): Record<string, unknown>;
}

export interface Hydratable {
hydrate(data: Record<string, any>): void;
}
Expand Down

0 comments on commit b9b49fe

Please sign in to comment.