summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorray-pixar <pixar@chmail.ir>2015-09-10 19:19:15 +0430
committerray-pixar <pixar@chmail.ir>2015-09-10 19:19:15 +0430
commit6bb048c991a52c0b974bd4a316579f0a622a70ec (patch)
treea46258645f3647431c60379335d217445a22ab81
parenta4954856e680b85eebdcfa5dddf5c9baf8102077 (diff)
Fix for send files using multipart/form
-rw-r--r--include/tgbot/Api.h12
-rw-r--r--include/tgbot/net/HttpReqArg.h9
-rw-r--r--include/tgbot/types/InputFile.h9
-rw-r--r--src/Api.cpp28
-rw-r--r--src/TgTypeParser.cpp12
-rw-r--r--src/net/HttpClient.cpp1
-rw-r--r--src/net/HttpParser.cpp18
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);
}