mirror of
https://github.com/UltraCoderRU/telebotxx.git
synced 2026-01-28 04:05:13 +00:00
Class Message implemented.
Fixed class Chat (type of id changed to std::int64_t). Class PhotoSizeArray implemented. JSON-parsing functions were rewritten and moved to JsonObjects.cpp. Implemented new JSON-parsing functions.
This commit is contained in:
parent
fd98bb70fe
commit
6cb17ac538
11 changed files with 1008 additions and 84 deletions
|
|
@ -16,7 +16,7 @@ namespace telebotxx
|
|||
Audio,
|
||||
Document,
|
||||
Game,
|
||||
PhotoSize,
|
||||
PhotoSizeArray,
|
||||
Sticker,
|
||||
Video,
|
||||
Voice,
|
||||
|
|
@ -40,7 +40,7 @@ namespace telebotxx
|
|||
|
||||
using AttachmentPtr = std::shared_ptr<Attachment>;
|
||||
|
||||
class PhotoSize : public Attachment
|
||||
class PhotoSize
|
||||
{
|
||||
public:
|
||||
PhotoSize();
|
||||
|
|
@ -73,6 +73,27 @@ namespace telebotxx
|
|||
|
||||
using PhotoSizePtr = std::shared_ptr<PhotoSize>;
|
||||
|
||||
class PhotoSizeArray : public Attachment
|
||||
{
|
||||
public:
|
||||
PhotoSizeArray();
|
||||
PhotoSizeArray(const PhotoSizeArray&);
|
||||
PhotoSizeArray(PhotoSizeArray&&);
|
||||
~PhotoSizeArray();
|
||||
|
||||
const std::vector<PhotoSize>& getArray() const;
|
||||
void setArray(const std::vector<PhotoSize>& array);
|
||||
|
||||
void swap(PhotoSizeArray& other) noexcept;
|
||||
|
||||
const PhotoSizeArray& operator=(PhotoSizeArray other) noexcept;
|
||||
|
||||
private:
|
||||
std::vector<PhotoSize> array_;
|
||||
};
|
||||
|
||||
using PhotoSizeArrayPtr = std::shared_ptr<PhotoSizeArray>;
|
||||
|
||||
class Audio : public Attachment
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#define TELEBOTXX_CHAT_HPP
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
namespace telebotxx
|
||||
{
|
||||
|
|
@ -21,8 +23,8 @@ namespace telebotxx
|
|||
Chat(Chat&&);
|
||||
~Chat();
|
||||
|
||||
int getId() const;
|
||||
void setId(int id);
|
||||
std::int64_t getId() const;
|
||||
void setId(std::int64_t id);
|
||||
|
||||
Type getType() const;
|
||||
void setType(Type type);
|
||||
|
|
@ -47,7 +49,7 @@ namespace telebotxx
|
|||
const Chat& operator=(Chat other) noexcept;
|
||||
|
||||
private:
|
||||
int id_;
|
||||
std::int64_t id_;
|
||||
Type type_;
|
||||
std::string title_;
|
||||
std::string username_;
|
||||
|
|
@ -56,6 +58,8 @@ namespace telebotxx
|
|||
bool allAdmins_;
|
||||
};
|
||||
|
||||
using ChatPtr = std::shared_ptr<Chat>;
|
||||
|
||||
void swap(Chat& lhs, Chat& rhs);
|
||||
|
||||
Chat::Type chatTypeFromString(const std::string& str);
|
||||
|
|
|
|||
185
include/telebotxx/Message.hpp
Normal file
185
include/telebotxx/Message.hpp
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
#ifndef TELEBOTXX_MESSAGE_HPP
|
||||
#define TELEBOTXX_MESSAGE_HPP
|
||||
|
||||
#include "User.hpp"
|
||||
#include "Chat.hpp"
|
||||
#include "Attachment.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
|
||||
namespace telebotxx
|
||||
{
|
||||
class MessageEntity
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
Mention,
|
||||
Hashtag,
|
||||
BotCommand,
|
||||
Url,
|
||||
Email,
|
||||
Bold,
|
||||
Italic,
|
||||
Code,
|
||||
Pre,
|
||||
TextLink,
|
||||
TextMention
|
||||
};
|
||||
|
||||
MessageEntity();
|
||||
MessageEntity(const MessageEntity&);
|
||||
MessageEntity(MessageEntity&&);
|
||||
~MessageEntity();
|
||||
|
||||
Type getType() const;
|
||||
void setType(Type type);
|
||||
|
||||
int getOffset() const;
|
||||
void setOffset(int offset);
|
||||
|
||||
size_t getLength() const;
|
||||
void setLength(size_t length);
|
||||
|
||||
const std::string& getUrl() const;
|
||||
void setUrl(const std::string& url);
|
||||
|
||||
const User& getUser() const;
|
||||
void setUser(const User& user);
|
||||
|
||||
void swap(MessageEntity& other) noexcept;
|
||||
|
||||
const MessageEntity& operator=(MessageEntity other);
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
int offset_;
|
||||
std::size_t length_;
|
||||
std::string url_;
|
||||
User user_;
|
||||
};
|
||||
|
||||
MessageEntity::Type messageEntityTypeFromString(const std::string& str);
|
||||
|
||||
using MessageEntities = std::vector<MessageEntity>;
|
||||
|
||||
class Message;
|
||||
using MessagePtr = std::shared_ptr<Message>;
|
||||
|
||||
class Message
|
||||
{
|
||||
public:
|
||||
Message();
|
||||
Message(const Message&);
|
||||
Message(Message&&);
|
||||
~Message();
|
||||
|
||||
int getId() const;
|
||||
void setId(int id);
|
||||
|
||||
const UserPtr getFrom() const;
|
||||
void setFrom(UserPtr from);
|
||||
|
||||
time_t getDate() const;
|
||||
void setDate(time_t date);
|
||||
|
||||
const Chat& getChat() const;
|
||||
void setChat(const Chat& chat);
|
||||
|
||||
const UserPtr getForwardFrom() const;
|
||||
void setForwardFrom(UserPtr forwardFrom);
|
||||
|
||||
const ChatPtr getForwardFromChat() const;
|
||||
void setForwardFromChat(ChatPtr forwardFromChat);
|
||||
|
||||
time_t getForwardDate() const;
|
||||
void setForwardDate(time_t forwardDate);
|
||||
|
||||
const MessagePtr getReplyToMessage() const;
|
||||
void setReplyToMessage(MessagePtr replyToMessage);
|
||||
|
||||
time_t getEditDate() const;
|
||||
void setEditDate(time_t editDate);
|
||||
|
||||
const std::string& getText() const;
|
||||
void setText(const std::string& text);
|
||||
|
||||
const MessageEntities& getEntities() const;
|
||||
void setEntities(MessageEntities&& entities);
|
||||
|
||||
const AttachmentPtr getAttachment() const;
|
||||
void setAttachment(AttachmentPtr attachment);
|
||||
|
||||
const std::string& getCaption() const;
|
||||
void setCaption(const std::string& caption);
|
||||
|
||||
const UserPtr getNewChatMember() const;
|
||||
void setNewChatMember(UserPtr newChatMember);
|
||||
|
||||
const UserPtr getLeftChatMember() const;
|
||||
void setLeftChatMember(UserPtr leftChatMember);
|
||||
|
||||
const std::string& getNewChatTitle() const;
|
||||
void setNewChatTitle(const std::string& newChatTitle);
|
||||
|
||||
const PhotoSizeArrayPtr getNewChatPhoto() const;
|
||||
void setNewChatPhoto(PhotoSizeArrayPtr newChatPhoto);
|
||||
|
||||
bool isDeleteChatPhoto() const;
|
||||
void setDeleteChatPhoto(bool deleteChatPhoto);
|
||||
|
||||
bool isGroupChatCreated() const;
|
||||
void setGroupChatCreated(bool groupChatCreated);
|
||||
|
||||
bool isSuperGroupChatCreated() const;
|
||||
void setSuperGroupChatCreated(bool superGroupChatCreated);
|
||||
|
||||
bool isChannelChatCreated() const;
|
||||
void setChannelChatCreated(bool channelChatCreated);
|
||||
|
||||
std::int64_t getMigrateToChatId() const;
|
||||
void setMigrateToChatId(std::int64_t migrateToChatId);
|
||||
|
||||
std::int64_t getMigrateFromChatId() const;
|
||||
void setMigrateFromChatId(std::int64_t migrateFromChatId);
|
||||
|
||||
const MessagePtr getPinnedMessage() const;
|
||||
void setPinnedMessage(MessagePtr pinnedMessage);
|
||||
|
||||
void swap(Message& other) noexcept;
|
||||
|
||||
const Message& operator=(Message other) noexcept;
|
||||
|
||||
private:
|
||||
int id_;
|
||||
UserPtr from_;
|
||||
std::time_t date_;
|
||||
Chat chat_;
|
||||
UserPtr forwardFrom_;
|
||||
ChatPtr forwardFromChat_;
|
||||
std::time_t forwardDate_;
|
||||
MessagePtr replyToMessage_;
|
||||
std::time_t editDate_;
|
||||
std::string text_;
|
||||
MessageEntities entities_;
|
||||
AttachmentPtr attachment_;
|
||||
std::string caption_;
|
||||
UserPtr newChatMember_;
|
||||
UserPtr leftChatMember_;
|
||||
std::string newChatTitle_;
|
||||
PhotoSizeArrayPtr newChatPhoto_;
|
||||
bool deleteChatPhoto_;
|
||||
bool groupChatCreated_;
|
||||
bool superGroupChatCreated_;
|
||||
bool channelChatCreated_;
|
||||
std::int64_t migrateToChatId_;
|
||||
std::int64_t migrateFromChatId_;
|
||||
MessagePtr pinnedMessage_;
|
||||
};
|
||||
|
||||
void swap(Message& lhs, Message& rhs);
|
||||
}
|
||||
|
||||
#endif // TELEBOTXX_MESSAGE_HPP
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#define TELEBOTXX_USER_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace telebotxx
|
||||
{
|
||||
|
|
@ -54,6 +55,8 @@ namespace telebotxx
|
|||
std::string lastName_;
|
||||
std::string username_;
|
||||
};
|
||||
|
||||
using UserPtr = std::shared_ptr<User>;
|
||||
}
|
||||
|
||||
#endif // TELEBOTXX_USER_H
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ void Attachment::swap(Attachment& other) noexcept
|
|||
////////////////////////////////////////////////////////////////
|
||||
|
||||
PhotoSize::PhotoSize()
|
||||
: Attachment(Type::PhotoSize),
|
||||
width_(-1),
|
||||
: width_(-1),
|
||||
height_(-1),
|
||||
fileSize_(-1)
|
||||
{
|
||||
|
|
@ -77,7 +76,6 @@ void PhotoSize::setFileSize(int fileSize)
|
|||
|
||||
void PhotoSize::swap(PhotoSize& other) noexcept
|
||||
{
|
||||
Attachment::swap(other);
|
||||
using std::swap;
|
||||
swap(fileId_, other.fileId_);
|
||||
swap(width_, other.width_);
|
||||
|
|
@ -93,6 +91,39 @@ const PhotoSize& PhotoSize::operator=(PhotoSize other) noexcept
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
PhotoSizeArray::PhotoSizeArray()
|
||||
: Attachment(Attachment::Type::PhotoSizeArray)
|
||||
{
|
||||
}
|
||||
|
||||
PhotoSizeArray::PhotoSizeArray(const PhotoSizeArray&) = default;
|
||||
PhotoSizeArray::PhotoSizeArray(PhotoSizeArray&&) = default;
|
||||
PhotoSizeArray::~PhotoSizeArray() = default;
|
||||
|
||||
const std::vector<PhotoSize>& PhotoSizeArray::getArray() const
|
||||
{
|
||||
return array_;
|
||||
}
|
||||
|
||||
void PhotoSizeArray::setArray(const std::vector<PhotoSize>& array)
|
||||
{
|
||||
array_ = array;
|
||||
}
|
||||
|
||||
void PhotoSizeArray::swap(PhotoSizeArray& other) noexcept
|
||||
{
|
||||
using std::swap;
|
||||
swap(array_, other.array_);
|
||||
}
|
||||
|
||||
const PhotoSizeArray& PhotoSizeArray::operator=(PhotoSizeArray other) noexcept
|
||||
{
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Audio::Audio()
|
||||
: Attachment(Type::Audio),
|
||||
duration_(-1),
|
||||
|
|
|
|||
|
|
@ -1,79 +1,15 @@
|
|||
#include <telebotxx/BotApi.hpp>
|
||||
#include <telebotxx/Exception.hpp>
|
||||
#include <telebotxx/Logging.hpp>
|
||||
#include "JsonObjects.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
|
||||
#include <cpr/cpr.h>
|
||||
|
||||
namespace telebotxx
|
||||
{
|
||||
const rapidjson::Value& parseResponse(const rapidjson::Document& doc)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
if (!doc.IsObject())
|
||||
throw ParseError("Object expected");
|
||||
|
||||
// Get status
|
||||
if (!doc.HasMember("ok") || !doc["ok"].IsBool())
|
||||
throw ParseError("Field 'ok' not found or has invalid type");
|
||||
bool ok = doc["ok"].GetBool();
|
||||
|
||||
if (ok)
|
||||
{
|
||||
if (!doc.HasMember("result") || !doc["result"].IsObject())
|
||||
throw ParseError("Field 'result' not found or has invalid type");
|
||||
return doc["result"];
|
||||
} else
|
||||
{
|
||||
if (!doc.HasMember("error_code") || !doc["error_code"].IsInt())
|
||||
throw ParseError("Field 'error_code' not found or has invalid type");
|
||||
int code = doc["error_code"].GetInt();
|
||||
|
||||
if (!doc.HasMember("description") || !doc["description"].IsString())
|
||||
throw ParseError("Field 'description' not found or has invalid type");
|
||||
std::string description(doc["description"].GetString());
|
||||
|
||||
throw ApiError(code, description);
|
||||
}
|
||||
}
|
||||
|
||||
User parseUser(const rapidjson::Value& obj)
|
||||
{
|
||||
if (!obj.HasMember("id") || !obj["id"].IsInt())
|
||||
throw ParseError("Field 'id' not found or has invalid type");
|
||||
int id = obj["id"].GetInt();
|
||||
|
||||
if (!obj.HasMember("first_name") || !obj["first_name"].IsString())
|
||||
throw ParseError("Field 'first_name' not found or has invalid type");
|
||||
std::string firstName(obj["first_name"].GetString());
|
||||
|
||||
std::string lastName;
|
||||
if (obj.HasMember("last_name"))
|
||||
{
|
||||
if (obj["last_name"].IsString())
|
||||
lastName = obj["last_name"].GetString();
|
||||
else
|
||||
throw ParseError("Field 'last_name' has invalid type");
|
||||
}
|
||||
|
||||
std::string username;
|
||||
if (obj.HasMember("username"))
|
||||
{
|
||||
if (obj["username"].IsString())
|
||||
username = obj["username"].GetString();
|
||||
else
|
||||
throw ParseError("Field 'username' has invalid type");
|
||||
}
|
||||
|
||||
return User(id, firstName, lastName, username);
|
||||
}
|
||||
}
|
||||
|
||||
using namespace telebotxx;
|
||||
|
||||
class BotApi::Impl
|
||||
|
|
@ -94,11 +30,11 @@ public:
|
|||
if (debugMode)
|
||||
std::cout << "Response: " << response << std::endl;
|
||||
|
||||
using namespace rapidjson;
|
||||
Document doc;
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(response.c_str());
|
||||
|
||||
return parseUser(parseResponse(doc));
|
||||
parseResponse(doc);
|
||||
return *parseUser(doc, "result", REQUIRED);
|
||||
}
|
||||
|
||||
inline void sendMessage(const std::string& chat, const std::string& text, ParseMode parseMode)
|
||||
|
|
@ -131,12 +67,12 @@ public:
|
|||
if (debugMode)
|
||||
std::cout << "Response: " << response << std::endl;
|
||||
|
||||
using namespace rapidjson;
|
||||
Document doc;
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(response.c_str());
|
||||
|
||||
/// \todo Parse message
|
||||
parseResponse(doc);
|
||||
MessagePtr message = parseMessage(doc, "result", REQUIRED);
|
||||
}
|
||||
|
||||
inline void sendPhoto(const std::string& chat, const std::string& filename, const std::string& caption)
|
||||
|
|
@ -152,12 +88,12 @@ public:
|
|||
if (debugMode)
|
||||
std::cout << "Response: " << response << std::endl;
|
||||
|
||||
using namespace rapidjson;
|
||||
Document doc;
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(response.c_str());
|
||||
|
||||
/// \todo Parse message
|
||||
parseResponse(doc);
|
||||
MessagePtr message = parseMessage(doc, "result", REQUIRED);
|
||||
}
|
||||
|
||||
inline void sendPhotoUrl(const std::string& chat, const std::string& url, const std::string& caption)
|
||||
|
|
@ -187,12 +123,12 @@ public:
|
|||
if (debugMode)
|
||||
std::cout << "Response: " << response << std::endl;
|
||||
|
||||
using namespace rapidjson;
|
||||
Document doc;
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(response.c_str());
|
||||
|
||||
/// \todo Parse message
|
||||
parseResponse(doc);
|
||||
MessagePtr message = parseMessage(doc, "result", REQUIRED);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ set(LIBRARY_OUTPUT_PATH "../lib")
|
|||
set(SOURCE_FILES Attachment.cpp
|
||||
BotApi.cpp
|
||||
Chat.cpp
|
||||
JsonObjects.cpp
|
||||
Logging.cpp
|
||||
Message.cpp
|
||||
User.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ Chat::Chat(const Chat&) = default;
|
|||
Chat::Chat(Chat&&) = default;
|
||||
Chat::~Chat() = default;
|
||||
|
||||
int Chat::getId() const
|
||||
std::int64_t Chat::getId() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
void Chat::setId(int id)
|
||||
void Chat::setId(std::int64_t id)
|
||||
{
|
||||
id_ = id;
|
||||
}
|
||||
|
|
|
|||
287
src/JsonObjects.cpp
Normal file
287
src/JsonObjects.cpp
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
#include "JsonObjects.hpp"
|
||||
#include <telebotxx/Exception.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace telebotxx
|
||||
{
|
||||
namespace impl
|
||||
{
|
||||
template<typename T> bool is(const rapidjson::Value& obj);
|
||||
template<> bool is<int>(const rapidjson::Value& obj) { return obj.IsInt(); }
|
||||
template<> bool is<std::int64_t>(const rapidjson::Value& obj) { return obj.IsInt64(); }
|
||||
template<> bool is<bool>(const rapidjson::Value& obj) { return obj.IsBool(); }
|
||||
template<> bool is<std::string>(const rapidjson::Value& obj) { return obj.IsString(); }
|
||||
|
||||
template<typename T> const T get(const rapidjson::Value& obj);
|
||||
template<> const int get(const rapidjson::Value& obj) { return obj.GetInt(); }
|
||||
template<> const std::int64_t get(const rapidjson::Value& obj) { return obj.GetInt64(); }
|
||||
template<> const bool get(const rapidjson::Value& obj) { return obj.GetBool(); }
|
||||
template<> const std::string get(const rapidjson::Value& obj) { return obj.GetString(); }
|
||||
|
||||
template<typename T> const T null();
|
||||
template<> const int null() { return 0; }
|
||||
template<> const std::int64_t null() { return 0; }
|
||||
template<> const bool null() { return false; }
|
||||
template<> const std::string null() { return ""; }
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T parse(const rapidjson::Value& obj, const char* name, bool required)
|
||||
{
|
||||
if (obj.HasMember(name))
|
||||
{
|
||||
if (impl::is<T>(obj[name]))
|
||||
return impl::get<T>(obj[name]);
|
||||
else
|
||||
throw ParseError(std::string("Field '")+ name + "' has invalid type");
|
||||
}
|
||||
else if (required)
|
||||
throw ParseError(std::string("Field '")+ name + "' not found");
|
||||
else
|
||||
return impl::null<T>();
|
||||
}
|
||||
|
||||
const rapidjson::Value& parseObject(const rapidjson::Value& parent, const char* name, bool required, bool& found)
|
||||
{
|
||||
if (parent.HasMember(name))
|
||||
{
|
||||
if (parent[name].IsObject())
|
||||
{
|
||||
found = true;
|
||||
return parent[name];
|
||||
}
|
||||
else
|
||||
throw ParseError(std::string("Field '")+ name + "' has invalid type");
|
||||
}
|
||||
else if (required)
|
||||
throw ParseError(std::string("Field '")+ name + "' not found");
|
||||
else
|
||||
{
|
||||
found = false;
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
const rapidjson::Value& parseArray(const rapidjson::Value& parent, const char* name, bool required, bool& found)
|
||||
{
|
||||
if (parent.HasMember(name))
|
||||
{
|
||||
if (parent[name].IsArray())
|
||||
{
|
||||
found = true;
|
||||
return parent[name];
|
||||
}
|
||||
else
|
||||
throw ParseError(std::string("Field '")+ name + "' has invalid type");
|
||||
}
|
||||
else if (required)
|
||||
throw ParseError(std::string("Field '")+ name + "' not found");
|
||||
else
|
||||
{
|
||||
found = false;
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<PhotoSize> parsePhotoSize(const rapidjson::Value& obj)
|
||||
{
|
||||
auto photo = std::make_unique<PhotoSize>();
|
||||
photo->setFileId(parse<std::string>(obj, "file_id", REQUIRED));
|
||||
photo->setWidth(parse<int>(obj, "width", REQUIRED));
|
||||
photo->setHeight(parse<int>(obj, "height", REQUIRED));
|
||||
photo->setFileSize(parse<int>(obj, "file_size", OPTIONAL));
|
||||
return photo;
|
||||
}
|
||||
|
||||
std::unique_ptr<PhotoSize> parsePhotoSize(const rapidjson::Value& parent, const char* name, bool required)
|
||||
{
|
||||
bool found;
|
||||
auto& obj = parseObject(parent, name, required, found);
|
||||
if (found)
|
||||
{
|
||||
return parsePhotoSize(obj);
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<PhotoSizeArray> parsePhotoSizeArray(const rapidjson::Value& parent, const char* name, bool required)
|
||||
{
|
||||
bool found;
|
||||
auto& obj = parseArray(parent, name, required, found);
|
||||
if (found)
|
||||
{
|
||||
std::vector<PhotoSize> photos;
|
||||
for (auto& elem : obj.GetArray())
|
||||
{
|
||||
auto photo = parsePhotoSize(elem);
|
||||
photos.push_back(std::move(*photo));
|
||||
}
|
||||
auto result = std::make_unique<PhotoSizeArray>();
|
||||
result->setArray(photos);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Audio> parseAudio(const rapidjson::Value& parent, const char* name, bool required)
|
||||
{
|
||||
bool found;
|
||||
auto& obj = parseObject(parent, name, required, found);
|
||||
if (found)
|
||||
{
|
||||
auto audio = std::make_unique<Audio>();
|
||||
audio->setFileId(parse<std::string>(obj, "file_id", REQUIRED));
|
||||
audio->setDuration(parse<int>(obj, "duration", REQUIRED));
|
||||
audio->setPerformer(parse<std::string>(obj, "performer", OPTIONAL));
|
||||
audio->setTitle(parse<std::string>(obj, "title", OPTIONAL));
|
||||
audio->setMimeType(parse<std::string>(obj, "mime_type", OPTIONAL));
|
||||
audio->setFileSize(parse<int>(obj, "file_size", OPTIONAL));
|
||||
return audio;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Document> parseDocument(const rapidjson::Value& parent, const char* name, bool required)
|
||||
{
|
||||
bool found;
|
||||
auto& obj = parseObject(parent, name, required, found);
|
||||
if (found)
|
||||
{
|
||||
auto document = std::make_unique<Document>();
|
||||
document->setFileId(parse<std::string>(obj, "file_id", REQUIRED));
|
||||
document->setThumb(parsePhotoSize(obj, "thumb", OPTIONAL));
|
||||
document->setFileName(parse<std::string>(obj, "file_name", OPTIONAL));
|
||||
document->setMimeType(parse<std::string>(obj, "mime_type", OPTIONAL));
|
||||
document->setFileSize(parse<int>(obj, "file_size", OPTIONAL));
|
||||
return document;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Sticker> parseSticker(const rapidjson::Value& parent, const char* name, bool required)
|
||||
{
|
||||
bool found;
|
||||
auto& obj = parseObject(parent, name, required, found);
|
||||
if (found)
|
||||
{
|
||||
auto sticker = std::make_unique<Sticker>();
|
||||
sticker->setFileId(parse<std::string>(obj, "file_id", REQUIRED));
|
||||
sticker->setWidth(parse<int>(obj, "width", REQUIRED));
|
||||
sticker->setHeight(parse<int>(obj, "height", REQUIRED));
|
||||
sticker->setThumb(parsePhotoSize(obj, "thumb", OPTIONAL));
|
||||
sticker->setEmoji(parse<std::string>(obj, "emoji", OPTIONAL));
|
||||
sticker->setFileSize(parse<int>(obj, "file_size", OPTIONAL));
|
||||
return sticker;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Message> parseMessage(const rapidjson::Value& parent, const char* name, bool required)
|
||||
{
|
||||
bool found;
|
||||
auto& obj = parseObject(parent, name, required, found);
|
||||
if (found)
|
||||
{
|
||||
auto message = std::make_unique<Message>();
|
||||
|
||||
message->setId(parse<int>(obj, "message_id", REQUIRED));
|
||||
message->setFrom(parseUser(obj, "from", OPTIONAL));
|
||||
message->setDate(parse<int>(obj, "date", REQUIRED));
|
||||
message->setChat(*parseChat(obj, "chat", REQUIRED));
|
||||
message->setForwardFrom(parseUser(obj, "forward_from", OPTIONAL));
|
||||
message->setForwardFromChat(parseChat(obj, "forward_from_chat", OPTIONAL));
|
||||
message->setForwardDate(parse<int>(obj, "forward_date", OPTIONAL));
|
||||
message->setReplyToMessage(parseMessage(obj, "reply_to_message", OPTIONAL));
|
||||
message->setEditDate(parse<int>(obj, "edit_date", OPTIONAL));
|
||||
message->setText(parse<std::string>(obj, "text", OPTIONAL));
|
||||
//message->setEntities(parseEntities(obj, "entities", OPTIONAL));
|
||||
|
||||
/// \todo: Parse one of the possible attachments
|
||||
std::shared_ptr<Attachment> attachment;
|
||||
if (!(attachment = parsePhotoSizeArray(obj, "photo", OPTIONAL)))
|
||||
if (!(attachment = parseAudio(obj, "audio", OPTIONAL)))
|
||||
if (!(attachment = parseDocument(obj, "document", OPTIONAL)))
|
||||
attachment = parseSticker(obj, "sticker", OPTIONAL);
|
||||
message->setAttachment(attachment);
|
||||
|
||||
message->setCaption(parse<std::string>(obj, "caption", OPTIONAL));
|
||||
message->setNewChatMember(parseUser(obj, "new_chat_member", OPTIONAL));
|
||||
message->setLeftChatMember(parseUser(obj, "left_chat_member", OPTIONAL));
|
||||
message->setNewChatTitle(parse<std::string>(obj, "new_chat_title", OPTIONAL));
|
||||
message->setNewChatPhoto(parsePhotoSizeArray(obj, "new_chat_photo", OPTIONAL));
|
||||
message->setDeleteChatPhoto(parse<bool>(obj, "delete_chat_photo", OPTIONAL));
|
||||
message->setGroupChatCreated(parse<bool>(obj, "group_chat_created", OPTIONAL));
|
||||
message->setSuperGroupChatCreated(parse<bool>(obj, "supergroup_chat_created", OPTIONAL));
|
||||
message->setChannelChatCreated(parse<bool>(obj, "channel_chat_created", OPTIONAL));
|
||||
message->setMigrateToChatId(parse<std::int64_t>(obj, "migrate_to_chat_id", OPTIONAL));
|
||||
message->setMigrateFromChatId(parse<std::int64_t>(obj, "migrate_from_chat_id", OPTIONAL));
|
||||
message->setPinnedMessage(parseMessage(obj, "pinned_message", OPTIONAL));
|
||||
|
||||
return message;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Chat> parseChat(const rapidjson::Value& parent, const char* name, bool required)
|
||||
{
|
||||
bool found;
|
||||
auto& obj = parseObject(parent, name, required, found);
|
||||
if (found)
|
||||
{
|
||||
auto chat = std::make_unique<Chat>();
|
||||
chat->setId(parse<std::int64_t>(obj, "id", REQUIRED));
|
||||
chat->setType(chatTypeFromString(parse<std::string>(obj, "type", REQUIRED)));
|
||||
chat->setTitle(parse<std::string>(obj, "title", OPTIONAL));
|
||||
chat->setUsername(parse<std::string>(obj, "username", OPTIONAL));
|
||||
chat->setFirstName(parse<std::string>(obj, "first_name", OPTIONAL));
|
||||
chat->setLastName(parse<std::string>(obj, "last_name", OPTIONAL));
|
||||
chat->setAllAdmins(parse<bool>(obj, "all_members_are_administrators", OPTIONAL));
|
||||
return chat;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<User> parseUser(const rapidjson::Value& parent, const char* name, bool required)
|
||||
{
|
||||
bool found;
|
||||
auto& obj = parseObject(parent, name, required, found);
|
||||
if (found)
|
||||
{
|
||||
int id = parse<int>(obj, "id", REQUIRED);
|
||||
auto firstName = parse<std::string>(obj, "first_name", REQUIRED);
|
||||
auto lastName = parse<std::string>(obj, "last_name", OPTIONAL);
|
||||
auto username = parse<std::string>(obj, "username", OPTIONAL);
|
||||
return std::make_unique<User>(id, firstName, lastName, username);
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const rapidjson::Value& parseResponse(const rapidjson::Document& doc)
|
||||
{
|
||||
if (!doc.IsObject())
|
||||
throw ParseError("Object expected");
|
||||
|
||||
// Get status
|
||||
bool ok = parse<bool>(doc, "ok", REQUIRED);
|
||||
if (ok)
|
||||
{
|
||||
bool found;
|
||||
return parseObject(doc, "result", REQUIRED, found);
|
||||
}
|
||||
else
|
||||
{
|
||||
int code = parse<int>(doc, "error_code", REQUIRED);
|
||||
std::string description(parse<std::string>(doc, "description", REQUIRED));
|
||||
throw ApiError(code, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
72
src/JsonObjects.hpp
Normal file
72
src/JsonObjects.hpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#ifndef TELEBOTXX_JSON_OBJECTS_HPP
|
||||
#define TELEBOTXX_JSON_OBJECTS_HPP
|
||||
|
||||
#include <telebotxx/Attachment.hpp>
|
||||
#include <telebotxx/Message.hpp>
|
||||
#include <telebotxx/User.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
namespace telebotxx
|
||||
{
|
||||
const bool REQUIRED = true;
|
||||
const bool OPTIONAL = false;
|
||||
|
||||
/// \brief Parse JSON object to PhotoSize
|
||||
/// \param parent reference to parent JSON object
|
||||
/// \param name field with PhotoSize object
|
||||
/// \param required REQUIRED or OPTIONAL
|
||||
/// \return pointer to PhotoSize
|
||||
std::unique_ptr<PhotoSize> parsePhotoSize(const rapidjson::Value& parent, const char* name, bool required);
|
||||
|
||||
/// \brief Parse JSON object to Audio
|
||||
/// \param parent reference to parent JSON object
|
||||
/// \param name field with Audio object
|
||||
/// \param required REQUIRED or OPTIONAL
|
||||
/// \return pointer to Audio
|
||||
std::unique_ptr<Audio> parseAudio(const rapidjson::Value& parent, const char* name, bool required);
|
||||
|
||||
/// \brief Parse JSON object to Document
|
||||
/// \param parent reference to parent JSON object
|
||||
/// \param name field with Document object
|
||||
/// \param required REQUIRED or OPTIONAL
|
||||
/// \return pointer to Document
|
||||
std::unique_ptr<Document> parseDocument(const rapidjson::Value& parent, const char* name, bool required);
|
||||
|
||||
/// \brief Parse JSON object to Sticker
|
||||
/// \param parent reference to parent JSON object
|
||||
/// \param name field with Sticker object
|
||||
/// \param required REQUIRED or OPTIONAL
|
||||
/// \return pointer to Sticker
|
||||
std::unique_ptr<Document> parseDocument(const rapidjson::Value& parent, const char* name, bool required);
|
||||
|
||||
/// \brief Parse JSON object to Chat
|
||||
/// \param parent reference to parent JSON object
|
||||
/// \param name field with Chat object
|
||||
/// \param required REQUIRED or OPTIONAL
|
||||
/// \return pointer to Chat
|
||||
std::unique_ptr<Chat> parseChat(const rapidjson::Value& parent, const char* name, bool required);
|
||||
|
||||
/// \brief Parse JSON object to User
|
||||
/// \param parent reference to parent JSON object
|
||||
/// \param name field with Document object
|
||||
/// \param required REQUIRED or OPTIONAL
|
||||
/// \return pointer to User
|
||||
std::unique_ptr<User> parseUser(const rapidjson::Value& parent, const char* name, bool required);
|
||||
|
||||
/// \brief Parse JSON object to Message
|
||||
/// \param parent reference to parent JSON object
|
||||
/// \param name field with Message object
|
||||
/// \param required REQUIRED or OPTIONAL
|
||||
/// \return pointer to Message
|
||||
std::unique_ptr<Message> parseMessage(const rapidjson::Value& parent, const char* name, bool required);
|
||||
|
||||
/// \brief Parse JSON response
|
||||
/// \param doc reference to JSON document
|
||||
/// \return reference to 'result' value
|
||||
const rapidjson::Value& parseResponse(const rapidjson::Document& doc);
|
||||
}
|
||||
|
||||
#endif // TELEBOTXX_JSON_OBJECTS_HPP
|
||||
383
src/Message.cpp
Normal file
383
src/Message.cpp
Normal file
|
|
@ -0,0 +1,383 @@
|
|||
#include <telebotxx/Message.hpp>
|
||||
|
||||
using namespace telebotxx;
|
||||
|
||||
MessageEntity::MessageEntity()
|
||||
: type_(Type::Mention),
|
||||
offset_(-1),
|
||||
length_(0)
|
||||
{
|
||||
}
|
||||
|
||||
MessageEntity::MessageEntity(const MessageEntity&) = default;
|
||||
MessageEntity::MessageEntity(MessageEntity&&) = default;
|
||||
MessageEntity::~MessageEntity() = default;
|
||||
|
||||
MessageEntity::Type MessageEntity::getType() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
void MessageEntity::setType(MessageEntity::Type type)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
int MessageEntity::getOffset() const
|
||||
{
|
||||
return offset_;
|
||||
}
|
||||
|
||||
void MessageEntity::setOffset(int offset)
|
||||
{
|
||||
offset_ = offset;
|
||||
}
|
||||
|
||||
size_t MessageEntity::getLength() const
|
||||
{
|
||||
return length_;
|
||||
}
|
||||
|
||||
void MessageEntity::setLength(size_t length)
|
||||
{
|
||||
length_ = length;
|
||||
}
|
||||
|
||||
const std::string& MessageEntity::getUrl() const
|
||||
{
|
||||
return url_;
|
||||
}
|
||||
|
||||
void MessageEntity::setUrl(const std::string& url)
|
||||
{
|
||||
url_ = url;
|
||||
}
|
||||
|
||||
const User& MessageEntity::getUser() const
|
||||
{
|
||||
return user_;
|
||||
}
|
||||
|
||||
void MessageEntity::setUser(const User& user)
|
||||
{
|
||||
user_ = user;
|
||||
}
|
||||
|
||||
void MessageEntity::swap(MessageEntity& other) noexcept
|
||||
{
|
||||
using std::swap;
|
||||
swap(type_, other.type_);
|
||||
swap(offset_, other.offset_);
|
||||
swap(length_, other.length_);
|
||||
swap(url_, other.url_);
|
||||
swap(user_, other.user_);
|
||||
}
|
||||
|
||||
const MessageEntity& MessageEntity::operator=(MessageEntity other)
|
||||
{
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MessageEntity::Type telebotxx::messageEntityTypeFromString(const std::string& str)
|
||||
{
|
||||
if (str == "mention")
|
||||
return MessageEntity::Type::Mention;
|
||||
else if (str == "hashtag")
|
||||
return MessageEntity::Type::Hashtag;
|
||||
else if (str == "bot_command")
|
||||
return MessageEntity::Type::BotCommand;
|
||||
else if (str == "url")
|
||||
return MessageEntity::Type::Url;
|
||||
else if (str == "email")
|
||||
return MessageEntity::Type::Email;
|
||||
else if (str == "bold")
|
||||
return MessageEntity::Type::Bold;
|
||||
else if (str == "italic")
|
||||
return MessageEntity::Type::Italic;
|
||||
else if (str == "code")
|
||||
return MessageEntity::Type::Code;
|
||||
else if (str == "pre")
|
||||
return MessageEntity::Type::Pre;
|
||||
else if (str == "text_link")
|
||||
return MessageEntity::Type::TextLink;
|
||||
else if (str == "text_mention")
|
||||
return MessageEntity::Type::TextMention;
|
||||
else
|
||||
throw std::invalid_argument("Unknown message entity type");
|
||||
}
|
||||
|
||||
Message::Message()
|
||||
: id_(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Message::Message(const Message&) = default;
|
||||
Message::Message(Message&&) = default;
|
||||
Message::~Message() = default;
|
||||
|
||||
int Message::getId() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
void Message::setId(int id)
|
||||
{
|
||||
id_ = id;
|
||||
}
|
||||
|
||||
const UserPtr Message::getFrom() const
|
||||
{
|
||||
return from_;
|
||||
}
|
||||
|
||||
void Message::setFrom(UserPtr from)
|
||||
{
|
||||
from_ = from;
|
||||
}
|
||||
|
||||
time_t Message::getDate() const
|
||||
{
|
||||
return date_;
|
||||
}
|
||||
|
||||
void Message::setDate(time_t date)
|
||||
{
|
||||
date_ = date;
|
||||
}
|
||||
|
||||
const Chat& Message::getChat() const
|
||||
{
|
||||
return chat_;
|
||||
}
|
||||
|
||||
void Message::setChat(const Chat& chat)
|
||||
{
|
||||
chat_ = chat;
|
||||
}
|
||||
|
||||
const UserPtr Message::getForwardFrom() const
|
||||
{
|
||||
return forwardFrom_;
|
||||
}
|
||||
|
||||
void Message::setForwardFrom(UserPtr forwardFrom)
|
||||
{
|
||||
forwardFrom_ = forwardFrom;
|
||||
}
|
||||
|
||||
const ChatPtr Message::getForwardFromChat() const
|
||||
{
|
||||
return forwardFromChat_;
|
||||
}
|
||||
|
||||
void Message::setForwardFromChat(ChatPtr forwardFromChat)
|
||||
{
|
||||
forwardFromChat_ = forwardFromChat;
|
||||
}
|
||||
|
||||
time_t Message::getForwardDate() const
|
||||
{
|
||||
return forwardDate_;
|
||||
}
|
||||
|
||||
void Message::setForwardDate(time_t forwardDate)
|
||||
{
|
||||
forwardDate_ = forwardDate;
|
||||
}
|
||||
|
||||
const MessagePtr Message::getReplyToMessage() const
|
||||
{
|
||||
return replyToMessage_;
|
||||
}
|
||||
|
||||
void Message::setReplyToMessage(MessagePtr replyToMessage)
|
||||
{
|
||||
replyToMessage_ = replyToMessage;
|
||||
}
|
||||
|
||||
time_t Message::getEditDate() const
|
||||
{
|
||||
return editDate_;
|
||||
}
|
||||
|
||||
void Message::setEditDate(time_t editDate)
|
||||
{
|
||||
editDate_ = editDate;
|
||||
}
|
||||
|
||||
const std::string& Message::getText() const
|
||||
{
|
||||
return text_;
|
||||
}
|
||||
|
||||
void Message::setText(const std::string& text)
|
||||
{
|
||||
text_ = text;
|
||||
}
|
||||
|
||||
const MessageEntities& Message::getEntities() const
|
||||
{
|
||||
return entities_;
|
||||
}
|
||||
|
||||
void Message::setEntities(MessageEntities&& entities)
|
||||
{
|
||||
entities_ = entities;
|
||||
}
|
||||
|
||||
const AttachmentPtr Message::getAttachment() const
|
||||
{
|
||||
return attachment_;
|
||||
}
|
||||
|
||||
void Message::setAttachment(AttachmentPtr attachment)
|
||||
{
|
||||
attachment_ = attachment;
|
||||
}
|
||||
|
||||
const std::string& Message::getCaption() const
|
||||
{
|
||||
return caption_;
|
||||
}
|
||||
|
||||
void Message::setCaption(const std::string& caption)
|
||||
{
|
||||
caption_ = caption;
|
||||
}
|
||||
|
||||
const UserPtr Message::getNewChatMember() const
|
||||
{
|
||||
return newChatMember_;
|
||||
}
|
||||
|
||||
void Message::setNewChatMember(UserPtr newChatMember)
|
||||
{
|
||||
newChatMember_ = newChatMember;
|
||||
}
|
||||
|
||||
const UserPtr Message::getLeftChatMember() const
|
||||
{
|
||||
return leftChatMember_;
|
||||
}
|
||||
|
||||
void Message::setLeftChatMember(UserPtr leftChatMember)
|
||||
{
|
||||
leftChatMember_ = leftChatMember;
|
||||
}
|
||||
|
||||
const std::string& Message::getNewChatTitle() const
|
||||
{
|
||||
return newChatTitle_;
|
||||
}
|
||||
|
||||
void Message::setNewChatTitle(const std::string& newChatTitle)
|
||||
{
|
||||
newChatTitle_ = newChatTitle;
|
||||
}
|
||||
|
||||
const PhotoSizeArrayPtr Message::getNewChatPhoto() const
|
||||
{
|
||||
return newChatPhoto_;
|
||||
}
|
||||
|
||||
void Message::setNewChatPhoto(PhotoSizeArrayPtr newChatPhoto)
|
||||
{
|
||||
newChatPhoto_ = newChatPhoto;
|
||||
}
|
||||
|
||||
bool Message::isDeleteChatPhoto() const
|
||||
{
|
||||
return deleteChatPhoto_;
|
||||
}
|
||||
|
||||
void Message::setDeleteChatPhoto(bool deleteChatPhoto)
|
||||
{
|
||||
deleteChatPhoto_ = deleteChatPhoto;
|
||||
}
|
||||
|
||||
bool Message::isGroupChatCreated() const
|
||||
{
|
||||
return groupChatCreated_;
|
||||
}
|
||||
|
||||
void Message::setGroupChatCreated(bool groupChatCreated)
|
||||
{
|
||||
groupChatCreated_ = groupChatCreated;
|
||||
}
|
||||
|
||||
bool Message::isSuperGroupChatCreated() const
|
||||
{
|
||||
return superGroupChatCreated_;
|
||||
}
|
||||
|
||||
void Message::setSuperGroupChatCreated(bool superGroupChatCreated)
|
||||
{
|
||||
superGroupChatCreated_ = superGroupChatCreated;
|
||||
}
|
||||
|
||||
bool Message::isChannelChatCreated() const
|
||||
{
|
||||
return channelChatCreated_;
|
||||
}
|
||||
|
||||
void Message::setChannelChatCreated(bool channelChatCreated)
|
||||
{
|
||||
channelChatCreated_ = channelChatCreated;
|
||||
}
|
||||
|
||||
std::int64_t Message::getMigrateToChatId() const
|
||||
{
|
||||
return migrateToChatId_;
|
||||
}
|
||||
|
||||
void Message::setMigrateToChatId(std::int64_t migrateToChatId)
|
||||
{
|
||||
migrateToChatId_ = migrateToChatId;
|
||||
}
|
||||
|
||||
std::int64_t Message::getMigrateFromChatId() const
|
||||
{
|
||||
return migrateFromChatId_;
|
||||
}
|
||||
|
||||
void Message::setMigrateFromChatId(std::int64_t migrateFromChatId)
|
||||
{
|
||||
migrateFromChatId_ = migrateFromChatId;
|
||||
}
|
||||
|
||||
const MessagePtr Message::getPinnedMessage() const
|
||||
{
|
||||
return pinnedMessage_;
|
||||
}
|
||||
|
||||
void Message::setPinnedMessage(MessagePtr pinnedMessage)
|
||||
{
|
||||
pinnedMessage_ = pinnedMessage;
|
||||
}
|
||||
|
||||
void Message::swap(Message& other) noexcept
|
||||
{
|
||||
using std::swap;
|
||||
swap(id_, other.id_);
|
||||
swap(from_, other.from_);
|
||||
swap(date_, other.date_);
|
||||
swap(chat_, other.chat_);
|
||||
swap(forwardFrom_, other.forwardFrom_);
|
||||
swap(forwardFromChat_, other.forwardFromChat_);
|
||||
swap(forwardDate_, other.forwardDate_);
|
||||
swap(replyToMessage_, other.replyToMessage_);
|
||||
swap(editDate_, other.editDate_);
|
||||
swap(text_, other.text_);
|
||||
}
|
||||
|
||||
const Message& Message::operator=(Message other) noexcept
|
||||
{
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void telebotxx::swap(Message& lhs, Message& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue