Skip to content

A webmention receiver written in Python Flask with sqlite3.

License

Notifications You must be signed in to change notification settings

capjamesg/webmention-receiver

Repository files navigation

Python Webmention Receiver

This project contains the source code for a webmention receiver. There is also an endpoint for sending webmentions in this codebase.

If you have not heard of webmentions, I would encourage you to check out the IndieWeb wiki webmentions page to learn more. In short, webmentions are a way for you to send a message from one website to another. This approach lets you maintain control over your own content while also allowing you to share your content with others.

To use this project, you will need to replace all mentions of "jamesg.blog" with your own domain name in the codebase.

Screenshot

Microsub channel list

API Endpoints

The webmention receiver comes with a few API endpoints that may be useful.

Send a Webmention

The following endpoint lets you send a webmention via API. This endpoint is open to anyone, including visitors who are not authenticated with your endpoint. You may want to use this endpoint to let people submit webmentions from a form on your website.

POST /send/open

{
    "source": "https://jamesg.blog/webmention.html",
    "target": "https://jamesg.blog/post.html",
}

This endpoint will return a 201 wstatus code if the webmention was successfully sent.

Discover a Webmention Endpoint

You can use the /discover endpoint to find the webmention endpoint associated with a site, if one is specified.

POST /discover

{
    "target": "https://jamesg.blog"
}

This endpoint will return a response like:

{"success": True, "endpoint": "https://webmention.jamesg.blog/webmention"}

Get Webmentions for a Page

You can retrieve webmentions for a specific page using the API. Here is the request you need to make, where URL is the URL of the page for which you want to retrieve webmentions:

GET /received?target=URL

This endpoint will return an object like this:

{
    "count": 1,
    "count_by_property": {
        "like-of": 1,
    },
    "webmentions": [
        {
            "approved_to_show": 1,
            "author_name": "Ryan Barrett",
            "author_photo": "https://webmention.jamesg.blog/static/images/ycaoqndg.jpeg",
            "author_url": "https://snarfed.org/",
            "content_html": "likes <a class=\"u-like u-like-of\" href=\"https://jamesg.blog/2021/11/16/i-love-my-website\">I love my website | James’ Coffee Blog</a>",
            "contents": "likes I love my website | James’ Coffee Blog",
            "property": "like-of",
            "received_date": "2021-11-16 14:31:50.407750",
            "source": "https://snarfed.org/2021-11-16_i-love-my-website-james-coffee-blog",
            "status": "valid",
            "target": "https://jamesg.blog/2021/11/16/i-love-my-website",
            "vouch": null
        },
    ]
}

The "count" value tells you how many webmentions have been sent to a specific page. The webmention types that can appear in count_by_property are:

  • like-of
  • in-reply-to
  • bookmark-of
  • poke-of
  • repost-of

By default, this endpoint only returns webmentions that have been approved to show.

Webmentions are approved to show by default. However, you can hide a webmention in the admin dashboard. This may be useful for spam prevention.

You can also delete a webmention from the admin dashboard. Deleting a webmention means it will be removed from the database.

Endpoints

Here are the endpoints supported by this project:

  • / - Endpoint for receiving webmentions.
  • /home - See the webmentions you have received.
  • /sent - See webmentions you have sent.
  • /send - Endpoint to send a webmention.
  • /send/open - Open endpoint for anyone to submit a webmention to my site. Used on my "Submit a webmention" forms on my blog posts.
  • /retrieve - See webmentions you have received in JSON.

webmention.rocks Validation

webmention.rocks is being used to test compliance with the webmention specification for receiving and sending webmentions.

Vouch Support

This project is capable of sending and processing Vouch Webmentions as per the Vouch specification. The Vouch specification was designed to help prevent against spam. Vouch lets a sender specify a URL owned by a third party that will "vouch" for them. The webmention reciever checks if the "Vouch" domain is on an approved list. If the receiver trusts the vouch domain, the receiver will then go on to make sure that the specified URL links to their site. If the vouch link contains a hyperlink to the sender's URL, the specification states you can trust the webmention. Otherwise, the webmention is flagged as "needs approval".

Please refer to the IndieWeb wiki Vouch page for more information on how to send and receive a Vouch.

To configure Vouch, you will need to add all of the domains you trust to the your vouch list on the /vouch web page. These are domains from whom you will accept a vouch so long as the "vouch" URL the sender specifies links to your blog.

Sending a webmention with vouch

To send a Vouch webmention, you can specify an optional "Vouch" URL when you go to send a webmention. If one is not specified, a vouch is not sent with your webmention. Please note that not all webmention receivers will accept a vouch. Vouch is a separate specification. The Webmention spec does not require a receiver to implement Vouch support to be compliant with the spec.

Sender Discovery Compliance

This repository has passed tests in the "sender discovery" category.

Please refer to the webmention.rocks website for specifics on each of these tests and what they mean.

Reciever Tests

This application has passed the following receiver tests:

How to set up

To set up this project, first configure a Python virtual environment:

virtualenv venv
source venv/bin/activate

Then you should install the dependencies necessary to run this project:

pip install -r requirements.txt

Configuration variables

Copy the sample_config.py file into a new file called config.py. Then, adjust the variables according to your needs.

Here are the definitions of each variable:

  • RSS_DIRECTORY: The path of folder in which you want to save your RSS feed.
  • CALLBACK_URL: The place where the authentication server should send a callback response.
  • CLIENT_ID: The client ID for your application.
  • TOKEN_ENDPOINT: The IndieAuth token endpoint you are going to use for authentication.
  • AUTH_ENDPOINT: The IndieAuth authorization endpoint you are going to use for authentication.
  • ME: Your domain name that you are going to use to authenticate with the service.
  • SHOW_SETUP: Show the /setup page.
  • SECRET_KEY: Secret key for Flask.
  • WEBHOOK_SERVER: Enable this if you want to receive notifications when you get a webmention.
  • WEBHOOK_URL: The URL to which webhooks are sent.
  • WEBHOOK_API_KEY: A key you use to protect your webhook endpoint.

The other variables in sample_config.py can be left as is.

Webhook Support

This application sends a webhook to the specified webhook server with the following payload:

{"message": "You have received a webmention from SOURCE to TARGET"}

The source value is the URL where the webmention sent can be found. The target is the URL on your site to which the webmention was sent.

This stage happens when you receive a webmention, not when a webmention is validated.

Setting up the database

To set up the database for this project, execute the following command:

flask seed create-tables

The command above creates the database tables for this project.

Now you are ready to use the endpoint. To run the server, run this command:

flask run

In accordance with the webmention specification, the webmention receiver processes webmentions asynchronously. I use cron to process webmentions every hour.

To process webmentions, you should set up a cron job that executes the validate_webmention.py script. An example cron job you could use is:

0 * * * * python3 /path/to/webmention_receiver/validate_webmention.py

api-key should be equal to the value of api-key that you set in your .env file.

Configuring Automatic Webmention Sending

You can request that mentions are sent to all links in a h-feed as soon as you publish a resource on your website.

This is useful if you want people who use webmentions to get notified when you link to their content without having to manually send webmentions to each link.

You can do this by triggering the following webhook after your site has been deployed:

https://yourwebmentionendpoint.com/webhook?url=https://yourdomain.com/

This webhook can be triggered for any URL on your site that contains a h-feed.

License

This project is licenced under the MIT License.

Contributing

If you have ideas on how to make this webmention endpoint better, feel free to create an Issue for discussion on the GitHub Issues page.

Contributors

  • capjamesg

About

A webmention receiver written in Python Flask with sqlite3.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages