Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic plugins through simple scripts #1736

Open
gabek opened this issue Feb 14, 2022 · 4 comments
Open

Dynamic plugins through simple scripts #1736

gabek opened this issue Feb 14, 2022 · 4 comments
Assignees
Labels
backlog Ideas that might be cool and can be looked into later. big feature A major feature that requires planning, design input and discussion enhancement New feature or request research Something to look up or a big question that needs an answer

Comments

@gabek
Copy link
Member

gabek commented Feb 14, 2022

I've yet to give up on the plugin idea, even though it's been in a state of limbo for a long time because there hasn't been a clear solution for it. But I think I've come up with something simple, extensible, and flexible enough for a lot of people.

I'd like to experiment with stdin/out-based "plugin" system that almost works like the webhooks, but requires no servers, and no external infrastructure.

  • You write code in whatever language you want, as long as you adhere to a specific JSON payload that Owncast will be sending and receiving. While most people would probably write in a simple scripting language of their choice, you could also write a Go or Rust binary if you wanted to, as long as you can send/receive through stdin/out.
  • You drop it in the plugins directory.
  • Owncast will load up any script in that directory and make callbacks to it any time an event happens within Owncast.
  • Owncast will listen for specific inbound commands from the scripts and act upon them.
  • Things that are chat related will use the existing access tokens that already identify API-based users.
  • We can provide basic, language-specific, SDKs for the most popular languages to make writing scripts easier.
  • In theory you could write something like a basic Owncast chat bot in only a few lines of code, with no networking required.
  • This could even work for UI, where Owncast asks a plugin to give it some arbitrary HTML and it gets rendered on the page.

Pros:

  • You can write in any language
  • Simple SDKs can be built and added to the package manager for popular languages so people don't have to worry about the specifics of sending/receiving events.
  • People can use the extensive library ecosystem of whatever language they use.

Cons:

  • You're limited to a specific set of commands and callbacks and you can't arbitrarily change the deep innards of Owncast.
  • We can't support every language, people will be on their own.
  • People will be required to have a working environment for running whatever language. We can't be supporting people's Python environments on their servers, for example.

This isn't something I'm going to rush to get in, but I think it could ease the extensibility of Owncast, and could grow over time with more events. I'd love to hear any feedback people have!

@gabek gabek added enhancement New feature or request research Something to look up or a big question that needs an answer big feature A major feature that requires planning, design input and discussion labels Feb 14, 2022
@gabek gabek self-assigned this Feb 14, 2022
@nebunez
Copy link
Contributor

nebunez commented Feb 14, 2022

This seems like the closest to the idea of plugins that I've had in mind. I wonder what the limitations will be as I can't imagine them right now.

@gabek gabek added the backlog Ideas that might be cool and can be looked into later. label Feb 18, 2022
@Valinwolf
Copy link

That's a really interesting concept and maintains a high level of linguistic flexibility. JSON would probably give the best possible option since I haven't found a language that doesn't have JSON either built-in or a well maintained, stable library. XML is hit or miss most of the time. As an idea though, it could even be set as a one-shot type system - only running the scripts/execs when needed, thus saving resources. It would have to launch it STDIN the data and wait for exit. You could probably get an initial system up with a single direction of communication, from Owncast to plugin, up and running with little effort and worry about the other direction later.

@jprjr
Copy link
Member

jprjr commented Apr 23, 2024

This is a really cool idea!

So a few thoughts: probably the best way to save resources/maintain performance is for the plugins to launch as a long-lived process, as opposed to launching a process for each and every event.

The plugin API could be as simple as - a process reads a JSON stanzas on stdin, writes a JSON stanza on stdout, Owncast reacts accordingly. If the process exits successfully, Owncast relaunches it on the next event, if it exits with a non-zero exit code, it doesn't get started again. This would allow for both the long-lived process model, or for users to write simple scripts that just do a single thing and exit.

As far as SDKs go, I probably wouldn't put a lot of effort into that part. There's so many languages, and if the API is simple enough, most people would just need JSON serialization/deserialization libraries.

Would there need to be a method of registering for specific events? Or would just having all events go to these plugins work OK? One idea is you could have folders representing event types, every executable in those folders only gets those events. Or maybe you have the plugin write out some JSON at start-up indicating what events its interested in?

@gabek
Copy link
Member Author

gabek commented Apr 23, 2024

I'm not sure about registration for events. Maybe. The thing about stdin is if you pass something there, and wait for a response (for example, your filtering idea), but that plugin doesn't support filtering, there's no way for Owncast to know that, and the event would go into the void. So maybe registering for events would be required. Or maybe a plugin can have a manifest that describes what events it knows how to handle, or like you said, the plugin itself just does it, and Owncast reads it upon plugin loading.

The downside of a plugin per event is from a developer standpoint, I wouldn't want to write and build 20 Go binaries, for example. And from the Owncast side, it has to manage more stdin/stdout connections to plugins. Not that it's a huge deal, since that would have to be managed anyway to support multiple different plugins being loaded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog Ideas that might be cool and can be looked into later. big feature A major feature that requires planning, design input and discussion enhancement New feature or request research Something to look up or a big question that needs an answer
Projects
None yet
Development

No branches or pull requests

4 participants