Add toggleGroupCallIsMyVideoEnabled.

This commit is contained in:
levlam 2021-05-02 02:40:22 +03:00
parent 8e0f14bc93
commit 8485867fe0
6 changed files with 146 additions and 10 deletions

View File

@ -2162,12 +2162,13 @@ groupCallRecentSpeaker participant_id:MessageSender is_speaking:Bool = GroupCall
//@participant_count Number of participants in the group call //@participant_count Number of participants in the group call
//@loaded_all_participants True, if all group call participants are loaded //@loaded_all_participants True, if all group call participants are loaded
//@recent_speakers Recently speaking users in the group call //@recent_speakers Recently speaking users in the group call
//@is_my_video_enabled True, if the current user's video is enabled
//@can_start_video True, if video can be enabled by group call participants //@can_start_video True, if video can be enabled by group call participants
//@mute_new_participants True, if only group call administrators can unmute new participants //@mute_new_participants True, if only group call administrators can unmute new participants
//@can_change_mute_new_participants True, if the current user can enable or disable mute_new_participants setting //@can_change_mute_new_participants True, if the current user can enable or disable mute_new_participants setting
//@record_duration Duration of the ongoing group call recording, in seconds; 0 if none. An updateGroupCall update is not triggered when value of this field changes, but the same recording goes on //@record_duration Duration of the ongoing group call recording, in seconds; 0 if none. An updateGroupCall update is not triggered when value of this field changes, but the same recording goes on
//@duration Call duration; for ended calls only //@duration Call duration; for ended calls only
groupCall id:int32 title:string scheduled_start_date:int32 enabled_start_notification:Bool is_active:Bool is_joined:Bool need_rejoin:Bool can_be_managed:Bool participant_count:int32 loaded_all_participants:Bool recent_speakers:vector<groupCallRecentSpeaker> can_start_video:Bool mute_new_participants:Bool can_change_mute_new_participants:Bool record_duration:int32 duration:int32 = GroupCall; groupCall id:int32 title:string scheduled_start_date:int32 enabled_start_notification:Bool is_active:Bool is_joined:Bool need_rejoin:Bool can_be_managed:Bool participant_count:int32 loaded_all_participants:Bool recent_speakers:vector<groupCallRecentSpeaker> is_my_video_enabled:Bool can_start_video:Bool mute_new_participants:Bool can_change_mute_new_participants:Bool record_duration:int32 duration:int32 = GroupCall;
//@description Represents a group call participant //@description Represents a group call participant
@ -4618,9 +4619,9 @@ toggleGroupCallEnabledStartNotification group_call_id:int32 enabled_start_notifi
//@audio_source Caller audio synchronization source identifier; received from tgcalls //@audio_source Caller audio synchronization source identifier; received from tgcalls
//@payload Group call join payload; received from tgcalls //@payload Group call join payload; received from tgcalls
//@is_muted True, if the user's microphone is muted //@is_muted True, if the user's microphone is muted
//@is_video_enabled True, if the user's video is enabled //@is_my_video_enabled True, if the user's video is enabled
//@invite_hash If non-empty, invite hash to be used to join the group call without being muted by administrators //@invite_hash If non-empty, invite hash to be used to join the group call without being muted by administrators
joinGroupCall group_call_id:int32 participant_id:MessageSender audio_source:int32 payload:string is_muted:Bool is_video_enabled:Bool invite_hash:string = Text; joinGroupCall group_call_id:int32 participant_id:MessageSender audio_source:int32 payload:string is_muted:Bool is_my_video_enabled:Bool invite_hash:string = Text;
//@description Starts screen sharing in a joined group call. Returns join response payload for tgcalls @group_call_id Group call identifier @payload Group call join payload; received from tgcalls //@description Starts screen sharing in a joined group call. Returns join response payload for tgcalls @group_call_id Group call identifier @payload Group call join payload; received from tgcalls
startGroupCallScreenSharing group_call_id:int32 payload:string = Text; startGroupCallScreenSharing group_call_id:int32 payload:string = Text;
@ -4653,6 +4654,9 @@ startGroupCallRecording group_call_id:int32 title:string = Ok;
//@description Ends recording of an active group call. Requires groupCall.can_be_managed group call flag @group_call_id Group call identifier //@description Ends recording of an active group call. Requires groupCall.can_be_managed group call flag @group_call_id Group call identifier
endGroupCallRecording group_call_id:int32 = Ok; endGroupCallRecording group_call_id:int32 = Ok;
//@description Toggles whether current user's video is enabled @group_call_id Group call identifier @is_my_video_enabled Pass true if the current user's video is enabled
toggleGroupCallIsMyVideoEnabled group_call_id:int32 is_my_video_enabled:Bool = Ok;
//@description Informs TDLib that speaking state of a participant of an active group has changed @group_call_id Group call identifier //@description Informs TDLib that speaking state of a participant of an active group has changed @group_call_id Group call identifier
//@audio_source Group call participant's synchronization audio source identifier, or 0 for the current user @is_speaking True, if the user is speaking //@audio_source Group call participant's synchronization audio source identifier, or 0 for the current user @is_speaking True, if the user is speaking
setGroupCallParticipantIsSpeaking group_call_id:int32 audio_source:int32 is_speaking:Bool = Ok; setGroupCallParticipantIsSpeaking group_call_id:int32 audio_source:int32 is_speaking:Bool = Ok;

