Add event participants to the Nextcloud Talk room
This commit is contained in:
parent
b0f306eaf1
commit
b06f1e3941
2 changed files with 146 additions and 2 deletions
|
@ -1063,6 +1063,7 @@ $("#rcmfd_new_category").keypress(function(event) {
|
|||
|
||||
$this->cleanup_event($event);
|
||||
$this->event_save_success($event, null, $action, true);
|
||||
$this->talk_room_update($event);
|
||||
}
|
||||
|
||||
$reload = $success && !empty($event['recurrence']) ? 2 : 1;
|
||||
|
@ -1075,6 +1076,7 @@ $("#rcmfd_new_category").keypress(function(event) {
|
|||
else if ($success = $this->driver->edit_event($event)) {
|
||||
$this->cleanup_event($event);
|
||||
$this->event_save_success($event, $old, $action, $success);
|
||||
$this->talk_room_update($event);
|
||||
}
|
||||
|
||||
$reload = $success && (!empty($event['recurrence']) || !empty($event['_savemode']) || !empty($event['_fromcalendar'])) ? 2 : 1;
|
||||
|
@ -3895,6 +3897,44 @@ $("#rcmfd_new_category").keypress(function(event) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a Nextcould Talk room
|
||||
*/
|
||||
public function talk_room_update($event)
|
||||
{
|
||||
// If a room is assigned to the event...
|
||||
if (
|
||||
($talk_url = $this->rc->config->get('calendar_nextcloud_url'))
|
||||
&& isset($event['attendees'])
|
||||
&& !empty($event['location'])
|
||||
&& strpos($event['location'], unslashify($talk_url) . '/call/') === 0
|
||||
) {
|
||||
$participants = [];
|
||||
$organizer = null;
|
||||
|
||||
// ollect participants' and organizer's email addresses
|
||||
foreach ($event['attendees'] as $attendee) {
|
||||
if (!empty($attendee['email'])) {
|
||||
if ($attendee['role'] == 'ORGANIZER') {
|
||||
$organizer = $attendee['email'];
|
||||
}
|
||||
else if ($attendee['cutype'] == 'INDIVIDUAL') {
|
||||
$participants[] = $attendee['email'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the event is owned by the current user update the room
|
||||
if ($organizer && in_array($organizer, $this->get_user_emails())) {
|
||||
require_once __DIR__ . '/lib/calendar_nextcloud_api.php';
|
||||
|
||||
$api = new calendar_nextcloud_api();
|
||||
|
||||
$api->talk_room_update($event['location'], $participants);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of email addresses of the current user (from login and identities)
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,14 @@
|
|||
class calendar_nextcloud_api
|
||||
{
|
||||
|
||||
const PARTICIPANT_OWNER = 1;
|
||||
const PARTICIPANT_MODERATOR = 2;
|
||||
const PARTICIPANT_USER = 3;
|
||||
const PARTICIPANT_GUEST = 4;
|
||||
const PARTICIPANT_PUBLIC = 5;
|
||||
const PARTICIPANT_GUEST_MODERATOR = 6;
|
||||
|
||||
|
||||
/**
|
||||
* Make a request to the Nextcloud API
|
||||
*
|
||||
|
@ -56,15 +64,24 @@ class calendar_nextcloud_api
|
|||
]);
|
||||
|
||||
if (!empty($params)) {
|
||||
$request->addPostParameter($params);
|
||||
if ($method == 'POST') {
|
||||
$request->addPostParameter($params);
|
||||
}
|
||||
else {
|
||||
$request->setUrl($url . '?' . http_build_query($params));
|
||||
}
|
||||
}
|
||||
|
||||
// rcube::console($method . ": " . (string) $request->getUrl());
|
||||
|
||||
// Send the request
|
||||
$response = $request->send();
|
||||
|
||||
$body = $response->getBody();
|
||||
$code = $response->getStatus();
|
||||
|
||||
// rcube::console($code, $body);
|
||||
|
||||
if ($code < 400) {
|
||||
return json_decode($body, true);
|
||||
}
|
||||
|
@ -88,9 +105,40 @@ class calendar_nextcloud_api
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find user by email address
|
||||
*/
|
||||
protected function findUserByEmail($email)
|
||||
{
|
||||
$email = strtolower($email);
|
||||
$params = [
|
||||
'search' => $email,
|
||||
'itemType' => 'call',
|
||||
'itemId' => ' ',
|
||||
'shareTypes' => [0, 1, 7, 4],
|
||||
];
|
||||
|
||||
// FIXME: Is this the only way to find a user by his email address?
|
||||
$response = $this->request("core/autocomplete/get", 'GET', $params);
|
||||
|
||||
if (!empty($response['ocs']['data'])) {
|
||||
foreach ($response['ocs']['data'] as $user) {
|
||||
// FIXME: This is the only field that contains email address?
|
||||
// Note: A Nextcloud contact (the "emails" source) will have an email address in
|
||||
// the 'id' attribute instead in 'shareWithDisplayNameUnique'.
|
||||
// Another option might be to parse 'label' attribute
|
||||
if (strtolower($user['shareWithDisplayNameUnique']) == $email) {
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Talk room
|
||||
*
|
||||
* @param string $name Room name
|
||||
*
|
||||
* @return string|false Room URL
|
||||
*/
|
||||
public function talk_room_create($name = '')
|
||||
|
@ -105,10 +153,66 @@ class calendar_nextcloud_api
|
|||
$response = $this->request('apps/spreed/api/v4/room', 'POST', $params);
|
||||
|
||||
if (is_array($response) && !empty($response['ocs']['data']['token'])) {
|
||||
$token = $response['ocs']['data']['token'];
|
||||
$url = unslashify($rcmail->config->get('calendar_nextcloud_url'));
|
||||
return $url . '/call/' . $response['ocs']['data']['token'];
|
||||
|
||||
return $url . '/call/' . $token;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a Talk room
|
||||
*
|
||||
* @param string $room Room ID (or url)
|
||||
* @param array $participants Room participants' email addresses (extept the owner)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function talk_room_update($room = '', $participants = [])
|
||||
{
|
||||
if (preg_match('|https?://|', $room)) {
|
||||
$arr = explode('/', $room);
|
||||
$room = $arr[count($arr) - 1];
|
||||
}
|
||||
|
||||
// Get existing room participants
|
||||
$response = $this->request("apps/spreed/api/v4/room/{$room}/participants", 'GET');
|
||||
|
||||
if ($response === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$attendees = [];
|
||||
foreach ($response['ocs']['data'] as $attendee) {
|
||||
if ($attendee['participantType'] != self::PARTICIPANT_OWNER) {
|
||||
$attendees[$attendee['actorId']] = $attendee['attendeeId'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($participants as $email) {
|
||||
if ($user = $this->findUserByEmail($email)) {
|
||||
// Participant already exists, skip
|
||||
// Note: We're dealing with 'users' source here for now, 'emails' source
|
||||
// will have an email address in 'actorId'
|
||||
if (isset($attendees[$user['id']])) {
|
||||
unset($attendees[$user['id']]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Register the participant
|
||||
$params = ['newParticipant' => $user['id'], 'source' => $user['source']];
|
||||
$response = $this->request("apps/spreed/api/v4/room/{$room}/participants", 'POST', $params);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove participants not in the event anymore
|
||||
foreach ($attendees as $attendeeId) {
|
||||
$params = ['attendeeId' => $attendeeId];
|
||||
$response = $this->request("apps/spreed/api/v4/room/{$room}/attendees", 'DELETE', $params);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue