Support permanent invite links.

This commit is contained in:
levlam 2021-01-13 18:16:33 +03:00
parent 5016197cf9
commit 1816a6c7a5
8 changed files with 36 additions and 15 deletions

View File

@ -887,8 +887,9 @@ chatsNearby users_nearby:vector<chatNearby> supergroups_nearby:vector<chatNearby
//@description Contains a chat invite link @invite_link Chat invite link @administrator_user_id User identifier of an administrator created the link //@description Contains a chat invite link @invite_link Chat invite link @administrator_user_id User identifier of an administrator created the link
//@date Point in time (Unix timestamp) when the link was created @expire_date Point in time (Unix timestamp) when the link will expire; 0 if never //@date Point in time (Unix timestamp) when the link was created @expire_date Point in time (Unix timestamp) when the link will expire; 0 if never
//@usage_limit Maximum number of times the link can be used; 0 if not limited @usage_count Number of times the link has already been used //@usage_limit Maximum number of times the link can be used; 0 if not limited @usage_count Number of times the link has already been used
//@is_permanent True, if the link is permanent. Permanent invite link can't have expire date or usage limit. There is exactly one permanent invite link for each administrator at any time
//@is_expired True, if the link is already expired @is_revoked True, if the link was revoked //@is_expired True, if the link is already expired @is_revoked True, if the link was revoked
chatInviteLink invite_link:string administrator_user_id:int32 date:int32 expire_date:int32 usage_limit:int32 usage_count:int32 is_expired:Bool is_revoked:Bool = ChatInviteLink; chatInviteLink invite_link:string administrator_user_id:int32 date:int32 expire_date:int32 usage_limit:int32 usage_count:int32 is_permanent:Bool is_expired:Bool is_revoked:Bool = ChatInviteLink;
//@description Contains information about a chat invite link //@description Contains information about a chat invite link
//@chat_id Chat identifier of the invite link; 0 if the user has no access to the chat before joining //@chat_id Chat identifier of the invite link; 0 if the user has no access to the chat before joining
@ -4353,7 +4354,8 @@ deleteFile file_id:int32 = Ok;
//@chat_id Chat identifier //@chat_id Chat identifier
//@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never
//@usage_limit Maximum number of times the link can be used; pass 0 if not limited //@usage_limit Maximum number of times the link can be used; pass 0 if not limited
createChatInviteLink chat_id:int53 expire_date:int32 usage_limit:int32 = ChatInviteLink; //@is_permanent True, if new permanent chat link needs to be created instead of the previous
createChatInviteLink chat_id:int53 expire_date:int32 usage_limit:int32 is_permanent:Bool = ChatInviteLink;
//@description Edits an invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right //@description Edits an invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right
//@chat_id Chat identifier //@chat_id Chat identifier

Binary file not shown.

View File

