Localghost
choose a theme

Sending webmentions from a static site

Sophie Koonin

It occurred to me this week that even though I’ve been using webmentions as comments for a really long time, I hadn’t actually been sending them myself. The shame! Here's how I set it up.

Edit 22/01/23: I've added in some checks to make sure I don't send webmentions for a post if I've already done it before.

Certified good egg Remy Sharp has a tool called webmention.app which will send webmentions for you – you CURL it with the URL of your post, and it’ll search through it for any links and check to see if the owners of those sites have webmentions or pingbacks set up. There’s also an npm package, @remy/webmention, which you give an RSS feed and it does the same thing. That’s the version I’ve used.

You can add it as the postbuild script in package.json, so it’ll run after every yarn build.

"scripts": {
    "postbuild": "webmention _site/feed.xml --limit 1 --send"
},

I was concerned that if my build runs every 12 hours, it’ll keep sending webmentions for the same posts. Remy assures me that duplicate webmentions aren’t an issue, as the accepting server will just respond with a 200 if I send a webmention that it’s already seen. However, if you build your site very often you might be at risk of nearly DOS-ing the websites you're sending mentions to. To get around this, you could:

  • write a script that runs the webmention CLI but only after checking the post timestamp of the last post to see if it's recent enough
  • keep a record somehow of the last post you sent webmentions for, e.g. in a text file in the repo
  • check the message from the last commit and only send the webmentions if you mention "new post" or similar

To be super safe, I've added it as a script in package.json but I'm calling it from within a bash script that checks the commit hash for the last commit, and records whether or not I've sent webmentions for that commit already.

#! /usr/bin/env bash

if ! test -f ./last_webmentions_commit; then
  echo "Last webmention commit file not found, exiting"
  exit 1
fi

# Read the contents of the file
LAST_COMMIT_SENT=$(cat ./last_webmentions_commit)

# Get latest commit hash
LATEST_COMMIT=$(git rev-parse --short HEAD)

# If the last commit hash I sent webmentions for is
# the same as the latest commit hash, exit
if [[ $LAST_COMMIT_SENT == $LATEST_COMMIT ]]; then
  echo "No new commits since we last sent webmentions, nothing to do"
  exit 0
fi

# Get the last commit message
LAST_COMMIT_MESSAGE=$(git log -1 --pretty=%B)

# Does the commit message contain 'post'?
if ! [[ $LAST_COMMIT_MESSAGE == *"post"* ]]; then
  echo "Last commit message does not contain 'post', nothing to do"
  exit 0
fi

# Update the file with the latest commit hash
echo $LATEST_COMMIT > ./last_webmentions_commit

yarn send-webmentions

When I write a new post, I always use the word "post" in the commit message, so this will help distinguish which commits we need to send webmentions for.

Now, every time I build and deploy my site, the script will send webmentions to anyone I’ve mentioned in the last post I wrote, as long as I haven't already sent webmentions for that post and the recipients have the webmention meta tags set up!

Webmentions

Comments

  1. Tamas
    @sophie @rem Heh. If a site sending and recieving async requests, is it still static in a HTML way?
  2. Bob Monsour
    @sophie @rem Thank you both for solving the next step in my webmentions journey. Only my postbuild has to both build a pagefind index and now send out WMs. All good.
  3. Juhis
    @sophie This is brilliant! I really need to add this to my workflow.
  4. TinheadNed
    @sophie @rem I've been using Hugo to write a blog but webdev is not my speciality. Webmentions look like a neat way of linking into the fediverse but perhaps a bit a bit too much to bite off? Incoming shown on the webpage at least. Grateful for your thoughts.
  5. Sophie
    @tinheadned @rem I recommend leaning on libraries and services that do a lot of the heavy lifting for you. Eleventy has a plugin for webmentions and I’d be surprised if there isn’t one for Hugo.