Add internalLinkTypeBotAddToChannel.

This commit is contained in:
levlam 2022-04-02 14:51:20 +03:00
parent 7364334ebe
commit fd00755bec
4 changed files with 121 additions and 1 deletions

View File

@ -3354,10 +3354,16 @@ internalLinkTypeBackground background_name:string = InternalLinkType;
internalLinkTypeBotStart bot_username:string start_parameter:string = InternalLinkType;
//@description The link is a link to a Telegram bot, which is supposed to be added to a group chat. Call searchPublicChat with the given bot username, check that the user is a bot and can be added to groups,
//-ask the current user to select a group to add the bot to, and then call sendBotStartMessage with the given start parameter and the chosen group chat. Bots can be added to a public group only by administrators of the group
//-ask the current user to select a basic group or a supergroup chat to add the bot to, and then call sendBotStartMessage with the given start parameter and the chosen chat. Bots can be added to a public supergroup only by administrators of the supergroup
//@bot_username Username of the bot @start_parameter The parameter to be passed to sendBotStartMessage
internalLinkTypeBotStartInGroup bot_username:string start_parameter:string = InternalLinkType;
//@description The link is a link to a Telegram bot, which is supposed to be added to a channel chat as an administrator. Call searchPublicChat with the given bot username and check that the user is a bot,
//-ask the current user to select a channel chat to add the bot to as an administrator. Then call getChatMember to receive the current bot rights in the chat and if the bot already is an administrator,
//-check that the current user can edit its administrator rights and combine received rights with the requested administrator rights. Then show confirmation box to the user, and call setChatMemberStatus with the chosen chat and confirmed rights
//@bot_username Username of the bot @administrator_rights Expected administrator rights for the bot
internalLinkTypeBotAddToChannel bot_username:string administrator_rights:chatAdministratorRights = InternalLinkType;
//@description The link is a link to the change phone number section of the app
internalLinkTypeChangePhoneNumber = InternalLinkType;

View File

