Skip to content

Commit

Permalink
don't start TG client unless routes are requested
Browse files Browse the repository at this point in the history
  • Loading branch information
synchrone committed Mar 8, 2024
1 parent 71c6f5c commit bec5b6e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 39 deletions.
4 changes: 2 additions & 2 deletions lib/routes/telegram/router.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { config } from '@/config';
import channelMedia from './tglib/channel-media';

export default (router) => {
if (config.telegram.session) {
router.get('/channel/:username', './tglib/channel');
import('./tglib/channel-media').then((channelMedia) =>
router.app.get('/channel/:username/:media', channelMedia.default));
router.app.get('/channel/:username/:media', channelMedia);
} else {
router.get('/channel/:username/:routeParams?', './channel');
}
Expand Down
18 changes: 9 additions & 9 deletions lib/routes/telegram/tglib/channel-media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { config } from '@/config';
import cacheModule from '@/utils/cache/index';
import { stream } from 'hono/streaming';
import { getAppropriatedPartSize } from 'telegram/Utils';
import { Api } from 'telegram';
import { Api, TelegramClient } from 'telegram';
import { returnBigInt as bigInt } from 'telegram/Helpers';
import { client, getFilename } from './client';
import { getClient, getFilename } from './client';
import { StreamingApi } from 'hono/utils/stream';
/**
* https://core.telegram.org/api/files#stripped-thumbnails
Expand Down Expand Up @@ -81,7 +81,7 @@ export function streamThumbnail(doc: Api.Document) {
throw new Error('not supported');
}

export async function decodeMedia(channelName: string, x: string, retry = false) {
export async function decodeMedia(client: TelegramClient, channelName: string, x: string, retry = false) {
const [channel, msg] = x.split('_');

try {
Expand All @@ -93,13 +93,13 @@ export async function decodeMedia(channelName: string, x: string, retry = false)
if (!retry) {
// channel likely not seen before, we need to resolve ID and retry
await client.getInputEntity(channelName);
return decodeMedia(channelName, x, true);
return decodeMedia(client, channelName, x, true);
}
throw error;
}
}

export function streamDocument(obj: Api.Document, thumbSize = '', offset?, limit?) {
export function streamDocument(client: TelegramClient, obj: Api.Document, thumbSize = '', offset?, limit?) {
const chunkSize = (obj.size ? getAppropriatedPartSize(obj.size) : 64) * 1024;
const iterFileParams = {
file: new Api.InputDocumentFileLocation({
Expand Down Expand Up @@ -177,8 +177,8 @@ function streamResponse(c, bodyIter, cb?: (e: Error | undefined, s: StreamingApi

export default async function handler(ctx) {
await configureMiddlewares(ctx);

const media = await decodeMedia(ctx.req.param('username'), ctx.req.param('media'));
const client = await getClient();
const media = await decodeMedia(client, ctx.req.param('username'), ctx.req.param('media'));
if (!media) {
return ctx.text('Unknown media', 404);
}
Expand Down Expand Up @@ -212,14 +212,14 @@ export default async function handler(ctx) {
!doc.mimeType.startsWith('image/')) {
ctx.header('Content-Disposition', `attachment; filename="${encodeURIComponent(getFilename(media))}"`);
}
stream = streamDocument(doc);
stream = streamDocument(client, doc);
} else {
const [offset, limit] = range[0];
// console.log(`${ctx.method} ${ctx.req.url} Range: ${rangeHeader}`);
ctx.status(206); // partial content
ctx.header('Content-Length', (limit - offset + 1).toString());
ctx.header('Content-Range', `bytes ${offset}-${limit}/${doc.size}`);
stream = streamDocument(doc, '', offset, limit);
stream = streamDocument(client, doc, '', offset, limit);
}
return streamResponse(ctx, stream, () => stream.close());
}
Expand Down
10 changes: 2 additions & 8 deletions lib/routes/telegram/tglib/channel.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import wait from '@/utils/wait';
import { config } from '@/config';
import { Api } from 'telegram';
import { HTMLParser } from 'telegram/extensions/html';
import { client, getFilename } from './client';
import { getClient, getFilename } from './client';

function getMediaLink(ctx, channel, channelName, message) {
const base = `${new URL(ctx.req.url).origin}/telegram/channel/${channelName}/`;
Expand Down Expand Up @@ -36,12 +35,7 @@ function humanFileSize(size) {
}

export default async function handler(ctx) {
if (!config.telegram.session) {
return [];
}
if (!client.connected) {
await wait(1000);
}
const client = await getClient();

const item: object[] = [];
const chat = await client.getInputEntity(ctx.req.param('username'));
Expand Down
45 changes: 25 additions & 20 deletions lib/routes/telegram/tglib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,31 @@ import * as readline from 'node:readline/promises';
import process from 'node:process';
import { fileURLToPath } from 'node:url';
import { Api, TelegramClient } from 'telegram';
import { UserAuthParams } from 'telegram/client/auth';
import { StringSession } from 'telegram/sessions';

const apiId = Number(config.telegram.apiId ?? 4);
const apiHash = config.telegram.apiHash ?? '014b35b6184100b085b0d0572f9b5103';

const stringSession = new StringSession(config.telegram.session);
export const client = new TelegramClient(stringSession, apiId, apiHash, {
connectionRetries: Infinity,
autoReconnect: true,
retryDelay: 3000,
maxConcurrentDownloads: Number(config.telegram.maxConcurrentDownloads ?? 10),
});
let client: TelegramClient | undefined;
export async function getClient(authParams?: UserAuthParams, session?: string) {
if (!config.telegram.session && session === undefined) {
throw new Error('TELEGRAM_SESSION is not configured');
}
if (client) {
return client;
}
const apiId = Number(config.telegram.apiId ?? 4);
const apiHash = config.telegram.apiHash ?? '014b35b6184100b085b0d0572f9b5103';

if (config.telegram.session) {
client.start({
onError: (err) => {
throw 'Cannot start TG: ' + err;
},
const stringSession = new StringSession(session ?? config.telegram.session);
client = new TelegramClient(stringSession, apiId, apiHash, {
connectionRetries: Infinity,
autoReconnect: true,
retryDelay: 3000,
maxConcurrentDownloads: Number(config.telegram.maxConcurrentDownloads ?? 10),
});
await client.start(Object.assign(authParams ?? {}, {
onError: (err) => { throw new Error('Cannot start TG: ' + err); },
}) as any);
return client;
}

export function getFilename(x) {
Expand All @@ -36,14 +42,13 @@ export function getFilename(x) {

if (process.argv[1] === fileURLToPath(import.meta.url)) {
Promise.resolve().then(async () => {
client.session = new StringSession('');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
await client.start({
phoneNumber: () => rl.question('Please enter your number: '),
const client = await getClient({
phoneNumber: () => rl.question('Please enter your phone number: '),
password: () => rl.question('Please enter your password: '),
phoneCode: () => rl.question('Please enter the code you received: '),
onError: (err) => process.stderr.write(err),
});
onError: (err) => process.stderr.write(err.toString()),
}, '');
process.stdout.write(`TELEGRAM_SESSION=${client.session.save()}\n`);
process.exit(0);
});
Expand Down

0 comments on commit bec5b6e

Please sign in to comment.