Add td_api::getChatStoryInteractions.

This commit is contained in:
levlam 2023-12-26 14:24:42 +03:00
parent e83e1ba095
commit c3c14ee65e
6 changed files with 170 additions and 0 deletions

View File

@ -8223,6 +8223,15 @@ setStoryReaction story_sender_chat_id:int53 story_id:int32 reaction_type:Reactio
//@limit The maximum number of story interactions to return
getStoryInteractions story_id:int32 query:string only_contacts:Bool prefer_forwards:Bool prefer_with_reaction:Bool offset:string limit:int32 = StoryInteractions;
//@description Returns interactions with a story posted in a chat. Can be used only if story is posted on behalf of a chat and the user is an administrator in the chat
//@story_sender_chat_id The identifier of the sender of the story
//@story_id Story identifier
//@reaction_type Pass a reaction type to receive only interactions with the specified reaction type; pass null to receive all interactions
//@prefer_forwards Pass true to get forwards and reposts first, then reactions, then other views; pass false to get interactions sorted just by interaction date
//@offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results
//@limit The maximum number of story interactions to return
getChatStoryInteractions story_sender_chat_id:int53 story_id:int32 reaction_type:ReactionType prefer_forwards:Bool offset:string limit:int32 = StoryInteractions;
//@description Reports a story to the Telegram moderators
//@story_sender_chat_id The identifier of the sender of the story to report
//@story_id The identifier of the story to report

View File

