Écrire un plugin xbar pour Plausible.io

Comment j'ai écrit un plugin JS pour l'application xbar pour voir le nombre actuel de visiteurs

Ecrire un plugin xbar en Javascript

En tant que projet de week-end, je voulais écrire un simple plugin pour xbar, une application sur laquelle j'ai récemment trébuché. xbar lui-même est écrit dans le langage de programmation "Go" et utilise "Wails" comme service sous-jacent pour permettre aux développeurs d'écrire des entrées de menu personnalisées pour la barre de menus dans macOS (oui, il est actuellement limité à macOS uniquement).

La bonne chose à propos de xbar est qu'il prend en charge une grande variété de langages de programmation, qui incluent également Javascript. En tant que développeur Web moi-même, je voulais donc voir à quel point il est facile d'écrire un plugin personnalisé qui se connecte à Plausible.io, mon service d'analyse respectueux de la vie privée. L'objectif est de rendre tous les utilisateurs actuels qui sont actuellement sur cette application Web. Au moment de la rédaction, la demande de tirage est toujours en cours d'examen.

Image 52d29c4414ce

Image 67e4f6e5107d

Configuration de base de la barre x

xbar peut simplement être téléchargé et installé sur votre Mac. Une fois que vous le lancez pour la première fois, un écran contenant tous les plugins téléchargeables et publiés peut être utilisé pour obtenir le plugin que vous souhaitez avoir.

Le processus d'installation copie simplement le code source du plugin (un seul fichier par plugin) dans un dossier spécial, à partir duquel xbar lit tous les plugins actuellement installés. Pour commencer à écrire votre propre plugin, il vous suffit de créer un fichier dans le répertoire et de commencer à pirater. Soigné!

convention de nom de fichier xbar

Le nom du fichier se compose de trois parties, toutes séparées par un point.

  • votre nom de plugin unique
  • l'intervalle de temps dans lequel votre code est exécuté, similaire à un travail CRON
  • le suffixe de fichier commun
plausible.1m.js

Codage d'un plugin xbar en JS

Vous êtes maintenant prêt à commencer à coder ! Incluez d'abord la directive shebang requise pour indiquer à xbar où l'instance de nœud doit être trouvée.

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

La partie suivante consiste ensuite à ajouter des métadonnées. Bien sûr, pour le développement local, cela peut être omis, mais voici ce que j'utilise pour le plugin 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>

Et c'est tout ce qui est nécessaire pour que votre plugin s'exécute. Vous avez maintenant un canevas où vous pouvez coder en Javascript pur, exécuté par l'instance Node.js de l'utilisateur. Cela signifie que nous avons accès à tous les packages Node principaux, tels que "https". Pour mon cas d'utilisation, c'est tout ce dont j'ai besoin, car le suivi des utilisateurs nécessite simplement une récupération à partir de l'API Plausible.io.

Les morceaux de code suivants montrent la partie la plus pertinente dont je pense qu'il vaut la peine de parler. Le code complet est disponible dans le référentiel public associé, lien dans l'addendum à la fin de cette page.

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

Le codage pour xbar est facile

L'ensemble du processus m'a pris quelques heures, principalement en vérifiant l'API à partir de xbar et en jouant avec différentes configurations de style. Dans l'ensemble, écrire un plugin simple comme celui-ci n'est vraiment pas beaucoup d'efforts qui est vraiment amusant à faire. Si vous avez des heures libres, vous devriez aussi l'essayer!

Je pense que ce qui parle le plus pour xbar, c'est l'opportunité de script que ce développement flexible et rapide permet. Vous pouvez écrire des trackers personnalisés pour vos configurations cloud ou vos services d'analyse, afin que les métriques soient toutes visibles en un coup d'œil dans votre barre de menus dans macOS. Je l'aime bien!