@ -12,6 +12,7 @@
#include "td/telegram/ConfigShared.h"
#include "td/telegram/ContactsManager.h"
#include "td/telegram/DialogId.h"
#include "td/telegram/DialogParticipant.h"
#include "td/telegram/Global.h"
#include "td/telegram/MessageEntity.h"
#include "td/telegram/MessageId.h"
@ -102,6 +103,59 @@ static string get_url_query_hash(bool is_tg, const HttpUrlQuery &url_query) {
return string();
}
static AdministratorRights get_administrator_rights(Slice rights, bool for_channel) {
bool can_manage_dialog = false;
bool can_change_info = false;
bool can_post_messages = false;
bool can_edit_messages = false;
bool can_delete_messages = false;
bool can_invite_users = false;
bool can_restrict_members = false;
bool can_pin_messages = false;
bool can_promote_members = false;
bool can_manage_calls = false;
bool is_anonymous = false;
for (auto right : full_split(rights, ' ')) {
if (right == "change_info") {
can_change_info = true;
} else if (right == "post_messages") {
can_post_messages = true;
} else if (right == "edit_messages") {
can_edit_messages = true;
} else if (right == "delete_messages") {
can_delete_messages = true;
} else if (right == "restrict_members") {
can_restrict_members = true;
} else if (right == "invite_users") {
can_invite_users = true;
} else if (right == "pin_messages") {
can_pin_messages = true;
} else if (right == "promote_members") {
can_promote_members = true;
} else if (right == "manage_video_chats") {
can_manage_calls = true;
} else if (right == "anonymous") {
is_anonymous = true;
} else if (right == "manage_chat") {
can_manage_dialog = true;
}
}
if (for_channel) {
can_pin_messages = false;
is_anonymous = false;
if (can_manage_dialog || can_change_info || can_post_messages || can_edit_messages || can_delete_messages ||
can_invite_users || can_promote_members || can_manage_calls) {
can_restrict_members = true;
}
} else {
can_post_messages = false;
can_edit_messages = false;
}
return AdministratorRights(is_anonymous, can_manage_dialog, can_change_info, can_post_messages, can_edit_messages,
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages,
can_promote_members, can_manage_calls);
}
class LinkManager::InternalLinkActiveSessions final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeActiveSessions>();
@ -151,6 +205,21 @@ class LinkManager::InternalLinkBackground final : public InternalLink {
}
};
class LinkManager::InternalLinkBotAddToChannel final : public InternalLink {
string bot_username_;
AdministratorRights administrator_rights_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeBotAddToChannel>(
bot_username_, administrator_rights_.get_chat_administrator_rights_object());
}
public:
InternalLinkBotAddToChannel(string bot_username, AdministratorRights &&administrator_rights)
: bot_username_(std::move(bot_username)), administrator_rights_(std::move(administrator_rights)) {
}
};
class LinkManager::InternalLinkBotStart final : public InternalLink {
string bot_username_;
string start_parameter_;
@ -856,6 +925,13 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
// resolve?domain=<bot_username>&startgroup=<parameter>
return td::make_unique<InternalLinkBotStartInGroup>(std::move(username), arg.second);
}
if (arg.first == "startchannel") {
// resolve?domain=<bot_username>&startchannel&admin=change_info+post_messages+promote_members
auto administrator_rights = get_administrator_rights(url_query.get_arg("admin"), true);
if (administrator_rights != AdministratorRights()) {
return td::make_unique<InternalLinkBotAddToChannel>(std::move(username), std::move(administrator_rights));
}
}
if (arg.first == "game" && !arg.second.empty()) {
// resolve?domain=<bot_username>&game=<short_name>
return td::make_unique<InternalLinkGame>(std::move(username), arg.second);
@ -1154,6 +1230,13 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
// /<bot_username>?startgroup=<parameter>
return td::make_unique<InternalLinkBotStartInGroup>(std::move(username), arg.second);
}
if (arg.first == "startchannel") {
// /<bot_username>?startchannel&admin=change_info+post_messages+promote_members
auto administrator_rights = get_administrator_rights(url_query.get_arg("admin"), true);
if (administrator_rights != AdministratorRights()) {
return td::make_unique<InternalLinkBotAddToChannel>(std::move(username), std::move(administrator_rights));
}
}
if (arg.first == "game" && !arg.second.empty()) {
// /<bot_username>?game=<short_name>
return td::make_unique<InternalLinkGame>(std::move(username), arg.second);

View File

@ -85,6 +85,7 @@ class LinkManager final : public Actor {
class InternalLinkAttachMenuBot;
class InternalLinkAuthenticationCode;
class InternalLinkBackground;
class InternalLinkBotAddToChannel;
class InternalLinkBotStart;
class InternalLinkBotStartInGroup;
class InternalLinkChangePhoneNumber;

View File

@ -109,6 +109,11 @@ TEST(Link, parse_internal_link) {
auto background = [](const td::string &background_name) {
return td::td_api::make_object<td::td_api::internalLinkTypeBackground>(background_name);
};
auto bot_add_to_channel = [](const td::string &bot_username,
td::td_api::object_ptr<td::td_api::chatAdministratorRights> &&administrator_rights) {
return td::td_api::make_object<td::td_api::internalLinkTypeBotAddToChannel>(bot_username,
std::move(administrator_rights));
};
auto bot_start = [](const td::string &bot_username, const td::string &start_parameter) {
return td::td_api::make_object<td::td_api::internalLinkTypeBotStart>(bot_username, start_parameter);
};
@ -640,6 +645,18 @@ TEST(Link, parse_internal_link) {
parse_internal_link("tg:resolve?domain=&startgroup=", unknown_deep_link("tg://resolve?domain=&startgroup="));
parse_internal_link("tg:resolve?domain=telegram&&&&&&&startgroup=%30", bot_start_in_group("telegram", "0"));
parse_internal_link("tg:resolve?domain=username&startchannel", public_chat("username"));
parse_internal_link("tg:resolve?domain=username&startchannel&admin=", public_chat("username"));
parse_internal_link(
"tg:resolve?domain=username&startchannel&admin=post_messages",
bot_add_to_channel("username", td::td_api::make_object<td::td_api::chatAdministratorRights>(
true, false, true, false, false, false, true, false, false, false, false)));
parse_internal_link(
"tg:resolve?domain=username&startchannel&admin=manage_chat+change_info+post_messages+edit_messages+delete_"
"messages+invite_users+restrict_members+pin_messages+promote_members+manage_video_chats+anonymous",
bot_add_to_channel("username", td::td_api::make_object<td::td_api::chatAdministratorRights>(
true, true, true, true, true, true, true, false, true, true, false)));
parse_internal_link("t.me/username/0/a//s/as?startgroup=", bot_start_in_group("username", ""));
parse_internal_link("t.me/username/aasdas?test=1&startgroup=#12312", bot_start_in_group("username", ""));
parse_internal_link("t.me/username/0?startgroup=", bot_start_in_group("username", ""));
@ -649,6 +666,19 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me//username?startgroup=", nullptr);
parse_internal_link("https://telegram.dog/tele%63ram?startgroup=t%63st", bot_start_in_group("telecram", "tcst"));
parse_internal_link("t.me/username?startchannel", public_chat("username"));
parse_internal_link("t.me/username?startchannel&admin=", public_chat("username"));
parse_internal_link(
"t.me/username?startchannel&admin=post_messages",
bot_add_to_channel("username", td::td_api::make_object<td::td_api::chatAdministratorRights>(
true, false, true, false, false, false, true, false, false, false, false)));
parse_internal_link(
"t.me/"
"username?startchannel&admin=manage_chat+change_info+post_messages+edit_messages+delete_messages+invite_users+"
"restrict_members+pin_messages+promote_members+manage_video_chats+anonymous",
bot_add_to_channel("username", td::td_api::make_object<td::td_api::chatAdministratorRights>(
true, true, true, true, true, true, true, false, true, true, false)));
parse_internal_link("tg:resolve?domain=username&game=aasdasd", game("username", "aasdasd"));
parse_internal_link("TG://resolve?domain=username&game=", public_chat("username"));
parse_internal_link("TG://test@resolve?domain=username&game=asd", nullptr);