Skip to content

Commit

Permalink
Added ability to send local files media group
Browse files Browse the repository at this point in the history
  • Loading branch information
baderouaich committed Jan 5, 2024
1 parent 215bb52 commit f45105e
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 17 deletions.
19 changes: 13 additions & 6 deletions include/tgbotxx/objects/InputMedia.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ namespace tgbotxx {
/// @brief Type of the result.
std::string type;

/// @brief File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended),
/// Pass an HTTP URL for Telegram to get a file from the Internet, or
/// Pass “attach://<file_attach_name>” to upload a new one using multipart/form-data under <file_attach_name> name.
/// @brief File to send.
/// - Pass a file_id std::string to send a file that exists on the Telegram servers (recommended),
/// - Pass an HTTP URL std::string for Telegram to get a file from the Internet, or
/// - Pass a cpr::File to upload a local file
/// The latter will internally use “attach://<file_attach_name>” with multipart/form-data under <file_attach_name> name to upload the local file.
/// More information on Sending Files » https://core.telegram.org/bots/api#sending-files
std::string media;
std::variant<cpr::File, std::string> media{""};

/// @brief Optional. Caption of the media to be sent, 0-1024 characters after entities parsing
std::string caption;
Expand All @@ -41,7 +43,11 @@ namespace tgbotxx {
virtual nl::json toJson() const {
nl::json json = nl::json::object();
OBJECT_SERIALIZE_FIELD(json, "type", type);
OBJECT_SERIALIZE_FIELD(json, "media", media);
// media variant
if (auto idx = media.index(); idx == 0)
json["media"] = std::get<cpr::File>(media).filepath;
else if (idx == 1)
json["media"] = std::get<std::string>(media);
OBJECT_SERIALIZE_FIELD(json, "caption", caption);
OBJECT_SERIALIZE_FIELD(json, "parse_mode", parseMode);
OBJECT_SERIALIZE_FIELD_PTR_ARRAY(json, "caption_entities", captionEntities);
Expand All @@ -51,7 +57,8 @@ namespace tgbotxx {
/// @brief Deserializes this object from JSON
virtual void fromJson(const nl::json& json) {
OBJECT_DESERIALIZE_FIELD(json, "type", type, "", false);
OBJECT_DESERIALIZE_FIELD(json, "media", media, "", false);
// media variant, we can't get a local file from remote, so it's always a URL or file id std::string.
OBJECT_DESERIALIZE_FIELD(json, "media", std::get<std::string>(media), "", false);
OBJECT_DESERIALIZE_FIELD(json, "caption", caption, "", true);
OBJECT_DESERIALIZE_FIELD(json, "parse_mode", parseMode, "", true);
OBJECT_DESERIALIZE_FIELD_PTR_ARRAY(json, "caption_entities", captionEntities, true);
Expand Down
21 changes: 20 additions & 1 deletion src/Api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,8 +731,27 @@ std::vector<Ptr<Message>> Api::sendMediaGroup(const std::variant<std::int64_t, s
if (media.size() > 10 or media.size() < 2)
throw Exception("Api::sendMediaGroup(): media must include 2-10 items. See https://core.telegram.org/bots/api#sendmediagroup");
nl::json mediaJson = nl::json::array();
// Handle local media files if available, see https://core.telegram.org/bots/api#inputmediaphoto
for (const Ptr<InputMedia>& m: media)
mediaJson.push_back(m->toJson());
{
nl::json mJson = m->toJson();
switch(m->media.index()) {
case 0: // cpr::File (Local File)
{
const cpr::File& file = std::get<cpr::File>(m->media);
std::string fileKey = StringUtils::random(8);
mJson["media"] = "attach://" + fileKey;
data.parts.emplace_back(fileKey, cpr::Files{file});
break;
}
case 1: // std::string (URL, File ID)
{
// do nothing as toJson will export the "media": "URL or file ID" object.
break;
}
}
mediaJson.push_back(mJson);
}
data.parts.emplace_back("media", mediaJson.dump());
if (messageThreadId)
data.parts.emplace_back("message_thread_id", messageThreadId);
Expand Down
32 changes: 22 additions & 10 deletions tests/manual_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class MyBot : public Bot {
getApi()->sendMessage(message->chat->id, "Sending URL photo...");
getApi()->sendPhoto(message->chat->id, "https://www.hdwallpapers.in/download/landscape_view_of_sunset_under_yellow_black_cloudy_sky_4k_5k_hd_nature-5120x2880.jpg");
getApi()->sendMessage(message->chat->id, "Sending File photo...");
getApi()->sendPhoto(message->chat->id, cpr::File{"/home/bader/Pictures/2021/05/30/thumb-1920-642642.jpg"});
getApi()->sendPhoto(message->chat->id, cpr::File{fs::path(__FILE__).parent_path().parent_path() / "examples/sendPhoto/photos/image1.jpg"});
} else if (message->text == "/inline_buttons") {
/*
Create inline keyboard buttons
Expand Down Expand Up @@ -226,28 +226,40 @@ class MyBot : public Bot {
{
getApi()->sendMessage(message->chat->id, "Sending pdf media group ...");
std::vector<Ptr<InputMedia>> mediaGroup;
for (const std::string_view docURL: {"https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4928.pdf",
for (const std::string docURL: {"https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4928.pdf",
"https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4933.pdf",
"https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4934.pdf",
"https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2759r0.pdf"}) {
Ptr<InputMediaDocument> document(new InputMediaDocument());
document->media = docURL;
mediaGroup.push_back(document);
}
// add extra local doc
Ptr<InputMediaDocument> localDoc(new InputMediaDocument());
localDoc->media = cpr::File{__FILE__};
mediaGroup.push_back(localDoc);

api()->sendMediaGroup(message->chat->id, mediaGroup);
}
{
getApi()->sendMessage(message->chat->id, "Sending photo media group ...");
std::vector<Ptr<InputMedia>> mediaGroup;
for (const std::string_view photoURL: {"https://images.alphacoders.com/129/1299740.jpg",
"https://images2.alphacoders.com/112/1128233.jpg",
"https://images2.alphacoders.com/131/1311487.jpg",
"https://images5.alphacoders.com/129/1295587.jpg",
"https://images5.alphacoders.com/121/1217119.png",
"https://images6.alphacoders.com/510/510365.jpg"}) {
for (const fs::path& localPhotoPath: {fs::path(__FILE__).parent_path().parent_path() / "examples/sendPhoto/photos/image1.jpg",
fs::path(__FILE__).parent_path().parent_path() / "examples/sendPhoto/photos/image2.jpg"}) {
Ptr<InputMediaPhoto> photo(new InputMediaPhoto());
photo->media = cpr::File{localPhotoPath}; // Local
photo->hasSpoiler = false;
mediaGroup.push_back(photo);
}
for (const std::string photoURL: {"https://images.alphacoders.com/129/1299740.jpg",
"https://images2.alphacoders.com/112/1128233.jpg",
"https://images2.alphacoders.com/131/1311487.jpg",
"https://images5.alphacoders.com/129/1295587.jpg",
"https://images5.alphacoders.com/121/1217119.png",
"https://images6.alphacoders.com/510/510365.jpg"}) {
Ptr<InputMediaPhoto> photo(new InputMediaPhoto());
photo->media = photoURL;
photo->hasSpoiler = !!(std::rand() % 3);
photo->media = photoURL; // URL
photo->hasSpoiler = false;
mediaGroup.push_back(photo);
}
api()->sendMediaGroup(message->chat->id, mediaGroup);
Expand Down

0 comments on commit f45105e

Please sign in to comment.