• Stars
    star
    681
  • Rank 63,588 (Top 2 %)
  • Language
    Ruby
  • License
    Other
  • Created almost 12 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Easily enable webmentions and pingbacks on any web page

Webmention.io

Travis build status

This project is an implementation of the Webmention and Pingback protocols. It allows the receiving service to be run separately from the blogging software or website environment, making it easier to manage and integrate with other services.

Say you have a statically-generated website using Jekyll or something similar, you can simply add the appropriate <link> tags to this service, and now you have Webmention and Pingback enabled on your static site!

<link rel="webmention" href="https://webmention.io/username/webmention" />
<link rel="pingback" href="https://webmention.io/username/xmlrpc" />

The Webmention and Pingback protocols also support specifying the endpoint in the headers,

Link: <https://webmention.io/username/webmention>; rel="webmention"
X-Pingback: https://webmention.io/username/xmlrpc

Features

  • Accept Webmentions for any site by adding a simple html tag: <link rel="webmention" href="https://webmention.io/username/webmention" />
  • Accept Pingbacks for any site by adding a simple html tag: <link rel="pingback" href="https://webmention.io/username/xmlrpc" />
  • API to get a list of pages linking to your site or a specific page
  • If you want to receive Pingbacks on your site but don't want to deal with XMLRPC, then you can use this service to convert Pingbacks to Webmentions

API

Find links to a specific page

This service provides an API for returning a list of pages that have linked to a given page. For example:

GET https://webmention.io/api/mentions.jf2?target=https://indieweb.org

{
  "type": "feed",
  "name": "Webmentions",
  "children": [
    {
      "type": "entry",
      "author": {
        "type": "card",
        "name": "Tantek Γ‡elik",
        "url": "http://tantek.com/",
        "photo": "http://tantek.com/logo.jpg"
      },
      "url": "http://tantek.com/2013/112/t2/milestone-show-indieweb-comments-h-entry-pingback",
      "published": "2013-04-22T15:03:00-07:00",
      "wm-received": "2013-04-25T17:09:33-07:00",
      "wm-id": 900,
      "content": {
        "text": "Another milestone: @eschnou automatically shows #indieweb comments with h-entry sent via pingback http://eschnou.com/entry/testing-indieweb-federation-with-waterpigscouk-aaronpareckicom-and--62-24908.html",
        "html": "Another milestone: &lt;a href=\"https:\/\/twitter.com\/eschnou\">@eschnou&lt;\/a> automatically shows #indieweb comments with h-entry sent via pingback &lt;a href=\"http:\/\/eschnou.com\/entry\/testing-indieweb-federation-with-waterpigscouk-aaronpareckicom-and--62-24908.html\">http:\/\/eschnou.com\/entry\/testing-indieweb-federation-with-waterpigscouk-aaronpareckicom-and--62-24908.html&lt;\/a>"
      }
    }
  ]
}

Find links of a specific type to a specific page

You can include a parameter to limit the returned links to mentions of a specific type:

GET https://webmention.io/api/mentions.jf2?target=https://indieweb.org&wm-property=in-reply-to

or request multiple types by repeating the query parameter:

GET https://webmention.io/api/mentions.jf2?target=https://indieweb.org&wm-property[]=in-reply-to&wm-property[]=rsvp

The full list of recognized properties is below:

  • in-reply-to
  • like-of
  • repost-of
  • bookmark-of
  • mention-of
  • rsvp

Find links to multiple pages

This is useful for retrieving mentions from a post if you've changed the URL.

GET https://webmention.io/api/mentions.jf2?target[]=https://indieweb.org/a-blog-post&target[]=https://indieweb.org/a-different-post

Find all links to your domain

You can also find all links to your domain:

GET https://webmention.io/api/mentions.jf2?domain=indiewebcamp.com&token=xxxxx

