@mtkruto/node 0.1.114 → 0.1.116

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,9 +9,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _Client_instances, _a, _Client_auth, _Client_sessionId, _Client_state, _Client_promises, _Client_toAcknowledge, _Client_updateState, _Client_publicKeys, _Client_autoStart, _Client_constructContext, _Client_propagateConnectionState, _Client_lastPropagatedConnectionState, _Client_storageInited, _Client_setAuth, _Client_authKeyWasCreated, _Client_connectMutex, _Client_assertUser, _Client_assertBot, _Client_fetchState, _Client_connectionInited, _Client_initConnection, _Client_lastPropagatedAuthorizationState, _Client_propagateAuthorizationState, _Client_selfId, _Client_getSelfId, _Client_receiveLoop, _Client_pingInterval, _Client_pingLoop, _Client_pingLoopStarted, _Client_autoStarted, _Client_lastMsgId, _Client_invoke, _Client_handleInvokeError, _Client_processChats, _Client_processUsers, _Client_handleUpdateQueue, _Client_processUpdatesQueue, _Client_checkChannelGap, _Client_processUpdates, _Client_setUpdateStateDate, _Client_getLocalState, _Client_recoverUpdateGap, _Client_recoverChannelUpdateGap, _Client_getChannelAccessHash, _Client_getInputPeerInner, _Client_updatesToMessages, _Client_resolveSendAs, _Client_parseText, _Client_getMessagesInner, _Client_downloadInner, _Client_handleUpdate, _Client_usernameResolver, _Client_constructReplyMarkup, _Client_assertMsgHas, _Client_handle, _Client_setMyInfo, _Client_getMyInfo;
12
+ var _Client_instances, _a, _Client_auth, _Client_sessionId, _Client_state, _Client_promises, _Client_toAcknowledge, _Client_updateState, _Client_publicKeys, _Client_autoStart, _Client_ignoreOutgoing, _Client_constructContext, _Client_propagateConnectionState, _Client_lastPropagatedConnectionState, _Client_storageInited, _Client_setAuth, _Client_authKeyWasCreated, _Client_connectMutex, _Client_assertUser, _Client_assertBot, _Client_fetchState, _Client_connectionInited, _Client_initConnection, _Client_lastPropagatedAuthorizationState, _Client_propagateAuthorizationState, _Client_selfId, _Client_getSelfId, _Client_receiveLoop, _Client_pingInterval, _Client_pingLoop, _Client_pingLoopStarted, _Client_autoStarted, _Client_lastMsgId, _Client_invoke, _Client_handleInvokeError, _Client_processChats, _Client_processUsers, _Client_handleUpdateQueue, _Client_processUpdatesQueue, _Client_checkChannelGap, _Client_processUpdates, _Client_setUpdateStateDate, _Client_getLocalState, _Client_recoverUpdateGap, _Client_recoverChannelUpdateGap, _Client_getChannelAccessHash, _Client_getInputPeerInner, _Client_updatesToMessages, _Client_resolveSendAs, _Client_parseText, _Client_getMessagesInner, _Client_downloadInner, _Client_lastGetMe, _Client_getMe, _Client_handleUpdate, _Client_usernameResolver, _Client_constructReplyMarkup, _Client_assertMsgHas, _Client_handle, _Client_setMyInfo, _Client_getMyInfo;
13
13
  import { debug, gunzip, Mutex } from "../0_deps.js";
14
- import { bigIntFromBuffer, drop, getRandomBigInt, getRandomId, mod, mustPrompt, mustPromptOneOf, Queue, sha1, UNREACHABLE } from "../1_utilities.js";
14
+ import { bigIntFromBuffer, cleanObject, drop, getRandomBigInt, getRandomId, mod, mustPrompt, mustPromptOneOf, Queue, sha1, UNREACHABLE } from "../1_utilities.js";
15
15
  import { as, functions, getChannelChatId, Message_, MessageContainer, peerToChatId, RPCResult, TLError, TLReader, types } from "../2_tl.js";
16
16
  import { StorageMemory } from "../3_storage.js";
17
17
  import { botCommandScopeToTlObject, constructCallbackQuery, constructInlineQuery, constructMessage, constructUser, FileID, FileType, inlineQueryResultToTlObject, messageEntityToTlObject, replyMarkupToTlObject, ThumbnailSource } from "../3_types.js";
@@ -20,7 +20,7 @@ import { AuthKeyUnregistered, FloodWait, Migrate, PasswordHashInvalid, PhoneNumb
20
20
  import { parseHtml } from "./0_html.js";
21
21
  import { decryptMessage, encryptMessage, getMessageId } from "./0_message.js";
22
22
  import { checkPassword } from "./0_password.js";
23
- import { getFileContents, isChannelPtsUpdate, isHttpUrl, isPtsUpdate, resolve } from "./0_utilities.js";
23
+ import { getFileContents, getUsername, isChannelPtsUpdate, isHttpUrl, isPtsUpdate, resolve } from "./0_utilities.js";
24
24
  import { ClientAbstract } from "./1_client_abstract.js";
25
25
  import { ClientPlain } from "./2_client_plain.js";
26
26
  import { Composer, concat, flatten, skip } from "./4_composer.js";
@@ -119,7 +119,8 @@ export class Client extends ClientAbstract {
119
119
  });
