Emissary is Whatever You Want It To Be

A platform with powerful customization abilities.

There were some really cool demos at FediForum last month, but the one that really opened my eyes was Emissary. It’s a newer project developed by Ben Pate, and it does something totally new: composable interfaces.

Fediforum Demo: Emissary

The secret sauce behind Emissary as a project is brilliant in its simplicity: it gives you a server and a bunch of tools, and gives you the power to build whatever interface you want on top of it. It’s very reminiscent of Hubzilla, but it makes customization a first-class citizen.

Deep Customization

There’s a lot of moving parts here, but it’s pretty easy to summarize: instead of simply giving you the power to customize how Emissary looks, you’re also given the power to customize how it works.

Emissary offers comprehensive documentation, and a bunch of different template types that can assist in building whatever app comes to mind. From the layout and widgets to the timelines and data types.

By following this method, is possible to turn Emissary into whatever platform you want. It uses a special JSON templating system, and the frontend processes everything with a toolkit based on HTMX. For developers, this means that you don’t need to write a frontend in a special custom framework – instead, Emissary uses the principles of HTML for development.

Contrary to other attempts to build this kind of thing in the past, Emissary lets developers write timelines and activity data as templates. Here’s how you can define a simple to-do list item:

Template Definitions

This part exists at the top of the template, and simply defines what it is, and provides some instructions for how it’s used by Emissary.

templateId:"test-todo-item"
	templateRole:"todo-item"
	socialRole:"Note"
	model:"stream"
	containedBy: ["todo"]
	label:"To Do Item"
	description:"A single item in a to-do list"
	icon:"check-badge"

Schema

This part defines the actual fields of the object itself. Every single property is defined as a type, with additional fields nested in the actual data itself. Here, the data property includes dueDate and complete.

schema: {
		type:"object"
		properties: {
			label: {type:"string", maxlength: 64}
			summary: {type:"string", maxlength: 256}
			data: {type:"object", properties: {
				dueDate: {type:"string", format:"date"}
				complete: {type:"boolean"}
			}}
		}

Actions

Here, the allowed actions are defined. Each action is built up of multiple steps, which are tasks that can be mixed and matched to make something happen. Let’s look through it.

actions: {
		create: {
			steps: [
				{do:"as-modal", "steps": [
					{do:"edit", "form": {
						type:"layout-vertical"
						label:"Add Task"
						children: [
							{type:"text", label:"Name", path:"label"}
							{type:"textarea", label:"Details", path:"summary"}
							{type:"text", label:"Due Date", path:"data.dueDate"}
						]
					}}
					{do:"publish", outbox:true}
					{do:"trigger-event", "event":"refreshPage"}
				]}
			]
		}
		view: {
			steps:[
				{do:"include", "action":"edit"}
			]
		}
		edit: {
			steps: [
				{do:"as-modal", "steps": [
					{
						do:"edit"
						form: {
							type:"layout-vertical"
							label:"Edit Task"
							children: [
								{type:"text", label:"Name", path:"label"}
								{type:"textarea", label:"Details", path:"summary"}
								{type:"text", label:"Due Date", path:"data.dueDate"}
								{type:"toggle", path:"data.complete", options:{true-text:"Complete", false-text:"Not Complete"}}
							]
						}
						options: ["delete: /{{.StreamID}}/delete"]
					}
					{do:"publish", outbox:true}
					{do:"trigger-event", "event":"refreshPage"}
				]}
			]
		}
		delete: {
			"steps": [
				{do:"unpublish", outbox:true}
				{do:"delete", "title":"Delete Task?"}
				{do:"trigger-event", "event":"refreshPage"}
			]
		}

		discuss: {
			steps: [
				{do:"as-modal", "steps": [
					{do:"view-html"}
				]}
			]
		}
	}

The Create action adds a popup modal as a step, which then has the Name, Details, and dueDate values. After it’s filled out, the activity gets published to an outbox, which is the standard method for dispatching in ActivityPub. The page refreshes, and now it’s possible to edit or delete the item, or add a comment.

When we put it all together, we get something that defines what data is available, what actions are taken in processing that data, how it all looks, and what interactions are available to users. As someone who had messed around with PHP, Rails, and Node apps over the years, I cannot begin to tell you how wild this is.

Federated Music Demo

The latest demo Ben showcased is an attempt to create an alternative to Bandcamp. It’s called Arcadium, and is designed around letting artists customize the look and feel of their band pages. It includes support for streaming audio, links to other services, a custom home page, and events.

It’s an incredible example, and as of this writing, has a little over two weeks of active development time. The idea that this kind of thing is possible so quickly is nothing short of astonishing.

Ben continues to work on Arcadium, but is also seeking insight from Fediverse musicians looking for another Bandcamp alternative. Tapping into an existing community and building for their needs would be a great idea, as we’ve already seen Bonfire do with Open Science Network.

Who is this for?

It could be argued that Emissary is for power users and developers, but I think that’s only part of the picture. Emissary is based on IndieWeb principles, and a big motivation for the project involves giving people the power to shape their Web environment into whatever they want. It’s a powerful, intoxicating idea, and I can’t stop thinking about it.

I’m going to download Emissary and tinker with it. Should my efforts bear fruit, I hope to write some guides in the near future!

Sean Tilley

Sean Tilley has been a part of the federated social web for over 15+ years, starting with his experiences with Identi.ca back in 2008. Sean was involved with the Diaspora project as a Community Manager from 2011 to 2013, and helped the project move to a self-governed model. Since then, Sean has continued to study, discuss, and document the evolution of the space and the new platforms that have risen within it.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button