View File

@ -823,6 +823,7 @@ struct GroupCallManager::GroupCall {
bool need_syncing_participants = false; bool need_syncing_participants = false;
bool loaded_all_participants = false; bool loaded_all_participants = false;
bool start_subscribed = false; bool start_subscribed = false;
bool is_my_video_enabled = false;
bool mute_new_participants = false; bool mute_new_participants = false;
bool allowed_change_mute_new_participants = false; bool allowed_change_mute_new_participants = false;
bool joined_date_asc = false; bool joined_date_asc = false;
@ -848,6 +849,8 @@ struct GroupCallManager::GroupCall {
vector<Promise<Unit>> after_join; vector<Promise<Unit>> after_join;
bool have_pending_start_subscribed = false; bool have_pending_start_subscribed = false;
bool pending_start_subscribed = false; bool pending_start_subscribed = false;
bool have_pending_is_my_video_enabled = false;
bool pending_is_my_video_enabled = false;
bool have_pending_mute_new_participants = false; bool have_pending_mute_new_participants = false;
bool pending_mute_new_participants = false; bool pending_mute_new_participants = false;
string pending_title; string pending_title;
@ -1457,6 +1460,12 @@ bool GroupCallManager::get_group_call_start_subscribed(const GroupCall *group_ca
: group_call->start_subscribed; : group_call->start_subscribed;
} }
bool GroupCallManager::get_group_call_is_my_video_enabled(const GroupCall *group_call) {
CHECK(group_call != nullptr);
return group_call->have_pending_is_my_video_enabled ? group_call->pending_is_my_video_enabled
: group_call->is_my_video_enabled;
}
bool GroupCallManager::get_group_call_mute_new_participants(const GroupCall *group_call) { bool GroupCallManager::get_group_call_mute_new_participants(const GroupCall *group_call) {
CHECK(group_call != nullptr); CHECK(group_call != nullptr);
return group_call->have_pending_mute_new_participants ? group_call->pending_mute_new_participants return group_call->have_pending_mute_new_participants ? group_call->pending_mute_new_participants
@ -2365,7 +2374,7 @@ void GroupCallManager::start_scheduled_group_call(GroupCallId group_call_id, Pro
} }
void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_dialog_id, int32 audio_source, void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_dialog_id, int32 audio_source,
string &&payload, bool is_muted, bool is_video_enabled, string &&payload, bool is_muted, bool is_my_video_enabled,
const string &invite_hash, Promise<string> &&promise) { const string &invite_hash, Promise<string> &&promise) {
TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id)); TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id));
@ -2431,7 +2440,7 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di
}); });
request->query_ref = request->query_ref =
td_->create_handler<JoinGroupCallQuery>(std::move(query_promise)) td_->create_handler<JoinGroupCallQuery>(std::move(query_promise))
->send(input_group_call_id, as_dialog_id, payload, is_muted, !is_video_enabled, invite_hash, generation); ->send(input_group_call_id, as_dialog_id, payload, is_muted, !is_my_video_enabled, invite_hash, generation);
if (group_call->dialog_id.is_valid()) { if (group_call->dialog_id.is_valid()) {
td_->messages_manager_->on_update_dialog_default_join_group_call_as_dialog_id(group_call->dialog_id, as_dialog_id, td_->messages_manager_->on_update_dialog_default_join_group_call_as_dialog_id(group_call->dialog_id, as_dialog_id,
@ -2452,7 +2461,7 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di
// it contains reasonable default "!call.mute_new_participants || call.can_be_managed" // it contains reasonable default "!call.mute_new_participants || call.can_be_managed"
participant.server_is_muted_by_admin = !group_call->can_self_unmute && !can_manage_group_call(input_group_call_id); participant.server_is_muted_by_admin = !group_call->can_self_unmute && !can_manage_group_call(input_group_call_id);
participant.server_is_muted_by_themselves = is_muted && !participant.server_is_muted_by_admin; participant.server_is_muted_by_themselves = is_muted && !participant.server_is_muted_by_admin;
participant.server_is_video_muted = !is_video_enabled || participant.server_is_muted_by_admin; participant.server_is_video_muted = !is_my_video_enabled || participant.server_is_muted_by_admin;
participant.is_just_joined = !is_rejoin; participant.is_just_joined = !is_rejoin;
participant.is_fake = true; participant.is_fake = true;
int diff = process_group_call_participant(input_group_call_id, std::move(participant)); int diff = process_group_call_participant(input_group_call_id, std::move(participant));
@ -2462,6 +2471,10 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di
set_group_call_participant_count(group_call, group_call->participant_count + diff, "join_group_call", true); set_group_call_participant_count(group_call, group_call->participant_count + diff, "join_group_call", true);
} }
} }
if (group_call->is_my_video_enabled != is_my_video_enabled) {
group_call->is_my_video_enabled = is_my_video_enabled;
need_update = true;
}
if (group_call->is_inited && need_update) { if (group_call->is_inited && need_update) {
send_update_group_call(group_call, "join_group_call"); send_update_group_call(group_call, "join_group_call");
@ -2800,6 +2813,95 @@ void GroupCallManager::on_edit_group_call_title(InputGroupCallId input_group_cal
} }
} }
void GroupCallManager::toggle_group_call_is_my_video_enabled(GroupCallId group_call_id, bool is_my_video_enabled,
Promise<Unit> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id));
auto *group_call = get_group_call(input_group_call_id);
if (group_call == nullptr || !group_call->is_inited || !group_call->is_active) {
return promise.set_error(Status::Error(400, "GROUPCALL_JOIN_MISSING"));
}
if (!group_call->is_joined) {
if (is_group_call_being_joined(input_group_call_id) || group_call->need_rejoin) {
group_call->after_join.push_back(
PromiseCreator::lambda([actor_id = actor_id(this), group_call_id, is_my_video_enabled,
promise = std::move(promise)](Result<Unit> &&result) mutable {
if (result.is_error()) {
promise.set_error(Status::Error(400, "GROUPCALL_JOIN_MISSING"));
} else {
send_closure(actor_id, &GroupCallManager::toggle_group_call_is_my_video_enabled, group_call_id,
is_my_video_enabled, std::move(promise));
}
}));
return;
}
return promise.set_error(Status::Error(400, "GROUPCALL_JOIN_MISSING"));
}
if (is_my_video_enabled == get_group_call_is_my_video_enabled(group_call)) {
return promise.set_value(Unit());
}
// there is no reason to save promise; we will send an update with actual value anyway
group_call->pending_is_my_video_enabled = is_my_video_enabled;
if (!group_call->have_pending_is_my_video_enabled) {
group_call->have_pending_is_my_video_enabled = true;
send_toggle_group_call_is_my_video_enabled_query(input_group_call_id, group_call->as_dialog_id,
is_my_video_enabled);
}
send_update_group_call(group_call, "toggle_group_call_is_my_video_enabled");
promise.set_value(Unit());
}
void GroupCallManager::send_toggle_group_call_is_my_video_enabled_query(InputGroupCallId input_group_call_id,
DialogId as_dialog_id,
bool is_my_video_enabled) {
auto promise = PromiseCreator::lambda(
[actor_id = actor_id(this), input_group_call_id, is_my_video_enabled](Result<Unit> result) {
send_closure(actor_id, &GroupCallManager::on_toggle_group_call_is_my_video_enabled, input_group_call_id,
is_my_video_enabled, std::move(result));
});
td_->create_handler<EditGroupCallParticipantQuery>(std::move(promise))
->send(input_group_call_id, as_dialog_id, false, false, 0, false, false, true, !is_my_video_enabled);
}
void GroupCallManager::on_toggle_group_call_is_my_video_enabled(InputGroupCallId input_group_call_id,
bool is_my_video_enabled, Result<Unit> &&result) {
if (G()->close_flag()) {
return;
}
auto *group_call = get_group_call(input_group_call_id);
if (group_call == nullptr || !group_call->is_inited || !group_call->is_active ||
!group_call->have_pending_is_my_video_enabled) {
return;
}
if (result.is_error()) {
group_call->have_pending_is_my_video_enabled = false;
LOG(ERROR) << "Failed to set is_my_video_enabled to " << is_my_video_enabled << " in " << input_group_call_id
<< ": " << result.error();
if (group_call->pending_is_my_video_enabled != group_call->is_my_video_enabled) {
send_update_group_call(group_call, "on_toggle_group_call_is_my_video_enabled failed");
}
} else {
group_call->is_my_video_enabled = is_my_video_enabled;
if (group_call->pending_is_my_video_enabled != is_my_video_enabled) {
// need to send another request
send_toggle_group_call_is_my_video_enabled_query(input_group_call_id, group_call->as_dialog_id,
group_call->pending_is_my_video_enabled);
return;
}
group_call->have_pending_is_my_video_enabled = false;
}
}
void GroupCallManager::toggle_group_call_start_subscribed(GroupCallId group_call_id, bool start_subscribed, void GroupCallManager::toggle_group_call_start_subscribed(GroupCallId group_call_id, bool start_subscribed,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
if (G()->close_flag()) { if (G()->close_flag()) {
@ -2838,7 +2940,7 @@ void GroupCallManager::toggle_group_call_start_subscribed(GroupCallId group_call
group_call->have_pending_start_subscribed = true; group_call->have_pending_start_subscribed = true;
send_toggle_group_call_start_subscription_query(input_group_call_id, start_subscribed); send_toggle_group_call_start_subscription_query(input_group_call_id, start_subscribed);
} }
send_update_group_call(group_call, "toggle_group_call_start_subscription"); send_update_group_call(group_call, "toggle_group_call_start_subscribed");
promise.set_value(Unit()); promise.set_value(Unit());
} }
@ -3624,6 +3726,8 @@ void GroupCallManager::on_group_call_left_impl(GroupCall *group_call, bool need_
} }
group_call->is_being_left = false; group_call->is_being_left = false;
group_call->is_speaking = false; group_call->is_speaking = false;
group_call->is_my_video_enabled = false;
group_call->have_pending_is_my_video_enabled = false;
if (!group_call->is_active) { if (!group_call->is_active) {
group_call->can_be_managed = false; group_call->can_be_managed = false;
} }
@ -3808,6 +3912,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptr<telegra
call.need_rejoin = group_call->need_rejoin; call.need_rejoin = group_call->need_rejoin;
call.is_being_left = group_call->is_being_left; call.is_being_left = group_call->is_being_left;
call.is_speaking = group_call->is_speaking; call.is_speaking = group_call->is_speaking;
call.is_my_video_enabled = group_call->is_my_video_enabled;
call.syncing_participants = group_call->syncing_participants; call.syncing_participants = group_call->syncing_participants;
call.need_syncing_participants = group_call->need_syncing_participants; call.need_syncing_participants = group_call->need_syncing_participants;
call.loaded_all_participants = group_call->loaded_all_participants; call.loaded_all_participants = group_call->loaded_all_participants;
@ -4244,6 +4349,7 @@ tl_object_ptr<td_api::groupCall> GroupCallManager::get_group_call_object(
bool is_active = scheduled_start_date == 0 ? group_call->is_active : 0; bool is_active = scheduled_start_date == 0 ? group_call->is_active : 0;
bool is_joined = group_call->is_joined && !group_call->is_being_left; bool is_joined = group_call->is_joined && !group_call->is_being_left;
bool start_subscribed = get_group_call_start_subscribed(group_call); bool start_subscribed = get_group_call_start_subscribed(group_call);
bool is_my_video_enabled = get_group_call_is_my_video_enabled(group_call);
bool mute_new_participants = get_group_call_mute_new_participants(group_call); bool mute_new_participants = get_group_call_mute_new_participants(group_call);
bool can_change_mute_new_participants = bool can_change_mute_new_participants =
group_call->is_active && group_call->can_be_managed && group_call->allowed_change_mute_new_participants; group_call->is_active && group_call->can_be_managed && group_call->allowed_change_mute_new_participants;
@ -4252,7 +4358,7 @@ tl_object_ptr<td_api::groupCall> GroupCallManager::get_group_call_object(
return td_api::make_object<td_api::groupCall>( return td_api::make_object<td_api::groupCall>(
group_call->group_call_id.get(), get_group_call_title(group_call), scheduled_start_date, start_subscribed, group_call->group_call_id.get(), get_group_call_title(group_call), scheduled_start_date, start_subscribed,
is_active, is_joined, group_call->need_rejoin, group_call->can_be_managed, group_call->participant_count, is_active, is_joined, group_call->need_rejoin, group_call->can_be_managed, group_call->participant_count,
group_call->loaded_all_participants, std::move(recent_speakers), group_call->can_start_video, group_call->loaded_all_participants, std::move(recent_speakers), is_my_video_enabled, group_call->can_start_video,
mute_new_participants, can_change_mute_new_participants, record_duration, group_call->duration); mute_new_participants, can_change_mute_new_participants, record_duration, group_call->duration);
} }