120
120
  _Client_publicKeys.set(this, void 0);
121
121
  _Client_autoStart.set(this, void 0);
122
- _Client_constructContext.set(this, (update) => {
122
+ _Client_ignoreOutgoing.set(this, void 0);
123
+ _Client_constructContext.set(this, async (update) => {
123
124
  const msg = update.message ?? update.editedMessage ?? update.callbackQuery?.message;
124
125
  const mustGetMsg = () => {
125
126
  if (msg !== undefined) {
@@ -137,9 +138,11 @@ export class Client extends ClientAbstract {
137
138
  const replyToMessageId = shouldQuote ? effectiveMessage.id : undefined;
138
139
  return replyToMessageId;
139
140
  };
140
- return {
141
+ const me = update.connectionState !== undefined ? __classPrivateFieldGet(this, _Client_lastGetMe, "f") : (update.authorizationState !== undefined && !update.authorizationState.authorized) ? __classPrivateFieldGet(this, _Client_lastGetMe, "f") : await __classPrivateFieldGet(this, _Client_instances, "m", _Client_getMe).call(this);
142
+ return cleanObject({
141
143
  ...update,
142
144
  client: this,
145
+ me: me == null ? undefined : me,
143
146
  msg,
144
147
  chat,
145
148
  from,
@@ -216,7 +219,7 @@ export class Client extends ClientAbstract {
216
219
  get toJSON() {
217
220
  return () => update;
218
221
  },
219
- };
222
+ });
220
223
  });
221
224
  _Client_lastPropagatedConnectionState.set(this, null);
222
225
  Object.defineProperty(this, "stateChangeHandler", {
@@ -276,6 +279,7 @@ export class Client extends ClientAbstract {
276
279
  });
277
280
  _Client_handleUpdateQueue.set(this, new Queue("handleUpdate"));
278
281
  _Client_processUpdatesQueue.set(this, new Queue("processUpdates"));
282
+ _Client_lastGetMe.set(this, null);
279
283
  _Client_usernameResolver.set(this, async (v) => {
280
284
  const inputPeer = await this.getInputPeer(v).then((v) => v[as](types.InputPeerUser));
281
285
  return new types.InputUser({ userId: inputPeer.userId, accessHash: inputPeer.accessHash });
@@ -292,6 +296,7 @@ export class Client extends ClientAbstract {
292
296
  this.systemVersion = params?.systemVersion ?? SYSTEM_VERSION;
293
297
  __classPrivateFieldSet(this, _Client_publicKeys, params?.publicKeys, "f");
294
298
  __classPrivateFieldSet(this, _Client_autoStart, params?.autoStart ?? true, "f");
299
+ __classPrivateFieldSet(this, _Client_ignoreOutgoing, params?.ignoreOutgoing ?? null, "f");
295
300
  if (params?.defaultHandlers ?? true) {
296
301
  this.on("connectionState", ({ connectionState }, next) => {
297
302
  drop((async () => {
@@ -401,9 +406,9 @@ export class Client extends ClientAbstract {
401
406
  release();
402
407
  }
403
408
  }
404
- async [(_Client_auth = new WeakMap(), _Client_sessionId = new WeakMap(), _Client_state = new WeakMap(), _Client_promises = new WeakMap(), _Client_toAcknowledge = new WeakMap(), _Client_updateState = new WeakMap(), _Client_publicKeys = new WeakMap(), _Client_autoStart = new WeakMap(), _Client_constructContext = new WeakMap(), _Client_lastPropagatedConnectionState = new WeakMap(), _Client_storageInited = new WeakMap(), _Client_authKeyWasCreated = new WeakMap(), _Client_connectMutex = new WeakMap(), _Client_connectionInited = new WeakMap(), _Client_lastPropagatedAuthorizationState = new WeakMap(), _Client_selfId = new WeakMap(), _Client_pingInterval = new WeakMap(), _Client_pingLoopStarted = new WeakMap(), _Client_autoStarted = new WeakMap(), _Client_lastMsgId = new WeakMap(), _Client_handleInvokeError = new WeakMap(), _Client_handleUpdateQueue = new WeakMap(), _Client_processUpdatesQueue = new WeakMap(), _Client_usernameResolver = new WeakMap(), _Client_handle = new WeakMap(), _Client_instances = new WeakSet(), _Client_propagateConnectionState = function _Client_propagateConnectionState(connectionState) {
409
+ async [(_Client_auth = new WeakMap(), _Client_sessionId = new WeakMap(), _Client_state = new WeakMap(), _Client_promises = new WeakMap(), _Client_toAcknowledge = new WeakMap(), _Client_updateState = new WeakMap(), _Client_publicKeys = new WeakMap(), _Client_autoStart = new WeakMap(), _Client_ignoreOutgoing = new WeakMap(), _Client_constructContext = new WeakMap(), _Client_lastPropagatedConnectionState = new WeakMap(), _Client_storageInited = new WeakMap(), _Client_authKeyWasCreated = new WeakMap(), _Client_connectMutex = new WeakMap(), _Client_connectionInited = new WeakMap(), _Client_lastPropagatedAuthorizationState = new WeakMap(), _Client_selfId = new WeakMap(), _Client_pingInterval = new WeakMap(), _Client_pingLoopStarted = new WeakMap(), _Client_autoStarted = new WeakMap(), _Client_lastMsgId = new WeakMap(), _Client_handleInvokeError = new WeakMap(), _Client_handleUpdateQueue = new WeakMap(), _Client_processUpdatesQueue = new WeakMap(), _Client_lastGetMe = new WeakMap(), _Client_usernameResolver = new WeakMap(), _Client_handle = new WeakMap(), _Client_instances = new WeakSet(), _Client_propagateConnectionState = function _Client_propagateConnectionState(connectionState) {
405
410
  __classPrivateFieldGet(this, _Client_handleUpdateQueue, "f").add(async () => {
406
- await __classPrivateFieldGet(this, _Client_handle, "f").call(this, __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { connectionState }), resolve);
411
+ await __classPrivateFieldGet(this, _Client_handle, "f").call(this, await __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { connectionState }), resolve);
407
412
  });
408
413
  }, _Client_setAuth = async function _Client_setAuth(key) {
409
414
  const hash = await sha1(key);
@@ -639,24 +644,19 @@ export class Client extends ClientAbstract {
639
644
  send(function_) {
640
645
  return this.invoke(function_, true);
641
646
  }
642
- async checkGap(pts, ptsCount, assertNoGap) {
647
+ async checkGap(pts, ptsCount) {
643
648
  const localState = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_getLocalState).call(this);
644
649
  if (localState.pts + ptsCount < pts) {
645
- if (assertNoGap) {
646
- UNREACHABLE();
647
- }
648
- else {
649
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_recoverUpdateGap).call(this, "processUpdates");
650
- }
650
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_recoverUpdateGap).call(this, "processUpdates");
651
651
  }
652
652
  }
653
653
  async getUserAccessHash(userId) {
654
654
  const users = await this.invoke(new functions.UsersGetUsers({ id: [new types.InputUser({ userId, accessHash: 0n })] }));
655
- return users[0][as](types.User).accessHash ?? 0n;
655
+ return users[0]?.[as](types.User).accessHash ?? 0n;
656
656
  }
657
657
  async getInputPeer(id) {
658
658
  const inputPeer = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_getInputPeerInner).call(this, id);
659
- if (inputPeer instanceof types.InputPeerUser || inputPeer instanceof types.InputPeerChannel && inputPeer.accessHash == 0n && await this.storage.getAccountType() == "bot") {
659
+ if ((inputPeer instanceof types.InputPeerUser || inputPeer instanceof types.InputPeerChannel && inputPeer.accessHash == 0n) && await this.storage.getAccountType() == "bot") {
660
660
  if ("channelId" in inputPeer) {
661
661
  inputPeer.accessHash = await __classPrivateFieldGet(this, _Client_instances, "m", _Client_getChannelAccessHash).call(this, inputPeer.channelId);
662
662
  }
@@ -687,7 +687,7 @@ export class Client extends ClientAbstract {
687
687
  }
688
688
  }, _Client_propagateAuthorizationState = async function _Client_propagateAuthorizationState(authorized) {
689
689
  if (__classPrivateFieldGet(this, _Client_lastPropagatedAuthorizationState, "f") != authorized) {
690
- await __classPrivateFieldGet(this, _Client_handle, "f").call(this, __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { authorizationState: { authorized } }), resolve);
690
+ await __classPrivateFieldGet(this, _Client_handle, "f").call(this, await __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { authorizationState: { authorized } }), resolve);
691
691
  __classPrivateFieldSet(this, _Client_lastPropagatedAuthorizationState, authorized, "f");
692
692
  }
693
693
  }, _Client_getSelfId = async function _Client_getSelfId() {
@@ -723,7 +723,7 @@ export class Client extends ClientAbstract {
723
723
  }
724
724
  dRecv("received %s", body.constructor.name);
725
725
  if (body instanceof types._TypeUpdates || body instanceof types._TypeUpdate) {
726
- __classPrivateFieldGet(this, _Client_processUpdatesQueue, "f").add(() => __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, body));
726
+ __classPrivateFieldGet(this, _Client_processUpdatesQueue, "f").add(() => __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, body, true));
727
727
  }
728
728
  else if (body instanceof types.NewSessionCreated) {
729
729
  __classPrivateFieldGet(this, _Client_state, "f").salt = body.serverSalt;
@@ -755,7 +755,7 @@ export class Client extends ClientAbstract {
755
755
  };
756
756
  if (result instanceof types._TypeUpdates || result instanceof types._TypeUpdate) {
757
757
  __classPrivateFieldGet(this, _Client_processUpdatesQueue, "f").add(async () => {
758
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, result);
758
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, result, true);
759
759
  resolvePromise();
760
760
  });
761
761
  }
@@ -911,20 +911,15 @@ export class Client extends ClientAbstract {
911
911
  }
912
912
  }
913
913
  }
914
- }, _Client_checkChannelGap = async function _Client_checkChannelGap(channelId, pts, ptsCount, assertNoGap) {
914
+ }, _Client_checkChannelGap = async function _Client_checkChannelGap(channelId, pts, ptsCount) {
915
915
  let localPts = await this.storage.getChannelPts(channelId);
916
916
  if (!localPts) {
917
917
  localPts = pts - ptsCount;
918
918
  }
919
919
  if (localPts + ptsCount < pts) {
920
- if (assertNoGap) {
921
- UNREACHABLE();
922
- }
923
- else {
924
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_recoverChannelUpdateGap).call(this, channelId, "processUpdates");
925
- }
920
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_recoverChannelUpdateGap).call(this, channelId, "processUpdates");
926
921
  }
927
- }, _Client_processUpdates = async function _Client_processUpdates(updates_, assertNoGap = false) {
922
+ }, _Client_processUpdates = async function _Client_processUpdates(updates_, checkGap) {
928
923
  /// First, individual updates (Update[1]) and updateShort* are extracted from Updates.[2]
929
924
  ///
930
925
  /// If an updatesTooLong[3] was received, an update gap recovery is initiated and no further action will be taken.
@@ -966,7 +961,9 @@ export class Client extends ClientAbstract {
966
961
  if (update.pts == 0) {
967
962
  continue;
968
963
  }
969
- await this.checkGap(update.pts, update.ptsCount, assertNoGap);
964
+ if (checkGap) {
965
+ await this.checkGap(update.pts, update.ptsCount);
966
+ }
970
967
  localState ??= await __classPrivateFieldGet(this, _Client_instances, "m", _Client_getLocalState).call(this);
971
968
  originalPts ??= localState.pts;
972
969
  if (localState.pts + update.ptsCount > update.pts) {
@@ -982,7 +979,9 @@ export class Client extends ClientAbstract {
982
979
  }
983
980
  const ptsCount = update.ptsCount;
984
981
  const channelId = update instanceof types.UpdateNewChannelMessage || update instanceof types.UpdateEditChannelMessage ? update.message.peerId[as](types.PeerChannel).channelId : update.channelId;
985
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_checkChannelGap).call(this, channelId, update.pts, ptsCount, assertNoGap);
982
+ if (checkGap) {
983
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_checkChannelGap).call(this, channelId, update.pts, ptsCount);
984
+ }
986
985
  let currentPts = channelPtsMap.get(channelId);
987
986
  if (currentPts === undefined) {
988
987
  currentPts = await this.storage.getChannelPts(channelId);
@@ -996,14 +995,6 @@ export class Client extends ClientAbstract {
996
995
  }
997
996
  }
998
997
  }
999
- if (!assertNoGap) {
1000
- if (localState != null && originalPts != null && localState.pts != originalPts) {
1001
- await this.storage.setState(localState);
1002
- }
1003
- for (const [channelId, pts] of channelPtsMap.entries()) {
1004
- await this.storage.setChannelPts(channelId, pts);
1005
- }
1006
- }
1007
998
  /// We process the updates when we are sure there is no gap.
1008
999
  if (updates_ instanceof types.Updates || updates_ instanceof types.UpdatesCombined) {
1009
1000
  await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processChats).call(this, updates_.chats);
@@ -1082,10 +1073,10 @@ export class Client extends ClientAbstract {
1082
1073
  await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processChats).call(this, difference.chats);
1083
1074
  await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUsers).call(this, difference.users);
1084
1075
  for (const message of difference.newMessages) {
1085
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, new types.UpdateNewMessage({ message, pts: 0, ptsCount: 0 }), true);
1076
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, new types.UpdateNewMessage({ message, pts: 0, ptsCount: 0 }), false);
1086
1077
  }
1087
1078
  for (const update of difference.otherUpdates) {
1088
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, update, true);
1079
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, update, false);
1089
1080
  }
1090
1081
  if (difference instanceof types.UpdatesDifference) {
1091
1082
  await this.storage.setState(difference.state);
@@ -1133,10 +1124,10 @@ export class Client extends ClientAbstract {
1133
1124
  await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processChats).call(this, difference.chats);
1134
1125
  await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUsers).call(this, difference.users);
1135
1126
  for (const message of difference.newMessages) {
1136
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, new types.UpdateNewChannelMessage({ message, pts: 0, ptsCount: 0 }), true);
1127
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, new types.UpdateNewChannelMessage({ message, pts: 0, ptsCount: 0 }), false);
1137
1128
  }
1138
1129
  for (const update of difference.otherUpdates) {
1139
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, update, true);
1130
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, update, false);
1140
1131
  }
