Scrivere un plugin xbar per Plausible.io

Come ho scritto un plug-in JS per l'app xbar per vedere il numero attuale di visitatori

Scrivere un plugin xbar in Javascript

Come progetto del fine settimana volevo scrivere un semplice plugin per xbar, un'applicazione in cui mi sono imbattuto di recente. xbar stesso è scritto nel linguaggio di programmazione "Go" e utilizza "Wails" come servizio sottostante per consentire agli sviluppatori di scrivere voci di menu personalizzate per la barra dei menu in macOS (sì, attualmente è limitato solo a macOS).

La cosa bella di xbar è che supporta un'ampia varietà di linguaggi di programmazione, che include anche Javascript. Come sviluppatore web, volevo quindi vedere quanto fosse facile scrivere un plug-in personalizzato che si collegasse a Plausible.io, il mio servizio di analisi rispettoso della privacy. L'obiettivo è eseguire il rendering di tutti gli utenti attuali che sono attualmente su questa app Web. Al momento della stesura, la richiesta pull è ancora in fase di revisione.

Image 52d29c4414ce

Image 67e4f6e5107d

Configurazione di base di xbar

xbar può essere semplicemente scaricato e installato sul tuo Mac. Una volta avviato per la prima volta, è possibile utilizzare una schermata che contiene tutti i plug-in scaricabili e pubblicati per ottenere il plug-in che si desidera avere.

Il processo di installazione copia semplicemente il codice sorgente del plugin (un singolo file per plugin) in una cartella speciale, dalla quale xbar legge tutti i plugin attualmente installati. Per iniziare a scrivere il tuo plugin, devi semplicemente creare un file nella directory e iniziare a hackerare. Pulito!

convenzione del nome del file xbar

Il nome del file è composto da tre parti, tutte separate da un punto.

  • il tuo nome univoco del plugin
  • l'intervallo di tempo in cui viene eseguito il codice, simile a un lavoro CRON
  • il suffisso file comune
plausible.1m.js

Codificare un plugin xbar in JS

Ora sei pronto per iniziare a programmare! Per prima cosa includi la direttiva shebang richiesta per dire a xbar dove dovrebbe essere trovata l'istanza del nodo.

#!/usr/bin/env /usr/local/bin/node

La parte successiva è quindi l'aggiunta di alcuni metadati. Naturalmente, per lo sviluppo locale questo può essere omesso, ma ecco cosa sto usando per il plug-in plausibile.

// Metadata allows your plugin to show up in the app, and website.
//
//  <xbar.title>Plausible Tracker</xbar.title>
//  <xbar.version>v1.0</xbar.version>
//  <xbar.author>Tom Schönmann</xbar.author>
//  <xbar.author.github>flaming-codes</xbar.author.github>
//  <xbar.desc>See who's on your site at-a-glance.</xbar.desc>
//  <xbar.dependencies>node</xbar.dependencies>
//  <xbar.abouturl>https://flaming.codes</xbar.abouturl>
//  <xbar.image>https://raw.githubusercontent.com/flaming-codes/xbar-plausible-stats/main/plausible-icon-36-36-144.png</xbar.image>

E questo è tutto ciò che è necessario per l'esecuzione del tuo plug-in. Ora hai una tela in cui puoi codificare in puro Javascript, eseguito dall'istanza Node.js dell'utente. Ciò significa che abbiamo accesso a tutti i pacchetti Node principali, come "https". Per il mio caso d'uso, questo è tutto ciò di cui ho bisogno, poiché il tracciamento degli utenti richiede semplicemente un recupero dall'API Plausible.io.

I seguenti pezzi di codice mostrano la parte più rilevante di cui penso valga la pena parlare. Il codice completo è disponibile nel relativo repository pubblico, link nell'addendum alla fine di questa pagina.

// Here you see how to make network
// requests with 'https'-only.
// This is a native node-lib that
// works w/ data streams, as you'll see.

const https = require("https");

// Those have to edited by the
// user directly in the file,
// after it has been downloaded
// (aka installed)!
const SITE_ID = "";
const API_KEY = "";

// ... other code ...

async function fetcher() {
  return new Promise((resolve, reject) => {
    let body = "";
    const request = {
      host: "plausible.io",
      path: `/api/v1/stats/realtime/visitors?site_id=${SITE_ID}`,
      method: "GET",
      headers: {
        Authorization: `Bearer ${API_KEY}`,
      },
    };

    try {
      const req = https.get(request, (res) => {
        res.on("data", (data) => {
          body += data;
        });
        res.on("end", () => {
          resolve(JSON.parse(body));
        });
      });

      req.on("error", (error) => {
        console.error(error);
      });

      req.end();
    } catch (error) {
      reject(error);
    }
  });
}
// I've implemented an array of tuples
// that hold an icon + count threshold
// when to active it.

// The first entry doesn't render a 
// string (which can be direclty used),
// but rather a mapping that results in
// the following code:
//
// `image="..." font=Menlo color=white`
//
// This is a special syntax that tells
// xbar to render a base64 image w/
// a custom font and color.
//
// 'plausibleIconWhite' is just the string
// for the base64-image.
const stepIcons = [
  [0, `${plausibleIconWhite} Menlo white`, "image font color"],
  [5, "💫"],
  [10, "⭐️"],
  [50, "🌟"],
  [100, "⚡️"],
  [500, "💥"],
];
// Actually rendering stuff in xbar
// is super simple - just output it
// with console.log(...).
//
// As you'll see, '---' define 
// separator. The first log-call
// gets rendered as acutal menu item.

const linksMenu = [
  "---",
  `🔮 Open dashboard | href=https://plausible.io/${SITE_ID}`,
  `🔥 Made by flaming.codes | href=https://flaming.codes`,
];

function renderError(props) {
  const { error } = props;
  const output = [
    "❔",
    "---",
    "No data accessible",
    "Please check your user data",
    ...linksMenu,
  ];

  console.log(output.join("\n"));
}

// Finally, I defined a single function
// where everything starts. This function
// just gets called to kick everyting off.
// Plain JS, it's that simple.

async function render() {
  const { data, error } = await fetcher()
    .then((data) => ({ data }))
    .catch((error) => ({ error }));

  if (data >= 0) return renderData({ data });
  if (error) return renderError({ error });
}

render();

La codifica per xbar è facile

L'intero processo mi ha richiesto alcune ore per essere completato, principalmente controllando l'API da xbar e giocando con diverse configurazioni per lo stile. Tutto sommato, scrivere un semplice plugin come questo non è davvero un grande sforzo che è davvero divertente da fare. Se hai qualche ora libera, dovresti provare anche tu!

Penso che ciò che parla di più per xbar sia l'opportunità di scripting che questo sviluppo flessibile e veloce consente. Puoi scrivere tracker personalizzati per le tue configurazioni cloud o servizi di analisi, in modo che le metriche siano tutte visibili a colpo d'occhio nella barra dei menu in macOS. Mi piace!