data_business_chatbots.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "data/business/data_business_chatbots.h"
  8. #include "apiwrap.h"
  9. #include "data/business/data_business_common.h"
  10. #include "data/business/data_business_info.h"
  11. #include "data/data_session.h"
  12. #include "data/data_user.h"
  13. #include "main/main_session.h"
  14. namespace Data {
  15. Chatbots::Chatbots(not_null<Session*> owner)
  16. : _owner(owner) {
  17. }
  18. Chatbots::~Chatbots() = default;
  19. void Chatbots::preload() {
  20. if (_loaded || _requestId) {
  21. return;
  22. }
  23. _requestId = _owner->session().api().request(
  24. MTPaccount_GetConnectedBots()
  25. ).done([=](const MTPaccount_ConnectedBots &result) {
  26. _requestId = 0;
  27. _loaded = true;
  28. const auto &data = result.data();
  29. _owner->processUsers(data.vusers());
  30. const auto &list = data.vconnected_bots().v;
  31. if (!list.isEmpty()) {
  32. const auto &bot = list.front().data();
  33. const auto botId = bot.vbot_id().v;
  34. _settings = ChatbotsSettings{
  35. .bot = _owner->session().data().user(botId),
  36. .recipients = FromMTP(_owner, bot.vrecipients()),
  37. .repliesAllowed = bot.is_can_reply(),
  38. };
  39. } else {
  40. _settings.force_assign(ChatbotsSettings());
  41. }
  42. }).fail([=](const MTP::Error &error) {
  43. _requestId = 0;
  44. LOG(("API Error: Could not get connected bots %1 (%2)"
  45. ).arg(error.code()
  46. ).arg(error.type()));
  47. }).send();
  48. }
  49. bool Chatbots::loaded() const {
  50. return _loaded;
  51. }
  52. const ChatbotsSettings &Chatbots::current() const {
  53. return _settings.current();
  54. }
  55. rpl::producer<ChatbotsSettings> Chatbots::changes() const {
  56. return _settings.changes();
  57. }
  58. rpl::producer<ChatbotsSettings> Chatbots::value() const {
  59. return _settings.value();
  60. }
  61. void Chatbots::save(
  62. ChatbotsSettings settings,
  63. Fn<void()> done,
  64. Fn<void(QString)> fail) {
  65. const auto was = _settings.current();
  66. if (was == settings) {
  67. return;
  68. } else if (was.bot || settings.bot) {
  69. using Flag = MTPaccount_UpdateConnectedBot::Flag;
  70. const auto api = &_owner->session().api();
  71. api->request(MTPaccount_UpdateConnectedBot(
  72. MTP_flags(!settings.bot
  73. ? Flag::f_deleted
  74. : settings.repliesAllowed
  75. ? Flag::f_can_reply
  76. : Flag()),
  77. (settings.bot ? settings.bot : was.bot)->inputUser,
  78. ForBotsToMTP(settings.recipients)
  79. )).done([=](const MTPUpdates &result) {
  80. api->applyUpdates(result);
  81. if (done) {
  82. done();
  83. }
  84. }).fail([=](const MTP::Error &error) {
  85. _settings = was;
  86. if (fail) {
  87. fail(error.type());
  88. }
  89. }).send();
  90. }
  91. _settings = settings;
  92. }
  93. void Chatbots::togglePaused(not_null<PeerData*> peer, bool paused) {
  94. const auto type = paused
  95. ? SentRequestType::Pause
  96. : SentRequestType::Unpause;
  97. const auto api = &_owner->session().api();
  98. const auto i = _sentRequests.find(peer);
  99. if (i != end(_sentRequests)) {
  100. const auto already = i->second.type;
  101. if (already == SentRequestType::Remove || already == type) {
  102. return;
  103. }
  104. api->request(i->second.requestId).cancel();
  105. _sentRequests.erase(i);
  106. }
  107. const auto id = api->request(MTPaccount_ToggleConnectedBotPaused(
  108. peer->input,
  109. MTP_bool(paused)
  110. )).done([=] {
  111. if (_sentRequests[peer].type != type) {
  112. return;
  113. } else if (const auto settings = peer->barSettings()) {
  114. peer->setBarSettings(paused
  115. ? ((*settings | PeerBarSetting::BusinessBotPaused)
  116. & ~PeerBarSetting::BusinessBotCanReply)
  117. : ((*settings & ~PeerBarSetting::BusinessBotPaused)
  118. | PeerBarSetting::BusinessBotCanReply));
  119. } else {
  120. api->requestPeerSettings(peer);
  121. }
  122. _sentRequests.remove(peer);
  123. }).fail([=] {
  124. if (_sentRequests[peer].type != type) {
  125. return;
  126. }
  127. api->requestPeerSettings(peer);
  128. _sentRequests.remove(peer);
  129. }).send();
  130. _sentRequests[peer] = SentRequest{ type, id };
  131. }
  132. void Chatbots::removeFrom(not_null<PeerData*> peer) {
  133. const auto type = SentRequestType::Remove;
  134. const auto api = &_owner->session().api();
  135. const auto i = _sentRequests.find(peer);
  136. if (i != end(_sentRequests)) {
  137. const auto already = i->second.type;
  138. if (already == type) {
  139. return;
  140. }
  141. api->request(i->second.requestId).cancel();
  142. _sentRequests.erase(i);
  143. }
  144. const auto id = api->request(MTPaccount_DisablePeerConnectedBot(
  145. peer->input
  146. )).done([=] {
  147. if (_sentRequests[peer].type != type) {
  148. return;
  149. } else if (const auto settings = peer->barSettings()) {
  150. peer->clearBusinessBot();
  151. } else {
  152. api->requestPeerSettings(peer);
  153. }
  154. _sentRequests.remove(peer);
  155. reload();
  156. }).fail([=] {
  157. api->requestPeerSettings(peer);
  158. _sentRequests.remove(peer);
  159. }).send();
  160. _sentRequests[peer] = SentRequest{ type, id };
  161. }
  162. void Chatbots::reload() {
  163. _loaded = false;
  164. _owner->session().api().request(base::take(_requestId)).cancel();
  165. preload();
  166. }
  167. } // namespace Data