TelegramTUI/inc/tgclient.h

187 lines
7.4 KiB
C++

#pragma once
#include <td/telegram/Client.h>
#include <td/telegram/td_api.h>
#include <atomic>
#include <functional>
#include <map>
#include <mutex>
#include <string>
#include <set>
#include "chat.h"
#include "message.h"
#include "userstatus.h"
#include "user.h"
namespace td_api = td::td_api;
using Object = td_api::object_ptr<td_api::Object>;
template<typename T>
using objptr = td_api::object_ptr<T>;
using MessageCallback = std::function<void(objptr<td_api::message>)>;
using StatusCallback = std::function<void(const td_api::updateUserStatus&)>;
using DraftCallback = std::function<void(int64_t chatid, const std::string&)>;
using ActionCallback = std::function<void(int64_t chatid, int64_t userid, ChatAction::ChatAction)>;
using DeleteCallback = std::function<void(int64_t chatid, int64_t msgid)>;
using UserUpdateCallback = std::function<void(const User&)>;
using EditMessageCallback = std::function<void(objptr<td_api::message>)>;
using IndexDoneCallback = std::function<void(int64_t)>;
using FileUpdateCallback = std::function<void(objptr<td_api::file>)>;
using NewChatCallback = std::function<void(objptr<td_api::chat>)>;
using ChatFiltersCallback = std::function<void(std::map<int32_t, std::string>)>;
class TGClient {
public:
static const uint64_t STATICHANDLERCOUNT = 128;
static void(TGClient::* STATICHANDLERS [STATICHANDLERCOUNT])(objptr<td_api::Object>);
TGClient(std::function<void()> initDoneCallback = {});
void setAuthData(std::function<std::string()> getAuthCodeCallback);
void loop();
void stop();
void registerNewMessageHandler(MessageCallback mclb);
void registerStatusUpdateHandler(StatusCallback sclb);
void registerDraftHandler(DraftCallback dclb);
void registerActionHandler(ActionCallback clb);
void registerDeleteHandler(DeleteCallback dclb);
void registerUserUpdateHandler(UserUpdateCallback uuclb);
void registerEditMessageHandler(EditMessageCallback emclb);
void registerIndexDoneHandle(IndexDoneCallback idclb);
void registerFileUpdateCallback(FileUpdateCallback fuclb);
void registerNewChatCallback(NewChatCallback ncclb);
void registerChatFiltersCallback(ChatFiltersCallback cfclb);
//exposed apicalls
void openChat(int64_t chatid);
void closeChat(int64_t chatid);
void deleteMessage(int64_t chatid, int64_t messageid, bool forall = true);
void screenShottaken(int64_t chatid);
void reply(const objptr<td_api::message>& rplyto, const std::string& awnser);
void reply(int64_t chat, int64_t msg, const std::string& awnser);
void editMessage(const objptr<td_api::message>& toEdit, const std::string& newText);
void editMessage(const objptr<td_api::message>& toEdit, const std::string& newText, std::vector<objptr<td_api::textEntity>>& entities);
void editMessageCaption(const objptr<td_api::message>& toEdit, const std::string& newText, std::vector<objptr<td_api::textEntity>>& entities);
void sendCallbackQuery(int64_t chat, int64_t messageid, const std::string& payload = "");
// mute for is in seconds (more than 604800 => forever)
void muteChat(int64_t chatid, int32_t mutefor = 1<<30);
void addChatToChatListFilter(int64_t chatid, int32_t chatfilterid);
//index chat (editMessageCallback is called for every Message in the chat)
void indexChat(int64_t chatid);
void getAllTextMessages(int64_t chatid, std::function<void(std::map<int64_t, std::string>)>);
void getLastMessages(int64_t chatid, std::function<void(const std::vector<std::shared_ptr<Message>>&)>);
void downloadFile(int32_t file_id);
void sendTextMessage(int64_t chatid, const std::string& text);
void sendTextMessageToSelf(const std::string& text);
void getMessage(int64_t chatid, int64_t messageid, std::function<void(objptr<td_api::message>)> f);
//drafts
void setDraft(int64_t chat, const std::string& text = "", int64_t replyto = 0, int64_t messageThread = 0);
void clearDraft(int64_t chat, int64_t messageThread = 0);
bool hasDraft(int64_t chat) const;
const User* getCachedUser(int64_t userid);
int64_t me = 0; //my chatid
private:
bool shouldrun = false;
bool initDone = false;
std::unique_ptr<td::ClientManager> client_manager_;
std::int32_t client_id_{0};
td_api::object_ptr<td_api::AuthorizationState> authorization_state_;
bool are_authorized_{false};
bool need_restart_{false};
std::uint64_t current_query_id_ = STATICHANDLERCOUNT;
std::uint64_t authentication_query_id_{0};
std::map<std::uint64_t, std::function<void(Object)>> handlers_; //handler list maps updateid -> callback
std::map<int64_t, objptr<td_api::draftMessage>> drafts; // chatid -> draft message / list of user drafts (does not contain drafts from the client itself)
//user cache
struct CachedUser : public User {
uint64_t lastaccessed = 0;
};
std::map<int64_t, CachedUser> usercache; //list of cached users
std::multimap<uint64_t, int64_t> usercache_timeout; //list of last access -> to know when to clean up which object
static const uint32_t MAXCACHEDUSERCOUNT; //at how many users are allowed until the cache si cleand
static const uint64_t CACHEDUSERCOUNTCLEANUPTIME; //how old is a cached user allowed to get before beeing purged from the cache (in seconds)
std::function<void()> initDoneCallback;
//callbacks
std::function<std::string()> getAuthCodeCallback;
MessageCallback messageCallback;
StatusCallback statusCallback;
DraftCallback draftCallback;
ActionCallback actionCallback;
DeleteCallback deleteCallback;
UserUpdateCallback userupdCallback;
EditMessageCallback editMessageCallback;
IndexDoneCallback indexDoneCallback;
FileUpdateCallback fileUpdateCallback;
NewChatCallback newChatCallback;
ChatFiltersCallback chatFiltersCallback;
//user cache
void accessUser(std::map<int64_t, CachedUser>::iterator it); //iterator to cached user object in usercache
void addUser(CachedUser& u);
void removeUser(std::map<int64_t, CachedUser>::iterator it); //iterator to cached user object in usercache)
void checkUserCache();
//wrapped requests
void requestMessages(int64_t chatid, int64_t from_message_id = 0, std::function<void(int64_t)> onDone = {}, std::function<void(td_api::object_ptr<td_api::message>)> forMessage = {}, bool recurse = true);
//helper
void iterate(const td_api::array<td_api::object_ptr<td_api::message>>& messages, std::function<void(const td_api::message&)> handler);
void setOption(const std::string& name, objptr<td_api::OptionValue> val);
void setOptions();
//load me and chat list, initDoneCallback is triggered after that
void loadInit();
void loadInitInternalCallback(Object o);
void restart();
void send_query(td_api::object_ptr<td_api::Function> f, std::function<void(Object)> handler = {});
void send_staticquery(td_api::object_ptr<td_api::Function> f, uint64_t handlerid);
template<typename T>
void send_wrappedquery(td_api::object_ptr<td_api::Function> f, std::function<void(td::tl_object_ptr<T>)> handler = {}, std::function<void()> onError = {}, bool printError = true);
template<typename T>
static bool catchErrors(const Object& o, std::function<void()> onError = {}, bool printError = true);
template<typename RequestType, typename ResponseType, typename... Args>
void send_inplace(Args... args, std::function<void(td::tl_object_ptr<ResponseType>)> handler = {}, bool printError = true);
void process_response(td::ClientManager::Response response);
void process_update(td_api::object_ptr<td_api::Object> update);
auto create_authentication_query_handler();
void on_authorization_state_update();
void check_authentication_error(Object object);
std::uint64_t next_query_id();
};