@ -1544,7 +1544,7 @@ class ExportChatInviteLinkQuery : public Td::ResultHandler {
: promise_(std::move(promise)) { : promise_(std::move(promise)) {
} }
void send(DialogId dialog_id, int32 expire_date, int32 usage_limit) { void send(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool is_permanent) {
dialog_id_ = dialog_id; dialog_id_ = dialog_id;
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
if (input_peer == nullptr) { if (input_peer == nullptr) {
@ -1558,6 +1558,9 @@ class ExportChatInviteLinkQuery : public Td::ResultHandler {
if (usage_limit > 0) { if (usage_limit > 0) {
flags |= telegram_api::messages_exportChatInvite::USAGE_LIMIT_MASK; flags |= telegram_api::messages_exportChatInvite::USAGE_LIMIT_MASK;
} }
if (is_permanent) {
flags |= telegram_api::messages_exportChatInvite::LEGACY_REVOKE_PERMANENT_MASK;
}
send_query(G()->net_query_creator().create(telegram_api::messages_exportChatInvite( send_query(G()->net_query_creator().create(telegram_api::messages_exportChatInvite(
flags, false /*ignored*/, std::move(input_peer), expire_date, usage_limit))); flags, false /*ignored*/, std::move(input_peer), expire_date, usage_limit)));
} }
@ -1582,8 +1585,8 @@ class ExportChatInviteLinkQuery : public Td::ResultHandler {
} }
void on_error(uint64 id, Status status) override { void on_error(uint64 id, Status status) override {
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "ExportChatInviteLinkQuery");
promise_.set_error(std::move(status)); promise_.set_error(std::move(status));
td->updates_manager_->get_difference("ExportChatInviteLinkQuery");
} }
}; };
@ -1636,8 +1639,8 @@ class EditChatInviteLinkQuery : public Td::ResultHandler {
} }
void on_error(uint64 id, Status status) override { void on_error(uint64 id, Status status) override {
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditChatInviteLinkQuery");
promise_.set_error(std::move(status)); promise_.set_error(std::move(status));
td->updates_manager_->get_difference("EditChatInviteLinkQuery");
} }
}; };
@ -6568,21 +6571,23 @@ Status ContactsManager::can_manage_dialog_invite_links(DialogId dialog_id) {
} }
void ContactsManager::export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit, void ContactsManager::export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit,
bool is_permanent,
Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise) { Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise) {
LOG(INFO) << "Receive CreateDialogInviteLink request for " << dialog_id; LOG(INFO) << "Receive CreateDialogInviteLink request for " << dialog_id;
get_me(PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, expire_date, usage_limit, get_me(PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, expire_date, usage_limit, is_permanent,
promise = std::move(promise)](Result<Unit> &&result) mutable { promise = std::move(promise)](Result<Unit> &&result) mutable {
if (result.is_error()) { if (result.is_error()) {
promise.set_error(result.move_as_error()); promise.set_error(result.move_as_error());
} else { } else {
send_closure(actor_id, &ContactsManager::export_dialog_invite_link_impl, dialog_id, expire_date, usage_limit, send_closure(actor_id, &ContactsManager::export_dialog_invite_link_impl, dialog_id, expire_date, usage_limit,
std::move(promise)); is_permanent, std::move(promise));
} }
})); }));
} }
void ContactsManager::export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit, void ContactsManager::export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit,
bool is_permanent,
Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise) { Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise) {
if (G()->close_flag()) { if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted")); return promise.set_error(Status::Error(500, "Request aborted"));
@ -6590,7 +6595,8 @@ void ContactsManager::export_dialog_invite_link_impl(DialogId dialog_id, int32 e
TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id));
td_->create_handler<ExportChatInviteLinkQuery>(std::move(promise))->send(dialog_id, expire_date, usage_limit); td_->create_handler<ExportChatInviteLinkQuery>(std::move(promise))
->send(dialog_id, expire_date, usage_limit, is_permanent);
} }
void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string &invite_link, int32 expire_date, void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string &invite_link, int32 expire_date,

View File

