added channels and events generation

This commit is contained in:
ArnabChatterjee20k
2026-04-15 18:16:51 +05:30
parent 7e18e6f8c5
commit cd6a6956d6
6 changed files with 118 additions and 3 deletions
@@ -589,6 +589,11 @@ class Realtime extends MessagingAdapter
$roles = [Role::team($project->getAttribute('teamId'))->toString()];
}
break;
case 'presences':
$channels[] = 'presences';
$channels[] = 'presences.' . $parts[1];
$roles = $payload->getRead();
break;
}
return [
@@ -2,6 +2,7 @@
namespace Appwrite\Platform\Modules\Presences\HTTP;
use Appwrite\Event\Event;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Modules\Compute\Base;
use Appwrite\SDK\AuthType;
@@ -31,6 +32,9 @@ class Delete extends Base
->desc('Delete presence')
->groups(['api', 'presences'])
->label('scope', 'users.write')
->label('event', 'presences.[presenceId].delete')
->label('audits.event', 'presence.delete')
->label('audits.resource', 'presence/{request.presenceId}')
->label('sdk', new Method(
namespace: 'presences',
group: 'presences',
@@ -48,10 +52,11 @@ class Delete extends Base
->param('presenceId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Presence unique ID.', false, ['dbForProject'])
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->callback($this->action(...));
}
public function action(string $presenceId, Response $response, Database $dbForProject): void
public function action(string $presenceId, Response $response, Database $dbForProject, Event $queueForEvents): void
{
$presence = $dbForProject->getDocument('presenceLogs', $presenceId);
@@ -60,6 +65,7 @@ class Delete extends Base
}
$dbForProject->deleteDocument('presenceLogs', $presenceId);
$queueForEvents->setParam('presenceId', $presence->getId());
$response->noContent();
}
@@ -2,6 +2,7 @@
namespace Appwrite\Platform\Modules\Presences\HTTP;
use Appwrite\Event\Event;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Modules\Presences\HTTP\Action as PresenceAction;
use Appwrite\SDK\AuthType;
@@ -35,6 +36,9 @@ class Update extends PresenceAction
->desc('Update presence')
->groups(['api', 'presences'])
->label('scope', 'users.write')
->label('event', 'presences.[presenceId].update')
->label('audits.event', 'presence.update')
->label('audits.resource', 'presence/{response.$id}')
->label('sdk', new Method(
namespace: 'presences',
group: 'presences',
@@ -58,6 +62,7 @@ class Update extends PresenceAction
->inject('dbForProject')
->inject('user')
->inject('authorization')
->inject('queueForEvents')
->callback($this->action(...));
}
@@ -71,7 +76,8 @@ class Update extends PresenceAction
Response $response,
Database $dbForProject,
User $user,
Authorization $authorization
Authorization $authorization,
Event $queueForEvents
): void {
$isAPIKey = $user->isApp($authorization->getRoles());
$isPrivilegedUser = $user->isPrivileged($authorization->getRoles());
@@ -118,6 +124,7 @@ class Update extends PresenceAction
}
$presence = $dbForProject->updateDocument('presenceLogs', $presenceId, $updates);
$queueForEvents->setParam('presenceId', $presence->getId());
$response->dynamic($presence, Response::MODEL_PRESENCE);
}
@@ -2,6 +2,7 @@
namespace Appwrite\Platform\Modules\Presences\HTTP;
use Appwrite\Event\Event;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Modules\Presences\HTTP\Action as PresenceAction;
use Appwrite\SDK\AuthType;
@@ -39,6 +40,9 @@ class Upsert extends PresenceAction
->desc('Upsert presence')
->groups(['api', 'presences'])
->label('scope', 'users.write')
->label('event', 'presences.[presenceId].upsert')
->label('audits.event', 'presence.upsert')
->label('audits.resource', 'presence/{response.$id}')
->label('sdk', new Method(
namespace: 'presences',
group: 'presences',
@@ -63,6 +67,7 @@ class Upsert extends PresenceAction
->inject('dbForProject')
->inject('user')
->inject('authorization')
->inject('queueForEvents')
->callback($this->action(...));
}
@@ -76,7 +81,8 @@ class Upsert extends PresenceAction
Response $response,
Database $dbForProject,
User $user,
Authorization $authorization
Authorization $authorization,
Event $queueForEvents
): void {
$isAPIKey = $user->isApp($authorization->getRoles());
$isPrivilegedUser = $user->isPrivileged($authorization->getRoles());
@@ -121,6 +127,7 @@ class Upsert extends PresenceAction
}
$presence = $dbForProject->upsertDocument('presenceLogs', $presenceDocument);
$queueForEvents->setParam('presenceId', $presence->getId());
$response->dynamic($presence, Response::MODEL_PRESENCE);
}
@@ -208,4 +208,73 @@ class PresenceRealtimeClientTest extends Scope
$client->close();
}
public function testChannelParsing(): void
{
$presenceId = ID::unique();
$userId = $this->getUser()['$id'];
$headers = [
'origin' => 'http://localhost',
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $this->getUser()['session'],
];
$client = $this->getWebsocket(['presences', 'presences.' . $presenceId], $headers, timeout: 5);
$connected = \json_decode($client->receive(), true);
$this->assertSame('connected', $connected['type'] ?? null);
$this->assertCount(2, $connected['data']['channels'] ?? []);
$this->assertContains('presences', $connected['data']['channels']);
$this->assertContains('presences.' . $presenceId, $connected['data']['channels']);
$create = $this->client->call(
Client::METHOD_PUT,
'/presences/' . $presenceId,
$this->getServerHeaders(),
[
'userId' => $userId,
'status' => 'online',
'metadata' => ['source' => 'channel-parsing-create'],
'permissions' => $this->getPresencePermissions($userId),
]
);
$this->assertSame(200, $create['headers']['status-code']);
$createEvent = \json_decode($client->receive(), true);
$this->assertSame('event', $createEvent['type'] ?? null);
$this->assertContains('presences', $createEvent['data']['channels'] ?? []);
$this->assertContains('presences.' . $presenceId, $createEvent['data']['channels'] ?? []);
$this->assertContains('presences.' . $presenceId . '.upsert', $createEvent['data']['events'] ?? []);
$update = $this->client->call(
Client::METHOD_PATCH,
'/presences/' . $presenceId,
$this->getServerHeaders(),
[
'status' => 'away',
'metadata' => ['source' => 'channel-parsing-update'],
]
);
$this->assertSame(200, $update['headers']['status-code']);
$updateEvent = \json_decode($client->receive(), true);
$this->assertSame('event', $updateEvent['type'] ?? null);
$this->assertContains('presences', $updateEvent['data']['channels'] ?? []);
$this->assertContains('presences.' . $presenceId, $updateEvent['data']['channels'] ?? []);
$this->assertContains('presences.' . $presenceId . '.update', $updateEvent['data']['events'] ?? []);
$delete = $this->client->call(
Client::METHOD_DELETE,
'/presences/' . $presenceId,
$this->getServerHeaders()
);
$this->assertSame(204, $delete['headers']['status-code']);
$deleteEvent = \json_decode($client->receive(), true);
$this->assertSame('event', $deleteEvent['type'] ?? null);
$this->assertContains('presences', $deleteEvent['data']['channels'] ?? []);
$this->assertContains('presences.' . $presenceId, $deleteEvent['data']['channels'] ?? []);
$this->assertContains('presences.' . $presenceId . '.delete', $deleteEvent['data']['events'] ?? []);
$client->close();
}
}
+21
View File
@@ -330,4 +330,25 @@ class MessagingTest extends TestCase
$this->assertContains(Role::any()->toString(), $result['roles']);
$this->assertContains(Role::team('123abc')->toString(), $result['roles']);
}
public function testFromPayloadPresenceChannels(): void
{
$presenceId = ID::custom('presence123');
$result = Realtime::fromPayload(
event: 'presences.' . $presenceId . '.upsert',
payload: new Document([
'$id' => $presenceId,
'$permissions' => [
Permission::read(Role::any()),
Permission::update(Role::users()),
Permission::delete(Role::users()),
],
]),
);
$this->assertContains('presences', $result['channels']);
$this->assertContains('presences.' . $presenceId, $result['channels']);
$this->assertContains(Role::any()->toString(), $result['roles']);
}
}