26 public function createAction($type, $provider, $entityType, $entityId, $joinExisting =
false)
30 $lockName = static::getLockNameWithEntityId($entityType, $entityId, $currentUserId);
33 $this->errorCollection[] =
new Error(
"Could not get exclusive lock",
"could_not_lock");
37 $call = $joinExisting ? CallFactory::searchActive($type, $provider, $entityType, $entityId, $currentUserId) :
false;
43 if (!$call->getAssociatedEntity()->checkAccess($currentUserId))
45 $this->errorCollection[] =
new Error(
"You can not access this call",
'access_denied');
51 if (!$call->hasUser($currentUserId))
53 $addedUser = $call->addUser($currentUserId);
57 $this->errorCollection[] =
new Error(
"User limit reached",
"user_limit_reached");
68 $call = CallFactory::createWithEntity($type, $provider, $entityType, $entityId, $currentUserId);
69 }
catch (\Throwable $e) {
75 if (!$call->getAssociatedEntity()->canStartCall($currentUserId))
77 $this->errorCollection[] =
new Error(
"You can not create this call",
'access_denied');
82 $initiator = $call->getUser($currentUserId);
92 $this->errorCollection[] =
new Error(
93 "Can't initiate a call. Server error. (" . ($status ??
"") .
")",
100 $users = $call->getUsers();
101 $publicChannels = Loader::includeModule(
'pull')
102 ? \Bitrix\Pull\Channel::getPublicIds([
103 'TYPE' => \CPullChannel::TYPE_PRIVATE,
113 'call' => $call->toArray(),
114 'connectionData' => $call->getConnectionData($currentUserId),
118 'publicChannels' => $publicChannels,
119 'logToken' => $call->getLogToken($currentUserId),
136 $this->errorCollection[] =
new Error(
"You do not have access to the parent call",
"access_denied");
140 $childCall = $parentCall->makeClone($newProvider);
142 $initiator = $childCall->getUser($currentUserId);
144 $initiator->updateLastSeen(
new DateTime());
146 foreach ($newUsers as $userId)
148 if(!$childCall->hasUser($userId))
154 $users = $childCall->getUsers();
156 'call' => $childCall->toArray(),
157 'connectionData' => $childCall->getConnectionData($currentUserId),
160 'logToken' => $childCall->getLogToken($currentUserId)
167 $call = CallFactory::searchActive($type, $provider, $entityType, $entityId, $currentUserId);
175 if(!$call->getAssociatedEntity()->checkAccess($currentUserId))
177 $this->errorCollection[] =
new Error(
"You can not access this call",
'access_denied');
181 if(!$call->hasUser($currentUserId))
183 $addedUser = $call->addUser($currentUserId);
186 $this->errorCollection[] =
new Error(
"User limit reached",
"user_limit_reached");
189 $call->getSignaling()->sendUsersJoined($currentUserId, [$currentUserId]);
194 'call' => $call->toArray(),
195 'connectionData' => $call->getConnectionData($currentUserId),
196 'logToken' => $call->getLogToken($currentUserId)
212 $this->errorCollection[] =
new Error(
"You do not have access to the parent call",
"access_denied");
219 'call' => $call->toArray($currentUserId),
220 'connectionData' => $call->getConnectionData($currentUserId),
221 'logToken' => $call->getLogToken($currentUserId)
237 $this->errorCollection[] =
new Error(
"You do not have access to the parent call",
"access_denied");
241 $users = $call->getUsers();
243 'call' => $call->toArray($currentUserId),
244 'connectionData' => $call->getConnectionData($currentUserId),
247 'logToken' => $call->getLogToken($currentUserId)
251 public function inviteAction($callId, array $userIds, $video =
"N", $legacyMobile =
"N", $repeated =
"N")
253 $isVideo = ($video ===
"Y");
254 $isLegacyMobile = ($legacyMobile ===
"Y");
255 $isRepeated = ($repeated ===
"Y");
267 $call->getUser($currentUserId)->update([
269 'IS_MOBILE' => ($isLegacyMobile ?
'Y' :
'N')
272 $lockName = static::getLockNameWithCallId($callId);
275 $this->
addError(
new Error(
"Could not get exclusive lock",
"could_not_lock"));
279 $this->
inviteUsers($call, $userIds, $isLegacyMobile, $isVideo, $isRepeated);
289 foreach ($userIds as $userId)
291 $userId = (int)$userId;
296 if(!$call->hasUser($userId))
298 if(!$call->addUser($userId))
303 else if ($isRepeated ===
false && $call->getAssociatedEntity())
305 $call->getAssociatedEntity()->onExistingUserInvite($userId);
307 $usersToInvite[] = $userId;
308 $callUser = $call->getUser($userId);
315 if (count($usersToInvite) === 0)
317 $this->
addError(
new Error(
"No users to invite",
"empty_users"));
321 $sendPush = $isRepeated !==
true;
333 $allUsers = $call->getUsers();
334 $otherUsers = array_diff($allUsers, $userIds);
335 $call->getSignaling()->sendUsersInvited(
361 public function answerAction($callId, $callInstanceId, $legacyMobile =
"N")
363 $isLegacyMobile = $legacyMobile ===
"Y";
375 $callUser = $call->getUser($currentUserId);
377 $lockName = static::getLockNameWithCallId($callId);
380 $this->
addError(
new Error(
"Could not get exclusive lock",
"could_not_lock"));
389 'FIRST_JOINED' => $callUser->getFirstJoined() ? $callUser->getFirstJoined() :
new DateTime(),
390 'IS_MOBILE' => $isLegacyMobile ?
'Y' :
'N',
396 $call->getSignaling()->sendAnswer($currentUserId, $callInstanceId, $isLegacyMobile);
399 public function declineAction(
int $callId, $callInstanceId,
int $code = 603)
412 $lockName = static::getLockNameWithCallId($callId);
415 $this->
addError(
new Error(
"Could not get exclusive lock",
"could_not_lock"));
419 $callUser = $call->getUser($currentUserId);
422 $this->
addError(
new Error(
"User is not part of the call",
"unknown_call_user"));
429 $this->
addError(
new Error(
"Can not decline in {$callUser->getState()} user state",
"wrong_user_state"));
442 $callUser->updateLastSeen(
new DateTime());
444 $userIds = $call->getUsers();
445 $call->getSignaling()->sendHangup($currentUserId, $userIds, $callInstanceId, $code);
447 if(!$call->hasActiveUsers())
459 public function pingAction($callId, $requestId, $retransmit =
true)
472 $callUser = $call->getUser($currentUserId);
475 $callUser->updateLastSeen(
new DateTime());
484 $call->getSignaling()->sendPing($currentUserId, $requestId);
503 $callUser = $call->getUser($currentUserId);
507 'SHARED_SCREEN' =>
'Y'
525 $callUser = $call->getUser($currentUserId);
536 $restart = (bool)$restart;
548 $callUser = $call->getUser($currentUserId);
551 $callUser->updateLastSeen(
new DateTime());
554 $call->getSignaling()->sendNegotiationNeeded($currentUserId, $userId, $restart);
571 $callUser = $call->getUser($currentUserId);
574 $callUser->updateLastSeen(
new DateTime());
577 $call->getSignaling()->sendConnectionOffer($currentUserId, $userId, $connectionId, $sdp, $userAgent);
594 $callUser = $call->getUser($currentUserId);
597 $callUser->updateLastSeen(
new DateTime());
600 $call->getSignaling()->sendConnectionAnswer($currentUserId, $userId, $connectionId, $sdp, $userAgent);
615 $callUser = $call->getUser($currentUserId);
618 $callUser->updateLastSeen(
new DateTime());
621 $call->getSignaling()->sendIceCandidates($currentUserId, $userId, $connectionId, $candidates);
625 public function hangupAction($callId, $callInstanceId, $retransmit =
true)
638 $lockName = static::getLockNameWithCallId($callId);
641 $this->
addError(
new Error(
"Could not get exclusive lock",
"could_not_lock"));
645 $callUser = $call->getUser($currentUserId);
649 $callUser->updateLastSeen(
new DateTime());
652 if(!$call->hasActiveUsers())
661 $userIds = $call->getUsers();
662 $call->getSignaling()->sendHangup($currentUserId, $userIds, $callInstanceId);
678 $this->errorCollection[] =
new Error(
"You do not have access to the call",
"access_denied");
683 $allowedUserIds = $call->getUsers();
687 $allowedUserIds = array_filter($userIds,
function($userId) use ($call, $currentUserId)
689 return $userId == $currentUserId || $call->hasUser($userId);
693 if (empty($allowedUserIds))
695 $this->errorCollection[] =
new Error(
"Users are not part of the call",
"access_denied");
709 $this->errorCollection[] =
new Error(
"Call is not found or you do not have access to the call",
"access_denied");
715 $userId = $currentUserId;
718 $lockName = static::getLockNameWithCallId($callId);
721 $this->
addError(
new Error(
"Could not get exclusive lock",
"could_not_lock"));
725 $callUser = $call->getUser($userId);
728 $this->
addError(
new Error(
"User is not part of the call",
"unknown_call_user"));
734 return $callUser->toArray();
740 'callServerEnabled' => \Bitrix\Im\Call\Call::isCallServerEnabled(),
741 'maxParticipants' => \Bitrix\Im\Call\Call::getMaxParticipants(),
747 AddEventToStatFile(
'im',
'call_connection', $callId, ($connectionStatus ?
'Y' :
'N'));
752 if(!$call->checkAccess($userId))
754 $this->errorCollection[] =
new Error(
"You don't have access to the call " . $call->getId() .
"; (current user id: " . $userId .
")",
'access_denied');
767 $chatId = \Bitrix\Im\Dialog::getChatId($entityId, $currentUserId);
769 return "call_entity_{$entityType}_{$chatId}";
772 return "call_entity_{$entityType}_{$entityId}";
778 if (is_string($callId) || is_numeric($callId))
780 return "im_call_{$callId}";
792 'reportConnectionStatus' => [
static getCallWithId(int $id)
static getUsers(array $idList)
static getLockNameWithCallId($callId)
hangupAction($callId, $callInstanceId, $retransmit=true)
answerAction($callId, $callInstanceId, $legacyMobile="N")
tryJoinCallAction($type, $provider, $entityType, $entityId)
createAction($type, $provider, $entityType, $entityId, $joinExisting=false)
iceCandidateAction($callId, $userId, $connectionId, array $candidates)
getUsersAction($callId, array $userIds=[])
onShareScreenAction($callId)
createChildCallAction($parentId, $newProvider, $newUsers)
inviteAction($callId, array $userIds, $video="N", $legacyMobile="N", $repeated="N")
getUserStateAction($callId, int $userId=0)
negotiationNeededAction($callId, $userId, $restart=false)
checkCallAccess(\Bitrix\Im\Call\Call $call, $userId)
onStartRecordAction($callId)
static getLockNameWithEntityId(string $entityType, $entityId, $currentUserId)
connectionOfferAction($callId, $userId, $connectionId, $sdp, $userAgent)
pingAction($callId, $requestId, $retransmit=true)
connectionAnswerAction($callId, $userId, $connectionId, $sdp, $userAgent)
reportConnectionStatusAction(int $callId, bool $connectionStatus)
inviteUsers(\Bitrix\Im\Call\Call $call, $userIds, $isLegacyMobile, $isVideo, $isRepeated)
declineAction(int $callId, $callInstanceId, int $code=603)
static getConnection($name="")
static getMessage($code, $replace=null, $language=null)