Add td_api::messageStory and td_api::inputMessageStory.
This commit is contained in:
parent
9a8262f146
commit
686f0eabe6
@ -2530,6 +2530,12 @@ messageGame game:game = MessageContent;
|
||||
//@description A message with a poll @poll The poll description
|
||||
messagePoll poll:poll = MessageContent;
|
||||
|
||||
//@description A message with a forwarded story
|
||||
//@sender_user_id Identifier of the user that created the story
|
||||
//@story_id Story identifier
|
||||
//@via_mention True, if the story was forwarded because of a mention of the user
|
||||
messageStory sender_user_id:int53 story_id:int32 via_mention:Bool = MessageContent;
|
||||
|
||||
//@description A message with an invoice from a bot. Use getInternalLink with internalLinkTypeBotStart to share the invoice
|
||||
//@title Product title
|
||||
//@param_description Product description
|
||||
@ -2916,6 +2922,11 @@ inputMessageInvoice invoice:invoice title:string description:string photo_url:st
|
||||
//@is_closed True, if the poll needs to be sent already closed; for bots only
|
||||
inputMessagePoll question:string options:vector<string> is_anonymous:Bool type:PollType open_period:int32 close_date:int32 is_closed:Bool = InputMessageContent;
|
||||
|
||||
//@description A message with a forwarded story. Stories can't be sent to secret chats. A story can be forwarded only if it is available to everyone
|
||||
//@sender_user_id Identifier of the user that created the story
|
||||
//@story_id Story identifier
|
||||
inputMessageStory sender_user_id:int53 story_id:int32 = InputMessageContent;
|
||||
|
||||
//@description A forwarded message
|
||||
//@from_chat_id Identifier for the chat this forwarded message came from
|
||||
//@message_id Identifier of the message to forward
|
||||
|
@ -410,6 +410,7 @@ bool DialogAction::is_canceled_by_message_of_type(MessageContentType message_con
|
||||
case MessageContentType::RequestedDialog:
|
||||
case MessageContentType::WebViewWriteAccessAllowed:
|
||||
case MessageContentType::SetBackground:
|
||||
case MessageContentType::Story:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
@ -71,6 +71,8 @@
|
||||
#include "td/telegram/StickersManager.h"
|
||||
#include "td/telegram/StickersManager.hpp"
|
||||
#include "td/telegram/StickerType.h"
|
||||
#include "td/telegram/StoryFullId.h"
|
||||
#include "td/telegram/StoryManager.h"
|
||||
#include "td/telegram/Td.h"
|
||||
#include "td/telegram/TopDialogManager.h"
|
||||
#include "td/telegram/UserId.h"
|
||||
@ -473,7 +475,7 @@ class MessageChatSetTtl final : public MessageContent {
|
||||
|
||||
class MessageUnsupported final : public MessageContent {
|
||||
public:
|
||||
static constexpr int32 CURRENT_VERSION = 18;
|
||||
static constexpr int32 CURRENT_VERSION = 19;
|
||||
int32 version = CURRENT_VERSION;
|
||||
|
||||
MessageUnsupported() = default;
|
||||
@ -913,6 +915,20 @@ class MessageSetBackground final : public MessageContent {
|
||||
}
|
||||
};
|
||||
|
||||
class MessageStory final : public MessageContent {
|
||||
public:
|
||||
StoryFullId story_full_id;
|
||||
bool via_mention = false;
|
||||
|
||||
MessageStory() = default;
|
||||
MessageStory(StoryFullId story_full_id, bool via_mention) : story_full_id(story_full_id), via_mention(via_mention) {
|
||||
}
|
||||
|
||||
MessageContentType get_type() const final {
|
||||
return MessageContentType::Story;
|
||||
}
|
||||
};
|
||||
|
||||
template <class StorerT>
|
||||
static void store(const MessageContent *content, StorerT &storer) {
|
||||
CHECK(content != nullptr);
|
||||
@ -1305,6 +1321,14 @@ static void store(const MessageContent *content, StorerT &storer) {
|
||||
store(m->background_info, storer);
|
||||
break;
|
||||
}
|
||||
case MessageContentType::Story: {
|
||||
const auto *m = static_cast<const MessageStory *>(content);
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(m->via_mention);
|
||||
END_STORE_FLAGS();
|
||||
store(m->story_full_id, storer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -1836,6 +1860,15 @@ static void parse(unique_ptr<MessageContent> &content, ParserT &parser) {
|
||||
content = std::move(m);
|
||||
break;
|
||||
}
|
||||
case MessageContentType::Story: {
|
||||
auto m = make_unique<MessageStory>();
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(m->via_mention);
|
||||
END_PARSE_FLAGS();
|
||||
parse(m->story_full_id, parser);
|
||||
content = std::move(m);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG(FATAL) << "Have unknown message content type " << static_cast<int32>(content_type);
|
||||
}
|
||||
@ -2249,6 +2282,20 @@ static Result<InputMessageContent> create_input_message_content(
|
||||
std::move(explanation), open_period, close_date, is_closed));
|
||||
break;
|
||||
}
|
||||
case td_api::inputMessageStory::ID: {
|
||||
auto input_story = static_cast<td_api::inputMessageStory *>(input_message_content.get());
|
||||
UserId user_id(input_story->sender_user_id_);
|
||||
StoryId story_id(input_story->story_id_);
|
||||
StoryFullId story_full_id(DialogId(user_id), story_id);
|
||||
if (!td->story_manager_->have_story(story_full_id)) {
|
||||
return Status::Error(400, "Story not found");
|
||||
}
|
||||
if (td->contacts_manager_->get_input_user(user_id).is_error()) {
|
||||
return Status::Error(400, "Can't access the user");
|
||||
}
|
||||
content = make_unique<MessageStory>(story_full_id, false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -2367,6 +2414,12 @@ bool can_have_input_media(const Td *td, const MessageContent *content, bool is_s
|
||||
return is_server || static_cast<const MessageGame *>(content)->game.has_input_media();
|
||||
case MessageContentType::Poll:
|
||||
return td->poll_manager_->has_input_media(static_cast<const MessagePoll *>(content)->poll_id);
|
||||
case MessageContentType::Story: {
|
||||
auto story_full_id = static_cast<const MessageStory *>(content)->story_full_id;
|
||||
auto dialog_id = story_full_id.get_dialog_id();
|
||||
CHECK(dialog_id.get_type() == DialogType::User);
|
||||
return td->contacts_manager_->get_input_user(dialog_id.get_user_id()).is_ok();
|
||||
}
|
||||
case MessageContentType::Unsupported:
|
||||
case MessageContentType::ChatCreate:
|
||||
case MessageContentType::ChatChangeTitle:
|
||||
@ -2496,6 +2549,7 @@ SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td,
|
||||
case MessageContentType::Invoice:
|
||||
case MessageContentType::LiveLocation:
|
||||
case MessageContentType::Poll:
|
||||
case MessageContentType::Story:
|
||||
case MessageContentType::Unsupported:
|
||||
case MessageContentType::ChatCreate:
|
||||
case MessageContentType::ChatChangeTitle:
|
||||
@ -2605,6 +2659,10 @@ static tl_object_ptr<telegram_api::InputMedia> get_input_media_impl(
|
||||
return td->stickers_manager_->get_input_media(m->file_id, std::move(input_file), std::move(input_thumbnail),
|
||||
emoji);
|
||||
}
|
||||
case MessageContentType::Story: {
|
||||
const auto *m = static_cast<const MessageStory *>(content);
|
||||
return td->story_manager_->get_input_media(m->story_full_id);
|
||||
}
|
||||
case MessageContentType::Venue: {
|
||||
const auto *m = static_cast<const MessageVenue *>(content);
|
||||
return m->venue.get_input_media_venue();
|
||||
@ -2790,6 +2848,7 @@ void delete_message_content_thumbnail(MessageContent *content, Td *td) {
|
||||
case MessageContentType::Game:
|
||||
case MessageContentType::LiveLocation:
|
||||
case MessageContentType::Location:
|
||||
case MessageContentType::Story:
|
||||
case MessageContentType::Venue:
|
||||
case MessageContentType::VoiceNote:
|
||||
case MessageContentType::Text:
|
||||
@ -2942,13 +3001,18 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten
|
||||
}
|
||||
break;
|
||||
case MessageContentType::Sticker:
|
||||
if (!permissions.can_send_stickers()) {
|
||||
if (!permissions.can_send_messages()) {
|
||||
return Status::Error(400, "Not enough rights to send stickers to the chat");
|
||||
}
|
||||
if (get_message_content_sticker_type(td, content) == StickerType::CustomEmoji) {
|
||||
return Status::Error(400, "Can't send emoji stickers in messages");
|
||||
}
|
||||
break;
|
||||
case MessageContentType::Story:
|
||||
if (!permissions.can_send_photos() || !permissions.can_send_videos()) {
|
||||
return Status::Error(400, "Not enough rights to send stories to the chat");
|
||||
}
|
||||
break;
|
||||
case MessageContentType::Text:
|
||||
if (!permissions.can_send_messages()) {
|
||||
return Status::Error(400, "Not enough rights to send text messages to the chat");
|
||||
@ -3118,6 +3182,7 @@ static int32 get_message_content_media_index_mask(const MessageContent *content,
|
||||
case MessageContentType::LiveLocation:
|
||||
case MessageContentType::Location:
|
||||
case MessageContentType::Sticker:
|
||||
case MessageContentType::Story:
|
||||
case MessageContentType::Unsupported:
|
||||
case MessageContentType::Venue:
|
||||
case MessageContentType::ChatCreate:
|
||||
@ -3923,6 +3988,14 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MessageContentType::Story: {
|
||||
const auto *old_ = static_cast<const MessageStory *>(old_content);
|
||||
const auto *new_ = static_cast<const MessageStory *>(new_content);
|
||||
if (old_->story_full_id != new_->story_full_id || old_->via_mention != new_->via_mention) {
|
||||
need_update = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
@ -4019,6 +4092,7 @@ bool merge_message_content_file_id(Td *td, MessageContent *message_content, File
|
||||
case MessageContentType::Invoice:
|
||||
case MessageContentType::LiveLocation:
|
||||
case MessageContentType::Location:
|
||||
case MessageContentType::Story:
|
||||
case MessageContentType::Text:
|
||||
case MessageContentType::Venue:
|
||||
case MessageContentType::ChatCreate:
|
||||
@ -4782,8 +4856,23 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
|
||||
}
|
||||
return make_unique<MessagePoll>(poll_id);
|
||||
}
|
||||
case telegram_api::messageMediaStory::ID:
|
||||
return make_unique<MessageUnsupported>();
|
||||
case telegram_api::messageMediaStory::ID: {
|
||||
auto media = move_tl_object_as<telegram_api::messageMediaStory>(media_ptr);
|
||||
auto dialog_id = DialogId(UserId(media->user_id_));
|
||||
auto story_id = StoryId(media->id_);
|
||||
if (!dialog_id.is_valid() || !story_id.is_valid()) {
|
||||
LOG(ERROR) << "Receive " << to_string(media);
|
||||
break;
|
||||
}
|
||||
auto story_full_id = StoryFullId(dialog_id, story_id);
|
||||
if (media->story_ != nullptr) {
|
||||
auto actual_story_id = td->story_manager_->on_get_story(dialog_id, std::move(media->story_));
|
||||
if (story_id != actual_story_id) {
|
||||
LOG(ERROR) << "Receive " << actual_story_id << " instead of " << story_id;
|
||||
}
|
||||
}
|
||||
return make_unique<MessageStory>(story_full_id, media->via_mention_);
|
||||
}
|
||||
case telegram_api::messageMediaUnsupported::ID:
|
||||
return make_unique<MessageUnsupported>();
|
||||
default:
|
||||
@ -4969,6 +5058,8 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
|
||||
CHECK(result->file_id.is_valid());
|
||||
return std::move(result);
|
||||
}
|
||||
case MessageContentType::Story:
|
||||
return make_unique<MessageStory>(static_cast<const MessageStory *>(content)->story_full_id, false);
|
||||
case MessageContentType::Text: {
|
||||
auto result = make_unique<MessageText>(*static_cast<const MessageText *>(content));
|
||||
if (type == MessageContentDupType::Copy || type == MessageContentDupType::ServerCopy) {
|
||||
@ -5763,6 +5854,14 @@ tl_object_ptr<td_api::MessageContent> get_message_content_object(const MessageCo
|
||||
return td_api::make_object<td_api::messageChatSetBackground>(m->old_message_id.get(),
|
||||
m->background_info.get_chat_background_object(td));
|
||||
}
|
||||
case MessageContentType::Story: {
|
||||
const auto *m = static_cast<const MessageStory *>(content);
|
||||
auto story_sender_dialog_id = m->story_full_id.get_dialog_id();
|
||||
CHECK(story_sender_dialog_id.get_type() == DialogType::User);
|
||||
return td_api::make_object<td_api::messageStory>(
|
||||
td->contacts_manager_->get_user_id_object(story_sender_dialog_id.get_user_id(), "messageStory"),
|
||||
m->story_full_id.get_story_id().get(), m->via_mention);
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
@ -6070,6 +6169,9 @@ vector<FileId> get_message_content_file_ids(const MessageContent *content, const
|
||||
case MessageContentType::SetBackground:
|
||||
// background file references are repaired independently
|
||||
return {};
|
||||
case MessageContentType::Story:
|
||||
// story file references are repaired independently
|
||||
return {};
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
@ -6127,6 +6229,7 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte
|
||||
case MessageContentType::LiveLocation:
|
||||
case MessageContentType::Location:
|
||||
case MessageContentType::Sticker:
|
||||
case MessageContentType::Story:
|
||||
case MessageContentType::Unsupported:
|
||||
case MessageContentType::Venue:
|
||||
case MessageContentType::VideoNote:
|
||||
@ -6468,6 +6571,11 @@ void add_message_content_dependencies(Dependencies &dependencies, const MessageC
|
||||
break;
|
||||
case MessageContentType::SetBackground:
|
||||
break;
|
||||
case MessageContentType::Story: {
|
||||
const auto *content = static_cast<const MessageStory *>(message_content);
|
||||
dependencies.add_message_sender_dependencies(content->story_full_id.get_dialog_id());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -124,6 +124,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, MessageContentType cont
|
||||
return string_builder << "WebAppWriteAccessAllowed";
|
||||
case MessageContentType::SetBackground:
|
||||
return string_builder << "SetBackground";
|
||||
case MessageContentType::Story:
|
||||
return string_builder << "Story";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return string_builder;
|
||||
@ -189,6 +191,7 @@ bool is_allowed_media_group_content(MessageContentType content_type) {
|
||||
case MessageContentType::RequestedDialog:
|
||||
case MessageContentType::WebViewWriteAccessAllowed:
|
||||
case MessageContentType::SetBackground:
|
||||
case MessageContentType::Story:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -262,6 +265,7 @@ bool is_secret_message_content(int32 ttl, MessageContentType content_type) {
|
||||
case MessageContentType::RequestedDialog:
|
||||
case MessageContentType::WebViewWriteAccessAllowed:
|
||||
case MessageContentType::SetBackground:
|
||||
case MessageContentType::Story:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -291,6 +295,7 @@ bool is_service_message_content(MessageContentType content_type) {
|
||||
case MessageContentType::ExpiredVideo:
|
||||
case MessageContentType::Poll:
|
||||
case MessageContentType::Dice:
|
||||
case MessageContentType::Story:
|
||||
return false;
|
||||
case MessageContentType::ChatCreate:
|
||||
case MessageContentType::ChatChangeTitle:
|
||||
@ -394,6 +399,7 @@ bool can_have_message_content_caption(MessageContentType content_type) {
|
||||
case MessageContentType::RequestedDialog:
|
||||
case MessageContentType::WebViewWriteAccessAllowed:
|
||||
case MessageContentType::SetBackground:
|
||||
case MessageContentType::Story:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
@ -69,7 +69,8 @@ enum class MessageContentType : int32 {
|
||||
WriteAccessAllowed,
|
||||
RequestedDialog,
|
||||
WebViewWriteAccessAllowed,
|
||||
SetBackground
|
||||
SetBackground,
|
||||
Story
|
||||
};
|
||||
// increase MessageUnsupported::CURRENT_VERSION each time a new message content type is added
|
||||
|
||||
|
@ -25370,7 +25370,8 @@ void MessagesManager::do_send_message(DialogId dialog_id, const Message *m, vect
|
||||
auto input_media =
|
||||
get_input_media(content, td_, m->ttl, m->send_emoji, td_->auth_manager_->is_bot() && bad_parts.empty());
|
||||
if (input_media == nullptr) {
|
||||
if (content_type == MessageContentType::Game || content_type == MessageContentType::Poll) {
|
||||
if (content_type == MessageContentType::Game || content_type == MessageContentType::Poll ||
|
||||
content_type == MessageContentType::Story) {
|
||||
return;
|
||||
}
|
||||
if (get_main_file_type(file_view.get_type()) == FileType::Photo) {
|
||||
@ -26385,6 +26386,7 @@ bool MessagesManager::can_edit_message(DialogId dialog_id, const Message *m, boo
|
||||
}
|
||||
return !get_message_content_poll_is_closed(td_, m->content.get());
|
||||
}
|
||||
case MessageContentType::Story:
|
||||
case MessageContentType::Contact:
|
||||
case MessageContentType::Dice:
|
||||
case MessageContentType::Location:
|
||||
@ -31302,6 +31304,8 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) {
|
||||
error_message = "Wrong poll data specified";
|
||||
} else if (content_type == MessageContentType::Contact) {
|
||||
error_message = "Wrong phone number specified";
|
||||
} else if (content_type == MessageContentType::Story) {
|
||||
error_message = "Wrong story data specified";
|
||||
} else {
|
||||
error_message = "Wrong file identifier/HTTP URL specified";
|
||||
}
|
||||
|
@ -716,25 +716,25 @@ void StoryManager::change_story_files(StoryFullId story_full_id, const Story *st
|
||||
}
|
||||
}
|
||||
|
||||
void StoryManager::on_get_story(DialogId owner_dialog_id,
|
||||
telegram_api::object_ptr<telegram_api::StoryItem> &&story_item_ptr) {
|
||||
StoryId StoryManager::on_get_story(DialogId owner_dialog_id,
|
||||
telegram_api::object_ptr<telegram_api::StoryItem> &&story_item_ptr) {
|
||||
if (!owner_dialog_id.is_valid()) {
|
||||
LOG(ERROR) << "Receive a story in " << owner_dialog_id;
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
CHECK(story_item_ptr != nullptr);
|
||||
switch (story_item_ptr->get_id()) {
|
||||
case telegram_api::storyItemDeleted::ID: {
|
||||
auto story_item = telegram_api::move_object_as<telegram_api::storyItemDeleted>(story_item_ptr);
|
||||
on_delete_story(owner_dialog_id, StoryId(story_item->id_));
|
||||
break;
|
||||
StoryId story_id(story_item->id_);
|
||||
on_delete_story(owner_dialog_id, story_id);
|
||||
return story_id;
|
||||
}
|
||||
case telegram_api::storyItemSkipped::ID:
|
||||
LOG(ERROR) << "Receive storyItemSkipped";
|
||||
break;
|
||||
return {};
|
||||
case telegram_api::storyItem::ID: {
|
||||
on_get_story(owner_dialog_id, telegram_api::move_object_as<telegram_api::storyItem>(story_item_ptr));
|
||||
break;
|
||||
return on_get_story(owner_dialog_id, telegram_api::move_object_as<telegram_api::storyItem>(story_item_ptr));
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -1340,6 +1340,17 @@ void StoryManager::delete_story_on_server(DialogId dialog_id, StoryId story_id,
|
||||
td_->create_handler<DeleteStoriesQuery>(std::move(promise))->send({story_id.get()});
|
||||
}
|
||||
|
||||
telegram_api::object_ptr<telegram_api::InputMedia> StoryManager::get_input_media(StoryFullId story_full_id) const {
|
||||
auto dialog_id = story_full_id.get_dialog_id();
|
||||
CHECK(dialog_id.get_type() == DialogType::User);
|
||||
auto r_input_user = td_->contacts_manager_->get_input_user(dialog_id.get_user_id());
|
||||
if (r_input_user.is_error()) {
|
||||
return nullptr;
|
||||
}
|
||||
return telegram_api::make_object<telegram_api::inputMediaStory>(r_input_user.move_as_ok(),
|
||||
story_full_id.get_story_id().get());
|
||||
}
|
||||
|
||||
void StoryManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
||||
if (G()->close_flag()) {
|
||||
return;
|
||||
|
@ -103,7 +103,7 @@ class StoryManager final : public Actor {
|
||||
|
||||
void get_dialog_expiring_stories(DialogId owner_dialog_id, Promise<td_api::object_ptr<td_api::stories>> &&promise);
|
||||
|
||||
void on_get_story(DialogId owner_dialog_id, telegram_api::object_ptr<telegram_api::StoryItem> &&story_item_ptr);
|
||||
StoryId on_get_story(DialogId owner_dialog_id, telegram_api::object_ptr<telegram_api::StoryItem> &&story_item_ptr);
|
||||
|
||||
std::pair<int32, vector<StoryId>> on_get_stories(DialogId owner_dialog_id, vector<int32> &&expected_story_ids,
|
||||
telegram_api::object_ptr<telegram_api::stories_stories> &&stories);
|
||||
@ -121,6 +121,8 @@ class StoryManager final : public Actor {
|
||||
|
||||
FileSourceId get_story_file_source_id(StoryFullId story_full_id);
|
||||
|
||||
telegram_api::object_ptr<telegram_api::InputMedia> get_input_media(StoryFullId story_full_id) const;
|
||||
|
||||
void reload_story(StoryFullId story_full_id, Promise<Unit> &&promise);
|
||||
|
||||
void on_binlog_events(vector<BinlogEvent> &&events);
|
||||
|
@ -4684,6 +4684,12 @@ class CliClient final : public Actor {
|
||||
get_args(args, chat_id, file_id, emoji);
|
||||
send_message(chat_id,
|
||||
td_api::make_object<td_api::inputMessageSticker>(as_input_file_id(file_id), nullptr, 0, 0, emoji));
|
||||
} else if (op == "sstory") {
|
||||
ChatId chat_id;
|
||||
UserId user_id;
|
||||
StoryId story_id;
|
||||
get_args(args, chat_id, user_id, story_id);
|
||||
send_message(chat_id, td_api::make_object<td_api::inputMessageStory>(user_id, story_id));
|
||||
} else if (op == "sv") {
|
||||
ChatId chat_id;
|
||||
string video_path;
|
||||
|
Loading…
Reference in New Issue
Block a user