Improve td_api::getPublicMessageLink: add possibility to get public link for media album, return HTML-code for message embedding.

GitOrigin-RevId: 1a7c774eec4dfde60d460d097be672120d3f9c54
This commit is contained in:
levlam 2018-01-17 00:27:16 +03:00
parent bdd8420abd
commit 4a713beee1
10 changed files with 55 additions and 41 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(TDLib VERSION 1.0.2 LANGUAGES CXX C) project(TDLib VERSION 1.0.3 LANGUAGES CXX C)
if (NOT DEFINED CMAKE_MODULE_PATH) if (NOT DEFINED CMAKE_MODULE_PATH)
set(CMAKE_MODULE_PATH "") set(CMAKE_MODULE_PATH "")

View File

@ -81,7 +81,7 @@ target_link_library(YourLibrary Td::TdJson)
Or you could install `TDLib` and then reference it in your CMakeLists.txt like this: Or you could install `TDLib` and then reference it in your CMakeLists.txt like this:
``` ```
find_package(Td 1.0.2) find_package(Td 1.0.3)
target_link_library(YourLibrary Td::TdJson) target_link_library(YourLibrary Td::TdJson)
``` ```
See [example/cpp/CMakeLists.txt](https://github.com/tdlib/td/tree/master/example/cpp/CMakeLists.txt). See [example/cpp/CMakeLists.txt](https://github.com/tdlib/td/tree/master/example/cpp/CMakeLists.txt).

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
project(TdExample VERSION 1.0 LANGUAGES CXX) project(TdExample VERSION 1.0 LANGUAGES CXX)
find_package(Td 1.0.2 REQUIRED) find_package(Td 1.0.3 REQUIRED)
add_executable(tdjson_example tdjson_example.cpp) add_executable(tdjson_example tdjson_example.cpp)
target_link_libraries(tdjson_example PRIVATE Td::TdJson) target_link_libraries(tdjson_example PRIVATE Td::TdJson)

View File

@ -1531,8 +1531,8 @@ chatReportReasonPornography = ChatReportReason;
chatReportReasonCustom text:string = ChatReportReason; chatReportReasonCustom text:string = ChatReportReason;
//@description Contains a public HTTPS link to a message in a public supergroup or channel @link Message link //@description Contains a public HTTPS link to a message in a public supergroup or channel @link Message link @html HTML-code for embedding the message
publicMessageLink link:string = PublicMessageLink; publicMessageLink link:string html:string = PublicMessageLink;
//@class FileType @description Represents the type of a file //@class FileType @description Represents the type of a file
@ -2098,8 +2098,11 @@ getActiveLiveLocationMessages = Messages;
getChatMessageByDate chat_id:int53 date:int32 = Messages; getChatMessageByDate chat_id:int53 date:int32 = Messages;
//@description Returns a public HTTPS link to a message. Available only for messages in public supergroups and channels @chat_id Identifier of the chat to which the message belongs @message_id Identifier of the message //@description Returns a public HTTPS link to a message. Available only for messages in public supergroups and channels
getPublicMessageLink chat_id:int53 message_id:int53 = PublicMessageLink; //@chat_id Identifier of the chat to which the message belongs
//@message_id Identifier of the message
//@for_album Pass true if a link for a whole media album should be returned
getPublicMessageLink chat_id:int53 message_id:int53 for_album:Bool = PublicMessageLink;
//@description Sends a message. Returns the sent message @chat_id Target chat @reply_to_message_id Identifier of the message to reply to or 0 //@description Sends a message. Returns the sent message @chat_id Target chat @reply_to_message_id Identifier of the message to reply to or 0

Binary file not shown.

View File

@ -378,18 +378,20 @@ class ExportChannelMessageLinkQuery : public Td::ResultHandler {
Promise<Unit> promise_; Promise<Unit> promise_;
ChannelId channel_id_; ChannelId channel_id_;
MessageId message_id_; MessageId message_id_;
bool for_group_;
public: public:
explicit ExportChannelMessageLinkQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) { explicit ExportChannelMessageLinkQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
} }
void send(ChannelId channel_id, MessageId message_id) { void send(ChannelId channel_id, MessageId message_id, bool for_group) {
channel_id_ = channel_id; channel_id_ = channel_id;
message_id_ = message_id; message_id_ = message_id;
for_group_ = for_group;
auto input_channel = td->contacts_manager_->get_input_channel(channel_id); auto input_channel = td->contacts_manager_->get_input_channel(channel_id);
CHECK(input_channel != nullptr); CHECK(input_channel != nullptr);
send_query(G()->net_query_creator().create(create_storer(telegram_api::channels_exportMessageLink( send_query(G()->net_query_creator().create(create_storer(telegram_api::channels_exportMessageLink(
std::move(input_channel), message_id.get_server_message_id().get(), false)))); std::move(input_channel), message_id.get_server_message_id().get(), for_group))));
} }
void on_result(uint64 id, BufferSlice packet) override { void on_result(uint64 id, BufferSlice packet) override {
@ -400,7 +402,8 @@ class ExportChannelMessageLinkQuery : public Td::ResultHandler {
auto ptr = result_ptr.move_as_ok(); auto ptr = result_ptr.move_as_ok();
LOG(DEBUG) << "Receive result for ExportChannelMessageLinkQuery " << to_string(ptr); LOG(DEBUG) << "Receive result for ExportChannelMessageLinkQuery " << to_string(ptr);
td->messages_manager_->on_get_public_message_link({DialogId(channel_id_), message_id_}, std::move(ptr->link_)); td->messages_manager_->on_get_public_message_link({DialogId(channel_id_), message_id_}, for_group_,
std::move(ptr->link_), std::move(ptr->html_));
promise_.set_value(Unit()); promise_.set_value(Unit());
} }
@ -9952,14 +9955,13 @@ bool MessagesManager::is_message_unload_enabled() const {
} }
bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) const { bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) const {
// don't want to unload messages from opened dialogs and messages with resolved public links // don't want to unload messages from opened dialogs
// don't want to unload messages to which there are replies in yet unsent messages // don't want to unload messages to which there are replies in yet unsent messages
// don't want to unload messages with pending web pages // don't want to unload messages with pending web pages
// can't unload from memory last dialog, last database messages, yet unsent messages and active live locations // can't unload from memory last dialog, last database messages, yet unsent messages and active live locations
FullMessageId full_message_id{d->dialog_id, m->message_id}; FullMessageId full_message_id{d->dialog_id, m->message_id};
return !d->is_opened && m->message_id != d->last_message_id && m->message_id != d->last_database_message_id && return !d->is_opened && m->message_id != d->last_message_id && m->message_id != d->last_database_message_id &&
!m->message_id.is_yet_unsent() && m->public_link.empty() && !m->message_id.is_yet_unsent() && active_live_location_full_message_ids_.count(full_message_id) == 0 &&
active_live_location_full_message_ids_.count(full_message_id) == 0 &&
replied_by_yet_unsent_messages_.count(full_message_id) == 0 && replied_by_yet_unsent_messages_.count(full_message_id) == 0 &&
waiting_for_web_page_messages_.count(full_message_id) == 0; waiting_for_web_page_messages_.count(full_message_id) == 0;
} }
@ -10919,51 +10921,51 @@ bool MessagesManager::is_message_edited_recently(FullMessageId full_message_id,
return m->edit_date >= G()->unix_time() - seconds; return m->edit_date >= G()->unix_time() - seconds;
} }
string MessagesManager::get_public_message_link(FullMessageId full_message_id, Promise<Unit> &&promise) { std::pair<string, string> MessagesManager::get_public_message_link(FullMessageId full_message_id, bool for_group,
Promise<Unit> &&promise) {
auto dialog_id = full_message_id.get_dialog_id(); auto dialog_id = full_message_id.get_dialog_id();
auto d = get_dialog_force(dialog_id); auto d = get_dialog_force(dialog_id);
if (d == nullptr) { if (d == nullptr) {
promise.set_error(Status::Error(6, "Chat not found")); promise.set_error(Status::Error(6, "Chat not found"));
return string(); return {};
} }
if (!have_input_peer(dialog_id, AccessRights::Read)) { if (!have_input_peer(dialog_id, AccessRights::Read)) {
promise.set_error(Status::Error(6, "Can't access the chat")); promise.set_error(Status::Error(6, "Can't access the chat"));
return string(); return {};
} }
if (dialog_id.get_type() != DialogType::Channel || if (dialog_id.get_type() != DialogType::Channel ||
td_->contacts_manager_->get_channel_username(dialog_id.get_channel_id()).empty()) { td_->contacts_manager_->get_channel_username(dialog_id.get_channel_id()).empty()) {
promise.set_error(Status::Error( promise.set_error(Status::Error(
6, "Public message links are available only for messages in public supergroups and channel chats")); 6, "Public message links are available only for messages in public supergroups and channel chats"));
return string(); return {};
} }
auto message_id = full_message_id.get_message_id(); auto message_id = full_message_id.get_message_id();
auto message = get_message_force(d, message_id); auto message = get_message_force(d, message_id);
if (message == nullptr) { if (message == nullptr) {
promise.set_error(Status::Error(6, "Message not found")); promise.set_error(Status::Error(6, "Message not found"));
return string(); return {};
} }
if (!message_id.is_server()) { if (!message_id.is_server()) {
promise.set_error(Status::Error(6, "Message is local")); promise.set_error(Status::Error(6, "Message is local"));
return string(); return {};
} }
if (message->public_link.empty()) { auto it = public_message_links_[for_group].find(full_message_id);
if (it == public_message_links_[for_group].end()) {
td_->create_handler<ExportChannelMessageLinkQuery>(std::move(promise)) td_->create_handler<ExportChannelMessageLinkQuery>(std::move(promise))
->send(dialog_id.get_channel_id(), message_id); ->send(dialog_id.get_channel_id(), message_id, for_group);
return string(); return {};
} }
promise.set_value(Unit()); promise.set_value(Unit());
return message->public_link; return it->second;
} }
void MessagesManager::on_get_public_message_link(FullMessageId full_message_id, string url) { void MessagesManager::on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url,
LOG_IF(ERROR, url.empty()) << "Receive empty public link for " << full_message_id; string html) {
auto message = get_message_force(full_message_id); LOG_IF(ERROR, url.empty() && html.empty()) << "Receive empty public link for " << full_message_id;
if (message != nullptr) { public_message_links_[for_group][full_message_id] = {std::move(url), std::move(html)};
message->public_link = std::move(url);
}
} }
Status MessagesManager::delete_dialog_reply_markup(DialogId dialog_id, MessageId message_id) { Status MessagesManager::delete_dialog_reply_markup(DialogId dialog_id, MessageId message_id) {

View File

@ -1106,9 +1106,10 @@ class MessagesManager : public Actor {
bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds); bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds);
string get_public_message_link(FullMessageId full_message_id, Promise<Unit> &&promise); std::pair<string, string> get_public_message_link(FullMessageId full_message_id, bool for_group,
Promise<Unit> &&promise);
void on_get_public_message_link(FullMessageId full_message_id, string url); void on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url, string html);
Status delete_dialog_reply_markup(DialogId dialog_id, MessageId message_id) TD_WARN_UNUSED_RESULT; Status delete_dialog_reply_markup(DialogId dialog_id, MessageId message_id) TD_WARN_UNUSED_RESULT;
@ -1414,8 +1415,6 @@ class MessagesManager : public Actor {
unique_ptr<ReplyMarkup> reply_markup; unique_ptr<ReplyMarkup> reply_markup;
string public_link;
unique_ptr<Message> left; unique_ptr<Message> left;
unique_ptr<Message> right; unique_ptr<Message> right;
@ -2539,6 +2538,8 @@ class MessagesManager : public Actor {
std::unordered_map<int64, std::pair<int64, vector<FullMessageId>>> std::unordered_map<int64, std::pair<int64, vector<FullMessageId>>>
found_fts_messages_; // random_id -> [from_search_id, [full_message_id]...] found_fts_messages_; // random_id -> [from_search_id, [full_message_id]...]
std::unordered_map<FullMessageId, std::pair<string, string>, FullMessageIdHash> public_message_links_[2];
std::unordered_map<int64, tl_object_ptr<td_api::chatEvents>> chat_events_; // random_id -> chat events std::unordered_map<int64, tl_object_ptr<td_api::chatEvents>> chat_events_; // random_id -> chat events
std::unordered_map<int64, tl_object_ptr<td_api::gameHighScores>> game_high_scores_; // random_id -> high scores std::unordered_map<int64, tl_object_ptr<td_api::gameHighScores>> game_high_scores_; // random_id -> high scores

View File

@ -1005,20 +1005,25 @@ class GetMessagesRequest : public RequestOnceActor {
class GetPublicMessageLinkRequest : public RequestActor<> { class GetPublicMessageLinkRequest : public RequestActor<> {
FullMessageId full_message_id_; FullMessageId full_message_id_;
bool for_group_;
string link_; string link_;
string html_;
void do_run(Promise<Unit> &&promise) override { void do_run(Promise<Unit> &&promise) override {
link_ = td->messages_manager_->get_public_message_link(full_message_id_, std::move(promise)); std::tie(link_, html_) =
td->messages_manager_->get_public_message_link(full_message_id_, for_group_, std::move(promise));
} }
void do_send_result() override { void do_send_result() override {
send_result(make_tl_object<td_api::publicMessageLink>(link_)); send_result(make_tl_object<td_api::publicMessageLink>(link_, html_));
} }
public: public:
GetPublicMessageLinkRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id) GetPublicMessageLinkRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id, bool for_group)
: RequestActor(std::move(td), request_id), full_message_id_(DialogId(dialog_id), MessageId(message_id)) { : RequestActor(std::move(td), request_id)
, full_message_id_(DialogId(dialog_id), MessageId(message_id))
, for_group_(for_group) {
} }
}; };
@ -4754,7 +4759,7 @@ void Td::on_request(uint64 id, const td_api::getMessages &request) {
void Td::on_request(uint64 id, const td_api::getPublicMessageLink &request) { void Td::on_request(uint64 id, const td_api::getPublicMessageLink &request) {
CHECK_AUTH(); CHECK_AUTH();
CREATE_REQUEST(GetPublicMessageLinkRequest, request.chat_id_, request.message_id_); CREATE_REQUEST(GetPublicMessageLinkRequest, request.chat_id_, request.message_id_, request.for_album_);
} }
void Td::on_request(uint64 id, const td_api::getFile &request) { void Td::on_request(uint64 id, const td_api::getFile &request) {

View File

@ -187,7 +187,7 @@ class Td final : public NetQueryCallback {
static td_api::object_ptr<td_api::Object> static_request(td_api::object_ptr<td_api::Function> function); static td_api::object_ptr<td_api::Object> static_request(td_api::object_ptr<td_api::Function> function);
private: private:
static constexpr const char *tdlib_version = "1.0.2"; static constexpr const char *tdlib_version = "1.0.3";
static constexpr int32 ONLINE_TIMEOUT = 240; static constexpr int32 ONLINE_TIMEOUT = 240;
void send_result(uint64 id, tl_object_ptr<td_api::Object> object); void send_result(uint64 id, tl_object_ptr<td_api::Object> object);

View File

@ -1764,8 +1764,11 @@ class CliClient final : public Actor {
} else if (op == "gpml") { } else if (op == "gpml") {
string chat_id; string chat_id;
string message_id; string message_id;
std::tie(chat_id, message_id) = split(args); string for_album;
send_request(make_tl_object<td_api::getPublicMessageLink>(as_chat_id(chat_id), as_message_id(message_id))); std::tie(chat_id, args) = split(args);
std::tie(message_id, for_album) = split(args);
send_request(make_tl_object<td_api::getPublicMessageLink>(as_chat_id(chat_id), as_message_id(message_id),
as_bool(for_album)));
} else if (op == "gcmbd") { } else if (op == "gcmbd") {
string chat_id; string chat_id;
string date; string date;