Γράφοντας ένα πρόσθετο xbar για το Plausible.io

Πώς έγραψα μια προσθήκη JS για την εφαρμογή xbar για να βλέπω τον τρέχοντα αριθμό επισκεπτών

Γράφοντας ένα πρόσθετο xbar σε Javascript

Ως έργο-Σαββατοκύριακο ήθελα να γράψω ένα απλό plugin για το xbar, μια εφαρμογή που το έπεσα πρόσφατα. Το ίδιο το xbar είναι γραμμένο στη γλώσσα προγραμματισμού "Go" και χρησιμοποιεί το "Wails" ως βασική υπηρεσία για να επιτρέψει στους προγραμματιστές να γράφουν προσαρμοσμένες καταχωρήσεις μενού για τη γραμμή μενού στο macOS (ναι, αυτή τη στιγμή περιορίζεται μόνο στο macOS).

Το ωραίο με το xbar είναι ότι υποστηρίζει μια μεγάλη ποικιλία γλωσσών προγραμματισμού, η οποία περιλαμβάνει επίσης Javascript. Ως web developer, ήθελα να δω πόσο εύκολο είναι να γράψω μια προσαρμοσμένη προσθήκη που συνδέεται με το Plausible.io, την υπηρεσία ανάλυσης φιλικών προς το απόρρητο. Ο στόχος είναι να αποδώσουν όλοι οι τρέχοντες χρήστες που βρίσκονται αυτήν τη στιγμή σε αυτήν την εφαρμογή ιστού. Από το γράψιμο, το αίτημα έλξης είναι ακόμη υπό εξέταση.

Image 52d29c4414ce

Image 67e4f6e5107d

Βασική ρύθμιση xbar

Το xbar μπορεί απλά να μεταφορτωθεί και να εγκατασταθεί στο Mac σας. Μόλις το ξεκινήσετε για πρώτη φορά, μια οθόνη που περιέχει όλα τα πρόσθετα που μπορείτε να κατεβάσετε και να δημοσιευτούν μπορεί να χρησιμοποιηθεί για να λάβετε το πρόσθετο που θέλετε να έχετε.

Η διαδικασία εγκατάστασης απλώς αντιγράφει τον πηγαίο κώδικα της προσθήκης (ένα μόνο αρχείο ανά προσθήκη) σε έναν ειδικό φάκελο, από τον οποίο το xbar διαβάζει όλα τα εγκατεστημένα πρόσθετα. Για να ξεκινήσετε να γράφετε το δικό σας plugin, απλά δημιουργείτε ένα αρχείο στον κατάλογο και αρχίζετε το hacking. Καθαρός!

σύμβαση ονόματος αρχείου 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>

Και αυτό είναι το μόνο που απαιτείται για την εκτέλεση του plugin σας. Τώρα έχετε έναν καμβά όπου μπορείτε να κωδικοποιήσετε σε καθαρό Javascript, που εκτελείται από το παράδειγμα του Node.js του χρήστη. Αυτό σημαίνει ότι έχουμε πρόσβαση σε όλα τα βασικά πακέτα κόμβων, όπως το "https". Για την περίπτωση χρήσης μου, αυτό είναι ό, τι χρειάζομαι, καθώς η παρακολούθηση των χρηστών απαιτεί απλώς ανάκτηση από το Plausible.io-API.

Τα παρακάτω κομμάτια κώδικα δείχνουν το πιο σχετικό μέρος για το οποίο νομίζω ότι αξίζει να μιλήσουμε. Ο πλήρης κωδικός είναι διαθέσιμος στο σχετικό δημόσιο αποθετήριο, σύνδεσμος στο προσάρτημα στο τέλος αυτής της σελίδας.

// 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 καθώς και παίζοντας με διαφορετικές διαμορφώσεις για στυλ. Συνολικά, το να γράψεις ένα απλό plugin σαν αυτό δεν είναι πραγματικά μεγάλη προσπάθεια που είναι πραγματικά διασκεδαστικό να κάνεις. Εάν έχετε μερικές ελεύθερες ώρες, πρέπει να το δοκιμάσετε επίσης!

Νομίζω ότι αυτό που μιλά περισσότερο για το xbar είναι η ευκαιρία σεναρίου που επιτρέπει αυτή η ευέλικτη και γρήγορη ανάπτυξη. Μπορείτε να γράψετε προσαρμοσμένους ιχνηλάτες για τις ρυθμίσεις cloud ή τις υπηρεσίες ανάλυσης, έτσι ώστε οι μετρήσεις να είναι όλες ορατές με μια ματιά στη γραμμή μενού σας στο macOS. Μου αρέσει!