(You will see your account's token when you sign in.)

You can optionally add a since parameter to return new webmentions as of a certain date. This is useful to poll for new webmentions you haven't seen yet.

GET https://webmention.io/api/mentions.jf2?domain=indiewebcamp.com&token=xxxxx&since=2017-06-01T10:00:00-0700

Find all links to all sites in your account

With no parameters, the API will return all links to any site in your account:

GET https://webmention.io/api/mentions?token=xxxxxx

Sorting

You can choose the sorting mechanism to return the list of mentions. The following options are supported:

  • sort-by=created (default) - Sort by the date the mention was created in the webmention.io database.
  • sort-by=updated - Sort by the updated date of the page, as seen by webmention.io (not the date the post reports in its microformats data).
  • sort-by=published - Sort by the published date as reported by the linking page. Some pages don't include published date so this will fall back to created date if published is not present.
  • sort-by=rsvp - Sort by RSVP value, in the following order: "no", "interested", "maybe", "yes".

By default, results are returned in descending order. You can control the ordering with the sort-dir parameter:

  • sort-dir=down (default) - Newest first, RSVP "yes" first
  • sort-dir=up - Oldest first, RSVP "no" first

Paging

Basic paging is supported by using the per-page and page parameters. For example,

  • ?per-page=20&page=0 first page of 20 results
  • ?per-page=20&page=1 second page of 20 results

The default number of results per page is 20. Results are always sorted newest first.

Finding New Mentions

You can use the since or since_id parameters to find new mentions retrieved by the service.

  • since=2017-06-01T10:00:00-0700 - pass a full timestamp to the since parameter to return links created after that date. This corresponds to the date the link was created in the webmention.io service, not the published date that the page reports.
  • since_id=1000 - pass an ID to return links with a greater ID

JSONP

The API also supports JSONP so you can use it to show pingbacks on your own sites via JavaScript. Simply add a parameter jsonp to the API call, for example, https://webmention.io/api/mentions.jf2?jsonp=f&target=https%3A%2F%2Fwebmention.io

Atom

You can change /mentions to /mentions.atom to receive your results in the Atom format:

GET https://webmention.io/api/mentions.atom?token=xxxxxx

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://webmention.io/api/mentions.atom</id>
  <title>Mentions</title>
  <updated>2013-04-25T17:09:33-07:00</updated>
  <link href="https://webmention.io/api/mentions.atom"/>
  <author>
    <name>webmention.io</name>
  </author>
  <entry>
    <title>tantek.com mentioned /webmention</title>
    <id>https://webmention.io/api/mention/8675309</id>
    <summary>http://tantek.com/2013/113/b1/first-federated-indieweb-comment-thread mentioned http://indiewebcamp.com/webmention</summary>
    <updated>2013-04-25T17:09:33-07:00</updated>
    <content type="xhtml" xml:lang="en">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p><a href="http://tantek.com/2013/113/b1/first-federated-indieweb-comment-thread">http://tantek.com/2013/113/b1/first-federated-indieweb-comment-thread</a> mentioned <a href="http://indiewebcamp.com/webmention">http://indiewebcamp.com/webmention</a></p>
      </div>
    </content>
  </entry>
</feed>

About the Pingback Protocol

The pingback system is a way for a blog to be automatically notified when other Web sites link to it. It is entirely transparent to the linking author, requiring no user intervention to work, and operates on principles of automatic discovery of everything that it needs to know.

A sample blog post involving pingback might go like this:

  • Alice posts to her blog. The post she's made includes a link to a post on Bob's blog.
  • Alice's blogging system contacts Bob's blogging system and says "look, Alice made a post which linked to one of your posts".
  • Bob's blogging system then includes a link back to Alice's post on his original post.
  • Reader's of Bob's article can follow this link to Alice's post to read her opinion.

Read the full protocol here: http://www.hixie.ch/specs/pingback/pingback

Pingback to Webmention Service

Webmention is a modern alternative to Pingback. It's analogous to the Pingback protocol except does not use XML-RPC and is much easier to implement. This project also includes a simple API for converting XML-RPC Pingbacks to Webmentions and forwarding the request on to your own site.

Using Webmention.io in this mode does not require an registration, and this service does not store any of the information. The Pingback request is simply forwarded on to your server as a Webmention.

To use, add a Pingback header like the following:

<link rel="pingback" href="https://webmention.io/webmention?forward=https://example.com/webmention" />

Any Pingbacks received will be forwarded on to the specified Webmention endpoint. It is up to you to handle the Webmention and return an expected result. The Webmention result will be converted to a Pingback result and passed back to the sender.

Full Example

A blog links to your site, makes a GET request for the page to retrieve the Pingback header

GET http://example.com/post/1000

<html>
  <head>
    <title>Example Post 1000</title>
    <link rel="pingback" href="https://webmention.io/webmention?forward=http://example.com/webmention" />
    ...

The blog sends a Pingback request to webmention.io

POST https://webmention.io/webmention?forward=http://example.com/webmention
Content-Type: application/xml

<?xml version="1.0" ?>
<methodCall>
  <methodName>pingback.ping</methodName>
  <params>
    <param>
      <value>
        <string>http://aaronparecki.com/notes/2013/02/16/1/little-printer</string>
      </value>
    </param>
    <param>
      <value>
        <string>http://example.com/post/1000</string>
      </value>
    </param>
  </params>
</methodCall>

The webmention.io server forwards this on to your site as a Webmention

POST http://example.com/webmention
Content-Type: application/x-www-url-form-encoded

source=https://aaronparecki.com/2013/02/16/2/little-printer&
target=http://example.com/post/1000

Your server replies with a Webmention response indicating success

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "result": "Webmention was successful"
}

