Skip to content

Commit

Permalink
add webhook support
Browse files Browse the repository at this point in the history
  • Loading branch information
tapnisu committed Jan 30, 2025
1 parent 016359c commit 363d8fc
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 34 deletions.
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ TELEGRAM_CHAT_ID=<YOUR_TELEGRAM_CHAT_ID>

# output to discord webhook
# OUTPUT_BACKEND=discord_webhook
# DISCORD_WEBHOOK_URL=https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"dependencies": {
"@grammyjs/auto-retry": "^2.0.2",
"discord-webhook-node": "^1.1.8",
"discord.js": "^14.17.3",
"discord.js-selfbot-v13": "^3.5.1",
"dotenv": "^16.4.7",
Expand Down
56 changes: 56 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface Env {
TELEGRAM_TOPIC_ID?: string;
DISCORD_BOT_BACKEND?: BotBackend;
OUTPUT_BACKEND?: BotType;
DISCORD_WEBHOOK_URL?: string;
}

export function getEnv(): Env {
Expand Down
14 changes: 13 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Client as BotClient, GatewayIntentBits } from "discord.js";
import { Client as SelfBotClient } from "discord.js-selfbot-v13";
import { Webhook } from "discord-webhook-node";

import { Bot as GrammyBot } from "grammy";

Expand All @@ -19,14 +20,25 @@ const grammyClient =
? new GrammyBot(env.TELEGRAM_TOKEN)
: null;

const webhookClient =
env.OUTPUT_BACKEND == BotType.DiscordWebhook
? new Webhook(env.DISCORD_WEBHOOK_URL)
: null;

if (env.DISCORD_WEBHOOK_URL) {
const match = env.DISCORD_WEBHOOK_URL.match(/webhooks\/(\d+)\//);
if (match) config.mutedUsersIds?.push(match[1]);
}

const senderBot = new SenderBot({
chatsToSend,
disableLinkPreview: config.disableLinkPreview,

botType: env.OUTPUT_BACKEND,

grammyClient,
telegramTopicId: env.TELEGRAM_TOPIC_ID ? Number(env.TELEGRAM_TOPIC_ID) : null
telegramTopicId: env.TELEGRAM_TOPIC_ID ? Number(env.TELEGRAM_TOPIC_ID) : null,
webhookClient
});

senderBot.prepare();
Expand Down
92 changes: 59 additions & 33 deletions src/senderBot.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { autoRetry } from "@grammyjs/auto-retry";
import { Bot } from "grammy";
import { InputMediaPhoto } from "grammy/types";
import { Webhook } from "discord-webhook-node";

import { ChannelId } from "./config.js";

Expand All @@ -17,6 +18,7 @@ export class SenderBot {
botType: BotType = BotType.Telegram;

grammyClient?: Bot;
webhookClient?: Webhook;

constructor(options: {
chatsToSend: ChannelId[];
Expand All @@ -26,6 +28,8 @@ export class SenderBot {

grammyClient?: Bot;
telegramTopicId?: number;

webhookClient?: Webhook;
}) {
this.chatsToSend = options.chatsToSend;
this.disableLinkPreview = options.disableLinkPreview;
Expand All @@ -42,54 +46,76 @@ export class SenderBot {
this.grammyClient.catch((err) => {
console.error(err);
});

break;

case BotType.DiscordWebhook:
this.webhookClient = options.webhookClient;
break;
}
}

async prepare() {
const me = await this.grammyClient.api.getMe();
return console.log(`Logged into Telegram as @${me.username}`);
switch (this.botType) {
case BotType.Telegram: {
const me = await this.grammyClient.api.getMe();
return console.log(`Logged into Telegram as @${me.username}`);
}
}
}

async sendData(messagesToSend: string[], imagesToSend: InputMediaPhoto[]) {
if (messagesToSend.length == 0) return;

for (const chatId of this.chatsToSend) {
try {
if (imagesToSend.length != 0)
await this.grammyClient.api.sendMediaGroup(chatId, imagesToSend, {
async sendMessage(text: string) {
switch (this.botType) {
case BotType.Telegram: {
const messageChunks: string[] = [];
const MESSAGE_CHUNK = 4096;

for (
let i = 0, charsLength = text.length;
i < charsLength;
i += MESSAGE_CHUNK
) {
messageChunks.push(text.substring(i, i + MESSAGE_CHUNK));
}

for (const messageChunk of messageChunks.reverse()) {
await this.grammyClient.api.sendMessage(text, messageChunk, {
link_preview_options: {
is_disabled: this.disableLinkPreview
},
reply_parameters: {
message_id: this.telegramTopicId
}
});
} catch (err) {
console.error(err);
}
break;
}

if (messagesToSend.length == 0 || messagesToSend.join("") == "") return;

const renderedMessage = messagesToSend.join("\n");
case BotType.DiscordWebhook: {
this.webhookClient.send(text);
break;
}
}
}

const messageChunks: string[] = [];
const MESSAGE_CHUNK = 4096;
async sendData(messagesToSend: string[], imagesToSend: InputMediaPhoto[]) {
if (messagesToSend.length == 0) return;

for (
let i = 0, charsLength = renderedMessage.length;
i < charsLength;
i += MESSAGE_CHUNK
) {
messageChunks.push(renderedMessage.substring(i, i + MESSAGE_CHUNK));
}
for (const chatId of this.chatsToSend) {
if (this.botType == BotType.Telegram)
try {
if (imagesToSend.length != 0)
await this.grammyClient.api.sendMediaGroup(chatId, imagesToSend, {
reply_parameters: {
message_id: this.telegramTopicId
}
});
} catch (err) {
console.error(err);
}

for (const messageChunk of messageChunks.reverse()) {
await this.grammyClient.api.sendMessage(chatId, messageChunk, {
link_preview_options: {
is_disabled: this.disableLinkPreview
},
reply_parameters: {
message_id: this.telegramTopicId
}
});
}
if (messagesToSend.length == 0 || messagesToSend.join("") == "") return;
this.sendMessage(messagesToSend.join("\n"));
}
}
}

0 comments on commit 363d8fc

Please sign in to comment.