@ -389,7 +389,7 @@ class ContactsManager : public Actor {
void transfer_dialog_ownership(DialogId dialog_id, UserId user_id, const string &password, Promise<Unit> &&promise); void transfer_dialog_ownership(DialogId dialog_id, UserId user_id, const string &password, Promise<Unit> &&promise);
void export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit, void export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool is_permanent,
Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise); Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise);
void edit_dialog_invite_link(DialogId dialog_id, const string &link, int32 expire_date, int32 usage_limit, void edit_dialog_invite_link(DialogId dialog_id, const string &link, int32 expire_date, int32 usage_limit,
@ -1345,7 +1345,7 @@ class ContactsManager : public Actor {
static bool is_channel_public(const Channel *c); static bool is_channel_public(const Channel *c);
void export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit, void export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool is_permanent,
Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise); Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise);
void remove_dialog_access_by_invite_link(DialogId dialog_id); void remove_dialog_access_by_invite_link(DialogId dialog_id);

View File

@ -48,6 +48,14 @@ DialogInviteLink::DialogInviteLink(tl_object_ptr<telegram_api::chatInviteExporte
usage_count_ = 0; usage_count_ = 0;
} }
} }
is_revoked_ = exported_invite->revoked_;
is_permanent_ = exported_invite->permanent_;
if (is_permanent_ && (usage_limit_ > 0 || expire_date_ > 0)) {
LOG(ERROR) << "Receive wron permanent " << *this;
expire_date_ = 0;
usage_limit_ = 0;
}
} }
bool DialogInviteLink::is_expired() const { bool DialogInviteLink::is_expired() const {
@ -74,13 +82,14 @@ td_api::object_ptr<td_api::chatInviteLink> DialogInviteLink::get_chat_invite_lin
return td_api::make_object<td_api::chatInviteLink>( return td_api::make_object<td_api::chatInviteLink>(
invite_link_, contacts_manager->get_user_id_object(administrator_user_id_, "get_chat_invite_link_object"), date_, invite_link_, contacts_manager->get_user_id_object(administrator_user_id_, "get_chat_invite_link_object"), date_,
expire_date_, usage_limit_, usage_count_, is_expired(), is_revoked_); expire_date_, usage_limit_, usage_count_, is_permanent_, is_expired(), is_revoked_);
} }
bool operator==(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { bool operator==(const DialogInviteLink &lhs, const DialogInviteLink &rhs) {
return lhs.invite_link_ == rhs.invite_link_ && lhs.administrator_user_id_ == rhs.administrator_user_id_ && return lhs.invite_link_ == rhs.invite_link_ && lhs.administrator_user_id_ == rhs.administrator_user_id_ &&
lhs.date_ == rhs.date_ && lhs.expire_date_ == rhs.expire_date_ && lhs.usage_limit_ == rhs.usage_limit_ && lhs.date_ == rhs.date_ && lhs.expire_date_ == rhs.expire_date_ && lhs.usage_limit_ == rhs.usage_limit_ &&
lhs.usage_count_ == rhs.usage_count_ && lhs.is_revoked_ == rhs.is_revoked_; lhs.usage_count_ == rhs.usage_count_ && lhs.is_permanent_ == rhs.is_permanent_ &&
lhs.is_revoked_ == rhs.is_revoked_;
} }
bool operator!=(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { bool operator!=(const DialogInviteLink &lhs, const DialogInviteLink &rhs) {

View File

@ -26,6 +26,7 @@ class DialogInviteLink {
int32 usage_limit_ = 0; int32 usage_limit_ = 0;
int32 usage_count_ = 0; int32 usage_count_ = 0;
bool is_revoked_ = false; bool is_revoked_ = false;
bool is_permanent_ = false;
friend bool operator==(const DialogInviteLink &lhs, const DialogInviteLink &rhs); friend bool operator==(const DialogInviteLink &lhs, const DialogInviteLink &rhs);
@ -58,6 +59,7 @@ class DialogInviteLink {
bool has_usage_count = usage_count_ != 0; bool has_usage_count = usage_count_ != 0;
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(is_revoked_); STORE_FLAG(is_revoked_);
STORE_FLAG(is_permanent_);
STORE_FLAG(has_expire_date); STORE_FLAG(has_expire_date);
STORE_FLAG(has_usage_limit); STORE_FLAG(has_usage_limit);
STORE_FLAG(has_usage_count); STORE_FLAG(has_usage_count);
@ -84,6 +86,7 @@ class DialogInviteLink {
bool has_usage_count; bool has_usage_count;
BEGIN_PARSE_FLAGS(); BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_revoked_); PARSE_FLAG(is_revoked_);
PARSE_FLAG(is_permanent_);
PARSE_FLAG(has_expire_date); PARSE_FLAG(has_expire_date);
PARSE_FLAG(has_usage_limit); PARSE_FLAG(has_usage_limit);
PARSE_FLAG(has_usage_count); PARSE_FLAG(has_usage_count);

View File

@ -6278,7 +6278,7 @@ void Td::on_request(uint64 id, td_api::getChatAdministrators &request) {
void Td::on_request(uint64 id, const td_api::createChatInviteLink &request) { void Td::on_request(uint64 id, const td_api::createChatInviteLink &request) {
CREATE_REQUEST_PROMISE(); CREATE_REQUEST_PROMISE();
contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), request.expire_date_, request.usage_limit_, contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), request.expire_date_, request.usage_limit_,
std::move(promise)); request.is_permanent_, std::move(promise));
} }
void Td::on_request(uint64 id, td_api::editChatInviteLink &request) { void Td::on_request(uint64 id, td_api::editChatInviteLink &request) {

View File

@ -2682,12 +2682,13 @@ class CliClient final : public Actor {
send_request(td_api::make_object<td_api::leaveGroupCall>(as_group_call_id(args))); send_request(td_api::make_object<td_api::leaveGroupCall>(as_group_call_id(args)));
} else if (op == "dgc") { } else if (op == "dgc") {
send_request(td_api::make_object<td_api::discardGroupCall>(as_group_call_id(args))); send_request(td_api::make_object<td_api::discardGroupCall>(as_group_call_id(args)));
} else if (op == "gcil") { } else if (op == "ccilp" || op == "ccilt") {
string chat_id; string chat_id;
int32 expire_date; int32 expire_date;
int32 usage_limit; int32 usage_limit;
get_args(args, chat_id, expire_date, usage_limit); get_args(args, chat_id, expire_date, usage_limit);
send_request(td_api::make_object<td_api::createChatInviteLink>(as_chat_id(chat_id), expire_date, usage_limit)); send_request(td_api::make_object<td_api::createChatInviteLink>(as_chat_id(chat_id), expire_date, usage_limit,
op == "ccilp"));
} else if (op == "ecil") { } else if (op == "ecil") {
string chat_id; string chat_id;
string invite_link; string invite_link;