@ -391,6 +391,56 @@ class GetStoryViewsListQuery final : public Td::ResultHandler {
}
};
class GetStoryReactionsListQuery final : public Td::ResultHandler {
Promise<telegram_api::object_ptr<telegram_api::stories_storyReactionsList>> promise_;
DialogId dialog_id_;
public:
explicit GetStoryReactionsListQuery(
Promise<telegram_api::object_ptr<telegram_api::stories_storyReactionsList>> &&promise)
: promise_(std::move(promise)) {
}
void send(StoryFullId story_full_id, const ReactionType &reaction_type, bool prefer_forwards, const string &offset,
int32 limit) {
dialog_id_ = story_full_id.get_dialog_id();
auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Write);
if (input_peer == nullptr) {
return on_error(Status::Error(400, "Can't access the chat"));
}
int32 flags = 0;
if (!reaction_type.is_empty()) {
flags |= telegram_api::stories_getStoryReactionsList::REACTION_MASK;
}
if (!offset.empty()) {
flags |= telegram_api::stories_getStoryReactionsList::OFFSET_MASK;
}
if (prefer_forwards) {
flags |= telegram_api::stories_getStoryReactionsList::FORWARDS_FIRST_MASK;
}
send_query(G()->net_query_creator().create(telegram_api::stories_getStoryReactionsList(
flags, false /*ignored*/, std::move(input_peer), story_full_id.get_story_id().get(),
reaction_type.get_input_reaction(), offset, limit)));
}
void on_result(BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::stories_getStoryReactionsList>(packet);
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
auto result = result_ptr.move_as_ok();
LOG(DEBUG) << "Receive result for GetStoryReactionsListQuery: " << to_string(result);
td_->story_manager_->get_channel_differences_if_needed(std::move(result), std::move(promise_));
}
void on_error(Status status) final {
td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetStoryReactionsListQuery");
promise_.set_error(std::move(status));
}
};
class GetStoriesByIDQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
DialogId dialog_id_;
@ -2902,6 +2952,83 @@ void StoryManager::on_get_story_interactions(
promise.set_value(story_viewers.get_story_interactions_object(td_));
}
void StoryManager::get_channel_differences_if_needed(
telegram_api::object_ptr<telegram_api::stories_storyReactionsList> &&story_reactions,
Promise<telegram_api::object_ptr<telegram_api::stories_storyReactionsList>> promise) {
vector<const telegram_api::object_ptr<telegram_api::Message> *> messages;
for (const auto &reaction : story_reactions->reactions_) {
CHECK(reaction != nullptr);
if (reaction->get_id() != telegram_api::storyReactionPublicForward::ID) {
continue;
}
messages.push_back(&static_cast<const telegram_api::storyReactionPublicForward *>(reaction.get())->message_);
}
td_->messages_manager_->get_channel_differences_if_needed(
messages,
PromiseCreator::lambda([actor_id = actor_id(this), story_reactions = std::move(story_reactions),
promise = std::move(promise)](Result<Unit> &&result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
promise.set_value(std::move(story_reactions));
}
}),
"stories_storyReactionsList");
}
void StoryManager::get_dialog_story_interactions(StoryFullId story_full_id, ReactionType reaction_type,
bool prefer_forwards, const string &offset, int32 limit,
Promise<td_api::object_ptr<td_api::storyInteractions>> &&promise) {
const Story *story = get_story(story_full_id);
if (story == nullptr) {
return promise.set_error(Status::Error(400, "Story not found"));
}
if (limit <= 0) {
return promise.set_error(Status::Error(400, "Parameter limit must be positive"));
}
auto query_promise = PromiseCreator::lambda(
[actor_id = actor_id(this), story_full_id, promise = std::move(promise)](
Result<telegram_api::object_ptr<telegram_api::stories_storyReactionsList>> result) mutable {
send_closure(actor_id, &StoryManager::on_get_dialog_story_interactions, story_full_id, std::move(result),
std::move(promise));
});
td_->create_handler<GetStoryReactionsListQuery>(std::move(query_promise))
->send(story_full_id, reaction_type, prefer_forwards, offset, limit);
}
void StoryManager::on_get_dialog_story_interactions(
StoryFullId story_full_id,
Result<telegram_api::object_ptr<telegram_api::stories_storyReactionsList>> r_reaction_list,
Promise<td_api::object_ptr<td_api::storyInteractions>> &&promise) {
G()->ignore_result_if_closing(r_reaction_list);
if (r_reaction_list.is_error()) {
return promise.set_error(r_reaction_list.move_as_error());
}
auto reaction_list = r_reaction_list.move_as_ok();
Story *story = get_story_editable(story_full_id);
if (story == nullptr) {
return promise.set_value(td_api::make_object<td_api::storyInteractions>());
}
td_->contacts_manager_->on_get_users(std::move(reaction_list->users_), "on_get_dialog_story_interactions");
td_->contacts_manager_->on_get_chats(std::move(reaction_list->chats_), "on_get_dialog_story_interactions");
auto total_count = reaction_list->count_;
if (total_count < 0 || static_cast<size_t>(total_count) < reaction_list->reactions_.size()) {
LOG(ERROR) << "Receive total_count = " << total_count << " and " << reaction_list->reactions_.size()
<< " story reactioners";
total_count = static_cast<int32>(reaction_list->reactions_.size());
}
StoryViewers story_viewers(td_, total_count, std::move(reaction_list->reactions_),
std::move(reaction_list->next_offset_));
td_->contacts_manager_->on_view_dialog_active_stories(story_viewers.get_actor_dialog_ids());
promise.set_value(story_viewers.get_story_interactions_object(td_));
}
void StoryManager::report_story(StoryFullId story_full_id, ReportReason &&reason, Promise<Unit> &&promise) {
if (!have_story_force(story_full_id)) {
return promise.set_error(Status::Error(400, "Story not found"));

View File

@ -267,10 +267,18 @@ class StoryManager final : public Actor {
bool prefer_with_reaction, const string &offset, int32 limit,
Promise<td_api::object_ptr<td_api::storyInteractions>> &&promise);
void get_dialog_story_interactions(StoryFullId story_full_id, ReactionType reaction_type, bool prefer_forwards,
const string &offset, int32 limit,
Promise<td_api::object_ptr<td_api::storyInteractions>> &&promise);
void get_channel_differences_if_needed(
telegram_api::object_ptr<telegram_api::stories_storyViewsList> &&story_views,
Promise<telegram_api::object_ptr<telegram_api::stories_storyViewsList>> promise);
void get_channel_differences_if_needed(
telegram_api::object_ptr<telegram_api::stories_storyReactionsList> &&story_reactions,
Promise<telegram_api::object_ptr<telegram_api::stories_storyReactionsList>> promise);
void report_story(StoryFullId story_full_id, ReportReason &&reason, Promise<Unit> &&promise);
void activate_stealth_mode(Promise<Unit> &&promise);
@ -610,6 +618,11 @@ class StoryManager final : public Actor {
Result<telegram_api::object_ptr<telegram_api::stories_storyViewsList>> r_view_list,
Promise<td_api::object_ptr<td_api::storyInteractions>> &&promise);
void on_get_dialog_story_interactions(
StoryFullId story_full_id,
Result<telegram_api::object_ptr<telegram_api::stories_storyReactionsList>> r_reaction_list,
Promise<td_api::object_ptr<td_api::storyInteractions>> &&promise);
void on_set_story_reaction(StoryFullId story_full_id, Result<Unit> &&result, Promise<Unit> &&promise);
void load_expired_database_stories();

View File

@ -6690,6 +6690,15 @@ void Td::on_request(uint64 id, td_api::getStoryInteractions &request) {
request.limit_, std::move(promise));
}
void Td::on_request(uint64 id, td_api::getChatStoryInteractions &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.offset_);
CREATE_REQUEST_PROMISE();
story_manager_->get_dialog_story_interactions({DialogId(request.story_sender_chat_id_), StoryId(request.story_id_)},
ReactionType(request.reaction_type_), request.prefer_forwards_,
request.offset_, request.limit_, std::move(promise));
}
void Td::on_request(uint64 id, td_api::reportStory &request) {
CHECK_IS_USER();
auto r_report_reason = ReportReason::get_report_reason(std::move(request.reason_), std::move(request.text_));

View File

@ -1063,6 +1063,8 @@ class Td final : public Actor {
void on_request(uint64 id, td_api::getStoryInteractions &request);
void on_request(uint64 id, td_api::getChatStoryInteractions &request);
void on_request(uint64 id, td_api::reportStory &request);
void on_request(uint64 id, const td_api::activateStoryStealthMode &request);

View File

@ -4429,6 +4429,16 @@ class CliClient final : public Actor {
get_args(args, story_id, limit, offset, query, only_contacts, prefer_forwards, prefer_with_reaction);
send_request(td_api::make_object<td_api::getStoryInteractions>(story_id, query, only_contacts, prefer_forwards,
prefer_with_reaction, offset, as_limit(limit)));
} else if (op == "gcsi") {
ChatId chat_id;
StoryId story_id;
string limit;
string offset;
string reaction_type;
bool prefer_forwards;
get_args(args, chat_id, story_id, limit, offset, reaction_type, prefer_forwards);
send_request(td_api::make_object<td_api::getChatStoryInteractions>(
chat_id, story_id, as_reaction_type(reaction_type), prefer_forwards, offset, as_limit(limit)));
} else if (op == "rst") {
ChatId story_sender_chat_id;
StoryId story_id;