Juha-Matti Santala
Community Builder. Dreamer. Adventurer.

Webmention bookmarklet

Lately, I’ve been having some issues with automated Webmention sending tools so I’ve been sending a bunch of mentions manually with curl which can be a bit cumbersome.

The flow with sending them manually normally looks like this:

  1. Open my blog post
  2. Go through each link
  3. For each link, inspect the page source and search for rel=”webmention” element
  4. Copy my source post URL, add to curl command, then copy the target URL, add to curl command and finally copy the rel=”webmention” URL and add to curl

With my new Webmention bookmarklet, I get the entire 2a and two-thirds of the 2b of the workflow above for free with a click of a button.

What the bookmarklet does is that it searches for rel="webmention" link and if one exists, it grabs that and the URL of the page and crafts them into curl command that I can just paste into the terminal. If not, it’ll give me an alert so I know I can continue to next link.

So the new flow now looks like:

  1. Open my blog post
  2. Go through each link
  3. For each link, click my bookmarklet
  4. If webmention endpoint is found, a text of -d target="website url" webmention_endpoint gets added to clipboard
  5. Write curl -i -d source="my url" and hit paste and hit enter

Here’s the bookmarklet

(() => {
  const copy = () => {
    const textArea = document.createElement("textarea");
    const webmention = document.querySelector('link[rel="webmention"]')
    if(webmention) {
			const href = webmention.href
	
			const url = window.location;
			
	    textArea.value = `-d target="${url}" ${href}`;
	    textArea.style.top = "0";
	    textArea.style.left = "0";
	    textArea.style.position = "fixed";
	    document.body.appendChild(textArea);
	    textArea.focus();
	    textArea.select();
	    try {
	      document.execCommand("copy");
	    } catch (err) {
	      console.error("Copying err", err);
	    }
	
	    document.body.removeChild(textArea);
    } else {
	    alert('No webmention endpoint')
    }
  };

  copy();
})();

and minified to be copied to a new bookmarklet’s URL field:

javascript:(function()%7B(()%20%3D%3E%20%7B%0A%20%20const%20copy%20%3D%20()%20%3D%3E%20%7B%0A%20%20%20%20const%20textArea%20%3D%20document.createElement(%22textarea%22)%3B%0A%20%20%20%20const%20webmention%20%3D%20document.querySelector('link%5Brel%3D%22webmention%22%5D')%0A%20%20%20%20if(webmention)%20%7B%0A%20%20%20%20%20%20const%20href%20%3D%20webmention.href%0A%0A%20%20%20%20textArea.value%20%3D%20href%3B%0A%20%20%20%20textArea.style.top%20%3D%20%220%22%3B%0A%20%20%20%20textArea.style.left%20%3D%20%220%22%3B%0A%20%20%20%20textArea.style.position%20%3D%20%22fixed%22%3B%0A%20%20%20%20document.body.appendChild(textArea)%3B%0A%20%20%20%20textArea.focus()%3B%0A%20%20%20%20textArea.select()%3B%0A%20%20%20%20try%20%7B%0A%20%20%20%20%20%20document.execCommand(%22copy%22)%3B%0A%20%20%20%20%7D%20catch%20(err)%20%7B%0A%20%20%20%20%20%20console.error(%22Copying%20err%22%2C%20err)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20document.body.removeChild(textArea)%3B%0A%20%20%20%20%7D%0A%20%20%7D%3B%0A%0A%20%20copy()%3B%0A%7D)()%3B%7D)()%3B