Add BotCommandScope to setCommands.
This commit is contained in:
parent
16f52b59ab
commit
62a543cb35
@ -278,6 +278,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/AutoDownloadSettings.cpp
|
td/telegram/AutoDownloadSettings.cpp
|
||||||
td/telegram/BackgroundManager.cpp
|
td/telegram/BackgroundManager.cpp
|
||||||
td/telegram/BackgroundType.cpp
|
td/telegram/BackgroundType.cpp
|
||||||
|
td/telegram/BotCommandScope.cpp
|
||||||
td/telegram/CallActor.cpp
|
td/telegram/CallActor.cpp
|
||||||
td/telegram/CallDiscardReason.cpp
|
td/telegram/CallDiscardReason.cpp
|
||||||
td/telegram/CallManager.cpp
|
td/telegram/CallManager.cpp
|
||||||
@ -443,6 +444,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/BackgroundId.h
|
td/telegram/BackgroundId.h
|
||||||
td/telegram/BackgroundManager.h
|
td/telegram/BackgroundManager.h
|
||||||
td/telegram/BackgroundType.h
|
td/telegram/BackgroundType.h
|
||||||
|
td/telegram/BotCommandScope.h
|
||||||
td/telegram/CallActor.h
|
td/telegram/CallActor.h
|
||||||
td/telegram/CallDiscardReason.h
|
td/telegram/CallDiscardReason.h
|
||||||
td/telegram/CallId.h
|
td/telegram/CallId.h
|
||||||
|
@ -3469,6 +3469,30 @@ vectorPathCommandLine end_point:point = VectorPathCommand;
|
|||||||
vectorPathCommandCubicBezierCurve start_control_point:point end_control_point:point end_point:point = VectorPathCommand;
|
vectorPathCommandCubicBezierCurve start_control_point:point end_control_point:point end_point:point = VectorPathCommand;
|
||||||
|
|
||||||
|
|
||||||
|
//@class BotCommandScope @description Represents the scope to which bot commands are applied
|
||||||
|
|
||||||
|
//@description A scope covering all users
|
||||||
|
botCommandScopeDefault = BotCommandScope;
|
||||||
|
|
||||||
|
//@description A scope covering all private chats
|
||||||
|
botCommandScopeAllPrivateChats = BotCommandScope;
|
||||||
|
|
||||||
|
//@description A scope covering all group and supergroup chats
|
||||||
|
botCommandScopeAllGroupChats = BotCommandScope;
|
||||||
|
|
||||||
|
//@description A scope covering all group and supergroup chat administrators
|
||||||
|
botCommandScopeAllChatAdministrators = BotCommandScope;
|
||||||
|
|
||||||
|
//@description A scope covering all members of a chat @chat_id Chat identifier
|
||||||
|
botCommandScopeChat chat_id:int53 = BotCommandScope;
|
||||||
|
|
||||||
|
//@description A scope covering all administrators of a chat @chat_id Chat identifier
|
||||||
|
botCommandScopeChatAdministrators chat_id:int53 = BotCommandScope;
|
||||||
|
|
||||||
|
//@description A scope covering a member of a chat @chat_id Chat identifier @user_id User identifier
|
||||||
|
botCommandScopeChatMember chat_id:int53 user_id:int32 = BotCommandScope;
|
||||||
|
|
||||||
|
|
||||||
//@class Update @description Contains notifications about data changes
|
//@class Update @description Contains notifications about data changes
|
||||||
|
|
||||||
//@description The user authorization state has changed @authorization_state New authorization state
|
//@description The user authorization state has changed @authorization_state New authorization state
|
||||||
@ -4990,8 +5014,10 @@ resendChangePhoneNumberCode = AuthenticationCodeInfo;
|
|||||||
//@description Checks the authentication code sent to confirm a new phone number of the user @code Verification code received by SMS, phone call or flash call
|
//@description Checks the authentication code sent to confirm a new phone number of the user @code Verification code received by SMS, phone call or flash call
|
||||||
checkChangePhoneNumberCode code:string = Ok;
|
checkChangePhoneNumberCode code:string = Ok;
|
||||||
|
|
||||||
//@description Sets the list of commands supported by the bot; for bots only @commands List of the bot's commands
|
//@description Sets the list of commands supported by the bot for the given user scope and language; for bots only @scope The scope to which the commands are applied
|
||||||
setCommands commands:vector<botCommand> = Ok;
|
//@language_code A two-letter ISO 639-1 country code. If empty, the commands will be applied to all users from the given scope, for which language there are no dedicated commands
|
||||||
|
//@commands List of the bot's commands
|
||||||
|
setCommands scope:BotCommandScope language_code:string commands:vector<botCommand> = Ok;
|
||||||
|
|
||||||
|
|
||||||
//@description Returns all active sessions of the current user
|
//@description Returns all active sessions of the current user
|
||||||
|
136
td/telegram/BotCommandScope.cpp
Normal file
136
td/telegram/BotCommandScope.cpp
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/BotCommandScope.h"
|
||||||
|
|
||||||
|
#include "td/telegram/AuthManager.h"
|
||||||
|
#include "td/telegram/ContactsManager.h"
|
||||||
|
#include "td/telegram/MessagesManager.h"
|
||||||
|
#include "td/telegram/Td.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
BotCommandScope::BotCommandScope(Type type, DialogId dialog_id, UserId user_id)
|
||||||
|
: type_(type), dialog_id_(dialog_id), user_id_(user_id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<BotCommandScope> BotCommandScope::get_bot_command_scope(Td *td,
|
||||||
|
td_api::object_ptr<td_api::BotCommandScope> scope_ptr) {
|
||||||
|
if (scope_ptr == nullptr) {
|
||||||
|
return BotCommandScope(Type::Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(td->auth_manager_->is_bot());
|
||||||
|
Type type;
|
||||||
|
DialogId dialog_id;
|
||||||
|
UserId user_id;
|
||||||
|
switch (scope_ptr->get_id()) {
|
||||||
|
case td_api::botCommandScopeDefault::ID:
|
||||||
|
return BotCommandScope(Type::Default);
|
||||||
|
case td_api::botCommandScopeAllPrivateChats::ID:
|
||||||
|
return BotCommandScope(Type::AllUsers);
|
||||||
|
case td_api::botCommandScopeAllGroupChats::ID:
|
||||||
|
return BotCommandScope(Type::AllChats);
|
||||||
|
case td_api::botCommandScopeAllChatAdministrators::ID:
|
||||||
|
return BotCommandScope(Type::AllChatAdministrators);
|
||||||
|
case td_api::botCommandScopeChat::ID: {
|
||||||
|
auto scope = td_api::move_object_as<td_api::botCommandScopeChat>(scope_ptr);
|
||||||
|
type = Type::Dialog;
|
||||||
|
dialog_id = DialogId(scope->chat_id_);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case td_api::botCommandScopeChatAdministrators::ID: {
|
||||||
|
auto scope = td_api::move_object_as<td_api::botCommandScopeChatAdministrators>(scope_ptr);
|
||||||
|
type = Type::DialogAdministrators;
|
||||||
|
dialog_id = DialogId(scope->chat_id_);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case td_api::botCommandScopeChatMember::ID: {
|
||||||
|
auto scope = td_api::move_object_as<td_api::botCommandScopeChatMember>(scope_ptr);
|
||||||
|
type = Type::DialogParticipant;
|
||||||
|
dialog_id = DialogId(scope->chat_id_);
|
||||||
|
user_id = UserId(scope->user_id_);
|
||||||
|
if (!user_id.is_valid()) {
|
||||||
|
return Status::Error(400, "User not found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return BotCommandScope(Type::Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!td->messages_manager_->have_dialog_force(dialog_id, "get_bot_command_scope")) {
|
||||||
|
return Status::Error(400, "Chat not found");
|
||||||
|
}
|
||||||
|
if (!td->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) {
|
||||||
|
return Status::Error(400, "Can't access the chat");
|
||||||
|
}
|
||||||
|
switch (dialog_id.get_type()) {
|
||||||
|
case DialogType::User:
|
||||||
|
if (type != Type::Dialog) {
|
||||||
|
return Status::Error(400, "Can't use specified scope in private chats");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DialogType::Chat:
|
||||||
|
// ok
|
||||||
|
break;
|
||||||
|
case DialogType::Channel:
|
||||||
|
if (td->contacts_manager_->get_channel_type(dialog_id.get_channel_id()) !=
|
||||||
|
ContactsManager::ChannelType::Megagroup) {
|
||||||
|
return Status::Error(400, "Can't change commands in channel chats");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DialogType::SecretChat:
|
||||||
|
default:
|
||||||
|
return Status::Error(400, "Can't access the chat");
|
||||||
|
}
|
||||||
|
|
||||||
|
return BotCommandScope(type, dialog_id, user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BotCommandScope::have_input_bot_command_scope(const Td *td) const {
|
||||||
|
if (dialog_id_.is_valid() && !td->messages_manager_->have_input_peer(dialog_id_, AccessRights::Read)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (user_id_.is_valid() && !td->contacts_manager_->have_input_user(user_id_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
telegram_api::object_ptr<telegram_api::BotCommandScope> BotCommandScope::get_input_bot_command_scope(
|
||||||
|
const Td *td) const {
|
||||||
|
auto input_peer =
|
||||||
|
dialog_id_.is_valid() ? td->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read) : nullptr;
|
||||||
|
auto input_user = user_id_.is_valid() ? td->contacts_manager_->get_input_user(user_id_) : nullptr;
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Default:
|
||||||
|
return telegram_api::make_object<telegram_api::botCommandScopeDefault>();
|
||||||
|
case Type::AllUsers:
|
||||||
|
return telegram_api::make_object<telegram_api::botCommandScopeUsers>();
|
||||||
|
case Type::AllChats:
|
||||||
|
return telegram_api::make_object<telegram_api::botCommandScopeChats>();
|
||||||
|
case Type::AllChatAdministrators:
|
||||||
|
return telegram_api::make_object<telegram_api::botCommandScopeChatAdmins>();
|
||||||
|
case Type::Dialog:
|
||||||
|
CHECK(input_peer != nullptr);
|
||||||
|
return telegram_api::make_object<telegram_api::botCommandScopePeer>(std::move(input_peer));
|
||||||
|
case Type::DialogAdministrators:
|
||||||
|
CHECK(input_peer != nullptr);
|
||||||
|
return telegram_api::make_object<telegram_api::botCommandScopePeerAdmins>(std::move(input_peer));
|
||||||
|
case Type::DialogParticipant:
|
||||||
|
CHECK(input_peer != nullptr);
|
||||||
|
CHECK(input_user != nullptr);
|
||||||
|
return telegram_api::make_object<telegram_api::botCommandScopePeerUser>(std::move(input_peer),
|
||||||
|
std::move(input_user));
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
44
td/telegram/BotCommandScope.h
Normal file
44
td/telegram/BotCommandScope.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/UserId.h"
|
||||||
|
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class Td;
|
||||||
|
|
||||||
|
class BotCommandScope {
|
||||||
|
enum class Type : int32 {
|
||||||
|
Default,
|
||||||
|
AllUsers,
|
||||||
|
AllChats,
|
||||||
|
AllChatAdministrators,
|
||||||
|
Dialog,
|
||||||
|
DialogAdministrators,
|
||||||
|
DialogParticipant
|
||||||
|
};
|
||||||
|
Type type_ = Type::Default;
|
||||||
|
DialogId dialog_id_;
|
||||||
|
UserId user_id_;
|
||||||
|
|
||||||
|
explicit BotCommandScope(Type type, DialogId dialog_id = DialogId(), UserId user_id = UserId());
|
||||||
|
|
||||||
|
public:
|
||||||
|
static Result<BotCommandScope> get_bot_command_scope(Td *td, td_api::object_ptr<td_api::BotCommandScope> scope_ptr);
|
||||||
|
|
||||||
|
bool have_input_bot_command_scope(const Td *td) const;
|
||||||
|
|
||||||
|
telegram_api::object_ptr<telegram_api::BotCommandScope> get_input_bot_command_scope(const Td *td) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
@ -11,6 +11,7 @@
|
|||||||
#include "td/telegram/telegram_api.hpp"
|
#include "td/telegram/telegram_api.hpp"
|
||||||
|
|
||||||
#include "td/telegram/AuthManager.h"
|
#include "td/telegram/AuthManager.h"
|
||||||
|
#include "td/telegram/BotCommandScope.h"
|
||||||
#include "td/telegram/ConfigManager.h"
|
#include "td/telegram/ConfigManager.h"
|
||||||
#include "td/telegram/ConfigShared.h"
|
#include "td/telegram/ConfigShared.h"
|
||||||
#include "td/telegram/Dependencies.h"
|
#include "td/telegram/Dependencies.h"
|
||||||
@ -981,16 +982,14 @@ class UpdateUsernameQuery : public Td::ResultHandler {
|
|||||||
|
|
||||||
class SetBotCommandsQuery : public Td::ResultHandler {
|
class SetBotCommandsQuery : public Td::ResultHandler {
|
||||||
Promise<Unit> promise_;
|
Promise<Unit> promise_;
|
||||||
vector<std::pair<string, string>> commands_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SetBotCommandsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
explicit SetBotCommandsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void send(vector<std::pair<string, string>> &&commands) {
|
void send(BotCommandScope scope, const string &language_code, vector<std::pair<string, string>> &&commands) {
|
||||||
commands_ = std::move(commands);
|
|
||||||
send_query(G()->net_query_creator().create(telegram_api::bots_setBotCommands(
|
send_query(G()->net_query_creator().create(telegram_api::bots_setBotCommands(
|
||||||
make_tl_object<telegram_api::botCommandScopeDefault>(), string(), transform(commands_, [](const auto &command) {
|
scope.get_input_bot_command_scope(td), language_code, transform(commands, [](const auto &command) {
|
||||||
return make_tl_object<telegram_api::botCommand>(command.first, command.second);
|
return make_tl_object<telegram_api::botCommand>(command.first, command.second);
|
||||||
}))));
|
}))));
|
||||||
}
|
}
|
||||||
@ -1001,10 +1000,7 @@ class SetBotCommandsQuery : public Td::ResultHandler {
|
|||||||
return on_error(id, result_ptr.move_as_error());
|
return on_error(id, result_ptr.move_as_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool result = result_ptr.ok();
|
if (!result_ptr.ok()) {
|
||||||
if (result) {
|
|
||||||
td->contacts_manager_->on_set_bot_commands_success(std::move(commands_));
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "Set bot commands request failed";
|
LOG(ERROR) << "Set bot commands request failed";
|
||||||
}
|
}
|
||||||
promise_.set_value(Unit());
|
promise_.set_value(Unit());
|
||||||
@ -6255,7 +6251,18 @@ void ContactsManager::set_username(const string &username, Promise<Unit> &&promi
|
|||||||
td_->create_handler<UpdateUsernameQuery>(std::move(promise))->send(username);
|
td_->create_handler<UpdateUsernameQuery>(std::move(promise))->send(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::set_commands(vector<td_api::object_ptr<td_api::botCommand>> &&commands, Promise<Unit> &&promise) {
|
void ContactsManager::set_commands(td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||||
|
vector<td_api::object_ptr<td_api::botCommand>> &&commands, Promise<Unit> &&promise) {
|
||||||
|
TRY_RESULT_PROMISE(promise, scope, BotCommandScope::get_bot_command_scope(td_, std::move(scope_ptr)));
|
||||||
|
|
||||||
|
if (!language_code.empty() && (language_code.size() != 2 || language_code[0] < 'a' || language_code[0] > 'z' ||
|
||||||
|
language_code[1] < 'a' || language_code[1] > 'z')) {
|
||||||
|
return promise.set_error(Status::Error(400, "Invalid language code specified"));
|
||||||
|
}
|
||||||
|
if (!scope.have_input_bot_command_scope(td_)) {
|
||||||
|
return promise.set_error(Status::Error(400, "Invalid scope specified"));
|
||||||
|
}
|
||||||
|
|
||||||
vector<std::pair<string, string>> new_commands;
|
vector<std::pair<string, string>> new_commands;
|
||||||
for (auto &command : commands) {
|
for (auto &command : commands) {
|
||||||
if (command == nullptr) {
|
if (command == nullptr) {
|
||||||
@ -6297,22 +6304,7 @@ void ContactsManager::set_commands(vector<td_api::object_ptr<td_api::botCommand>
|
|||||||
new_commands.emplace_back(std::move(command->command_), std::move(command->description_));
|
new_commands.emplace_back(std::move(command->command_), std::move(command->description_));
|
||||||
}
|
}
|
||||||
|
|
||||||
td_->create_handler<SetBotCommandsQuery>(std::move(promise))->send(std::move(new_commands));
|
td_->create_handler<SetBotCommandsQuery>(std::move(promise))->send(scope, language_code, std::move(new_commands));
|
||||||
}
|
|
||||||
|
|
||||||
void ContactsManager::on_set_bot_commands_success(vector<std::pair<string, string>> &&commands) {
|
|
||||||
auto user_id = get_my_id();
|
|
||||||
BotInfo *bot_info = get_bot_info_force(user_id);
|
|
||||||
if (bot_info == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (bot_info->commands == commands) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bot_info->commands = std::move(commands);
|
|
||||||
bot_info->is_changed = true;
|
|
||||||
|
|
||||||
update_bot_info(bot_info, user_id, true, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::set_chat_description(ChatId chat_id, const string &description, Promise<Unit> &&promise) {
|
void ContactsManager::set_chat_description(ChatId chat_id, const string &description, Promise<Unit> &&promise) {
|
||||||
|
@ -160,7 +160,6 @@ class ContactsManager : public Actor {
|
|||||||
void on_get_channel_full_failed(ChannelId channel_id);
|
void on_get_channel_full_failed(ChannelId channel_id);
|
||||||
|
|
||||||
void on_update_profile_success(int32 flags, const string &first_name, const string &last_name, const string &about);
|
void on_update_profile_success(int32 flags, const string &first_name, const string &last_name, const string &about);
|
||||||
void on_set_bot_commands_success(vector<std::pair<string, string>> &&commands);
|
|
||||||
|
|
||||||
void on_update_user_name(UserId user_id, string &&first_name, string &&last_name, string &&username);
|
void on_update_user_name(UserId user_id, string &&first_name, string &&last_name, string &&username);
|
||||||
void on_update_user_phone_number(UserId user_id, string &&phone_number);
|
void on_update_user_phone_number(UserId user_id, string &&phone_number);
|
||||||
@ -329,7 +328,8 @@ class ContactsManager : public Actor {
|
|||||||
|
|
||||||
void set_username(const string &username, Promise<Unit> &&promise);
|
void set_username(const string &username, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void set_commands(vector<td_api::object_ptr<td_api::botCommand>> &&commands, Promise<Unit> &&promise);
|
void set_commands(td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||||
|
vector<td_api::object_ptr<td_api::botCommand>> &&commands, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void set_chat_description(ChatId chat_id, const string &description, Promise<Unit> &&promise);
|
void set_chat_description(ChatId chat_id, const string &description, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
@ -6874,7 +6874,8 @@ void Td::on_request(uint64 id, td_api::setUsername &request) {
|
|||||||
void Td::on_request(uint64 id, td_api::setCommands &request) {
|
void Td::on_request(uint64 id, td_api::setCommands &request) {
|
||||||
CHECK_IS_BOT();
|
CHECK_IS_BOT();
|
||||||
CREATE_OK_REQUEST_PROMISE();
|
CREATE_OK_REQUEST_PROMISE();
|
||||||
contacts_manager_->set_commands(std::move(request.commands_), std::move(promise));
|
contacts_manager_->set_commands(std::move(request.scope_), std::move(request.language_code_),
|
||||||
|
std::move(request.commands_), std::move(promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, const td_api::setLocation &request) {
|
void Td::on_request(uint64 id, const td_api::setLocation &request) {
|
||||||
|
Loading…
Reference in New Issue
Block a user