Skip to content

Commit

Permalink
implemented Api methods banChatMember, unbanChatMember
Browse files Browse the repository at this point in the history
  • Loading branch information
baderouaich committed Oct 13, 2023
1 parent 9a46b5e commit 8e53780
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 3 deletions.
35 changes: 35 additions & 0 deletions include/tgbotxx/Api.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include <cpr/cpr.h>
#include <cstdint>
#include <functional>
#include <nlohmann/json.hpp>
#include <optional>
Expand Down Expand Up @@ -718,6 +719,7 @@ namespace tgbotxx {
/// @ref https://core.telegram.org/bots/api#getfile
Ptr<File> getFile(const std::string& fileId) const;


/// @brief Use this method to download a file from Telegram and save it in memory.
/// For the moment, bots can download files of up to 20MB in size. See Api::getFile.
/// The file can then be downloaded via the link https://api.telegram.org/file/bot<token>/<file_path>, where <file_path> is taken from the response.
Expand All @@ -728,6 +730,39 @@ namespace tgbotxx {
/// @throws Exception on failure
std::string downloadFile(const std::string& filePath, const std::function<bool(cpr::cpr_off_t downloadTotal, cpr::cpr_off_t downloadNow)>& progressCallback = nullptr) const;


/// @brief Use this method to ban a user in a group, a supergroup or a channel.
/// In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless unbanned first.
/// The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. https://core.telegram.org/bots/api#unbanchatmember
/// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername)
/// @param userId Unique identifier of the target user
/// @param untilDate Optional. Date when the user will be unbanned; Unix time. If user is banned for more than 366 days or less than 30 seconds from the current time they are considered to be banned forever. .
/// AApplied for supergroups and channels only.
/// @param revokeMessages Optional. Pass True to delete all messages from the chat for the user that is being removed. If False, the user will be able to see messages in the group that were sent before the user was removed. Always True for supergroups and channels.
/// @returns True on success.
/// @note You can't ban members in private chats
/// @ref https://core.telegram.org/bots/api#banchatmember
bool banChatMember(std::int64_t chatId,
std::int64_t userId,
std::time_t untilDate = 0,
bool revokeMessages = false) const;


/// @brief Use this method to unban a previously banned user in a supergroup or channel.
/// The user will not return to the group or channel automatically, but will be able to join via link, etc.
/// The bot must be an administrator for this to work. By default, this method guarantees that after the call the user is not a member of the chat,
/// but will be able to join it. So if the user is a member of the chat they will also be removed from the chat. If you don't want this,
/// use the parameter onlyIfBanned.
/// @param chatId Integer Unique identifier for the target chat or username of the target channel (in the format \@channelusername)
/// @param userId Unique identifier of the target user
/// @param onlyIfBanned Optional. Do nothing if the user is not banned
/// @returns True on success.
/// @ref https://core.telegram.org/bots/api#unbanchatmember
bool unbanChatMember(std::int64_t chatId,
std::int64_t userId,
bool onlyIfBanned = false) const;


/// @brief Use this method to remove webhook integration if you decide to switch back to getUpdates.
/// Returns True on success.
/// @param dropPendingUpdates: Pass True to drop all pending updates.
Expand Down
29 changes: 29 additions & 0 deletions src/Api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -978,3 +978,32 @@ Ptr<UserProfilePhotos> Api::getUserProfilePhotos(std::int64_t userId,
Ptr<UserProfilePhotos> userProfilePhotos(new UserProfilePhotos(userProfilePhotosObj));
return userProfilePhotos;
}

bool Api::banChatMember(std::int64_t chatId,
std::int64_t userId,
std::time_t untilDate,
bool revokeMessages) const {
cpr::Multipart data{};
data.parts.reserve(4);
data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found
data.parts.emplace_back("user_id", std::to_string(userId));
if (untilDate)
data.parts.emplace_back("until_date", untilDate);
if (revokeMessages)
data.parts.emplace_back("revoke_messages", revokeMessages);

return sendRequest("banChatMember", data);
}

bool Api::unbanChatMember(std::int64_t chatId,
std::int64_t userId,
bool onlyIfBanned) const {
cpr::Multipart data{};
data.parts.reserve(3);
data.parts.emplace_back("chat_id", std::to_string(chatId)); // Since cpr::Part() does not take 64bit integers (only 32bit), passing a 64bit chatId to 32bit integer gets overflown and sends wrong chat_id which causes Bad Request: chat not found
data.parts.emplace_back("user_id", std::to_string(userId));
if (onlyIfBanned)
data.parts.emplace_back("only_if_banned", onlyIfBanned);

return sendRequest("unbanChatMember", data);
}
10 changes: 9 additions & 1 deletion tests/manual_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ class MyBot : public Bot {
Ptr<BotCommand> userProfilePhotos(new BotCommand());
userProfilePhotos->command = "/user_profile_photos";
userProfilePhotos->description = "You will receive a location";
getApi()->setMyCommands({greet, stop, photo, buttons, audio, document, animation, voice, mediaGroup, location, userProfilePhotos}); // The above commands will be shown in the bot chat menu (bottom left)
Ptr<BotCommand> ban(new BotCommand());
ban->command = "/ban";
ban->description = "You will be banned for 1 minute seconds";
getApi()->setMyCommands({greet, stop, photo, buttons, audio, document, animation, voice, mediaGroup, location, userProfilePhotos, ban}); // The above commands will be shown in the bot chat menu (bottom left)
}

/// Called when Bot is about to be stopped (triggered by Bot::stop())
Expand Down Expand Up @@ -182,6 +185,11 @@ class MyBot : public Bot {
std::ofstream{photoFile->fileUniqueId + ".jpg"} << bytes;
}
}
} else if (message->text == "/ban") {
std::time_t now = std::time(nullptr);
std::time_t oneMinuteAfter = now + 60;
api()->sendMessage(message->chat->id, "Banning you for 1 minute. You will be able to use this bot after " + DateTimeUtils::toString(oneMinuteAfter));
api()->banChatMember(message->chat->id, message->from->id, oneMinuteAfter);
}
}

Expand Down
2 changes: 0 additions & 2 deletions tests/src/TestUtils.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include "tgbotxx/utils/DateTimeUtils.hpp"
#include "tgbotxx/utils/Ptr.hpp"
#include <ostream>
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
Expand Down

0 comments on commit 8e53780

Please sign in to comment.