Support forum topic creation.
This commit is contained in:
parent
83a2a786ef
commit
eadf411679
@ -5291,6 +5291,10 @@ editInlineMessageReplyMarkup inline_message_id:string reply_markup:ReplyMarkup =
|
||||
editMessageSchedulingState chat_id:int53 message_id:int53 scheduling_state:MessageSchedulingState = Ok;
|
||||
|
||||
|
||||
//@description Creates a topic in a forum supergroup chat; requires can_manage_topics rights in the supergroup @chat_id Identifier of the chat @title Title of the topic @icon Icon of the topic. Icon color must be one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, 0x8EEE98, 0xFF93B2, or 0xFB6F5F. Icon custom emoji can be added only by Telegram Premium users
|
||||
createForumTopic chat_id:int53 title:string icon:forumTopicIcon = ForumTopicInfo;
|
||||
|
||||
|
||||
//@description Returns information about a emoji reaction. Returns a 404 error if the reaction is not found @emoji Text representation of the reaction
|
||||
getEmojiReaction emoji:string = EmojiReaction;
|
||||
|
||||
|
@ -35,6 +35,17 @@ class ForumTopicInfo {
|
||||
|
||||
explicit ForumTopicInfo(const tl_object_ptr<telegram_api::ForumTopic> &forum_topic_ptr);
|
||||
|
||||
ForumTopicInfo(MessageId top_thread_message_id, string title, ForumTopicIcon icon, int32 creation_date,
|
||||
DialogId creator_dialog_id, bool is_outgoing, bool is_closed)
|
||||
: top_thread_message_id_(top_thread_message_id)
|
||||
, title_(std::move(title))
|
||||
, icon_(std::move(icon))
|
||||
, creation_date_(creation_date)
|
||||
, creator_dialog_id_(creator_dialog_id)
|
||||
, is_outgoing_(is_outgoing)
|
||||
, is_closed_(is_closed) {
|
||||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return !top_thread_message_id_.is_valid();
|
||||
}
|
||||
|
@ -6,10 +6,92 @@
|
||||
//
|
||||
#include "td/telegram/ForumTopicManager.h"
|
||||
|
||||
#include "td/telegram/ContactsManager.h"
|
||||
#include "td/telegram/CustomEmojiId.h"
|
||||
#include "td/telegram/Global.h"
|
||||
#include "td/telegram/MessagesManager.h"
|
||||
#include "td/telegram/misc.h"
|
||||
#include "td/telegram/Td.h"
|
||||
#include "td/telegram/telegram_api.h"
|
||||
#include "td/telegram/UpdatesManager.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/Random.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
class CreateForumTopicQuery final : public Td::ResultHandler {
|
||||
Promise<td_api::object_ptr<td_api::forumTopicInfo>> promise_;
|
||||
ChannelId channel_id_;
|
||||
DialogId creator_dialog_id_;
|
||||
int64 random_id_;
|
||||
|
||||
public:
|
||||
explicit CreateForumTopicQuery(Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise)
|
||||
: promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(ChannelId channel_id, const string &title, int32 icon_color, CustomEmojiId icon_custom_emoji_id) {
|
||||
channel_id_ = channel_id;
|
||||
creator_dialog_id_ = DialogId(td_->contacts_manager_->get_my_id());
|
||||
|
||||
int32 flags = 0;
|
||||
if (icon_color != -1) {
|
||||
flags |= telegram_api::channels_createForumTopic::ICON_COLOR_MASK;
|
||||
}
|
||||
if (icon_custom_emoji_id.is_valid()) {
|
||||
flags |= telegram_api::channels_createForumTopic::ICON_EMOJI_ID_MASK;
|
||||
}
|
||||
|
||||
do {
|
||||
random_id_ = Random::secure_int64();
|
||||
} while (random_id_ == 0);
|
||||
|
||||
auto input_channel = td_->contacts_manager_->get_input_channel(channel_id);
|
||||
CHECK(input_channel != nullptr);
|
||||
send_query(G()->net_query_creator().create(
|
||||
telegram_api::channels_createForumTopic(flags, std::move(input_channel), title, icon_color,
|
||||
icon_custom_emoji_id.get(), random_id_, nullptr),
|
||||
{{channel_id}}));
|
||||
}
|
||||
|
||||
void on_result(BufferSlice packet) final {
|
||||
auto result_ptr = fetch_result<telegram_api::channels_createForumTopic>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
auto ptr = result_ptr.move_as_ok();
|
||||
LOG(INFO) << "Receive result for CreateForumTopicQuery: " << to_string(ptr);
|
||||
auto message = UpdatesManager::get_message_by_random_id(ptr.get(), DialogId(channel_id_), random_id_);
|
||||
if (message == nullptr || message->get_id() != telegram_api::messageService::ID) {
|
||||
LOG(ERROR) << "Receive invalid result for CreateForumTopicQuery: " << to_string(ptr);
|
||||
return promise_.set_error(Status::Error(400, "Invalid result received"));
|
||||
}
|
||||
auto service_message = static_cast<const telegram_api::messageService *>(message);
|
||||
if (service_message->action_->get_id() != telegram_api::messageActionTopicCreate::ID) {
|
||||
LOG(ERROR) << "Receive invalid result for CreateForumTopicQuery: " << to_string(ptr);
|
||||
return promise_.set_error(Status::Error(400, "Invalid result received"));
|
||||
}
|
||||
|
||||
auto action = static_cast<const telegram_api::messageActionTopicCreate *>(service_message->action_.get());
|
||||
ForumTopicInfo forum_topic_info(MessageId(ServerMessageId(service_message->id_)), action->title_,
|
||||
ForumTopicIcon(action->icon_color_, action->icon_emoji_id_), service_message->date_,
|
||||
creator_dialog_id_, true, false);
|
||||
td_->updates_manager_->on_get_updates(
|
||||
std::move(ptr), PromiseCreator::lambda([forum_topic_info = std::move(forum_topic_info),
|
||||
promise = std::move(promise_)](Unit result) mutable {
|
||||
send_closure(G()->forum_topic_manager(), &ForumTopicManager::on_forum_topic_created,
|
||||
std::move(forum_topic_info), std::move(promise));
|
||||
}));
|
||||
}
|
||||
|
||||
void on_error(Status status) final {
|
||||
td_->contacts_manager_->on_get_channel_error(channel_id_, status, "CreateForumTopicQuery");
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
ForumTopicManager::ForumTopicManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||
}
|
||||
|
||||
@ -19,4 +101,51 @@ void ForumTopicManager::tear_down() {
|
||||
parent_.reset();
|
||||
}
|
||||
|
||||
void ForumTopicManager::create_forum_topic(DialogId dialog_id, string &&title,
|
||||
td_api::object_ptr<td_api::forumTopicIcon> &&icon,
|
||||
Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise) {
|
||||
TRY_STATUS_PROMISE(promise, is_forum(dialog_id));
|
||||
auto channel_id = dialog_id.get_channel_id();
|
||||
|
||||
if (!td_->contacts_manager_->get_channel_permissions(channel_id).can_create_topics()) {
|
||||
return promise.set_error(Status::Error(400, "Not enough rights to create a topic"));
|
||||
}
|
||||
|
||||
auto new_title = clean_name(std::move(title), MAX_FORUM_TOPIC_TITLE_LENGTH);
|
||||
if (new_title.empty()) {
|
||||
return promise.set_error(Status::Error(400, "Title must be non-empty"));
|
||||
}
|
||||
|
||||
int32 icon_color = -1;
|
||||
CustomEmojiId icon_custom_emoji_id;
|
||||
if (icon != nullptr) {
|
||||
icon_color = icon->color_;
|
||||
if (icon_color < 0 || icon_color > 0xFFFFFF) {
|
||||
return promise.set_error(Status::Error(400, "Invalid icon color specified"));
|
||||
}
|
||||
icon_custom_emoji_id = CustomEmojiId(icon->custom_emoji_id_);
|
||||
}
|
||||
|
||||
td_->create_handler<CreateForumTopicQuery>(std::move(promise))
|
||||
->send(channel_id, new_title, icon_color, icon_custom_emoji_id);
|
||||
}
|
||||
|
||||
void ForumTopicManager::on_forum_topic_created(ForumTopicInfo &&forum_topic_info,
|
||||
Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise) {
|
||||
TRY_STATUS_PROMISE(promise, G()->close_status());
|
||||
|
||||
promise.set_value(forum_topic_info.get_forum_topic_info_object(td_));
|
||||
}
|
||||
|
||||
Status ForumTopicManager::is_forum(DialogId dialog_id) {
|
||||
if (!td_->messages_manager_->have_dialog_force(dialog_id, "ForumTopicManager::is_forum")) {
|
||||
return Status::Error(400, "Chat not found");
|
||||
}
|
||||
if (dialog_id.get_type() != DialogType::Channel ||
|
||||
!td_->contacts_manager_->is_forum_channel(dialog_id.get_channel_id())) {
|
||||
return Status::Error(400, "The chat is not a forum");
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -6,6 +6,10 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/DialogId.h"
|
||||
#include "td/telegram/ForumTopicInfo.h"
|
||||
#include "td/telegram/td_api.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
@ -24,9 +28,19 @@ class ForumTopicManager final : public Actor {
|
||||
ForumTopicManager &operator=(ForumTopicManager &&) = delete;
|
||||
~ForumTopicManager() final;
|
||||
|
||||
void create_forum_topic(DialogId dialog_id, string &&title, td_api::object_ptr<td_api::forumTopicIcon> &&icon,
|
||||
Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise);
|
||||
|
||||
void on_forum_topic_created(ForumTopicInfo &&forum_topic_info,
|
||||
Promise<td_api::object_ptr<td_api::forumTopicInfo>> &&promise);
|
||||
|
||||
private:
|
||||
static constexpr size_t MAX_FORUM_TOPIC_TITLE_LENGTH = 128; // server side limit for forum topic title
|
||||
|
||||
void tear_down() final;
|
||||
|
||||
Status is_forum(DialogId dialog_id);
|
||||
|
||||
Td *td_;
|
||||
ActorShared<> parent_;
|
||||
};
|
||||
|
@ -5509,6 +5509,14 @@ void Td::on_request(uint64 id, td_api::editMessageSchedulingState &request) {
|
||||
std::move(request.scheduling_state_), std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::createForumTopic &request) {
|
||||
CHECK_IS_USER();
|
||||
CLEAN_INPUT_STRING(request.title_);
|
||||
CREATE_REQUEST_PROMISE();
|
||||
forum_topic_manager_->create_forum_topic(DialogId(request.chat_id_), std::move(request.title_),
|
||||
std::move(request.icon_), std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::setGameScore &request) {
|
||||
CHECK_IS_BOT();
|
||||
CREATE_REQUEST_PROMISE();
|
||||
|
@ -730,6 +730,8 @@ class Td final : public Actor {
|
||||
|
||||
void on_request(uint64 id, td_api::editMessageSchedulingState &request);
|
||||
|
||||
void on_request(uint64 id, td_api::createForumTopic &request);
|
||||
|
||||
void on_request(uint64 id, td_api::setGameScore &request);
|
||||
|
||||
void on_request(uint64 id, td_api::setInlineGameScore &request);
|
||||
|
@ -1155,6 +1155,49 @@ FlatHashSet<int64> UpdatesManager::get_sent_messages_random_ids(const telegram_a
|
||||
return random_ids;
|
||||
}
|
||||
|
||||
const telegram_api::Message *UpdatesManager::get_message_by_random_id(const telegram_api::Updates *updates_ptr,
|
||||
DialogId dialog_id, int64 random_id) {
|
||||
auto updates = get_updates(updates_ptr);
|
||||
if (updates == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32 message_id = 0;
|
||||
for (auto &update : *updates) {
|
||||
if (update->get_id() == telegram_api::updateMessageID::ID) {
|
||||
auto update_message_id = static_cast<const telegram_api::updateMessageID *>(update.get());
|
||||
if (update_message_id->random_id_ == random_id) {
|
||||
if (message_id != 0 || update_message_id->id_ == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
message_id = update_message_id->id_;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (message_id == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const telegram_api::Message *result = nullptr;
|
||||
FullMessageId full_message_id(dialog_id, MessageId(ServerMessageId(message_id)));
|
||||
for (auto &update : *updates) {
|
||||
auto constructor_id = update->get_id();
|
||||
const tl_object_ptr<telegram_api::Message> *message = nullptr;
|
||||
if (constructor_id == telegram_api::updateNewMessage::ID) {
|
||||
message = &static_cast<const telegram_api::updateNewMessage *>(update.get())->message_;
|
||||
} else if (constructor_id == telegram_api::updateNewChannelMessage::ID) {
|
||||
message = &static_cast<const telegram_api::updateNewChannelMessage *>(update.get())->message_;
|
||||
}
|
||||
if (message != nullptr && MessagesManager::get_full_message_id(*message, false) == full_message_id) {
|
||||
if (result != nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
result = message->get();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<const tl_object_ptr<telegram_api::Message> *> UpdatesManager::get_new_messages(
|
||||
const telegram_api::Updates *updates_ptr) {
|
||||
vector<const tl_object_ptr<telegram_api::Message> *> messages;
|
||||
|
@ -103,6 +103,9 @@ class UpdatesManager final : public Actor {
|
||||
|
||||
static FlatHashSet<int64> get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr);
|
||||
|
||||
static const telegram_api::Message *get_message_by_random_id(const telegram_api::Updates *updates_ptr,
|
||||
DialogId dialog_id, int64 random_id);
|
||||
|
||||
static vector<const tl_object_ptr<telegram_api::Message> *> get_new_messages(
|
||||
const telegram_api::Updates *updates_ptr);
|
||||
|
||||
|
@ -3842,6 +3842,13 @@ class CliClient final : public Actor {
|
||||
get_args(args, chat_id, message_id, date);
|
||||
send_request(td_api::make_object<td_api::editMessageSchedulingState>(chat_id, message_id,
|
||||
as_message_scheduling_state(date)));
|
||||
} else if (op == "cft") {
|
||||
ChatId chat_id;
|
||||
string title;
|
||||
int32 icon_color;
|
||||
get_args(args, chat_id, title, icon_color);
|
||||
send_request(td_api::make_object<td_api::createForumTopic>(
|
||||
chat_id, title, td_api::make_object<td_api::forumTopicIcon>(icon_color, 0)));
|
||||
} else if (op == "gallm") {
|
||||
send_request(td_api::make_object<td_api::getActiveLiveLocationMessages>());
|
||||
} else if (op == "sbsm") {
|
||||
|
Loading…
Reference in New Issue
Block a user