mirror of
https://github.com/UltraCoderRU/telebotxx.git
synced 2026-01-28 04:05:13 +00:00
getUpdates() implemented.
This commit is contained in:
parent
5c1f3a3dd0
commit
9da2b2966e
8 changed files with 273 additions and 0 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "User.hpp"
|
#include "User.hpp"
|
||||||
#include "Message.hpp"
|
#include "Message.hpp"
|
||||||
|
#include "Update.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -49,6 +50,13 @@ namespace telebotxx
|
||||||
/// \return Message object, recieved from the server
|
/// \return Message object, recieved from the server
|
||||||
Message sendPhotoUrl(const std::string& chat, const std::string& url, const std::string& caption = "");
|
Message sendPhotoUrl(const std::string& chat, const std::string& url, const std::string& caption = "");
|
||||||
|
|
||||||
|
/// \brief Get updates using long polling
|
||||||
|
/// \param offset identifier of the first update to be returned
|
||||||
|
/// \param limit maximum number of updates to be retrieved
|
||||||
|
/// \param timeout timeout in seconds for long polling
|
||||||
|
/// \return Updates (vector of Update)
|
||||||
|
Updates getUpdates(int offset = 0, unsigned short limit = 0, unsigned timeout = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> impl_;
|
std::unique_ptr<Impl> impl_;
|
||||||
|
|
|
||||||
74
include/telebotxx/Update.hpp
Normal file
74
include/telebotxx/Update.hpp
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
#ifndef TELEBOTXX_UPDATE_HPP
|
||||||
|
#define TELEBOTXX_UPDATE_HPP
|
||||||
|
|
||||||
|
#include "Message.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace telebotxx
|
||||||
|
{
|
||||||
|
class Update
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Message,
|
||||||
|
EditedMessage,
|
||||||
|
InlineQuery,
|
||||||
|
ChosenInlineResult,
|
||||||
|
CallbackQuery
|
||||||
|
};
|
||||||
|
|
||||||
|
Update(int id, Type type);
|
||||||
|
Update(const Update&);
|
||||||
|
Update(Update&&);
|
||||||
|
virtual ~Update() = 0;
|
||||||
|
|
||||||
|
int getId() const;
|
||||||
|
Type getType() const;
|
||||||
|
|
||||||
|
void swap(Update& other) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int id_;
|
||||||
|
Type updateType_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using UpdatePtr = std::shared_ptr<Update>;
|
||||||
|
using Updates = std::vector<UpdatePtr>;
|
||||||
|
|
||||||
|
class MessageUpdate : public Update
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MessageUpdate(int id, const Message& message);
|
||||||
|
MessageUpdate(const MessageUpdate&);
|
||||||
|
MessageUpdate(MessageUpdate&&);
|
||||||
|
~MessageUpdate();
|
||||||
|
|
||||||
|
const Message& getMessage() const;
|
||||||
|
|
||||||
|
void swap(MessageUpdate& other) noexcept;
|
||||||
|
|
||||||
|
const MessageUpdate& operator=(MessageUpdate other);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Message message_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EditedMessageUpdate: public MessageUpdate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditedMessageUpdate(int id, const Message& message);
|
||||||
|
EditedMessageUpdate(const EditedMessageUpdate&);
|
||||||
|
EditedMessageUpdate(EditedMessageUpdate&&);
|
||||||
|
~EditedMessageUpdate();
|
||||||
|
|
||||||
|
void swap(EditedMessageUpdate& other) noexcept;
|
||||||
|
|
||||||
|
const EditedMessageUpdate& operator=(EditedMessageUpdate other);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TELEBOTXX_UPDATE_HPP
|
||||||
|
|
@ -131,6 +131,49 @@ public:
|
||||||
return *parseMessage(doc, "result", REQUIRED);
|
return *parseMessage(doc, "result", REQUIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Updates getUpdates(int offset, unsigned short limit, unsigned timeout)
|
||||||
|
{
|
||||||
|
// Construct JSON body
|
||||||
|
using namespace rapidjson;
|
||||||
|
StringBuffer s;
|
||||||
|
Writer<StringBuffer> writer(s);
|
||||||
|
|
||||||
|
writer.StartObject();
|
||||||
|
if (offset != 0)
|
||||||
|
{
|
||||||
|
writer.String("offset");
|
||||||
|
writer.Int(offset);
|
||||||
|
}
|
||||||
|
if (limit != 0)
|
||||||
|
{
|
||||||
|
writer.String("limit");
|
||||||
|
writer.Uint(limit);
|
||||||
|
}
|
||||||
|
if (timeout != 0)
|
||||||
|
{
|
||||||
|
writer.String("timeout");
|
||||||
|
writer.Uint(timeout);
|
||||||
|
}
|
||||||
|
writer.EndObject();
|
||||||
|
|
||||||
|
std::string request = s.GetString();
|
||||||
|
|
||||||
|
auto r = cpr::Post(cpr::Url{telegramMainUrl_ + "/getUpdates"},
|
||||||
|
cpr::Header{{"Content-Type", "application/json"}},
|
||||||
|
cpr::Body{request}
|
||||||
|
);
|
||||||
|
auto& response = r.text;
|
||||||
|
|
||||||
|
if (debugMode)
|
||||||
|
std::cout << "Response: " << response << std::endl;
|
||||||
|
|
||||||
|
rapidjson::Document doc;
|
||||||
|
doc.Parse(response.c_str());
|
||||||
|
|
||||||
|
checkResponse(doc);
|
||||||
|
return *parseUpdates(doc, "result", REQUIRED);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string token_;
|
std::string token_;
|
||||||
|
|
@ -164,3 +207,8 @@ Message BotApi::sendPhotoUrl(const std::string& chat, const std::string& url, co
|
||||||
{
|
{
|
||||||
return impl_->sendPhotoUrl(chat, url, caption);
|
return impl_->sendPhotoUrl(chat, url, caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Updates BotApi::getUpdates(int offset, unsigned short limit, unsigned int timeout)
|
||||||
|
{
|
||||||
|
return impl_->getUpdates(offset, limit, timeout);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ set(SOURCE_FILES Attachment.cpp
|
||||||
JsonObjects.cpp
|
JsonObjects.cpp
|
||||||
Logging.cpp
|
Logging.cpp
|
||||||
Message.cpp
|
Message.cpp
|
||||||
|
Update.cpp
|
||||||
User.cpp
|
User.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,38 @@ namespace telebotxx
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Update> parseUpdate(const rapidjson::Value& obj)
|
||||||
|
{
|
||||||
|
int id = parse<int>(obj, "update_id", REQUIRED);
|
||||||
|
|
||||||
|
std::unique_ptr<Message> message;
|
||||||
|
if (message = parseMessage(obj, "message", OPTIONAL))
|
||||||
|
return std::make_unique<MessageUpdate>(id, *message);
|
||||||
|
else if (message = parseMessage(obj, "edited_message", OPTIONAL))
|
||||||
|
return std::make_unique<EditedMessageUpdate>(id, *message);
|
||||||
|
/// \todo: other updates
|
||||||
|
else
|
||||||
|
throw ParseError("Unknown update type");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Updates> parseUpdates(const rapidjson::Value& parent, const char* name, bool required)
|
||||||
|
{
|
||||||
|
bool found;
|
||||||
|
auto& obj = parseArray(parent, name, required, found);
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
std::vector<UpdatePtr> updates;
|
||||||
|
for (auto& elem : obj.GetArray())
|
||||||
|
{
|
||||||
|
auto update = parseUpdate(elem);
|
||||||
|
updates.emplace_back(std::move(update));
|
||||||
|
}
|
||||||
|
return std::make_unique<Updates>(std::move(updates));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<User> parseUser(const rapidjson::Value& parent, const char* name, bool required)
|
std::unique_ptr<User> parseUser(const rapidjson::Value& parent, const char* name, bool required)
|
||||||
{
|
{
|
||||||
bool found;
|
bool found;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <telebotxx/Attachment.hpp>
|
#include <telebotxx/Attachment.hpp>
|
||||||
#include <telebotxx/Message.hpp>
|
#include <telebotxx/Message.hpp>
|
||||||
|
#include <telebotxx/Update.hpp>
|
||||||
#include <telebotxx/User.hpp>
|
#include <telebotxx/User.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -35,6 +36,13 @@ namespace telebotxx
|
||||||
/// \return pointer to Message
|
/// \return pointer to Message
|
||||||
std::unique_ptr<Message> parseMessage(const rapidjson::Value& parent, const char* name, bool required);
|
std::unique_ptr<Message> parseMessage(const rapidjson::Value& parent, const char* name, bool required);
|
||||||
|
|
||||||
|
/// \brief Parse JSON array of Update
|
||||||
|
/// \param parent reference to parent JSON object
|
||||||
|
/// \param name field with array of Update objects
|
||||||
|
/// \param required REQUIRED or OPTIONAL
|
||||||
|
/// \return Updates (vector of UpdatePtr>
|
||||||
|
std::unique_ptr<Updates> parseUpdates(const rapidjson::Value& parent, const char* name, bool required);
|
||||||
|
|
||||||
/// \brief Check JSON response
|
/// \brief Check JSON response
|
||||||
///
|
///
|
||||||
/// Throws an exception if error code recieved.
|
/// Throws an exception if error code recieved.
|
||||||
|
|
|
||||||
82
src/Update.cpp
Normal file
82
src/Update.cpp
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <telebotxx/Update.hpp>
|
||||||
|
|
||||||
|
using namespace telebotxx;
|
||||||
|
|
||||||
|
Update::Update(int id, Type type)
|
||||||
|
: id_(id),
|
||||||
|
updateType_(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Update::Update(const Update&) = default;
|
||||||
|
Update::Update(Update&&) = default;
|
||||||
|
Update::~Update() = default;
|
||||||
|
|
||||||
|
int Update::getId() const
|
||||||
|
{
|
||||||
|
return id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Update::Type Update::getType() const
|
||||||
|
{
|
||||||
|
return updateType_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update::swap(Update& other) noexcept
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(id_, other.id_);
|
||||||
|
swap(updateType_, other.updateType_);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
MessageUpdate::MessageUpdate(int id, const Message& message)
|
||||||
|
: Update(id, Type::Message),
|
||||||
|
message_(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageUpdate::MessageUpdate(const MessageUpdate&) = default;
|
||||||
|
MessageUpdate::MessageUpdate(MessageUpdate&&) = default;
|
||||||
|
MessageUpdate::~MessageUpdate() = default;
|
||||||
|
|
||||||
|
const Message& MessageUpdate::getMessage() const
|
||||||
|
{
|
||||||
|
return message_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageUpdate::swap(MessageUpdate& other) noexcept
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
Update::swap(other);
|
||||||
|
swap(message_, other.message_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MessageUpdate& MessageUpdate::operator=(MessageUpdate other)
|
||||||
|
{
|
||||||
|
swap(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
EditedMessageUpdate::EditedMessageUpdate(int id, const Message& message)
|
||||||
|
: MessageUpdate(id, message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EditedMessageUpdate::EditedMessageUpdate(const EditedMessageUpdate&) = default;
|
||||||
|
EditedMessageUpdate::EditedMessageUpdate(EditedMessageUpdate&&) = default;
|
||||||
|
EditedMessageUpdate::~EditedMessageUpdate() = default;
|
||||||
|
|
||||||
|
void EditedMessageUpdate::swap(EditedMessageUpdate& other) noexcept
|
||||||
|
{
|
||||||
|
MessageUpdate::swap(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
const EditedMessageUpdate& EditedMessageUpdate::operator=(EditedMessageUpdate other)
|
||||||
|
{
|
||||||
|
swap(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
@ -131,4 +131,24 @@ BOOST_AUTO_TEST_SUITE(TestBotApi)
|
||||||
BOOST_REQUIRE_NO_THROW(bot->sendPhotoUrl(chat, photoUrl, "Sample caption"));
|
BOOST_REQUIRE_NO_THROW(bot->sendPhotoUrl(chat, photoUrl, "Sample caption"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(GetUpdates)
|
||||||
|
{
|
||||||
|
using namespace telebotxx;
|
||||||
|
PRINT_TESTNAME;
|
||||||
|
BOOST_REQUIRE(bot);
|
||||||
|
Updates updates;
|
||||||
|
BOOST_REQUIRE_NO_THROW(updates = bot->getUpdates());
|
||||||
|
for (auto update : updates)
|
||||||
|
{
|
||||||
|
if (update->getType() == Update::Type::Message)
|
||||||
|
{
|
||||||
|
auto& message = std::dynamic_pointer_cast<MessageUpdate>(update)->getMessage();
|
||||||
|
if (message.getFrom())
|
||||||
|
std::cout << *message.getFrom() << ": ";
|
||||||
|
std::cout << message.getText() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue