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 "Message.hpp"
|
||||
#include "Update.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
|
@ -49,6 +50,13 @@ namespace telebotxx
|
|||
/// \return Message object, recieved from the server
|
||||
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:
|
||||
class 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);
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
Logging.cpp
|
||||
Message.cpp
|
||||
Update.cpp
|
||||
User.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -249,6 +249,38 @@ namespace telebotxx
|
|||
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)
|
||||
{
|
||||
bool found;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <telebotxx/Attachment.hpp>
|
||||
#include <telebotxx/Message.hpp>
|
||||
#include <telebotxx/Update.hpp>
|
||||
#include <telebotxx/User.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
|
@ -35,6 +36,13 @@ namespace telebotxx
|
|||
/// \return pointer to Message
|
||||
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
|
||||
///
|
||||
/// 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_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()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue