Best way for plugin to accept POSTs?

The problem: I’m developing a plugin which needs to accept POST data (webhooks from an external source). I do not have control over the format of the data POSTed. My only option for passing my own data is through URL arguments passed when registering the webhook.

So far I’ve come up with 3 ideas, none of which seem ideal, but two of which would definitely work (I don’t think #2 can work…). I’m hoping that there is a clean way to achieve this without hacking WordPress too badly.

  1. Point the webhook at the WP home and just listen within my plugin for the post (based on some arbitrary URL parameter I would include within the webhook). My issue with this is that going through the full generation of a WordPress page just to receive a POST is a lot more overhead than should be required.

  2. Along the way through my research I found XML-RPC, which looked promising, until I saw that it was reliant on the POST body containing invocation information. Obviously that won’t work. Is there any workaround that I am missing or is this a dead end?

  3. Posting directly to a URL within the plugin. This then requires manually bootstrapping WP. Not generally ideal…

1 Answer
1

One option is to use the add_rewrite_endpoint technique I mention in my comment.

Another option is to use the admin_post_{action} hook.

For example, you can POST data to your URL with an action GET parameter:

http://www.example.com/wp-admin/admin-post.php?action=my_plugin_action

Then hook that action via admin_post_nopriv_my_plugin_action to receive that request and process the data:

function wpd_my_plugin_action() {
    status_header(200);
    // do stuff
    echo $_POST['somedata'];
    die;
}
add_action( 'admin_post_nopriv_my_plugin_action', 'wpd_my_plugin_action' );

Both options load WordPress without running the main query and loading the template.

EDIT: To allow incoming POSTs, you must hook into the allowed_http_origin or allowed_http_origins (this filter will only work if POSTer is setting HTTP_ORIGIN), otherwise WordPress will throw out the requests before they hit your action.

Leave a Comment