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
//@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
//@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
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
//@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
//@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
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
//@chat_id Chat identifier

Binary file not shown.

View File

@ -1544,7 +1544,7 @@ class ExportChatInviteLinkQuery : public Td::ResultHandler {
: 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;
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
if (input_peer == nullptr) {
@ -1558,6 +1558,9 @@ class ExportChatInviteLinkQuery : public Td::ResultHandler {
if (usage_limit > 0) {
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(
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 {
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "ExportChatInviteLinkQuery");
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 {
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditChatInviteLinkQuery");
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,
bool is_permanent,
Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise) {
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 {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
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,
bool is_permanent,
Promise<td_api::object_ptr<td_api::chatInviteLink>> &&promise) {
if (G()->close_flag()) {
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));
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,

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 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);
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);
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);
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;
}
}
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 {
@ -74,13 +82,14 @@ td_api::object_ptr<td_api::chatInviteLink> DialogInviteLink::get_chat_invite_lin
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_,
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) {
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.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) {

View File

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

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)));
} else if (op == "dgc") {
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;
int32 expire_date;
int32 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") {
string chat_id;
string invite_link;