Написание плагина xbar для Plausible.io

Как я написал JS-плагин для приложения xbar, чтобы видеть текущее количество посетителей

Написание xbar-плагина на Javascript

В качестве проекта выходного дня я хотел написать простой плагин для xbar, приложение, с которым я недавно наткнулся. Сам xbar написан на языке программирования «Go» и использует «Wails» в качестве базовой службы, позволяющей разработчикам создавать собственные записи меню для строки меню в macOS (да, в настоящее время он ограничен только macOS).

Хорошая вещь в xbar заключается в том, что он поддерживает широкий спектр языков программирования, в том числе Javascript. Поэтому, как веб-разработчик, я хотел увидеть, насколько легко написать собственный плагин, который подключается к Plausible.io, моей аналитической службе, ориентированной на конфиденциальность. Цель состоит в том, чтобы отобразить всех текущих пользователей, которые в данный момент используют это веб-приложение. На момент написания запрос на перенос все еще находится на рассмотрении.

Image 52d29c4414ce

Image 67e4f6e5107d

Базовая настройка xbar

xbar можно просто загрузить и установить на свой Mac. После того, как вы запустите его в первый раз, экран, содержащий все загружаемые и опубликованные плагины, можно использовать для получения плагина, который вы хотите иметь.

Процесс установки просто копирует исходный код плагина (по одному файлу на плагин) в специальную папку, из которой xbar читает все установленные в данный момент плагины. Чтобы начать писать собственный плагин, вы просто создаете файл в каталоге и начинаете взламывать. Аккуратный!

соглашение об именах файлов xbar

Имя файла состоит из трех частей, разделенных точкой.

  • ваше уникальное имя плагина
  • временной интервал, в котором выполняется ваш код, аналогично CRON-заданию
  • общий суффикс файла
plausible.1m.js

Написание плагина xbar на JS

Теперь вы готовы приступить к программированию! Сначала включите необходимую директиву shebang, чтобы сообщить xbar, где должен быть найден экземпляр узла.

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

Следующая часть добавляет некоторые метаданные. Конечно, для локальной разработки это можно опустить, но вот что я использую для плагина Plausible-plugin.

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

И это все, что требуется для запуска вашего плагина. Теперь у вас есть холст, на котором вы можете писать код на чистом Javascript, выполняемый пользовательским экземпляром Node.js. Это означает, что у нас есть доступ ко всем базовым пакетам Node, таким как «https». В моем случае это все, что мне нужно, поскольку для отслеживания пользователей просто требуется выборка из API-интерфейса Plausible.io.

Следующие фрагменты кода показывают наиболее важную часть, о которой я думаю, стоит поговорить. Полный код доступен в соответствующем общедоступном репозитории по ссылке в приложении в конце этой страницы.

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

Кодировать для xbar легко

Весь процесс занял у меня несколько часов, в основном проверка API из xbar, а также экспериментирование с различными конфигурациями стилей. В общем, написание такого простого плагина, как этот, на самом деле не требует больших усилий, но это действительно весело. Если у вас есть свободные часы, вам тоже стоит попробовать!

Я думаю, что больше всего в пользу xbar говорит возможность создания сценариев, которую позволяет эта гибкая и быстрая разработка. Вы можете написать собственные трекеры для своих облачных настроек или сервисов аналитики, чтобы все показатели сразу были видны в строке меню в macOS. Мне это нравится!