View File

@ -65,7 +65,7 @@ class GroupCallManager : public Actor {
void start_scheduled_group_call(GroupCallId group_call_id, Promise<Unit> &&promise); void start_scheduled_group_call(GroupCallId group_call_id, Promise<Unit> &&promise);
void join_group_call(GroupCallId group_call_id, DialogId as_dialog_id, int32 audio_source, string &&payload, void join_group_call(GroupCallId group_call_id, DialogId as_dialog_id, int32 audio_source, string &&payload,
bool is_muted, bool is_video_enabled, const string &invite_hash, Promise<string> &&promise); bool is_muted, bool is_my_video_enabled, const string &invite_hash, Promise<string> &&promise);
void start_group_call_screen_sharing(GroupCallId group_call_id, string &&payload, Promise<string> &&promise); void start_group_call_screen_sharing(GroupCallId group_call_id, string &&payload, Promise<string> &&promise);
@ -73,6 +73,9 @@ class GroupCallManager : public Actor {
void set_group_call_title(GroupCallId group_call_id, string title, Promise<Unit> &&promise); void set_group_call_title(GroupCallId group_call_id, string title, Promise<Unit> &&promise);
void toggle_group_call_is_my_video_enabled(GroupCallId group_call_id, bool is_my_video_enabled,
Promise<Unit> &&promise);
void toggle_group_call_start_subscribed(GroupCallId group_call_id, bool start_subscribed, Promise<Unit> &&promise); void toggle_group_call_start_subscribed(GroupCallId group_call_id, bool start_subscribed, Promise<Unit> &&promise);
void toggle_group_call_mute_new_participants(GroupCallId group_call_id, bool mute_new_participants, void toggle_group_call_mute_new_participants(GroupCallId group_call_id, bool mute_new_participants,
@ -193,6 +196,8 @@ class GroupCallManager : public Actor {
static bool get_group_call_start_subscribed(const GroupCall *group_call); static bool get_group_call_start_subscribed(const GroupCall *group_call);
static bool get_group_call_is_my_video_enabled(const GroupCall *group_call);
static bool get_group_call_mute_new_participants(const GroupCall *group_call); static bool get_group_call_mute_new_participants(const GroupCall *group_call);
static int32 get_group_call_record_start_date(const GroupCall *group_call); static int32 get_group_call_record_start_date(const GroupCall *group_call);
@ -260,6 +265,12 @@ class GroupCallManager : public Actor {
void on_toggle_group_call_start_subscription(InputGroupCallId input_group_call_id, bool start_subscribed, void on_toggle_group_call_start_subscription(InputGroupCallId input_group_call_id, bool start_subscribed,
Result<Unit> &&result); Result<Unit> &&result);
void send_toggle_group_call_is_my_video_enabled_query(InputGroupCallId input_group_call_id, DialogId as_dialog_id,
bool is_my_video_enabled);
void on_toggle_group_call_is_my_video_enabled(InputGroupCallId input_group_call_id, bool is_my_video_enabled,
Result<Unit> &&result);
void send_toggle_group_call_mute_new_participants_query(InputGroupCallId input_group_call_id, void send_toggle_group_call_mute_new_participants_query(InputGroupCallId input_group_call_id,
bool mute_new_participants); bool mute_new_participants);

View File

@ -6032,7 +6032,7 @@ void Td::on_request(uint64 id, td_api::joinGroupCall &request) {
group_call_manager_->join_group_call(GroupCallId(request.group_call_id_), group_call_manager_->join_group_call(GroupCallId(request.group_call_id_),
group_call_manager_->get_group_call_participant_id(request.participant_id_), group_call_manager_->get_group_call_participant_id(request.participant_id_),
request.audio_source_, std::move(request.payload_), request.is_muted_, request.audio_source_, std::move(request.payload_), request.is_muted_,
request.is_video_enabled_, request.invite_hash_, std::move(query_promise)); request.is_my_video_enabled_, request.invite_hash_, std::move(query_promise));
} }
void Td::on_request(uint64 id, td_api::startGroupCallScreenSharing &request) { void Td::on_request(uint64 id, td_api::startGroupCallScreenSharing &request) {
@ -6113,6 +6113,13 @@ void Td::on_request(uint64 id, const td_api::endGroupCallRecording &request) {
std::move(promise)); std::move(promise));
} }
void Td::on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoEnabled &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->toggle_group_call_is_my_video_enabled(GroupCallId(request.group_call_id_),
request.is_my_video_enabled_, std::move(promise));
}
void Td::on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request) { void Td::on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request) {
CHECK_IS_USER(); CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();

View File

@ -733,6 +733,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::endGroupCallRecording &request); void on_request(uint64 id, const td_api::endGroupCallRecording &request);
void on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoEnabled &request);
void on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request); void on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request);
void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &request); void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &request);

View File

@ -2732,6 +2732,12 @@ class CliClient final : public Actor {
td_api::make_object<td_api::toggleGroupCallMuteNewParticipants>(as_group_call_id(args), op == "tgcmnpe")); td_api::make_object<td_api::toggleGroupCallMuteNewParticipants>(as_group_call_id(args), op == "tgcmnpe"));
} else if (op == "rgcil") { } else if (op == "rgcil") {
send_request(td_api::make_object<td_api::revokeGroupCallInviteLink>(as_group_call_id(args))); send_request(td_api::make_object<td_api::revokeGroupCallInviteLink>(as_group_call_id(args)));
} else if (op == "tgcimve") {
string group_call_id;
bool is_my_video_enabled;
get_args(args, group_call_id, is_my_video_enabled);
send_request(td_api::make_object<td_api::toggleGroupCallIsMyVideoEnabled>(as_group_call_id(group_call_id),
is_my_video_enabled));
} else if (op == "sgcpis") { } else if (op == "sgcpis") {
string group_call_id; string group_call_id;
int32 source; int32 source;