#If there's one that that has surprised me about getting webmentions working on the new blog it's that creating an endpoint is actually a lot easier that I initially thought. I think I had scared myself into not believing that I could make my own endpoint under the misguided impression that it was going to be beyond my limited coding knowledge.
Fuelled by yesterday's bout of positivity I thought I'd have another look but taking a different tack. Rather than thinking about it as a whole I decided to take a more granular approach and break it down.
Chris Aldrich had previously advised looking at the old versions of the WordPress webmention plugin as they were far simpler than at present. I also decided to start from first principles and check out the W3C Recommendation to check the actual specification.
I was previously conflating the mention itself with everything that goes with it (the microformats markup etc.) but looking at the spec a webmention is simply "a POST request containing the source and target parameters" - that's all. Consequently, an endpoint needs to receive that request, verify those parameters and respond to the sender accordingly. It's much easier to get your head around when you look at it like that.
So, a check on the source URL (and error response if it doesn't exist) would be something like:
if ( !isset( $_POST['source'] ) ) {
http_response_code(400);
exit ('source is missing');
}
The spec also says that the receiver must check the URLs are of supported schemes (normally http or https) - so simply check if parse_url($_POST['source'])['scheme'] equals http or https. While this is listed as a 'must' an endpoint will still function without it and other checks will likely return errors in any event were this going to fail.
The receiver "must perform an HTTP GET request on source ... to confirm that it actually mentions the target" so do this using cURL to get and test against the source content, returning an error if not.
Next up, the spec says the "source document must have an exact match of the target URL" so I perform a quick lookup in the database to confirm that the target URL resolves to a post ID.
If these checks are all passed then the endpoint sends a HTTP 202 response confirming the request has been accepted. And that's it from the actual webmention side of things.
That may look a bit long winded so here's the short version:

Are there source and target links?
Are they valid?
Does the source contain the target link?
Does the target link point to a valid item?

What happens after that, as the saying goes, is up to you and how you want to process the webmentions.
For a webmention to be really useful you want to be able to check what type of mention it is, who it's from, and what they say. I'm using mf2-php to parse the contents of the source page:
$jsonmf = new Mf2Parser($contents, $sourceURL, true);
$mf = $jsonmf->parse();
This is so handy as it translates the source page HTML into a standardised JSON array making it easier to pick out the elements like name and webmention type, for example:
$Name = $mf['items']['0']['properties']['author']['0']['properties']['name'][0];
As my 'posts' (or sections) for any given day all exist on the same page I have to go a level deeper if I mention one of my own posts:
$Name = $mf['items']['0']['children']["$s"]['properties']['author']['0']['properties']['name'][0];
(Where 'children' is the collection of 'sections' and $s selects the correct section number.)
Once the required information is collected I add a new comment to the database (using the ID found earlier as the parent post) and send myself an email notification using PHPmailer in the same way as I do for comments.
At present, I'm only checking for Likes and Replies - anything else will just show as a standard mention but I may expand this over time.