Webmention.io converts this to a Pingback success reply and sends it back to the original blog

HTTP/1.1 200 OK
Content-Type: application/xml

<?xml version="1.0" ?>
<methodResponse>
  <params>
    <param>
      <value>
        <string>Pingback from https://aaronparecki.com/2013/02/16/2/little-printer to http://example.com/post/1000 was successful!</string>
      </value>
    </param>
  </params>
</methodResponse>

Errors

Webmention errors are converted to Pingback errors as well! For example,

{
  "error": "no_link_found"
}

Is converted to:

<?xml version="1.0" ?>
<methodResponse>
  <fault>
    <value>
      <struct>
        <member>
          <name>faultCode</name>
          <value><i4>17</i4></value>
        </member>
        <member>
          <name>faultString</name>
          <value>
            <string>no_link_found</string>
          </value>
        </member>
      </struct>
    </value>
  </fault>
</methodResponse>

You can start using this right now to quickly handle Pingbacks as Webmentions on your own domain. This is a way to bootstrap the Webmention protocol until more services adopt it.

Development

First, check your Ruby version. 2.0.0 does not work; details below. Try 1.9.3 or anything >=2.1.3 instead, they should work. Here are minimal instructions for Mac OS X, using Homebrew, ruby-install, and chruby:

brew install ruby-install chruby libxml2 libxslt
ruby-install ruby 2.1.6
source /usr/local/opt/chruby/share/chruby/chruby.sh
chruby 2.1.6
gem install bundler

Now, run these commands to set up your environment and start the server locally:

bundle install
cp config.yml.template config.yml
mysql -u root -e 'CREATE USER webmention@localhost IDENTIFIED BY "webmention"; CREATE DATABASE webmention; GRANT ALL ON webmention.* TO webmention@localhost; FLUSH PRIVILEGES;'
export RACK_ENV=development
bundle exec rake db:bootstrap
./start.sh

Now open http://localhost:9019/ and check that you see the front page. You can also run bundle exec rake test:sample1 to send a test pingback.

Troubleshooting

If bundle install dies like this while compiling libxml-ruby:

...
ruby_xml_node.c:624:56: error: incomplete definition of type 'struct _xmlBuf'
    result = rxml_new_cstr((const char*) output->buffer->content, xencoding);
                                         ~~~~~~~~~~~~~~^
...
An error occurred while installing libxml-ruby (2.3.3), and Bundler cannot continue.
Make sure that `gem install libxml-ruby -v '2.3.3'` succeeds before bundling.

