diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 45e0b08f..e56aaf90 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1627,6 +1627,30 @@ callStateDiscarded reason:CallDiscardReason need_rating:Bool need_debug_informat callStateError error:error = CallState; +//@class CallProblem @description Describes a type of a problem that happened during a call + +//@description The user heard his own voice +callProblemEcho = CallProblem; + +//@description The user heard background noice +callProblemNoice = CallProblem; + +//@description The other side kept disappearing +callProblemInterruptions = CallProblem; + +//@description The speech was distorted +callProblemDistortedSpeech = CallProblem; + +//@description The user couldn't hear the other side +callProblemSilentLocal = CallProblem; + +//@description The other side couldn't hear the user +callProblemSilentRemote = CallProblem; + +//@description The call ended unexpectedly +callProblemDropped = CallProblem; + + //@description Describes a call @id Call identifier, not persistent @user_id Peer user identifier @is_outgoing True, if the call is outgoing @state Call state call id:int32 user_id:int32 is_outgoing:Bool state:CallState = Call; @@ -3415,8 +3439,8 @@ acceptCall call_id:int32 protocol:callProtocol = Ok; //@description Discards a call @call_id Call identifier @is_disconnected True, if the user was disconnected @duration The call duration, in seconds @connection_id Identifier of the connection used during the call discardCall call_id:int32 is_disconnected:Bool duration:int32 connection_id:int64 = Ok; -//@description Sends a call rating @call_id Call identifier @rating Call rating; 1-5 @comment An optional user comment if the rating is less than 5 -sendCallRating call_id:int32 rating:int32 comment:string = Ok; +//@description Sends a call rating @call_id Call identifier @rating Call rating; 1-5 @comment An optional user comment if the rating is less than 5 @problems List of problems with the call, specified by the user +sendCallRating call_id:int32 rating:int32 comment:string problems:vector = Ok; //@description Sends debug information for a call @call_id Call identifier @debug_information Debug information in application-specific format sendCallDebugInformation call_id:int32 debug_information:string = Ok; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 03c41f77..37dc47e5 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/CallActor.cpp b/td/telegram/CallActor.cpp index 056294da..84e9a4cb 100644 --- a/td/telegram/CallActor.cpp +++ b/td/telegram/CallActor.cpp @@ -29,9 +29,10 @@ #include "td/utils/Random.h" #include +#include namespace td { -// CallProtocol + CallProtocol CallProtocol::from_telegram_api(const telegram_api::phoneCallProtocol &protocol) { CallProtocol res; res.udp_p2p = protocol.udp_p2p_; @@ -110,7 +111,6 @@ tl_object_ptr CallState::as_td_api() const { } } -// CallActor CallActor::CallActor(CallId call_id, ActorShared<> parent, Promise promise) : parent_(std::move(parent)), call_id_promise_(std::move(promise)), local_call_id_(call_id) { } @@ -186,11 +186,53 @@ void CallActor::accept_call(CallProtocol &&protocol, Promise<> promise) { loop(); } -void CallActor::rate_call(int32 rating, string comment, Promise<> promise) { +void CallActor::rate_call(int32 rating, string comment, vector> &&problems, + Promise<> promise) { if (!call_state_.need_rating) { return promise.set_error(Status::Error(400, "Unexpected sendCallRating")); } promise.set_value(Unit()); + + if (rating == 5) { + comment.clear(); + } + + std::unordered_set tags; + for (auto &problem : problems) { + if (problem == nullptr) { + continue; + } + + const char *tag = [problem_id = problem->get_id()] { + switch (problem_id) { + case td_api::callProblemEcho::ID: + return "echo"; + case td_api::callProblemNoice::ID: + return "noise"; + case td_api::callProblemInterruptions::ID: + return "interruptions"; + case td_api::callProblemDistortedSpeech::ID: + return "distorted_speech"; + case td_api::callProblemSilentLocal::ID: + return "silent_local"; + case td_api::callProblemSilentRemote::ID: + return "silent_remote"; + case td_api::callProblemDropped::ID: + return "dropped"; + default: + UNREACHABLE(); + return ""; + } + }(); + if (tags.insert(tag).second) { + if (!comment.empty()) { + comment += ' '; + } + comment += '#'; + comment += tag; + } + } + auto tl_query = telegram_api::phone_setCallRating(0, false /*ignored*/, get_input_phone_call("rate_call"), rating, std::move(comment)); auto query = G()->net_query_creator().create(create_storer(tl_query)); diff --git a/td/telegram/CallActor.h b/td/telegram/CallActor.h index 97ddba36..aa24c496 100644 --- a/td/telegram/CallActor.h +++ b/td/telegram/CallActor.h @@ -81,7 +81,8 @@ class CallActor : public NetQueryCallback { bool is_video, Promise &&promise); void discard_call(bool is_disconnected, int32 duration, bool is_video, int64 connection_id, Promise<> promise); void accept_call(CallProtocol &&protocol, Promise<> promise); - void rate_call(int32 rating, string comment, Promise<> promise); + void rate_call(int32 rating, string comment, vector> &&problems, + Promise<> promise); void send_call_debug_information(string data, Promise<> promise); void update_call(tl_object_ptr call); diff --git a/td/telegram/CallManager.cpp b/td/telegram/CallManager.cpp index b99ee5ab..695cb14c 100644 --- a/td/telegram/CallManager.cpp +++ b/td/telegram/CallManager.cpp @@ -71,12 +71,13 @@ void CallManager::accept_call(CallId call_id, CallProtocol &&protocol, Promise<> send_closure(actor, &CallActor::accept_call, std::move(protocol), std::move(promise)); } -void CallManager::rate_call(CallId call_id, int32 rating, string comment, Promise<> promise) { +void CallManager::rate_call(CallId call_id, int32 rating, string comment, + vector> &&problems, Promise<> promise) { auto actor = get_call_actor(call_id); if (actor.empty()) { return promise.set_error(Status::Error(400, "Call not found")); } - send_closure(actor, &CallActor::rate_call, rating, std::move(comment), std::move(promise)); + send_closure(actor, &CallActor::rate_call, rating, std::move(comment), std::move(problems), std::move(promise)); } void CallManager::send_call_debug_information(CallId call_id, string data, Promise<> promise) { diff --git a/td/telegram/CallManager.h b/td/telegram/CallManager.h index f4f6d315..0679e526 100644 --- a/td/telegram/CallManager.h +++ b/td/telegram/CallManager.h @@ -9,6 +9,7 @@ #include "td/telegram/CallActor.h" #include "td/telegram/CallId.h" +#include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" @@ -32,7 +33,8 @@ class CallManager : public Actor { void discard_call(CallId call_id, bool is_disconnected, int32 duration, bool is_video, int64 connection_id, Promise<> promise); void accept_call(CallId call_id, CallProtocol &&protocol, Promise<> promise); - void rate_call(CallId call_id, int32 rating, string comment, Promise<> promise); + void rate_call(CallId call_id, int32 rating, string comment, + vector> &&problems, Promise<> promise); void send_call_debug_information(CallId call_id, string data, Promise<> promise); private: diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 0629f23b..9eb9d3f4 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5925,7 +5925,7 @@ void Td::on_request(uint64 id, td_api::sendCallRating &request) { CLEAN_INPUT_STRING(request.comment_); CREATE_OK_REQUEST_PROMISE(); send_closure(G()->call_manager(), &CallManager::rate_call, CallId(request.call_id_), request.rating_, - std::move(request.comment_), std::move(promise)); + std::move(request.comment_), std::move(request.problems_), std::move(promise)); } void Td::on_request(uint64 id, td_api::sendCallDebugInformation &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 53f2bfd7..c148a112 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2491,8 +2491,19 @@ class CliClient final : public Actor { send_request(td_api::make_object( as_call_id(args), td_api::make_object(true, true, 65, 65))); } else if (op == "scr" || op == "SendCallRating") { + string call_id; + string rating; + std::tie(call_id, rating) = split(args); + + vector> problems; + problems.emplace_back(td_api::make_object()); + problems.emplace_back(td_api::make_object()); + problems.emplace_back(nullptr); + problems.emplace_back(td_api::make_object()); + problems.emplace_back(td_api::make_object()); + problems.emplace_back(td_api::make_object()); send_request( - td_api::make_object(as_call_id(args), 5, "Wow, such good call! (TDLib test)")); + td_api::make_object(as_call_id(call_id), to_integer(rating), "Wow, such good call! (TDLib test)", std::move(problems))); } else if (op == "scdi" || op == "SendCallDebugInformation") { send_request(td_api::make_object(as_call_id(args), "{}")); } else if (op == "gcil") {