Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/gram-js/gramjs into gram-…
Browse files Browse the repository at this point in the history
…js-master
  • Loading branch information
r1ddev committed Nov 15, 2024
2 parents 7708535 + 3d77d52 commit 2227ea2
Show file tree
Hide file tree
Showing 38 changed files with 4,506 additions and 1,756 deletions.
27 changes: 17 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ Install GramJS:
$ npm i telegram
```

Install [input package](https://www.npmjs.com/package/input), we'll use it to prompt ourselves inside terminal for login information:

```bash
$ npm i input
```

After installation, you'll need to obtain an API ID and hash:

1. Login into your [telegram account](https://my.telegram.org/)
Expand All @@ -36,22 +30,35 @@ Then run this code to send a message to yourself.
```javascript
import { TelegramClient } from "telegram";
import { StringSession } from "telegram/sessions";
import input from "input";
import readline from "readline";

const apiId = 123456;
const apiHash = "123456abcdfg";
const stringSession = new StringSession(""); // fill this later with the value from session.save()

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

(async () => {
console.log("Loading interactive example...");
const client = new TelegramClient(stringSession, apiId, apiHash, {
connectionRetries: 5,
});
await client.start({
phoneNumber: async () => await input.text("Please enter your number: "),
password: async () => await input.text("Please enter your password: "),
phoneNumber: async () =>
new Promise((resolve) =>
rl.question("Please enter your number: ", resolve)
),
password: async () =>
new Promise((resolve) =>
rl.question("Please enter your password: ", resolve)
),
phoneCode: async () =>
await input.text("Please enter the code you received: "),
new Promise((resolve) =>
rl.question("Please enter the code you received: ", resolve)
),
onError: (err) => console.log(err),
});
console.log("You should now be connected.");
Expand Down
4 changes: 3 additions & 1 deletion gramjs/Helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ export function readBufferFromBigInt(
}

if (signed && bigIntVar.lesser(bigInt(0))) {
bigIntVar = bigInt(2).pow(bigInt(bytesNumber).multiply(8)).add(bigIntVar);
bigIntVar = bigInt(2)
.pow(bigInt(bytesNumber).multiply(8))
.add(bigIntVar);
}

const hex = bigIntVar.toString(16).padStart(bytesNumber * 2, "0");
Expand Down
5 changes: 2 additions & 3 deletions gramjs/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,8 @@ export function _photoSizeByteCount(size: Api.TypePhotoSize) {
} else if (size instanceof Api.PhotoSizeEmpty) {
return 0;
} else if (size instanceof Api.PhotoSizeProgressive) {
return size.sizes[size.sizes.length -1];
}
else {
return size.sizes[size.sizes.length - 1];
} else {
return undefined;
}
}
Expand Down
2 changes: 1 addition & 1 deletion gramjs/Version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const version = "2.20.3";
export const version = "2.26.1";
33 changes: 29 additions & 4 deletions gramjs/client/TelegramClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,27 @@ export class TelegramClient extends TelegramBaseClient {
) {
return chatMethods.getParticipants(this, entity, params);
}
/**
* Kicks a user from a chat.
*
* Kicking yourself (`'me'`) will result in leaving the chat.
*
* @note
* Attempting to kick someone who was banned will remove their
* restrictions (and thus unbanning them), since kicking is just
* ban + unban.
*
* @example
* // Kick some user from some chat, and deleting the service message
* const msg = await client.kickParticipant(chat, user);
* await msg.delete();
*
* // Leaving chat
* await client.kickParticipant(chat, 'me');
*/
kickParticipant(entity: EntityLike, participant: EntityLike) {
return chatMethods.kickParticipant(this, entity, participant);
}

//endregion

Expand Down Expand Up @@ -1226,6 +1247,8 @@ export class TelegramClient extends TelegramBaseClient {
* console.log("My username is",me.username);
* ```
*/
getMe(inputPeer: true): Promise<Api.InputPeerUser>;
getMe(inputPeer?: false): Promise<Api.User>;
getMe(inputPeer = false) {
return userMethods.getMe(this, inputPeer);
}
Expand Down Expand Up @@ -1275,11 +1298,11 @@ export class TelegramClient extends TelegramBaseClient {
* @example
* ```ts
* const me = await client.getEntity("me");
* console.log("My name is",utils.getDisplayName(me));
* console.log("My name is", utils.getDisplayName(me));
*
* const chat = await client.getInputEntity("username");
* for await (const message of client.iterMessages(chat){
* console.log("Message text is",message.text);
* for await (const message of client.iterMessages(chat)) {
* console.log("Message text is", message.text);
* }
*
* // Note that you could have used the username directly, but it's
Expand Down Expand Up @@ -1368,7 +1391,8 @@ export class TelegramClient extends TelegramBaseClient {
this._log.error(`Error while trying to reconnect`);
if (this._errorHandler) {
await this._errorHandler(e as Error);
} if (this._log.canSend(LogLevel.ERROR)) {
}
if (this._log.canSend(LogLevel.ERROR)) {
console.error(e);
}
}
Expand All @@ -1392,6 +1416,7 @@ export class TelegramClient extends TelegramBaseClient {
client: this,
securityChecks: this._securityChecks,
autoReconnectCallback: this._handleReconnect.bind(this),
_exportedSenderPromises: this._exportedSenderPromises,
});
}

Expand Down
60 changes: 58 additions & 2 deletions gramjs/client/chats.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import type { TelegramClient } from "./TelegramClient";
import type { EntitiesLike, Entity, EntityLike, ValueOf } from "../define";
import { sleep, getMinBigInt, TotalList, betterConsoleLog } from "../Helpers";
import {
sleep,
getMinBigInt,
TotalList,
betterConsoleLog,
returnBigInt,
} from "../Helpers";
import { RequestIter } from "../requestIter";
import { helpers, utils } from "../";
import { Api } from "../tl";
import bigInt, { BigInteger } from "big-integer";
import bigInt, { BigInteger, isInstance } from "big-integer";
import { inspect } from "../inspect";
import { getPeerId } from "../Utils";

const _MAX_PARTICIPANTS_CHUNK_SIZE = 200;
const _MAX_ADMIN_LOG_CHUNK_SIZE = 100;
Expand Down Expand Up @@ -441,3 +448,52 @@ export async function getParticipants(
const it = client.iterParticipants(entity, params);
return (await it.collect()) as TotalList<Api.User>;
}

/** @hidden */
export async function kickParticipant(
client: TelegramClient,
entity: EntityLike,
participant: EntityLike
) {
const peer = await client.getInputEntity(entity);
const user = await client.getInputEntity(participant);
let resp;
let request;

const type = helpers._entityType(peer);
if (type === helpers._EntityType.CHAT) {
request = new Api.messages.DeleteChatUser({
chatId: returnBigInt(getPeerId(entity)),
userId: returnBigInt(getPeerId(participant)),
});
resp = await client.invoke(request);
} else if (type === helpers._EntityType.CHANNEL) {
if (user instanceof Api.InputPeerSelf) {
request = new Api.channels.LeaveChannel({
channel: peer,
});
resp = await client.invoke(request);
} else {
request = new Api.channels.EditBanned({
channel: peer,
participant: user,
bannedRights: new Api.ChatBannedRights({
untilDate: 0,
viewMessages: true,
}),
});
resp = await client.invoke(request);
await sleep(500);
await client.invoke(
new Api.channels.EditBanned({
channel: peer,
participant: user,
bannedRights: new Api.ChatBannedRights({ untilDate: 0 }),
})
);
}
} else {
throw new Error("You must pass either a channel or a chat");
}
return client._getResponseMessage(request, resp, entity);
}
2 changes: 1 addition & 1 deletion gramjs/client/downloads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,13 +430,13 @@ export async function downloadFileV2(
msgData: msgData,
})) {
await writer.write(chunk);
downloaded = downloaded.add(chunk.length);
if (progressCallback) {
await progressCallback(
downloaded,
bigInt(fileSize || bigInt.zero)
);
}
downloaded = downloaded.add(chunk.length);
}
return returnWriterValue(writer);
} finally {
Expand Down
6 changes: 3 additions & 3 deletions gramjs/client/messageParse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,15 @@ export function _getResponseMessage(
return schedMessage;
}
client._log.warn(
`No randomId in ${request} to map to. returning undefined for ${result}`
`No randomId in ${request} to map to. returning undefined for ${result} (Message was empty)`
);
return undefined;
}
if (!isArrayLike(randomId)) {
let msg = idToMessage.get(randomToId.get(randomId.toString())!);
if (!msg) {
client._log.warn(
`Request ${request.className} had missing message mapping ${result.className}`
`Request ${request.className} had missing message mapping ${result.className} (Message was empty)`
);
}
return msg;
Expand All @@ -241,7 +241,7 @@ export function _getResponseMessage(
}
if (warned) {
client._log.warn(
`Request ${request.className} had missing message mapping ${result.className}`
`Request ${request.className} had missing message mapping ${result.className} (Message was empty)`
);
}
const finalToReturn = [];
Expand Down
4 changes: 3 additions & 1 deletion gramjs/client/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,9 @@ export async function getCommentData(
msgId: utils.getMessageId(message),
})
);
const relevantMessage = result.messages[0];
const relevantMessage = result.messages.reduce(
(p: Api.TypeMessage, c: Api.TypeMessage) => (p && p.id < c.id ? p : c)
);
let chat;
for (const c of result.chats) {
if (
Expand Down
22 changes: 16 additions & 6 deletions gramjs/client/telegramBaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export abstract class TelegramBaseClient {
[ReturnType<typeof setTimeout>, Api.TypeUpdate[]]
>();
/** @hidden */
private _exportedSenderPromises = new Map<number, Promise<MTProtoSender>>();
public _exportedSenderPromises = new Map<number, Promise<MTProtoSender>>();
/** @hidden */
private _exportedSenderReleaseTimeouts = new Map<
number,
Expand Down Expand Up @@ -289,11 +289,11 @@ export abstract class TelegramBaseClient {
}
this._connection = clientParams.connection;
let initProxy;
if (this._proxy?.MTProxy) {
if (this._proxy && "MTProxy" in this._proxy) {
this._connection = ConnectionTCPMTProxyAbridged;
initProxy = new Api.InputClientProxy({
address: this._proxy!.ip,
port: this._proxy!.port,
address: this._proxy.ip,
port: this._proxy.port,
});
}
this._initRequest = new Api.InitConnection({
Expand Down Expand Up @@ -529,7 +529,8 @@ export abstract class TelegramBaseClient {
} catch (err) {
if (this._errorHandler) {
await this._errorHandler(err as Error);
} if (this._log.canSend(LogLevel.ERROR)) {
}
if (this._log.canSend(LogLevel.ERROR)) {
console.error(err);
}
return this._borrowExportedSender(dcId, true);
Expand All @@ -544,7 +545,15 @@ export abstract class TelegramBaseClient {
dcId,
setTimeout(() => {
this._exportedSenderReleaseTimeouts.delete(dcId);
sender.disconnect();
if (sender._pendingState.values().length) {
console.log(
"sender already has some hanging states. reconnecting"
);
sender._reconnect();
this._borrowExportedSender(dcId, false, sender);
} else {
sender.disconnect();
}
}, EXPORTED_SENDER_RELEASE_TIMEOUT)
);

Expand All @@ -565,6 +574,7 @@ export abstract class TelegramBaseClient {
onConnectionBreak: this._cleanupExportedSender.bind(this),
client: this as unknown as TelegramClient,
securityChecks: this._securityChecks,
_exportedSenderPromises: this._exportedSenderPromises,
});
}

Expand Down
6 changes: 4 additions & 2 deletions gramjs/client/updates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ export async function _dispatchUpdate(
}
if (client._errorHandler) {
await client._errorHandler(e as Error);
} if (client._log.canSend(LogLevel.ERROR)) {
}
if (client._log.canSend(LogLevel.ERROR)) {
console.error(e);
}
}
Expand Down Expand Up @@ -245,7 +246,8 @@ export async function _updateLoop(client: TelegramClient) {
// eslint-disable-next-line no-console
if (client._errorHandler) {
await client._errorHandler(err as Error);
} if (client._log.canSend(LogLevel.ERROR)) {
}
if (client._log.canSend(LogLevel.ERROR)) {
console.error(err);
}

Expand Down
13 changes: 11 additions & 2 deletions gramjs/client/uploads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const LARGE_FILE_THRESHOLD = 10 * 1024 * 1024;
const UPLOAD_TIMEOUT = 15 * 1000;
const DISCONNECT_SLEEP = 1000;
const BUFFER_SIZE_2GB = 2 ** 31;
const BUFFER_SIZE_20MB = 20 * 1024 * 1024;

async function getFileBuffer(
file: File | CustomFile,
Expand Down Expand Up @@ -128,7 +129,7 @@ export async function uploadFile(
const buffer = await getFileBuffer(
file,
size,
fileParams.maxBufferSize || BUFFER_SIZE_2GB - 1
fileParams.maxBufferSize || BUFFER_SIZE_20MB - 1
);

// Make sure a new sender can be created before starting upload
Expand All @@ -154,7 +155,15 @@ export async function uploadFile(
}

for (let j = i; j < end; j++) {
const bytes = await buffer.slice(j * partSize, (j + 1) * partSize);
let endPart = (j + 1) * partSize;
if (endPart > size) {
endPart = size;
}
if (endPart == j * partSize) {
break;
}

const bytes = await buffer.slice(j * partSize, endPart);

// eslint-disable-next-line no-loop-func
sendingParts.push(
Expand Down
Loading

0 comments on commit 2227ea2

Please sign in to comment.