diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 262e9a21b..ed665ea2c 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1933,6 +1933,86 @@ checkChatUsernameResultPublicChatsTooMuch = CheckChatUsernameResult; checkChatUsernameResultPublicGroupsUnavailable = CheckChatUsernameResult; +//@class PushMessageContent @description Contains content of a push message notification + +//@description A general message with hidden content @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentHidden is_pinned:Bool = PushMessageContent; + +//@description An animation message (GIF-style) @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentAnimation is_pinned:Bool = PushMessageContent; + +//@description A message with a user contact @name Contact's name @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentContact name:string is_pinned:Bool = PushMessageContent; + +//@description A contact has registered with Telegram +pushMessageContentContactRegistered = PushMessageContent; + +//@description A document message (general file) @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentDocument is_pinned:Bool = PushMessageContent; + +//@description A message with a game @title Game title @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentGame title:string is_pinned:Bool = PushMessageContent; + +//@description A new high score was achieved in a game @title Game title, empty for pinned message @score New score, 0 for pinned message @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentGameScore title:string score:int32 is_pinned:Bool = PushMessageContent; + +//@description A message with an invoice from a bot @title Product title @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentInvoice title:string is_pinned:Bool = PushMessageContent; + +//@description A message with a location @is_live True, if the location is live @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentLocation is_live:Bool is_pinned:Bool = PushMessageContent; + +//@description A photo message @is_secret True, if the photo is secret @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentPhoto is_secret:Bool is_pinned:Bool = PushMessageContent; + +//@description A message with a poll @question Poll question @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentPoll question:string is_pinned:Bool = PushMessageContent; + +//@description A screenshot of a message in the chat has been taken +pushMessageContentScreenshotTaken = PushMessageContent; + +//@description A message with a sticker @emoji Emoji corresponding to the sticker; may be empty @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentSticker emoji:string is_pinned:Bool = PushMessageContent; + +//@description A text message @text Message text @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentText text:string is_pinned:Bool = PushMessageContent; + +//@description A video message @is_secret True, if the video is secret @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentVideo is_secret:Bool is_pinned:Bool = PushMessageContent; + +//@description A video note message @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentVideoNote is_pinned:Bool = PushMessageContent; + +//@description A voice note message @is_pinned True, if the message is a pinned message with the specified content +pushMessageContentVoiceNote is_pinned:Bool = PushMessageContent; + +//@description A newly created basic group +pushMessageContentBasicGroupChatCreate = PushMessageContent; + +//@description New chat members were invited to a group @member_name Name of the added member @is_current_user True, if the current user was added to the group +//@is_returned True, if the user has returned to the group himself +pushMessageContentChatAddMembers member_name:string is_current_user:Bool is_returned:Bool = PushMessageContent; + +//@description A chat photo was edited +pushMessageContentChatChangePhoto = PushMessageContent; + +//@description A chat title was edited +pushMessageContentChatChangeTitle = PushMessageContent; + +//@description A chat member was deleted @member_name Name of the deleted member @is_current_user True, if the current user was deleted from the group +//@is_left True, if the user has left the group himself +pushMessageContentChatDeleteMember member_name:string is_current_user:Bool is_left:Bool = PushMessageContent; + +//@description A new member joined the chat by invite link +pushMessageContentChatJoinByLink = PushMessageContent; + +//@description A forwarded messages @total_count Number of forwarded messages +pushMessageContentMessageForwards total_count:int32 = PushMessageContent; + +//@description A media album @total_count Number of messages in the album @has_photos True, if the album has at least one photo @has_videos True, if the album has at least one video +pushMessageContentMediaAlbum total_count:int32 has_photos:Bool has_videos:Bool = PushMessageContent; + + //@class NotificationType @description Contains detailed information about a notification //@description New message was received @message The message @@ -1944,10 +2024,10 @@ notificationTypeNewSecretChat = NotificationType; //@description New call was received @call_id Call identifier notificationTypeNewCall call_id:int32 = NotificationType; -//@description New message was received through a push notification @message_id The message identifier. The message will not be available in the chat history -//@sender_user_id Sender of the message. Corresponding user may be inaccessible -//@content_type Notification content type. See https://core.telegram.org/tdlib/notification-api for the list of available content types @argument Optional argument for the notification content type -notificationTypeNewPushMessage message_id:int53 sender_user_id:int32 content_type:string argument:string = NotificationType; +//@description New message was received through a push notification +//@message_id The message identifier. The message will not be available in the chat history, but the ID can be used in viewMessages and as reply_to_message_id +//@sender_user_id Sender of the message. Corresponding user may be inaccessible @content Push message content +notificationTypeNewPushMessage message_id:int53 sender_user_id:int32 content:PushMessageContent = NotificationType; //@class NotificationGroupType @description Describes type of notifications in the group diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 6dc8056a9..89951094a 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 67aa5c369..2d4839b2e 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -2611,11 +2611,17 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "MESSAGES") { return "MESSAGES"; } + if (loc_key.size() <= 8) { + return string(); + } switch (loc_key[8]) { case 'A': if (loc_key == "PINNED_GAME") { return "PINNED_MESSAGE_GAME"; } + if (loc_key == "PINNED_GAME_SCORE") { + return "PINNED_MESSAGE_GAME_SCORE"; + } if (loc_key == "CHAT_CREATED") { return "MESSAGE_BASIC_GROUP_CHAT_CREATE"; } @@ -2659,6 +2665,9 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "MESSAGE_GAME") { return "MESSAGE_GAME"; } + if (loc_key == "MESSAGE_GAME_SCORE") { + return "MESSAGE_GAME_SCORE"; + } if (loc_key == "MESSAGE_GEO") { return "MESSAGE_LOCATION"; } @@ -2776,6 +2785,9 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "MESSAGE_VIDEO") { return "MESSAGE_VIDEO"; } + if (loc_key == "MESSAGE_VIDEOS") { + return "MESSAGE_VIDEOS"; + } if (loc_key == "MESSAGE_VIDEO_SECRET") { return "MESSAGE_SECRET_VIDEO"; } @@ -3062,6 +3074,23 @@ Status NotificationManager::process_push_notification_payload(string payload, Pr // chat title or sender name for PINNED_* loc_args.erase(loc_args.begin()); + string arg; + if (loc_key == "MESSAGE_GAME_SCORE" && loc_args.size() == 2) { + TRY_RESULT(score, to_integer_safe(loc_args[1])); + if (score < 0) { + return Status::Error("Expected score to be non-negative"); + } + arg = PSTRING() << loc_args[1] << ' ' << loc_args[0]; + loc_args.clear(); + } + if (loc_args.size() > 1) { + return Status::Error("Receive too much arguments"); + } + + if (loc_args.size() == 1) { + arg = std::move(loc_args[0]); + } + if (sender_user_id.is_valid() && !td_->contacts_manager_->have_user_force(sender_user_id)) { int64 sender_access_hash = -1; telegram_api::object_ptr sender_photo; @@ -3093,15 +3122,6 @@ Status NotificationManager::process_push_notification_payload(string payload, Pr td_->contacts_manager_->on_get_user(std::move(user), "process_push_notification_payload"); } - if (loc_args.size() > 1) { - return Status::Error("Receive too much arguments"); - } - - string arg; - if (loc_args.size() == 1) { - arg = std::move(loc_args[0]); - } - process_message_push_notification(dialog_id, MessageId(server_message_id), random_id, sender_user_id, std::move(sender_name), sent_date, contains_mention, is_silent, std::move(loc_key), std::move(arg), NotificationId(), 0, std::move(promise)); diff --git a/td/telegram/NotificationType.cpp b/td/telegram/NotificationType.cpp index a86ac8e7f..eafc75e17 100644 --- a/td/telegram/NotificationType.cpp +++ b/td/telegram/NotificationType.cpp @@ -11,6 +11,9 @@ #include "td/telegram/MessagesManager.h" #include "td/telegram/Td.h" +#include "td/utils/misc.h" +#include "td/utils/Slice.h" + namespace td { class NotificationTypeMessage : public NotificationType { @@ -124,10 +127,158 @@ class NotificationTypePushMessage : public NotificationType { return message_id_; } + static td_api::object_ptr get_push_message_content_object(Slice key, const string &arg) { + bool is_pinned = false; + if (begins_with(key, "PINNED_")) { + is_pinned = true; + key = key.substr(7); + } + if (key == "MESSAGE") { + return td_api::make_object(is_pinned); + } + if (key == "MESSAGES") { + return td_api::make_object(to_integer(arg), true, true); + } + CHECK(key.size() > 8); + switch (key[8]) { + case 'A': + if (key == "MESSAGE_ANIMATION") { + return td_api::make_object(is_pinned); + } + break; + case 'B': + if (key == "MESSAGE_BASIC_GROUP_CHAT_CREATE") { + return td_api::make_object(); + } + break; + case 'C': + if (key == "MESSAGE_CHAT_ADD_MEMBERS") { + return td_api::make_object(arg, false, false); + } + if (key == "MESSAGE_CHAT_ADD_MEMBERS_RETURNED") { + return td_api::make_object(arg, false, true); + } + if (key == "MESSAGE_CHAT_ADD_MEMBERS_YOU") { + return td_api::make_object(arg, true, false); + } + if (key == "MESSAGE_CHAT_CHANGE_PHOTO") { + return td_api::make_object(); + } + if (key == "MESSAGE_CHAT_CHANGE_TITLE") { + return td_api::make_object(); + } + if (key == "MESSAGE_CHAT_DELETE_MEMBER") { + return td_api::make_object(arg, false, false); + } + if (key == "MESSAGE_CHAT_DELETE_MEMBER_LEFT") { + return td_api::make_object(arg, false, true); + } + if (key == "MESSAGE_CHAT_DELETE_MEMBER_YOU") { + return td_api::make_object(arg, true, false); + } + if (key == "MESSAGE_CHAT_JOIN_BY_LINK") { + return td_api::make_object(); + } + if (key == "MESSAGE_CONTACT") { + return td_api::make_object(arg, is_pinned); + } + if (key == "MESSAGE_CONTACT_REGISTERED") { + return td_api::make_object(); + } + break; + case 'D': + if (key == "MESSAGE_DOCUMENT") { + return td_api::make_object(is_pinned); + } + break; + case 'F': + if (key == "MESSAGE_FORWARDS") { + return td_api::make_object(to_integer(arg)); + } + break; + case 'G': + if (key == "MESSAGE_GAME") { + return td_api::make_object(arg, is_pinned); + } + if (key == "MESSAGE_GAME_SCORE") { + int32 score = 0; + string title; + if (!is_pinned) { + string score_str; + std::tie(score_str, title) = split(arg); + score = to_integer(score_str); + } + return td_api::make_object(title, score, is_pinned); + } + break; + case 'I': + if (key == "MESSAGE_INVOICE") { + return td_api::make_object(arg, is_pinned); + } + break; + case 'L': + if (key == "MESSAGE_LIVE_LOCATION") { + return td_api::make_object(false, is_pinned); + } + if (key == "MESSAGE_LOCATION") { + return td_api::make_object(true, is_pinned); + } + break; + case 'P': + if (key == "MESSAGE_PHOTO") { + return td_api::make_object(false, is_pinned); + } + if (key == "MESSAGE_PHOTOS") { + return td_api::make_object(to_integer(arg), true, false); + } + if (key == "MESSAGE_POLL") { + return td_api::make_object(arg, is_pinned); + } + break; + case 'S': + if (key == "MESSAGE_SECRET_PHOTO") { + return td_api::make_object(true, false); + } + if (key == "MESSAGE_SECRET_VIDEO") { + return td_api::make_object(true, false); + } + if (key == "MESSAGE_SCREENSHOT_TAKEN") { + return td_api::make_object(); + } + if (key == "MESSAGE_STICKER") { + return td_api::make_object(arg, is_pinned); + } + break; + case 'T': + if (key == "MESSAGE_TEXT") { + return td_api::make_object(arg, is_pinned); + } + break; + case 'V': + if (key == "MESSAGE_VIDEO") { + return td_api::make_object(false, is_pinned); + } + if (key == "MESSAGE_VIDEO_NOTE") { + return td_api::make_object(is_pinned); + } + if (key == "MESSAGE_VIDEOS") { + return td_api::make_object(to_integer(arg), false, true); + } + if (key == "MESSAGE_VOICE_NOTE") { + return td_api::make_object(is_pinned); + } + break; + default: + break; + } + UNREACHABLE(); + } + td_api::object_ptr get_notification_type_object(DialogId dialog_id) const override { auto sender_user_id = G()->td().get_actor_unsafe()->contacts_manager_->get_user_id_object( sender_user_id_, "get_notification_type_object"); - return td_api::make_object(message_id_.get(), sender_user_id, key_, arg_); + return td_api::make_object(message_id_.get(), sender_user_id, + get_push_message_content_object(key_, arg_)); } StringBuilder &to_string_builder(StringBuilder &string_builder) const override {