1141
1132
  await this.storage.setChannelPts(channelId, difference.pts);
1142
1133
  dGapC("recovered from update gap [%o, %s]", channelId, source);
@@ -1148,7 +1139,7 @@ export class Client extends ClientAbstract {
1148
1139
  await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processChats).call(this, difference.chats);
1149
1140
  await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUsers).call(this, difference.users);
1150
1141
  for (const message of difference.messages) {
1151
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, new types.UpdateNewChannelMessage({ message, pts: 0, ptsCount: 0 }), true);
1142
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUpdates).call(this, new types.UpdateNewChannelMessage({ message, pts: 0, ptsCount: 0 }), false);
1152
1143
  }
1153
1144
  const pts_ = difference.dialog[as](types.Dialog).pts;
1154
1145
  if (pts_ != undefined) {
@@ -1169,52 +1160,44 @@ export class Client extends ClientAbstract {
1169
1160
  return channels.chats[0][as](types.Channel).accessHash ?? 0n;
1170
1161
  }, _Client_getInputPeerInner = async function _Client_getInputPeerInner(id) {
1171
1162
  if (typeof id === "string") {
1172
- if (!id.startsWith("@")) {
1173
- throw new Error("Expected username to start with @");
1174
- }
1175
- else {
1176
- id = id.slice(1);
1177
- if (!id) {
1178
- throw new Error("Empty username");
1179
- }
1180
- let userId = 0n;
1181
- let channelId = 0n;
1182
- const maybeUsername = await this.storage.getUsername(id);
1183
- if (maybeUsername != null && Date.now() - maybeUsername[2].getTime() < USERNAME_TTL) {
1184
- const [type, id] = maybeUsername;
1185
- if (type == "user") {
1186
- userId = id;
1187
- }
1188
- else {
1189
- channelId = id;
1190
- }
1163
+ id = getUsername(id);
1164
+ let userId = 0n;
1165
+ let channelId = 0n;
1166
+ const maybeUsername = await this.storage.getUsername(id);
1167
+ if (maybeUsername != null && Date.now() - maybeUsername[2].getTime() < USERNAME_TTL) {
1168
+ const [type, id] = maybeUsername;
1169
+ if (type == "user") {
1170
+ userId = id;
1191
1171
  }
1192
1172
  else {
1193
- const resolved = await this.invoke(new functions.ContactsResolveUsername({ username: id }));
1194
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processChats).call(this, resolved.chats);
1195
- await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUsers).call(this, resolved.users);
1196
- if (resolved.peer instanceof types.PeerUser) {
1197
- userId = resolved.peer.userId;
1198
- }
1199
- else if (resolved.peer instanceof types.PeerChannel) {
1200
- channelId = resolved.peer.channelId;
1201
- }
1202
- else {
1203
- UNREACHABLE();
1204
- }
1173
+ channelId = id;
1205
1174
  }
1206
- if (userId) {
1207
- const accessHash = await this.storage.getUserAccessHash(userId);
1208
- return new types.InputPeerUser({ userId, accessHash: accessHash ?? 0n });
1175
+ }
1176
+ else {
1177
+ const resolved = await this.invoke(new functions.ContactsResolveUsername({ username: id }));
1178
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processChats).call(this, resolved.chats);
1179
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_processUsers).call(this, resolved.users);
1180
+ if (resolved.peer instanceof types.PeerUser) {
1181
+ userId = resolved.peer.userId;
1209
1182
  }
1210
- else if (channelId) {
1211
- const accessHash = await this.storage.getChannelAccessHash(channelId);
1212
- return new types.InputPeerChannel({ channelId, accessHash: accessHash ?? 0n });
1183
+ else if (resolved.peer instanceof types.PeerChannel) {
1184
+ channelId = resolved.peer.channelId;
1213
1185
  }
1214
1186
  else {
1215
1187
  UNREACHABLE();
1216
1188
  }
1217
1189
  }
1190
+ if (userId) {
1191
+ const accessHash = await this.storage.getUserAccessHash(userId);
1192
+ return new types.InputPeerUser({ userId, accessHash: accessHash ?? 0n });
1193
+ }
1194
+ else if (channelId) {
1195
+ const accessHash = await this.storage.getChannelAccessHash(channelId);
1196
+ return new types.InputPeerChannel({ channelId, accessHash: accessHash ?? 0n });
1197
+ }
1198
+ else {
1199
+ UNREACHABLE();
1200
+ }
1218
1201
  }
1219
1202
  else if (id > 0) {
1220
1203
  const id_ = BigInt(id);
@@ -1597,7 +1580,9 @@ export class Client extends ClientAbstract {
1597
1580
  if (users.length < 1) {
1598
1581
  UNREACHABLE();
1599
1582
  }
1600
- return constructUser(users[0][as](types.User));
1583
+ const user = constructUser(users[0][as](types.User));
1584
+ __classPrivateFieldSet(this, _Client_lastGetMe, user, "f");
1585
+ return user;
1601
1586
  }
1602
1587
  /**
1603
1588
  * Answer a callback query. Bot-only.
@@ -1868,7 +1853,9 @@ export class Client extends ClientAbstract {
1868
1853
  });
1869
1854
  }
1870
1855
  filter(predicate, ...middleware) {
1871
- return this.branch(predicate, middleware.length == 0 ? skip : middleware.map(flatten).reduce(concat), skip);
1856
+ const composer = new Composer(...middleware);
1857
+ this.branch(predicate, composer, skip);
1858
+ return composer;
1872
1859
  }
1873
1860
  on(filter, ...middleawre) {
1874
1861
  const type = typeof filter === "string" ? filter : filter[0];
@@ -1891,6 +1878,32 @@ export class Client extends ClientAbstract {
1891
1878
  }
1892
1879
  }, ...middleawre);
1893
1880
  }
1881
+ command(commands, ...middleawre) {
1882
+ const commands_ = Array.isArray(commands) ? commands : [commands];
1883
+ return this.on(["message", "text"]).filter((ctx) => {
1884
+ const botCommand = ctx.message.entities?.find((v) => v.type == "botCommand");
1885
+ if (!botCommand) {
1886
+ return false;
1887
+ }
1888
+ const cmd = ctx.message.text.slice(botCommand.offset, botCommand.offset + botCommand.length);
1889
+ if (cmd.includes("@")) {
1890
+ const username = cmd.split("@")[1];
1891
+ if (username.toLowerCase() !== ctx.me.username?.toLowerCase()) {
1892
+ return false;
1893
+ }
1894
+ }
1895
+ const command_ = cmd.split("@")[0].split("/")[1].toLowerCase();
1896
+ for (const command of commands_) {
1897
+ if (typeof command === "string" && (command.toLowerCase() == command_)) {
1898
+ return true;
1899
+ }
1900
+ else if (command instanceof RegExp && command.test(command_)) {
1901
+ return true;
1902
+ }
1903
+ }
1904
+ return false;
1905
+ }, ...middleawre);
1906
+ }
1894
1907
  /**
1895
1908
  * Set the bot's description in the given language. Bot-only.
1896
1909
  *
@@ -2044,7 +2057,16 @@ export class Client extends ClientAbstract {
2044
2057
  return __classPrivateFieldGet(Client, _a, "m", _Client_assertMsgHas).call(Client, message, "photo");
2045
2058
  }
2046
2059
  }
2047
- _a = Client, _Client_handleUpdate =
2060
+ _a = Client, _Client_getMe = async function _Client_getMe() {
2061
+ if (__classPrivateFieldGet(this, _Client_lastGetMe, "f") != null) {
2062
+ return __classPrivateFieldGet(this, _Client_lastGetMe, "f");
2063
+ }
2064
+ else {
2065
+ const user = await this.getMe();
2066
+ __classPrivateFieldSet(this, _Client_lastGetMe, user, "f");
2067
+ return user;
2068
+ }
2069
+ }, _Client_handleUpdate =
2048
2070
  // TODO: log errors
2049
2071
  async function _Client_handleUpdate(update) {
2050
2072
  if (update instanceof types.UpdateShortMessage) {
@@ -2102,8 +2124,15 @@ async function _Client_handleUpdate(update) {
2102
2124
  update instanceof types.UpdateEditChannelMessage) {
2103
2125
  const key = update instanceof types.UpdateNewMessage || update instanceof types.UpdateNewChannelMessage ? "message" : "editedMessage";
2104
2126
  if (!(update.message instanceof types.MessageEmpty)) {
2105
- const message = await constructMessage(update.message, this[getEntity].bind(this), this.getMessage.bind(this), this[getStickerSetName].bind(this));
2106
- await __classPrivateFieldGet(this, _Client_handle, "f").call(this, __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { [key]: message }), resolve);
2127
+ const isOutgoing = update.message.out;
2128
+ let shouldIgnore = isOutgoing ? (await this.storage.getAccountType()) == "user" ? false : true : false;
2129
+ if (__classPrivateFieldGet(this, _Client_ignoreOutgoing, "f") != null && isOutgoing) {
2130
+ shouldIgnore = __classPrivateFieldGet(this, _Client_ignoreOutgoing, "f");
2131
+ }
2132
+ if (!shouldIgnore) {
2133
+ const message = await constructMessage(update.message, this[getEntity].bind(this), this.getMessage.bind(this), this[getStickerSetName].bind(this));
2134
+ await __classPrivateFieldGet(this, _Client_handle, "f").call(this, await __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { [key]: message }), resolve);
2135
+ }
2107
2136
  }
2108
2137
  }
2109
2138
  if (update instanceof types.UpdateDeleteMessages) {
@@ -2119,7 +2148,7 @@ async function _Client_handleUpdate(update) {
2119
2148
  }
2120
2149
  }
2121
2150
  if (deletedMessages.length > 0) {
2122
- await __classPrivateFieldGet(this, _Client_handle, "f").call(this, __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { deletedMessages: deletedMessages }), resolve);
2151
+ await __classPrivateFieldGet(this, _Client_handle, "f").call(this, await __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { deletedMessages: deletedMessages }), resolve);
2123
2152
  }
2124
2153
  }
2125
2154
  else if (update instanceof types.UpdateDeleteChannelMessages) {
@@ -2133,14 +2162,14 @@ async function _Client_handleUpdate(update) {
2133
2162
  await this.storage.setMessage(chatId, messageId, null);
2134
2163
  }
2135
2164
  if (deletedMessages.length > 0) {
2136
- await __classPrivateFieldGet(this, _Client_handle, "f").call(this, __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { deletedMessages: deletedMessages }), resolve);
2165
+ await __classPrivateFieldGet(this, _Client_handle, "f").call(this, await __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { deletedMessages: deletedMessages }), resolve);
2137
2166
  }
2138
2167
  }
2139
2168
  if (update instanceof types.UpdateBotCallbackQuery || update instanceof types.UpdateInlineBotCallbackQuery) {
2140
- await __classPrivateFieldGet(this, _Client_handle, "f").call(this, __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { callbackQuery: await constructCallbackQuery(update, this[getEntity].bind(this), this[getMessageWithReply].bind(this)) }), resolve);
2169
+ await __classPrivateFieldGet(this, _Client_handle, "f").call(this, await __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { callbackQuery: await constructCallbackQuery(update, this[getEntity].bind(this), this[getMessageWithReply].bind(this)) }), resolve);
2141
2170
  }
2142
2171
  else if (update instanceof types.UpdateBotInlineQuery) {
2143
- await __classPrivateFieldGet(this, _Client_handle, "f").call(this, __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { inlineQuery: await constructInlineQuery(update, this[getEntity].bind(this)) }), resolve);
2172
+ await __classPrivateFieldGet(this, _Client_handle, "f").call(this, await __classPrivateFieldGet(this, _Client_constructContext, "f").call(this, { inlineQuery: await constructInlineQuery(update, this[getEntity].bind(this)) }), resolve);
2144
2173
  }
2145
2174
  }, _Client_constructReplyMarkup = async function _Client_constructReplyMarkup(params) {
2146
2175
  if (params?.replyMarkup) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "module": "./esm/mod.js",
3
3
  "main": "./script/mod.js",
4
4
  "name": "@mtkruto/node",
5
- "version": "0.1.114",
5
+ "version": "0.1.116",
6
6
  "description": "MTKruto for Node.js",
7
7
  "author": "Roj <rojvv@icloud.com>",
8
8
  "license": "LGPL-3.0-or-later",
@@ -5,7 +5,7 @@ export declare const PUBLIC_KEYS: PublicKeys;
5
5
  export declare const VECTOR_CONSTRUCTOR = 481674261;
6
6
  export declare const INITIAL_DC: DC;
7
7
  export declare const LAYER = 166;
8
- export declare const APP_VERSION = "MTKruto 0.1.114";
8
+ export declare const APP_VERSION = "MTKruto 0.1.116";
9
9
  export declare const DEVICE_MODEL: string;
10
10
  export declare const LANG_CODE: string;
11
11
  export declare const LANG_PACK = "";
@@ -80,7 +80,7 @@ exports.PUBLIC_KEYS = Object.freeze([
80
80
  exports.VECTOR_CONSTRUCTOR = 0x1CB5C415;
81
81
  exports.INITIAL_DC = "2";
82
82
  exports.LAYER = 166;
83
- exports.APP_VERSION = "MTKruto 0.1.114";
83
+ exports.APP_VERSION = "MTKruto 0.1.116";
84
84
  // @ts-ignore: lib
85
85
  exports.DEVICE_MODEL = typeof dntShim.Deno === "undefined" ? typeof navigator === "undefined" ? typeof process === "undefined" ? "Unknown" : process.platform + "-" + process.arch : navigator.userAgent.split(" ")[0] : dntShim.Deno.build.os + "-" + dntShim.Deno.build.arch;
86
86
  exports.LANG_CODE = typeof navigator === "undefined" ? "en" : navigator.language.split("-")[0];
@@ -9,3 +9,4 @@ export declare function isChannelPtsUpdate(v: types.TypeUpdate | types.TypeUpdat
9
9
  export type FileSource = string | URL | Uint8Array;
10
10
  export declare function getFileContents(source: FileSource, fileName?: string): Promise<readonly [Uint8Array, string]>;
11
11
  export declare function isHttpUrl(string: string): boolean;
12
+ export declare function getUsername(string: string): string;
@@ -23,11 +23,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.isHttpUrl = exports.getFileContents = exports.isChannelPtsUpdate = exports.isPtsUpdate = exports.resolve = void 0;
26
+ exports.getUsername = exports.isHttpUrl = exports.getFileContents = exports.isChannelPtsUpdate = exports.isPtsUpdate = exports.resolve = void 0;
27
27
  const dntShim = __importStar(require("../_dnt.shims.js"));
28
28
  const _0_deps_js_1 = require("../0_deps.js");
29
29
  const _1_utilities_js_1 = require("../1_utilities.js");
30
30
  const _2_tl_js_1 = require("../2_tl.js");
31
+ const _2_types_js_1 = require("../tl/2_types.js");
31
32
  const resolve = () => Promise.resolve();
32
33
  exports.resolve = resolve;
33
34
  function isPtsUpdate(v) {
@@ -105,3 +106,67 @@ function isHttpUrl(string) {
105
106
  }
106
107
  }
107
108
  exports.isHttpUrl = isHttpUrl;
109
+ function isAlpha(string) {
110
+ const c = string.charCodeAt(0) | 0x20;
111
+ return "a".charCodeAt(0) <= c && c <= "z".charCodeAt(0);
112
+ }
113
+ function isDigit(string) {
114
+ const c = string.charCodeAt(0);
115
+ return "0".charCodeAt(0) <= c && c <= "9".charCodeAt(0);
116
+ }
117
+ const errInvalidUsername = (u) => new Error("Invalid username: " + u);
118
+ function validateUsername(string, ignoreAt = false) {
119
+ string = string.trim();
120
+ if (ignoreAt && string.startsWith("@")) {
121
+ string = string.slice(1);
122
+ }
123
+ if (string.length == 0 || string.length > 32) {
124
+ throw errInvalidUsername(string);
125
+ }
126
+ if (!isAlpha(string[0])) {
127
+ throw errInvalidUsername(string);
128
+ }
129
+ for (const c of string) {
130
+ if (!isAlpha(c) && !isDigit(c) && c != "_") {
131
+ throw errInvalidUsername(string);
132
+ }
133
+ }
134
+ if (string[_2_types_js_1.Username.length - 1] == "_") {
135
+ throw errInvalidUsername(string);
136
+ }
137
+ for (let i = 1; i < string.length; ++i) {
138
+ if (string[i - 1] == "_" && string[i] == "_") {
139
+ throw errInvalidUsername(string);
140
+ }
141
+ }
142
+ return string;
143
+ }
144
+ function getUsername(string) {
145
+ let url = null;
146
+ try {
147
+ url = new URL(string);
148
+ }
149
+ catch {
150
+ try {
151
+ url = new URL("https://" + string);
152
+ }
153
+ catch {
154
+ //
155
+ }
156
+ }
157
+ if (url === null || (url.protocol != "http:" && url.protocol != "https:")) {
158
+ return validateUsername(string, true);
159
+ }
160
+ if (url.hostname != "telegram.dog" && url.hostname != "telegram.me" && url.hostname != "t.me" && !url.hostname.endsWith(".t.me")) {
161
+ return validateUsername(string, true);
162
+ }
163
+ if (url.hostname == "telegram.dog" || url.hostname == "telegram.me" || url.hostname == "t.me") {
164
+ return validateUsername(url.pathname.split("/")[1]);
165
+ }
166
+ const parts = url.hostname.split(".");
167
+ if (parts.length != 3) {
168
+ return validateUsername(string);
169
+ }
170
+ return validateUsername(parts[0]);
171
+ }
172
+ exports.getUsername = getUsername;
@@ -0,0 +1 @@
1
+ export {};
@@ -41,6 +41,10 @@ export interface ClientParams extends ClientPlainParams {
41
41
  * Whether to use default handlers. Defaults to `true`.
42
42
  */
43
43
  defaultHandlers?: boolean;
44
+ /**
45
+ * Whether to ignore outgoing messages. Defaults to `true` for bots, and `false` for users.
46
+ */
47
+ ignoreOutgoing?: boolean;
44
48
  }
45
49
  export interface AnswerCallbackQueryParams {
46
50
  /** A text to be shown to the user. */
@@ -1,4 +1,8 @@
1
- import { FilterableUpdates, FilterUpdate, Update } from "./3_types.js";
1
+ import { User } from "../3_types.js";
2
+ import { FilterableUpdates, FilterUpdate, Update as Update_ } from "./3_types.js";
3
+ interface Update extends Update_ {
4
+ me: undefined extends this["connectionState"] ? undefined extends this["authorizationState"] ? User : (User | undefined) : (User | undefined);
5
+ }
2
6
  type MaybePromise<T> = T | Promise<T>;
3
7
  export type NextFunction = () => Promise<void>;
4
8
  export type MiddlewareFn<C extends Update = Update> = (ctx: C, next: NextFunction) => MaybePromise<unknown>;
@@ -18,5 +22,6 @@ export declare class Composer<C extends Update> implements MiddlewareObj<C> {
18
22
  filter<D extends C>(predicate: (ctx: C) => ctx is D, ...middleware: Middleware<D>[]): Composer<D>;
19
23
  filter(predicate: (ctx: C) => MaybePromise<boolean>, ...middleware: Middleware<C>[]): Composer<C>;
20
24
  on<T extends keyof Update, F extends keyof NonNullable<Update[T]>>(filter: T extends FilterableUpdates ? T | [T, F, ...F[]] : T, ...middleawre: Middleware<FilterUpdate<C, T, F>>[]): Composer<FilterUpdate<C, T, F>>;
25
+ command(commands: string | RegExp | (string | RegExp)[], ...middleawre: Middleware<FilterUpdate<C, "message", "text">>[]): Composer<FilterUpdate<C, "message", "text">>;
21
26
  }
22
27
  export {};
@@ -60,7 +60,9 @@ class Composer {
60
60
  });
61
61
  }
62
62
  filter(predicate, ...middleware) {
63
- return this.branch(predicate, middleware.length == 0 ? exports.skip : middleware.map(flatten).reduce(concat), exports.skip);
63
+ const composer = new Composer(...middleware);
64
+ this.branch(predicate, composer, exports.skip);
65
+ return composer;
64
66
  }
65
67
  on(filter, ...middleawre) {
66
68
  const type = typeof filter === "string" ? filter : filter[0];
@@ -83,6 +85,32 @@ class Composer {
83
85
  }
84
86
  }, ...middleawre);
85
87
  }
88
+ command(commands, ...middleawre) {
89
+ const commands_ = Array.isArray(commands) ? commands : [commands];
90
+ return this.on(["message", "text"]).filter((ctx) => {
91
+ const botCommand = ctx.message.entities?.find((v) => v.type == "botCommand");
92
+ if (!botCommand) {
93
+ return false;
94
+ }
95
+ const cmd = ctx.message.text.slice(botCommand.offset, botCommand.offset + botCommand.length);
96
+ if (cmd.includes("@")) {
97
+ const username = cmd.split("@")[1];
98
+ if (username.toLowerCase() !== ctx.me.username?.toLowerCase()) {
99
+ return false;
100
+ }
101
+ }
102
+ const command_ = cmd.split("@")[0].split("/")[1].toLowerCase();
103
+ for (const command of commands_) {
104
+ if (typeof command === "string" && (command.toLowerCase() == command_)) {
105
+ return true;
106
+ }
107
+ else if (command instanceof RegExp && command.test(command_)) {
108
+ return true;
109
+ }
110
+ }
111
+ return false;
112
+ }, ...middleawre);
113
+ }
86
114
  }
87
115
  exports.Composer = Composer;
88
116
  _Composer_handle = new WeakMap();