Giter Club home page Giter Club logo

directus-realtime-extension's Introduction

Directus Realtime Extension

Add realtime capabilities to your Directus App


Description

Realtime extension simply adds very thing layer between your pusher / soketi server and your directus app.


Any Pusher-maintained or compatible client can connect to it.You have total control of your channels (What to publish or who to authorize) with pure javascript that you can edit in your admin panel per channel.

Project Status

  • Alpha: Under heavy development
  • Public Alpha: Ready for use. But go easy on me, there may be a few kinks.
  • Public Beta: Stable enough for most non-enterprise use-cases
  • Public: Production-ready

You can use soketi for free pusher alternative, its open-source.

Installing

  • Clone this repo
  • run npm install && npm run build in both "realtime-endpoints" and "realtime-hooks" directories.
  • Both extensions are outputs to dist/ folder and you have to move the output from the dist/ folder and /migrations folder into your project's ./extensions/ folder
  • and set ENV variables to your needs
  • restart your direcuts app

Note: Migration has Data Model for channels table for fast start if you don't want this simply remove it from migration file or set RT_DONT_PRESETenv variable on first start. (There is no need to disable it but its your call.)

Note : If you disabled Data Model presets you have te setup for yourself

Env variables

ENV NAME REQUIRED DEFAULT
RT_APP_ID YES "app-id"
RT_APP_KEY YES "app-key"
RT_APP_SECRET YES "app-secret"
RT_APP_HOST YES "soketi"
RT_APP_CLUSTER NOT REQUIRED FOR SOKETI (undefined | disabled)
RT_ENCRYPTION_MASTER_KEY NOT REQUIRED IF YOR NOT NEED ENCRYPTION ON CHANNELS (undefined | disabled)
RT_APP_PORT YES 6001
RT_USE_TLS NO
RT_USE_STATS NO (undefined | disabled)

What's Next?

  • You can create your channels like normal collection items from dashboard.
  • I try to fill all note sections for all fileds, its should be a self-explanatory.

Example Channel

channel name accepts value like express.js route variables (See path-to-regexp)

Channel name : private-chat-:userId

Collection : chat

Authorizer Context:

{
socket_id: "pusher socket id",
// requested channel name
channel_name : "private-chat-cd6feea9-bcb2-45bb-a664-6fea3fea88b8",

params : {
    userId:"cd6feea9-bcb2-45bb-a664-6fea3fea88b8"
    },

    auth: {
   user: { // All user fields
   	id: "cd6feea9-bcb2-45bb-a664-6fea3fea88b8",
   	first_name: "Admin",
   	last_name: "User",
   	email: "[email protected]",
   	password: "$argon2i$v=19$m=4096,t=3,p=1$h+TgmA2455KVE52jizvyMw$1T/DOdSRpxDlGBz/Uft7QzkpeWIIITZulIS82tu7TAw",
   	location: null,
   	title: null,
   	description: null,
   	tags: null,
   	avatar: null,
   	language: "en-US",
   	theme: "dark",
   	tfa_secret: null,
   	status: "active",
   	role: "8bb80a0b-0467-4351-bd29-4ad16ffc7f92",
   	token: null,
   	last_access: "2022-01-16T23:50:23.737Z",
   	last_page: "/content/realtime_channels/4e7b81a7-0e94-4b93-abc6-8ef7a40ab97d",
   	provider: "default",
   	external_identifier: null,
   	auth_data: null,
   	email_notifications: false
   },
   role: "8bb80a0b-0467-4351-bd29-4ad16ffc7f92",
   admin: true,
   app: true,
   ip: "172.18.0.1",
   userAgent: "insomnia/2021.7.2",
   permissions: [
       // ... user permissions
   ]
}
}

Example Authorizer Script

// For private channels
if (auth.user.id === params.userId) {

   return true;
}
// For presence Channels
if(auth.user.id === params.userId)
{
return {user_id:auth.user.id,user_info:{name:auth.user.first_name}}; // Check Pusher presence channel docs.
}

Publisher Context

    {
        collection:"chat",
        action:"create", // update,delete
        trigger: (channelParams,eventName,payload,exclude?) => {}, // trigger event on channel with given parameters,exclude is optional
        broadcastTo: (channelName, channelParams, eventName, payload, exclude?) => {}, // exclude is optional

    }

Example Publisher Script

// Remember this is PURE JAVASCRIPT
// YOU ARE RESPONSIBLE FOR WHAT IS SHARED WITH THE USER
// You can select which fields you want to see in meta.payload object (resolves relations with dot notation).
//
// in this situation fields can be : *,recipient.id,recipient.first_name
// to get all top-level fields and all second-level relational fields : *.*
trigger({userId:meta.payload.recipient.id},"message",meta.payload);
// if you want to trigger event on another channel use broadcastTo

// if it doesn't have any dynamic parameters in channel name,pass empty object on channelParams.
broadcastTo("another-channel",{},"somethingHappend",meta.payload);

// or with params

broadcastTo("private-chat-notification-:userId",{userId:meta.payload.recipient.id},"message",meta.payload);

When to trigger publisher

Just check in which action should publisher be called. Useful for avoid unnecessary 'if's in script.

Example Client

auth endpoint : {APP_PUBLIC_URL}/realtime/auth

const client = new Pusher('app-key', {
	wsHost: 'localhost',
	wsPort: 6001,
	forceTLS: false,
	disableStats: true,
	authEndpoint: `http://localhost:8055/realtime/auth`,
	auth: {
		headers: {
			Authorization: `Bearer ${directus.auth && directus.auth.token}`
		}
	},
	enabledTransports: ['ws', 'wss'],
});

Limits

except Pusher / Soketi server limits,extension doesn't have limit for implementations.Authorizer and Publisher fields are just a javascript functions with a useful parameters and functions.

Contributing

Contributions are welcome.

Reporting a Vulnerability

If you discover any security-related issues, please open a issue.

Authors

Contributors names and contact info

License

Its free and open-source do whatever you want with it. This project is licensed under the MIT License - see the LICENSE.md file for details


Sorry for any mistakes. English is not my native language

directus-realtime-extension's People

Contributors

erdemozveren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.