You're in...um...a weird state. You probably have an old version of the repo checked out with a Gemfile.lock that asks for libxml-ruby 2.3.3, which is incompatible with your system's libxml2 2.9.x. HEAD fixes this by asking for libxml-ruby 2.6.0. git pull and then rerun bundle install.

If bundle install dies with this message in the middle of its error output:

/.../lib/ruby/2.0.0/tmpdir.rb:92:in `mktmpdir': parent directory is world writable but not sticky (ArgumentError)

...you can fix this with either chmod +t $TMPDIR or (better) chmod 700 $TMPDIR. Evidently this problem is common on Mac OS X.

When you open the front page, if you see an error that includes Library not loaded: libmysqlclient.18.dylib, your MySQL shared libraries may not be installed at a standard location, e.g. if you installed MySQL via Homebrew. Try DYLD_LIBRARY_PATH=/usr/local/mysql/lib ./start.sh (or wherever your MySQL libraries are located).

Ruby 2.0.0 woes

If rake db:bootstrap raises an TypeError: no implicit conversion from nil to integer exception in quoting.rb, you've hit this Ruby 2.0.0 bug/incompatibility. Use a different Ruby version.

If rake db:bootstrap hangs while attempting to create the links table , Ruby 2.0.0 strikes again! Use a different version. (You won't see progress details per table by default; it'll just hang.)

If bundle exec rake ... complains Could not find rake-10.4.0 in any of the sources, and you run bundle install and bundle check and they're both happy, and vendor/bundle/ruby/2.0.0/gems/rake-10.4.0/ exists...Ruby 2.0.0 strikes again. (Maybe?) Use a different version.

Monitoring

This server collects stats on its own, caches in Redis, and provides a Munin plugin to retrieve the stats.

Counts that are tracked, one graph for webmention, another for pingback

  • success
  • dns_error
  • connect_error
  • timeout
  • ssl_error
  • ssl_cert_error
  • ssl_unsupported_cipher
  • too_many_redirects
  • no_content
  • invalid_content
  • no_link_found
  • unknown_error

FAQ

Is there a way to replay webhooks

Q: Is there a way to replay webhooks from webmention.io?

A: In short no, however you should be able to get the same data from the API, and make sure you use the .jf2 URLs instead of .json since that's the format it uses for the webhook.

License

Copyright 2018-2022 by Aaron Parecki.

Available under the BSD License. See LICENSE.txt

More Repositories

1

Overland-iOS

πŸ“Œ GPS logger for iOS devices
Objective-C
531
star
2

oauth.net

πŸ”’ The oauth.net website. Feel free to send pull requests with updates.
PHP
267
star
3

Google-Voice-PHP-API

Unmaintaned: Please do not contact me with support requests. If this no longer works, it's because Google Voice changed their systems. I will accept pull requests that fix things. Check out http://twilio.com for a much better API for sending and receiving SMSs.
PHP
229
star
4

iMessage-Export

Archive your iMessage history to HTML, CSV or SQL
PHP
187
star
5

IndieAuth.com

This service is being discontinued in favor of indielogin.com
Ruby
182
star
6

sign-in-with-apple-example

Sample code for the Sign in with Apple API
PHP
155
star
7

indielogin.com

Sign in with your domain name
JavaScript
131
star
8

emoji-detector-php

This library will find all emoji in an input string and return information about each emoji character.
PHP
126
star
9

live-chat-overlay

Restyle the YouTube "popout chat" window so you can key it over a video to show comments on a livestream
JavaScript
124
star
10

pkce-vanilla-js

A demonstration of the OAuth PKCE flow in plain JavaScript
HTML
122
star
11

Compass

Compass is a GPS tracking server that stores data in flat files.
JavaScript
111
star
12

Quill

πŸ–‹ A Micropub client for creating posts
PHP
111
star
13

Bootstrap-Skin

Bootstrap Skin for MediaWiki. Bootstrap is an excellent toolkit by Twitter. This is a MediaWiki skin based off of that template.
JavaScript
100
star
14

OwnYourGram

πŸ“· Save your Instagram photos to your own website!
PHP
92
star
15

sample-oauth2-client

Sample OAuth2 client using the GitHub API
PHP
86
star
16

XRay

X-Ray returns structured data from any URL
PHP
85
star
17

Nautilus

Turn your website into an ActivityPub profile
PHP
76
star
18

Meetable

a minimal website for posting events
PHP
70
star
19

Aperture

Aperture is a Microsub server. Currently in beta.
PHP
67
star
20

Device-Flow-Proxy-Server

Add the OAuth 2.0 Device Flow to any OAuth server
PHP
66
star
21

Monocle

Monocle is a reader app that talks to a Microsub server
Sass
47
star
22

quick-php-authentication

Add Authentication to your PHP App in 5 Minutes!
PHP
44
star
23

Watchtower

🏰 a minimal API for watching web pages for changes, roughly speaks the WebSub protocol
PHP
43
star
24

IndieNews

πŸ“° News aggregator for IndieWeb-related posts
PHP
35
star
25

Slack-IRC-Gateway

Bridge Slack rooms to IRC channels
JavaScript
34
star
26

atem-tally-controller

C++
34
star
27

Switchboard

a WebSub / PubSubHubbub 0.4 hub
PHP
33
star
28

ssh-config-aws

Helper scripts to generate an ~/.ssh/config file automatically from one or more AWS accounts
Ruby
31
star
29

micropub.rocks

Micropub test suite and debugging utility
PHP
31
star
30

Telegraph

Telegraph is an API for sending Webmentions
CSS
31
star
31

TikTokBot

TikTokBot is a bot framework for Slack and IRC.
Ruby
28
star
32

Flickr-Archiver-Ruby

Backs up your entire Flickr stream to a local site.
Ruby
27
star
33

Swarm-Checkins-Import

Import your Foursquare/Swarm checkins to your Micropub-enabled website
PHP
26
star
34

Atlas

🌎 Atlas is a set of APIs for looking up information about locations
CSS
25
star
35

Auto-AirBnB-Entry

Sets the door code to the last 4 digits of the next guest's phone number before they arrive.
PHP
25
star
36

websub.rocks

Test suite and debug utilities for W3C WebSub
PHP
24
star
37

checks

print your own checks!
PHP
23
star
38

rating-stars

⭐️⭐️⭐️⭐️⭐️ A 5-star rating widget implemented in JS and CSS
HTML
22
star
39

OwnYourSwarm

JavaScript
21
star
40

spiderpig

πŸ•·πŸ· reduces a dynamic website into a pile of smoldering html
JavaScript
20
star
41

webmention.rocks

a webmention validator and test suite
PHP
20
star
42

command-line-oauth

A quick demo of doing OAuth from the command line
PHP
19
star
43

picofeed

PHP library to parse and write RSS/Atom feeds
PHP
18
star
44

QuartzDB

A flat-file database optimized to hold time-series data.
PHP
18
star
45

twitter-slack-stream

Stream tweets from conference attendees to a Slack channel
Ruby
16
star
46

youtube-chat-map

Show your livestream viewers on a map!
PHP
15
star
47

p3k-http

A simple HTTP client, used by https://p3k.io projects
PHP
13
star
48

p3k

This is a repository for filing issues against the software the runs my website. The source code is not public, but various components are.
13
star
49

p3k-micropub

Utilities to help handle Micropub requests when building servers and clients
PHP
12
star
50

indieauth.rocks

IndieAuth test suite - in progress
CSS
12
star
51

Teacup

β˜•οΈ Teacup is a simple Micropub app for tracking what you eat and drink
JavaScript
11
star
52

oauth-v2-1

OAuth 2.1
Shell
11
star
53

Flickr-Archivr

Download and archive your entire Flickr account as a static website
PHP
11
star
54

m5-core2-atem-controller

An ATEM controller using an M5 Core2
C++
11
star
55

Local-MediaWiki-Sync

Downloads all pages from a MediaWiki install to local text files.
PHP
11
star
56

chrome-open-tabs

Track your open Chrome tabs
JavaScript
10
star
57

clone-media-fragment

Clone the Media Fragment from the page's URL to any embedded media on the page
JavaScript
10
star
58

aperture-wordpress

A WordPress plugin to use Aperture as your Microsub endpoint
PHP
9
star
59

p3k-utils

a collection of smaller helper functions used by many of my applications
PHP
8
star
60

Squash-Reports

JavaScript
8
star
61

Geoloqi-Emergency-Beacon-Map

This application is a resource for citizens, medical teams and governments before, during and after disasters.
PHP
8
star
62

live-chat-overlay-remote

The remote window for the Live Chat Overlay browser extension
JavaScript
7
star
63

xmlrpc-micropub-bridge

XML-RPC to Micropub Bridge
PHP
7
star
64

squawk-chat

A simple website chat widget backed by IRC
JavaScript
7
star
65

p3k-websub

A library for subscribing to and publishing WebSub feeds
PHP
7
star
66

Meme-API

An API and TikTokBot integration that implements a !meme command to generate a meme image
Ruby
7
star
67

IndieAuth-Token-Endpoint

PHP
7
star
68

Loqi

Loqi is a friendly IRC bot
6
star
69

p3k-html-sanitizer

PHP
6
star
70

ca3db-ruby

Content-Addressable Avatar Archive
Ruby
6
star
71

Caterpillar

πŸ› Caterpillar is a PHP job queueing system based on beanstalkd
PHP
6
star
72

Maniac-Clock

A sticky clock that also takes screenshots
JavaScript
6
star
73

Teacup-Offline

Offline-first app for tracking food and drink posts
HTML
6
star
74

oauth-browser-based-apps

Best practices for OAuth in Browser-Based Apps
HTML
5
star
75

omniauth-indieauth

IndieAuth strategy for OmniAuth
Ruby
5
star
76

music-map

Mapping all the songs we listened to on a road trip!
JavaScript
5
star
77

IndieWeb-Development

Makefile
5
star
78

Twitter-Archive-to-CSV

Convert your Twitter archive to a CSV file
PHP
5
star
79

esp-badge

esp32 with e-paper display
C++
5
star
80

microsub.rocks

PHP
4
star
81

BarBot

🍸
C++
4
star
82

MediaWiki-Changelog-Graphs

Adds a special page showing a chart of wiki edits broken down by day, hour and month
4
star
83

PushupCounter-iOS

A silly app that counts pushups when you touch your nose to your phone
Objective-C
4
star
84

twtr

Algorithmic Twitter URL shortener
CSS
4
star
85

p3k-timezone

Look up the timezone given a latitude and longitude
PHP
4
star
86

curly

curly: A wrapper for `curl` which pretty-prints JSON output
Ruby
4
star
87

php-multipart-encoder

Multipart encoder for PHP
PHP
4
star
88

Gramophone

a Micropub client for publishing podcasts
PHP
4
star
89

blade-markdown-directive

adds a `@markdown` Blade directive for use in Laravel views
PHP
3
star
90

MediaWiki-Github-Issues

Render a list of Github issues in a wiki page
3
star
91

gnap-client-php

Sample GNAP client in PHP
PHP
3
star
92

reserved-usernames-php

A list of reserved usernames to prevent url collision with resource paths. Packaged as a Composer library. Source data: https://github.com/shouldbee/reserved-usernames
PHP
3
star
93

Crosswalk-Photo-Booth

Shell
2
star
94

IndieWeb-Reply-Browser-Extension

A browser extension to intercept existing silos' "reply" buttons to post from your own site instead
JavaScript
2
star
95

automatic-indieauth-example

PHP
2
star
96

tz_world

A GeoJSON file of the TZ timezones of the world
Shell
2
star
97

discourse-disqus-oauth

Log in to Discourse with your Disqus account
Ruby
2
star
98

Airplane-Time

stretch time while flying between timezones - a progressive web app
HTML
2
star
99

IndieAuth-Client

Sample client app to authenticate against IndieAuth-enabled domains
PHP
2
star
100

ChatterCast-Seattle

Receive real-time 911 alerts from Seattle's open data feed. Works with Geoloqi.
PHP
2
star