diff options
author | ray-pixar <pixar@chmail.ir> | 2015-09-10 19:19:15 +0430 |
---|---|---|
committer | ray-pixar <pixar@chmail.ir> | 2015-09-10 19:19:15 +0430 |
commit | 6bb048c991a52c0b974bd4a316579f0a622a70ec (patch) | |
tree | a46258645f3647431c60379335d217445a22ab81 | |
parent | a4954856e680b85eebdcfa5dddf5c9baf8102077 (diff) |
Fix for send files using multipart/form
-rw-r--r-- | include/tgbot/Api.h | 12 | ||||
-rw-r--r-- | include/tgbot/net/HttpReqArg.h | 9 | ||||
-rw-r--r-- | include/tgbot/types/InputFile.h | 9 | ||||
-rw-r--r-- | src/Api.cpp | 28 | ||||
-rw-r--r-- | src/TgTypeParser.cpp | 12 | ||||
-rw-r--r-- | src/net/HttpClient.cpp | 1 | ||||
-rw-r--r-- | src/net/HttpParser.cpp | 18 |
7 files changed, 56 insertions, 33 deletions
diff --git a/include/tgbot/Api.h b/include/tgbot/Api.h index ebebfd7..1881015 100644 --- a/include/tgbot/Api.h +++ b/include/tgbot/Api.h @@ -46,7 +46,7 @@ class Bot; */ class Api { -friend Bot; +friend class Bot; public: Api(const std::string& token); @@ -97,7 +97,7 @@ public: * @param replyMarkup Optional. Additional interface options. An object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. * @return On success, the sent message is returned. */ - Message::Ptr sendPhoto(int32_t chatId, const std::string& photo, const std::string& caption = "", int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; + Message::Ptr sendPhoto(int32_t chatId, const std::string& photoId, const std::string& caption = "", int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; /** * Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as Document). @@ -119,7 +119,7 @@ public: * @param replyMarkup Optional. Additional interface options. An object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. * @return On success, the sent message is returned. */ - Message::Ptr sendAudio(int32_t chatId, const std::string& audio, int32_t duration = 0, int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; + Message::Ptr sendAudio(int32_t chatId, const std::string& audioId, int32_t duration = 0, int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; /** * Use this method to send general files. @@ -139,7 +139,7 @@ public: * @param replyMarkup Optional. Additional interface options. An object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. * @return On success, the sent message is returned. */ - Message::Ptr sendDocument(int32_t chatId, const std::string& document, int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; + Message::Ptr sendDocument(int32_t chatId, const std::string& documentId, int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; /** * Use this method to send .webp stickers. @@ -159,7 +159,7 @@ public: * @param replyMarkup Optional. Additional interface options. A object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. * @return On success, the sent message is returned. */ - Message::Ptr sendSticker(int32_t chatId, const std::string& sticker, int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; + Message::Ptr sendSticker(int32_t chatId, const std::string& stickerId, int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; /** * Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). @@ -179,7 +179,7 @@ public: * @param replyMarkup Optional. Additional interface options. A object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user. * @return On success, the sent message is returned. */ - Message::Ptr sendVideo(int32_t chatId, const std::string& video, int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; + Message::Ptr sendVideo(int32_t chatId, const std::string& videoId, int32_t replyToMessageId = 0, const GenericReply::Ptr& replyMarkup = GenericReply::Ptr()) const; /** * Use this method to send point on the map. diff --git a/include/tgbot/net/HttpReqArg.h b/include/tgbot/net/HttpReqArg.h index 65f4f52..683c2b0 100644 --- a/include/tgbot/net/HttpReqArg.h +++ b/include/tgbot/net/HttpReqArg.h @@ -37,8 +37,8 @@ class HttpReqArg { public: template<typename T> - HttpReqArg(const std::string& name, const T& value, bool isFile = false, const std::string& mimeType = "text/plain") : - name(name), value(boost::lexical_cast<std::string>(value)), isFile(isFile), mimeType(mimeType) + HttpReqArg(const std::string& name, const T& value, bool isFile = false, const std::string& mimeType = "text/plain", std::string fileName = "") : + name(name), value(boost::lexical_cast<std::string>(value)), isFile(isFile), mimeType(mimeType), fileName(fileName) { } @@ -61,6 +61,11 @@ public: * Mime type of an argument value. This field makes sense only if isFile is true. */ std::string mimeType = "text/plain"; + + /** + * Should be set if an argument value hold some file contents + */ + std::string fileName; }; } diff --git a/include/tgbot/types/InputFile.h b/include/tgbot/types/InputFile.h index 825e677..1228885 100644 --- a/include/tgbot/types/InputFile.h +++ b/include/tgbot/types/InputFile.h @@ -36,6 +36,10 @@ namespace TgBot { class InputFile { public: + InputFile() { + fileName = "set_file_name.ext"; + } + typedef std::shared_ptr<InputFile> Ptr; /** @@ -47,6 +51,11 @@ public: * Mime type of a file. */ std::string mimeType; + + /** + * File name. + */ + std::string fileName; }; } diff --git a/src/Api.cpp b/src/Api.cpp index 84caa74..237cf88 100644 --- a/src/Api.cpp +++ b/src/Api.cpp @@ -65,7 +65,7 @@ Message::Ptr Api::forwardMessage(int32_t chatId, int32_t fromChatId, int32_t mes Message::Ptr Api::sendPhoto(int32_t chatId, const InputFile::Ptr& photo, const string& caption, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("photo", photo->data, true, photo->mimeType)); + args.push_back(HttpReqArg("photo", photo->data, true, photo->mimeType, photo->fileName)); if (!caption.empty()) { args.push_back(HttpReqArg("caption", caption)); } @@ -78,10 +78,10 @@ Message::Ptr Api::sendPhoto(int32_t chatId, const InputFile::Ptr& photo, const s return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendPhoto", args)); } -Message::Ptr Api::sendPhoto(int32_t chatId, const string& photo, const string& caption, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { +Message::Ptr Api::sendPhoto(int32_t chatId, const string& photoId, const string& caption, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("photo", photo)); + args.push_back(HttpReqArg("photo", photoId)); if (!caption.empty()) { args.push_back(HttpReqArg("caption", caption)); } @@ -97,7 +97,7 @@ Message::Ptr Api::sendPhoto(int32_t chatId, const string& photo, const string& c Message::Ptr Api::sendAudio(int32_t chatId, const InputFile::Ptr& audio, int32_t duration, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("audio", audio->data, true, audio->mimeType)); + args.push_back(HttpReqArg("audio", audio->data, true, audio->mimeType, audio->fileName)); if (duration) { args.push_back(HttpReqArg("duration", duration)); } @@ -110,10 +110,10 @@ Message::Ptr Api::sendAudio(int32_t chatId, const InputFile::Ptr& audio, int32_t return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendAudio", args)); } -Message::Ptr Api::sendAudio(int32_t chatId, const string& audio, int32_t duration, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { +Message::Ptr Api::sendAudio(int32_t chatId, const string& audioId, int32_t duration, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("audio", audio)); + args.push_back(HttpReqArg("audio", audioId)); if (duration) { args.push_back(HttpReqArg("duration", duration)); } @@ -129,7 +129,7 @@ Message::Ptr Api::sendAudio(int32_t chatId, const string& audio, int32_t duratio Message::Ptr Api::sendDocument(int32_t chatId, const InputFile::Ptr& document, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("document", document->data, true, document->mimeType)); + args.push_back(HttpReqArg("document", document->data, true, document->mimeType, document->fileName)); if (replyToMessageId) { args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId)); } @@ -155,7 +155,7 @@ Message::Ptr Api::sendDocument(int32_t chatId, const string& document, int32_t r Message::Ptr Api::sendSticker(int32_t chatId, const InputFile::Ptr& sticker, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("sticker", sticker->data, true, sticker->mimeType)); + args.push_back(HttpReqArg("sticker", sticker->data, true, sticker->mimeType, sticker->fileName)); if (replyToMessageId) { args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId)); } @@ -165,10 +165,10 @@ Message::Ptr Api::sendSticker(int32_t chatId, const InputFile::Ptr& sticker, int return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendSticker", args)); } -Message::Ptr Api::sendSticker(int32_t chatId, const string& sticker, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { +Message::Ptr Api::sendSticker(int32_t chatId, const string& stickerId, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("sticker", sticker)); + args.push_back(HttpReqArg("sticker", stickerId)); if (replyToMessageId) { args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId)); } @@ -181,7 +181,7 @@ Message::Ptr Api::sendSticker(int32_t chatId, const string& sticker, int32_t rep Message::Ptr Api::sendVideo(int32_t chatId, const InputFile::Ptr& video, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("video", video->data, true, video->mimeType)); + args.push_back(HttpReqArg("video", video->data, true, video->mimeType, video->fileName)); if (replyToMessageId) { args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId)); } @@ -191,10 +191,10 @@ Message::Ptr Api::sendVideo(int32_t chatId, const InputFile::Ptr& video, int32_t return TgTypeParser::getInstance().parseJsonAndGetMessage(sendRequest("sendVideo", args)); } -Message::Ptr Api::sendVideo(int32_t chatId, const string& video, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { +Message::Ptr Api::sendVideo(int32_t chatId, const string& videoId, int32_t replyToMessageId, const GenericReply::Ptr& replyMarkup) const { vector<HttpReqArg> args; args.push_back(HttpReqArg("chat_id", chatId)); - args.push_back(HttpReqArg("video", video)); + args.push_back(HttpReqArg("video", videoId)); if (replyToMessageId) { args.push_back(HttpReqArg("reply_to_message_id", replyToMessageId)); } @@ -267,7 +267,7 @@ ptree Api::sendRequest(const string& method, const vector<HttpReqArg>& args) con ptree result = TgTypeParser::getInstance().parseJson(serverResponse); try { if (result.get<bool>("ok")) { - if(method != "getMe" && method != "sendMessage") + if(method != "getMe" && method != "sendMessage" && method != "sendDocument") return result; else return result.find("result")->second; diff --git a/src/TgTypeParser.cpp b/src/TgTypeParser.cpp index 81d2119..d4f4340 100644 --- a/src/TgTypeParser.cpp +++ b/src/TgTypeParser.cpp @@ -187,7 +187,9 @@ string TgTypeParser::parseAudio(const Audio::Ptr& object) const { Document::Ptr TgTypeParser::parseJsonAndGetDocument(const ptree& data) const { Document::Ptr result(new Document); result->fileId = data.get<string>("file_id"); - result->thumb = parseJsonAndGetPhotoSize(data.find("thumb")->second); + if(data.find("thumb") != data.not_found()) { + result->thumb = parseJsonAndGetPhotoSize(data.find("thumb")->second); + } result->fileName = data.get("file_name", ""); result->mimeType = data.get("mime_type", ""); result->fileSize = data.get("file_size", 0); @@ -215,7 +217,9 @@ Sticker::Ptr TgTypeParser::parseJsonAndGetSticker(const ptree& data) const { result->fileId = data.get<string>("file_id"); result->width = data.get<int32_t>("width"); result->height = data.get<int32_t>("height"); - result->thumb = parseJsonAndGetPhotoSize(data.find("thumb")->second); + if(data.find("thumb") != data.not_found()) { + result->thumb = parseJsonAndGetPhotoSize(data.find("thumb")->second); + } result->fileSize = data.get("file_size", 0); return result; } @@ -242,7 +246,9 @@ Video::Ptr TgTypeParser::parseJsonAndGetVideo(const ptree& data) const { result->width = data.get<int32_t>("width"); result->height = data.get<int32_t>("height"); result->duration = data.get<int32_t>("duration"); - result->thumb = parseJsonAndGetPhotoSize(data.find("thumb")->second); + if(data.find("thumb") != data.not_found()) { + result->thumb = parseJsonAndGetPhotoSize(data.find("thumb")->second); + } result->mimeType = data.get("mime_type", ""); result->fileSize = data.get("file_size", 0); return result; diff --git a/src/net/HttpClient.cpp b/src/net/HttpClient.cpp index b9813ad..f7f4a6b 100644 --- a/src/net/HttpClient.cpp +++ b/src/net/HttpClient.cpp @@ -27,7 +27,6 @@ using namespace std; using namespace boost::asio; using namespace boost::asio::ip; -using namespace boost::asio::local; namespace TgBot { diff --git a/src/net/HttpParser.cpp b/src/net/HttpParser.cpp index a2d9108..3ea95ec 100644 --- a/src/net/HttpParser.cpp +++ b/src/net/HttpParser.cpp @@ -63,16 +63,16 @@ string HttpParser::generateRequest(const Url& url, const vector<HttpReqArg>& arg string bondary = generateMultipartBoundary(args); if (bondary.empty()) { result += "Content-Type: application/x-www-form-urlencoded\r\n"; - requestData = generateWwwFormUrlencoded(args); + requestData = generateWwwFormUrlencoded(args); } else { result += "Content-Type: multipart/form-data; boundary="; result += bondary; - result += "\r\n"; + result += "\r\n"; requestData = generateMultipartFormData(args, bondary); - } + } - result += "Content-Length: "; - result += lexical_cast<string>(requestData.length()); + result += "Content-Length: "; + result += lexical_cast<string>(requestData.length()); result += "\r\n\r\n"; result += requestData; } @@ -86,8 +86,11 @@ string HttpParser::generateMultipartFormData(const vector<HttpReqArg>& args, con result += bondary; result += "\r\nContent-Disposition: form-data; name=\""; result += item.name; + if(item.isFile) { + result += "\"; filename=\"" + item.fileName; + } result += "\"\r\n"; - if (item.isFile) { + if (item.isFile) { result += "Content-Type: "; result += item.mimeType; result += "\r\n"; @@ -96,6 +99,7 @@ string HttpParser::generateMultipartFormData(const vector<HttpReqArg>& args, con result += item.value; result += "\r\n"; } + result += "--" + bondary + "--"; return result; } @@ -103,7 +107,7 @@ string HttpParser::generateMultipartBoundary(const vector<HttpReqArg>& args) { string result; srand((unsigned int) time(nullptr)); for (const HttpReqArg& item : args) { - if (item.isFile) { + if (item.isFile) { while (result.empty() || item.value.find(result) != item.value.npos) { result += StringTools::generateRandomString(4); } |