Skip to content

Instantly share code, notes, and snippets.

@ball6847
Last active February 6, 2024 08:03
Show Gist options
  • Save ball6847/3b4b9d45a0a48a30b1610cc125a8b66b to your computer and use it in GitHub Desktop.
Save ball6847/3b4b9d45a0a48a30b1610cc125a8b66b to your computer and use it in GitHub Desktop.
Using deno to subscribe or publish realtime message via Mercure Hub
import { load } from "https://deno.land/std@0.214.0/dotenv/mod.ts";
import jwtEncode from "https://esm.sh/jwt-encode@1.0.1";
const env = await load();
// create jwt token for publishing
const jwtSecret = env["JWT_SECRET_KEY"];
const jwtPayload = {
mercure: {
publish: ["/messages/{event}"],
},
};
const token = jwtEncode(jwtPayload, jwtSecret, { alg: "HS256" });
const params = new URLSearchParams({
"topic": "/messages/statistics",
"id": `/message/statistics/${crypto.randomUUID()}`,
"data": JSON.stringify({
registered_today: 100,
}),
});
const res = await fetch("http://localhost:8080/.well-known/mercure", {
method: "POST",
body: params,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": `Bearer ${token}`,
},
});
console.log(res.status);
console.log(await res.text());
import { load } from "https://deno.land/std@0.214.0/dotenv/mod.ts";
import polyfill from "https://esm.sh/event-source-polyfill@1.0.31";
import jwtEncode from "https://esm.sh/jwt-encode@1.0.1";
const { EventSourcePolyfill } = polyfill;
const env = await load();
// sign JWT token for Mercure hub
// DONT DO THIS IN PRODUCTION!!
// You should generate this on server side, on user login
// since we are using Deno, it is safe to do this here
const jwtSecret = env["JWT_SECRET_KEY"];
const jwtPayload = {
mercure: {
subscribe: ["/messages/{event}"],
},
};
const token = jwtEncode(jwtPayload, jwtSecret, { alg: "HS256" });
// get the connection URL ready
const url = new URL("http://localhost:8080/.well-known/mercure");
url.searchParams.append("topic", "/messages/{event}");
// connect to the Mercure hub
// note that EventSourcePolyfill has built-in reconnect support and allow passing headers (which native doesn't)
const source = new EventSourcePolyfill(url.toString(), {
headers: {
"Authorization": `Bearer ${token}`,
},
});
// listen for messages
source.onmessage = (event) => {
// our data is in the event.data property
// if we sent JSON, we can parse it
console.log("data", JSON.parse(event.data));
// the id of this event, useful for resuming the connection
// we can keep track of this to resume the connection
console.log("lastEventId", event.lastEventId);
};
@ball6847
Copy link
Author

ball6847 commented Feb 4, 2024

This implementation based on freddie (mercure hub implementation in PHP)

git clone git@github.com:bpolaszek/freddie.git
cd freddie
composer install

# update .env and add JWT_SECRET_KEY
vim .env

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment