Escribiendo un complemento xbar para Plausible.io

Cómo escribí un complemento JS para la aplicación xbar para ver el número actual de visitantes

Escribir un complemento xbar en Javascript

Como proyecto de fin de semana, quería escribir un complemento simple para xbar, una aplicación con la que me encontré recientemente. xbar en sí está escrito en el lenguaje de programación "Go" y utiliza "Wails" como su servicio subyacente para permitir a los desarrolladores escribir entradas de menú personalizadas para la barra de menú en macOS (sí, actualmente está limitado solo a macOS).

Lo bueno de xbar es que admite una amplia variedad de lenguajes de programación, que también incluye Javascript. Como desarrollador web, quería ver lo fácil que es escribir un complemento personalizado que se conecte a Plausible.io, mi servicio de análisis amigable con la privacidad. El objetivo es representar a todos los usuarios actuales que se encuentran actualmente en esta aplicación web. Al momento de escribir, la solicitud de extracción aún está en revisión.

Image 52d29c4414ce

Image 67e4f6e5107d

Configuración básica de xbar

xbar simplemente se puede descargar e instalar en su Mac. Una vez que lo inicie por primera vez, se puede usar una pantalla que contiene todos los complementos descargables y publicados para obtener el complemento que desea tener.

El proceso de instalación simplemente copia el código fuente del complemento (un solo archivo por complemento) en una carpeta especial, desde la cual xbar lee todos los complementos instalados actualmente. Para comenzar a escribir su propio complemento, simplemente cree un archivo en el directorio y comience a piratear. ¡Limpio!

Convención de nombre de archivo xbar

El nombre del archivo consta de tres partes, todas separadas por un punto.

  • su nombre de complemento único
  • el intervalo de tiempo en el que se ejecuta su código, similar a un trabajo CRON
  • el sufijo de archivo común
plausible.1m.js

Codificación de un complemento xbar en JS

¡Ahora está configurado para comenzar a codificar! Primero incluya la directiva shebang requerida para decirle a xbar dónde se debe encontrar la instancia del nodo.

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

La siguiente parte es agregar algunos metadatos. Por supuesto, para el desarrollo local esto se puede omitir, pero esto es lo que estoy usando para el complemento Plausible.

// 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>

Y eso es todo lo que se requiere para que se ejecute el complemento. Ahora tiene un lienzo donde puede codificar en Javascript puro, ejecutado por la instancia Node.js del usuario. Esto significa que tenemos acceso a todos los paquetes principales de Node, como "https". Para mi caso de uso, esto es todo lo que necesito, ya que el seguimiento de los usuarios simplemente requiere una búsqueda de Plausible.io-API.

Los siguientes fragmentos de código muestran la parte más relevante de la que creo que vale la pena hablar. El código completo está disponible en el repositorio público relacionado, enlace en el apéndice al final de esta página.

// 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();

Codificar para xbar es fácil

Todo el proceso me llevó unas horas completarlo, principalmente verificando la API de xbar y jugando con diferentes configuraciones de estilo. Con todo, escribir un complemento simple como este realmente no es mucho esfuerzo y es realmente divertido de hacer. Si tienes algunas horas libres, ¡deberías probarlo también!

Creo que lo que más habla de xbar es la oportunidad de creación de scripts que permite este desarrollo rápido y flexible. Puede escribir rastreadores personalizados para sus configuraciones en la nube o servicios de análisis, de modo que las métricas sean visibles de un vistazo en su barra de menú en macOS. ¡Me gusta esto!