diff --git a/QtTelegramBot.pri b/QtTelegramBot.pri index 9c1f7ae..44ba7de 100644 --- a/QtTelegramBot.pri +++ b/QtTelegramBot.pri @@ -16,7 +16,8 @@ SOURCES += \ $$PWD/types/video.cpp \ $$PWD/types/voice.cpp \ $$PWD/types/contact.cpp \ - $$PWD/types/location.cpp + $$PWD/types/location.cpp \ + $$PWD/types/callbackquery.cpp HEADERS += \ $$PWD/qttelegrambot.h \ @@ -37,7 +38,10 @@ HEADERS += \ $$PWD/types/reply/genericreply.h \ $$PWD/types/reply/replykeyboardmarkup.h \ $$PWD/types/reply/replykeyboardhide.h \ - $$PWD/types/reply/forcereply.h + $$PWD/types/reply/forcereply.h \ + $$PWD/types/callbackquery.h \ + $$PWD/types/reply/inlinekeyboardmarkup.h \ + $$PWD/types/reply/replykeyboardremove.h OTHER_FILES += \ $$PWD/README.md diff --git a/networking.h b/networking.h index 3b45722..2d5b186 100644 --- a/networking.h +++ b/networking.h @@ -20,6 +20,7 @@ #define ENDPOINT_SEND_VOICE "/sendVoice" #define ENDPOINT_SEND_LOCATION "/sendLocation" #define ENDPOINT_SEND_CHAT_ACTION "/sendChatAction" +#define ENDPOINT_ANSWER_CALLBACK_QUERY "/answerCallbackQuery" #define ENDPOINT_GET_USER_PROFILE_PHOTOS "/getUserProfilePhotos" #define ENDPOINT_GET_UPDATES "/getUpdates" #define ENDPOINT_SET_WEBHOOK "/setWebhook" diff --git a/qttelegrambot.cpp b/qttelegrambot.cpp index e16e7a7..72735f6 100644 --- a/qttelegrambot.cpp +++ b/qttelegrambot.cpp @@ -7,7 +7,9 @@ Bot::Bot(QString token, bool updates, quint32 updateInterval, quint32 pollingTim m_net(new Networking(token)), m_internalUpdateTimer(new QTimer(this)), m_updateInterval(updateInterval), + m_updateOffset(0), m_pollingTimeout(pollingTimeout) + { QLoggingCategory::setFilterRules("qt.network.ssl.warning=false"); @@ -218,6 +220,17 @@ bool Bot::sendChatAction(QVariant chatId, Bot::ChatAction action) return success; } +bool Bot::answerCallbackQuery(QVariant callback_query_id, QString text, bool show_alert, QString url, quint32 cache_time) +{ + ParameterList params; + params.insert("callback_query_id", HttpParameter(callback_query_id)); + if (!text.isEmpty()) params.insert("text", HttpParameter(text)); + if (show_alert) params.insert("show_alert", HttpParameter(show_alert)); + if (!url.isEmpty()) params.insert("url", HttpParameter(url)); + if (cache_time) params.insert("cache_time", HttpParameter(cache_time)); + return this->responseOk(m_net->request(ENDPOINT_ANSWER_CALLBACK_QUERY, params, Networking::POST)); +} + UserProfilePhotos Bot::getUserProfilePhotos(quint32 userId, qint16 offset, qint8 limit) { ParameterList params; @@ -396,6 +409,7 @@ void Bot::internalGetUpdates() m_updateOffset = (u.id >= m_updateOffset ? u.id + 1 : m_updateOffset); emit message(u.message); + emit update(u); } m_internalUpdateTimer->start(m_updateInterval); diff --git a/qttelegrambot.h b/qttelegrambot.h index e2f3403..7a8986f 100644 --- a/qttelegrambot.h +++ b/qttelegrambot.h @@ -25,7 +25,9 @@ #include "types/reply/genericreply.h" #include "types/reply/replykeyboardmarkup.h" #include "types/reply/replykeyboardhide.h" +#include "types/reply/replykeyboardremove.h" #include "types/reply/forcereply.h" +#include "types/reply/inlinekeyboardmarkup.h" namespace Telegram { @@ -245,6 +247,19 @@ public: */ bool sendChatAction(QVariant chatId, ChatAction action); + /** + *Use this method when you need to answer to the user in response to callback command sent + * @param callback_query_id - Unique identifier for the query to be answered + * @param text - Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters + * @param show_alert - If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to false. + * @param url - URL that will be opened by the user's client. If you have created a Game and accepted the conditions via + * @Botfather, specify the URL that opens your game – note that this will only work if the query comes from + * a callback_game button. + * @param cache_time - The maximum amount of time in seconds that the result of the callback query may be cached client-side. + * Telegram apps will support caching starting in version 3.14. Defaults to 0. + */ + bool answerCallbackQuery(QVariant callback_query_id, QString text = QString(), bool show_alert = false, QString url = QString(), quint32 cache_time = 0); + /** * Use this method to get a list of profile pictures for a user. * @param userId - Unique identifier of the target user @@ -302,6 +317,7 @@ private: signals: void message(Message message); + void update(Update update); }; } diff --git a/types/callbackquery.cpp b/types/callbackquery.cpp new file mode 100644 index 0000000..55c52d1 --- /dev/null +++ b/types/callbackquery.cpp @@ -0,0 +1,24 @@ +#include "callbackquery.h" + +using namespace Telegram; + +CallbackQuery::CallbackQuery(QJsonObject callbackquery) : empty(false) +{ + id = callbackquery.value("id").toString(); + from = User(callbackquery.value("from").toObject()); + if (callbackquery.contains("message")) { + message = Message(callbackquery.value("message").toObject()); + } + if (callbackquery.contains("inline_message_id")) { + inline_message_id = callbackquery.value("inline_message_id").toString(); + } + if (callbackquery.contains("chat_instance")) { + chat_instance = callbackquery.value("chat_instance").toString(); + } + if (callbackquery.contains("data")) { + data = callbackquery.value("data").toString(); + } + if (callbackquery.contains("game_short_name")) { + game_short_name = callbackquery.value("game_short_name").toString(); + } +} diff --git a/types/callbackquery.h b/types/callbackquery.h new file mode 100644 index 0000000..7d39e4e --- /dev/null +++ b/types/callbackquery.h @@ -0,0 +1,42 @@ +#ifndef CALLBACKQUERY_H +#define CALLBACKQUERY_H + +#include +#include +#include + +#include "user.h" +#include "message.h" + +namespace Telegram { + +class CallbackQuery +{ +public: + CallbackQuery() : empty(true) {} + CallbackQuery(QJsonObject callbackquery); + + QString id; + User from; + Message message; + QString inline_message_id; + QString chat_instance; + QString data; + QString game_short_name; + bool isEmpty() const { + return empty; + } +private: + bool empty; +}; + +inline QDebug operator<< (QDebug dbg, const CallbackQuery &callbackquery) +{ + dbg.nospace() << qUtf8Printable(QString("Telegram::CallbackQuery(id=%1; From=%2") + .arg(callbackquery.id) + .arg(callbackquery.from.username)); + return dbg.maybeSpace(); +} +} + +#endif // CALLBACKQUERY_H diff --git a/types/reply/inlinekeyboardmarkup.h b/types/reply/inlinekeyboardmarkup.h new file mode 100644 index 0000000..836d261 --- /dev/null +++ b/types/reply/inlinekeyboardmarkup.h @@ -0,0 +1,94 @@ +#ifndef INLINEKEYBOARDMARKUP_H +#define INLINEKEYBOARDMARKUP_H + +#include + +#include "genericreply.h" + +namespace Telegram { + +class InlineKeyboardButton +{ +public: + InlineKeyboardButton(QString text, QString url = QString(), QString callback_data = QString(), QString switch_inline_query = QString(), QString switch_inline_query_current_chat = QString()) + : text(text), + url(url), + callback_data(callback_data), + switch_inline_query(switch_inline_query), + switch_inline_query_current_chat(switch_inline_query_current_chat) + { + object = QJsonObject(); + object.insert("text", text); + if (!url.isEmpty()) { + object.insert("url", url); + return; + } + if (!callback_data.isEmpty()) + object.insert("callback_data", callback_data); + if (!switch_inline_query.isEmpty()) + object.insert("switch_inline_query", switch_inline_query); + if (!switch_inline_query_current_chat.isEmpty()) + object.insert("switch_inline_query_current_chat", switch_inline_query_current_chat); + } + /** + * @text - Label text on the button + */ + QString text; + + /** + * @url - Optional. HTTP url to be opened when button is pressed + */ + QString url; + + /** + * @callback_data - Optional. Data to be sent in a callback query to the bot when button is pressed, 1-64 bytes + */ + QString callback_data; + + /** + * @switch_inline_query - Optional. If set, pressing the button will prompt the user to select one of their chats, open that chat and insert the bot‘s username and the specified inline query in the input field. + * Can be empty, in which case just the bot’s username will be inserted. + */ + QString switch_inline_query; + + /** + * @switch_inline_query_current_chat - Optional. If set, pressing the button will insert the bot‘s username and the specified inline query in the current chat's input field. + * Can be empty, in which case only the bot’s username will be inserted. + */ + QString switch_inline_query_current_chat; + + QJsonObject toJsonObject(){ return object; } +private: + QJsonObject object; +}; + +typedef QList InlineKeyboardButtons; + +class InlineKeyboardMarkup : public GenericReply +{ +public: + InlineKeyboardMarkup(InlineKeyboardButtons buttons) + : GenericReply(false), + buttons(buttons) { qDebug()<<"InlineKeyboardMarkup Constructor";} + + /** + * @buttons - Array of button rows, each represented by an Array of InlineKeyboardButton objects + */ + InlineKeyboardButtons buttons; + + virtual QString serialize() const { + QJsonObject o = QJsonObject(); + QJsonArray keyboardButtons = QJsonArray(); + foreach (InlineKeyboardButton button, buttons) { + QJsonArray array; array.append(button.toJsonObject()); + keyboardButtons.append(array); + } + o.insert("inline_keyboard", keyboardButtons); + qDebug()< #include #include "message.h" +#include "callbackquery.h" namespace Telegram { @@ -15,6 +16,7 @@ public: quint32 id; Message message; + CallbackQuery callbackquery; }; inline QDebug operator<< (QDebug dbg, const Update &update)