Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/client/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,16 @@ class BaseClient extends EventEmitter {
>("setChatAdministratorCustomTitle", toSnakeCase(params));
}

/** Use this method to set a custom tag for a member of a supergroup. Returns True on success. */
async setChatMemberTag(
params: MethodParameters["setChatMemberTag"],
): Promise<MethodsLibReturnType["setChatMemberTag"]> {
return this.rest.request<true>(
"setChatMemberTag",
toSnakeCase(params),
);
}

/** Use this method to ban a channel chat in a supergroup or a channel. Until the chat is unbanned, the owner of the banned chat won't be able to send messages on behalf of any of their channels. The bot must be an administrator in the supergroup or channel for this to work and must have the appropriate administrator rights. Returns True on success. */
async banChatSenderChat(
chatId: number | string,
Expand Down
7 changes: 4 additions & 3 deletions src/client/interfaces/Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface User {
/** User's or bot's username */
username?: string;
/** IETF language tag of the user's language */
language_code?: LanguageCode;
language_code?: string;
/** True, if this user is a Telegram Premium user */
is_premium?: true;
/** True, if this user added the bot to the attachment menu */
Expand All @@ -36,7 +36,7 @@ export interface LinkPreviewOptions {

export declare namespace MessageEntity {
interface AbstractMessageEntity {
/** Type of the entity. Currently, can be “mention” (@username), “hashtag” (#hashtag), “cashtag” ($USD), “bot_command” (/start@jobs_bot), “url” (https://telegram.org), “email” (do-not-reply@telegram.org), “phone_number” (+1-212-555-0123), “bold” (bold text), “italic” (italic text), “underline” (underlined text), “strikethrough” (strikethrough text), “spoiler” (spoiler message), “blockquote” (block quotation), “expandable_blockquote” (collapsed-by-default block quotation), “code” (monowidth string), “pre” (monowidth block), “text_link” (for clickable text URLs), “text_mention” (for users without usernames), “custom_emoji” (for inline custom emoji stickers) */
/** Type of the entity. Currently, can be “mention” (@username), “hashtag” (#hashtag), “cashtag” ($USD), “bot_command” (/start@jobs_bot), “url” (https://telegram.org), “email” (do-not-reply@telegram.org), “phone_number” (+1-212-555-0123), “bold” (bold text), “italic” (italic text), “underline” (underlined text), “strikethrough” (strikethrough text), “spoiler” (spoiler message), “blockquote” (block quotation), “expandable_blockquote” (collapsed-by-default block quotation), “code” (monowidth string), “pre” (monowidth block), “text_link” (for clickable text URLs), “text_mention” (for users without usernames), “custom_emoji” (for inline custom emoji stickers), “date_time” (for a formatted date and time) */
type: string;
/** Offset in UTF-16 code units to the start of the entity */
offset: number;
Expand All @@ -59,7 +59,8 @@ export declare namespace MessageEntity {
| "spoiler"
| "blockquote"
| "expandable_blockquote"
| "code";
| "code"
| "date_time";
}
export interface PreMessageEntity extends AbstractMessageEntity {
type: "pre";
Expand Down
10 changes: 10 additions & 0 deletions src/client/interfaces/Methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,16 @@ export type ApiMethods = {
customTitle: string;
}): true;

/** Use this method to set a custom tag for a member of a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns True on success. */
setChatMemberTag(args: {
/** Unique identifier for the target supergroup (in the format @supergroupusername) */
chatId: number | string;
/** Unique identifier of the target user */
userId: string | number;
/** New tag for the member; 0-32 characters */
tag?: string;
}): true;

/** Use this method to ban a channel chat in a supergroup or a channel. Until the chat is unbanned, the owner of the banned chat won't be able to send messages on behalf of any of their channels. The bot must be an administrator in the supergroup or channel for this to work and must have the appropriate administrator rights. Returns True on success. */
banChatSenderChat(args: {
/** Unique identifier for the target chat or username of the target channel (in the format @channelusername) */
Expand Down
4 changes: 4 additions & 0 deletions src/structures/chat/ChatAdministratorRights.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class ChatAdministratorRights {
permissions.manageTopics = data.can_manage_topics;
}

if ("can_manage_tags" in data) {
permissions.manageTags = Boolean(data.can_manage_tags);
}

/** Represents the rights of an administrator in a chat */
this.permissions = new ChatPermissions(permissions);
}
Expand Down
34 changes: 34 additions & 0 deletions src/structures/chat/ChatMember.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class ChatMember extends Base {
permissions.manageTopics = data.can_manage_topics;
}

if ("can_manage_tags" in data) {
permissions.manageTags = Boolean(data.can_manage_tags);
}

if ("can_send_messages" in data) {
permissions.sendMessages = data.can_send_messages;
}
Expand Down Expand Up @@ -127,6 +131,10 @@ class ChatMember extends Base {
permissions.addWebPagePreviews = data.can_add_web_page_previews;
}

if ("can_edit_tag" in data) {
permissions.editTag = Boolean(data.can_edit_tag);
}

/** Represents the rights of an administrator in a chat */
this.permissions = new UserPermissions(
this.status === "creator" ? UserPermissions.Flags : permissions,
Expand Down Expand Up @@ -162,6 +170,14 @@ class ChatMember extends Base {
this.nickName = data.custom_title;
}

if ("tag" in data) {
/**
* Custom tag for this member
* @type {string | undefined}
*/
this.tag = typeof data.tag === "string" ? data.tag : undefined;
}

if ("is_member" in data) {
/**
* True, if the user is a member of the chat at the moment of the request
Expand Down Expand Up @@ -335,6 +351,23 @@ class ChatMember extends Base {
});
}

/**
* Use this method to set a custom tag for a member of a supergroup.
* @param {string} [tag] - New tag for the member; 0-32 characters
* @returns {Promise<true>} - Returns True on success.
*/
setTag(tag) {
if (!this.id) {
throw new TelegramError(ErrorCodes.UserIdNotAvailable);
}

return this.client.setChatMemberTag({
chatId: this.chatId,
userId: this.id,
...(tag !== undefined && { tag }),
});
}

/**
* Checks if this member is equal to another member.
* @param {ChatMember} other - The other object to compare with.
Expand All @@ -353,6 +386,7 @@ class ChatMember extends Base {
this.user.equals(other.user) &&
this.anonymous === other.anonymous &&
this.nickName === other.nickName &&
this.tag === other.tag &&
this.isMember === other.isMember &&
this.untilUnixTime === other.untilUnixTime
);
Expand Down
9 changes: 9 additions & 0 deletions src/structures/message/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,15 @@ class Message extends Base {
this.senderBusinessBot = this.client.users._add(data.sender_business_bot);
}

if ("sender_tag" in data) {
/**
* For messages in channels and replies to channel messages in supergroups, the tag of the message sender
* @type {string | undefined}
*/
this.senderTag =
typeof data.sender_tag === "string" ? data.sender_tag : undefined;
}

if ("forward_origin" in data) {
/**
* Information about the original message for forwarded messages
Expand Down
13 changes: 11 additions & 2 deletions src/structures/message/MessageEntities.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,17 @@ class MessageEntities extends Base {
);
}

/**
* Retrieves all date_time entities from the message.
* @returns {import("@telegram.ts/collection").ReadonlyCollection<number, SearchResult>} A collection of date_time entities.
*/
get dateTime() {
return this.searchEntity("date_time");
}

/**
* Searches for a specific type of entity in the message.
* @param {"mention" | "hashtag" | "cashtag" | "bot_command" | "url" | "email" | "phone_number" | "bold" | "italic" | "underline" | "strikethrough" | "spoiler" | "blockquote" | "code" | "pre" | "text_link" | "text_mention" | "custom_emoji"} searchType - The type of entity to search for.
* @param {"mention" | "hashtag" | "cashtag" | "bot_command" | "url" | "email" | "phone_number" | "bold" | "italic" | "underline" | "strikethrough" | "spoiler" | "blockquote" | "code" | "pre" | "text_link" | "text_mention" | "custom_emoji" | "date_time"} searchType - The type of entity to search for.
* @returns {import("@telegram.ts/collection").ReadonlyCollection<number, SearchResult & ({ language?: import("../../client/interfaces/Language").LanguageCode } | { url: string } | { user: User } | { customEmojiId: string })>} A collection of found entities.
*/
searchEntity(searchType) {
Expand Down Expand Up @@ -218,7 +226,7 @@ class MessageEntities extends Base {
/**
* Enables iteration over the message entities.
* @returns {Generator<(SearchResult & ({ type: "mention" | "hashtag" | "cashtag" | "botCommand" | "url" | "email" |
"phoneNumber" | "bold" | "italic" | "underline" | "strikethrough" | "spoiler" | "blockquote" | "code" | { type: "pre", language?: import("../../client/interfaces/Language").LanguageCode } | { type: "text_link", url: string } | { type: "text_mention", user: User } | { type: "customEmoji", customEmojiId: string }}))>} An iterator over the message entities.
"phoneNumber" | "bold" | "italic" | "underline" | "strikethrough" | "spoiler" | "blockquote" | "code" | "dateTime" | { type: "pre", language?: import("../../client/interfaces/Language").LanguageCode } | { type: "text_link", url: string } | { type: "text_mention", user: User } | { type: "customEmoji", customEmojiId: string }}))>} An iterator over the message entities.
*/
*[Symbol.iterator]() {
/** @type {(keyof MessageEntities)[]} */
Expand All @@ -241,6 +249,7 @@ class MessageEntities extends Base {
"textLink",
"textMention",
"customEmoji",
"dateTime",
];

const allEntities = new Collection();
Expand Down
2 changes: 1 addition & 1 deletion src/structures/message/MessageOrigin.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ class MessageOrigin extends Base {
/**
* Use this method to edit a checklist on behalf of a connected business account.
* @param {string} businessConnectionId - Unique identifier of the business connection on behalf of which the message will be sent.
* @param {import("@telegram.ts/types").InputChecklist} checklist - An object for the new checklist.
* @param {import("../../client/interfaces/Checklist").InputChecklist} checklist - An object for the new checklist.
* @param {Omit<MethodParameters["editMessageChecklist"], "messageId" | "chatId" | "checklist" | "businessConnectionId">} [options] - out parameters.
* @returns {Promise<import("./Message").Message & { checklist: import("../checklist/Checklist").Checklist }>} - On success, the edited Message is returned.
*/
Expand Down
6 changes: 1 addition & 5 deletions src/structures/misc/User.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// @ts-check
const { Base } = require("../Base");

/**
* @typedef {import("../../client/interfaces/Language").LanguageCode} LanguageCode
*/

/**
* @typedef {import("../../types").MethodParameters} MethodParameters
*/
Expand Down Expand Up @@ -55,7 +51,7 @@ class User extends Base {
if ("language_code" in data) {
/**
* IETF language tag of the user's language
* @type {LanguageCode | undefined}
* @type {string | undefined}
*/
this.language = data.language_code;
}
Expand Down
3 changes: 3 additions & 0 deletions src/util/permission/ApiPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const ApiPermissionsFlags = {
editStories: "can_edit_stories",
deleteStories: "can_delete_stories",
manageTopics: "can_manage_topics",
manageTags: "can_manage_tags",
editTag: "can_edit_tag",
manageDirectMessages: "can_manage_direct_messages",
} as const;

/**
Expand Down
10 changes: 8 additions & 2 deletions src/util/permission/ChatPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
type ChatPermissionString =
| "isAnonymous"
| "editTag"
| "sendMessages"
| "sendAudios"
| "sendDocuments"
Expand All @@ -17,13 +18,15 @@ type ChatPermissionString =
| "inviteUsers"
| "pinMessages"
| "manageTopics"
| "manageTags"
| "manageDirectMessages";

/**
* Interface representing the chat permission flags.
*/
interface ChatPermissionFlags {
isAnonymous?: boolean;
editTag?: boolean;
sendMessages?: boolean;
sendAudios?: boolean;
sendDocuments?: boolean;
Expand All @@ -38,6 +41,7 @@ interface ChatPermissionFlags {
inviteUsers?: boolean;
pinMessages?: boolean;
manageTopics?: boolean;
manageTags?: boolean;
manageDirectMessages?: boolean;
}

Expand Down Expand Up @@ -194,8 +198,10 @@ class ChatPermissions {
inviteUsers: 12,
pinMessages: 13,
manageTopics: 14,
manageDirectMessages: 15,
isAnonymous: 16,
manageTags: 15,
manageDirectMessages: 16,
isAnonymous: 17,
editTag: 18,
};
}

Expand Down
5 changes: 4 additions & 1 deletion src/util/permission/UserPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type UserPermissionString =
| "editMessages"
| "pinMessages"
| "manageTopics"
| "manageTags"
| "manageDirectMessages";

/**
Expand All @@ -36,6 +37,7 @@ interface UserPermissionFlags {
editMessages?: boolean;
pinMessages?: boolean;
manageTopics?: boolean;
manageTags?: boolean;
manageDirectMessages?: boolean;
}

Expand Down Expand Up @@ -192,7 +194,8 @@ class UserPermissions {
editMessages: 12,
pinMessages: 13,
manageTopics: 14,
manageDirectMessages: 15,
manageTags: 15,
manageDirectMessages: 16,
Comment on lines +197 to +198

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add editTag to user permission flags

ChatMember now reads can_edit_tag, but UserPermissions still does not define editTag in its canonical flag set. Because creator/admin permission snapshots are synthesized from UserPermissions.Flags (for example in ChatMember creator initialization and Chat.memberPermissions(..., checkAdmin=true)), this new right is silently dropped in those flows, so consumers cloning/promoting permissions cannot preserve can_edit_tag.

Useful? React with 👍 / 👎.

};
}

Expand Down
Loading
Loading