Posting to WordPress MU by email

Warning: This post contains material of a technical nature, if you start reading and feel dizzy or nauseous then stop reading immediately and go and lie down.

NOTE: The code and some of the details in this article have been superseded by a later post

There are a lot of clients for the PC/Mac/Linux which allow you to post to your WordPress blog without having to log into the back end, and some might question the need to be able to send posts into your blog via email but there are several situations where you can’t use a fat client or you don’t want to use the web back end for various reasons

WordPress MU (the multi-user/multi-blog version of WordPress) supports a basic post by email feature but it involves each user setting up their account to go out to an external email address and picking up the email. This seems rather “backwards” as it means your WPMU server is having to go out to find your new posts, and if you’ve got a lot of blogs then that’s potentially a lot of outgoing POP3 requests and it means that your have got the email account and passwords for your users, which some might see as not being a very good idea. WPMU suggest using a specific account to support posting by email and keeping the account “secret”.

Surely it makes sense for the posts to be delivered to the WPMU server and processed there. This has several advantages when you think about it.

So I’ve written a new version which uses a local virtual domain and a single pop3 box.

So the user emails theirwpmuloginid@some.domain.here which ends up in a pop3 mail box on a server somewhere (preferably the same server as WPMU). Every email sent to some.domain.here arrives into one single pop3 mail box rather than being in different ones. This “catch all” account means that you don’t have to do anything clever like creating email accounts for each user as they sign up.

My process then opens that pop3 account and reads each email in turn.

It will only post if the sender email ID matches the username it is associated with (from the user table). So you have to send email from the email address you signed up with, or the email address you’ve set it to in your account settings and you have to send it to the username you use to login to the site as. This is only very basic security and I will be adding more but for the first pass of the code I felt that this was good enough to prove the principle.

So apart from allowing me to post to my blog via email what else does this “extension” provide? Well users can specify some “options” in the email which affect how their post is handled:

There are currently 4 options that they can provide:

wppbm-tags: comma separated list of tags for this post
wppbm-status: publish [default] | draft | pending
wppbm-type: post [default] | page
wppbm-comments: open [default] | closed

All of these options are optional, you do not have to provide them and if you don’t provide them then the defaults indicated will apply. WPMU developers who have played with the wp_insert_post function will probably recognise them.

Posts accepted by email will be assigned to the default category for new posts.

It currently accepts basic html marked up (bold, italic, underline) messages (either manually coded or from the rich text editor in Google mail). Yahoo marks its html messages up differently so its not working if you try to use their Rich Text Editor, and “advanced” html mark up (like font sizes etc.) don’t work from Googlemail either. Again this will be addressed in a future release.

Things that need adding are:

  • A PID field (so that people can’t just “fake” the sender email address).
  • Ability to support posting to different blogs (rather than just primary).
  • Ability to support posting from more than one email account.

So if people want to try it, and leave feedback then this is how you implement it. If you can’t edit your Postfix configuration (or don’t know how to) then I’m sorry but I can’t help you. I don’t know if other MTAs support virtual domains but if they do and you get it working then we can add those instructions.

I’ve only tested this on Linux so you’ve been warned!!!

In these instructions I’m using posts.my-dummy.domain to represent the domain we’ll be using to send emails to.

Step 1 : DNS Records
Configure your DNS records to support posts.my-dummy.domain. You need to be able to send email to this domain.

Step 2 : Create a REAL email account on your server.
However you do it you need a local email account on the server that you’ll be directing email to. In this example I’m going to call this user wpmuposts

Step 3 : Postfix Configuration
Edit your postfix main.cf file and add the following two lines:

virtual_alias_domains = posts.my-dummy.domain
virtual_alias_maps=hash:/etc/postfix/virtual

NOTE: The virtual_alias_domain MUST NOT be listed in the mydestinations configuration parameter.

Create/edit the /etc/postfix/virtual file and add the following line :

@posts.my-dummy.domain wpmuposts

Save the file, and then you need to create a hash for it using the postmap command. I do this by going to the postfix directory (/etc/postfix on my server) and typing:

postmap virtual

You may then wish to check that everything works by waiting for your DNS to propogate and then going to an external email client and sending an email to anything-here@my-dummy.domain.

You should end up with an email sitting in the POP3 email box wpmuposts. If not then you need to review your settings. There is no point in going beyond this point unless you’ve got the “catch all” email working.

OK so email is now working. That really was the hard part. The rest is pretty easy, and if you’re doing this then going in and editing a php file isn’t the sort of thing that scares you right?

Step 4 : Getting and configuring the extension

Grab a copy of post_by_mail.php and save it to your computer.

Open the file in your favourite text editor and look for the following :

// USER NEEDS TO SET THESE.
// Postfix will need configuring to support virtual domains with a wildcard to deliver to the account given below.
define ("POP3HOST","your host here");
define ("POP3PORT","110");
define ("POP3USER","special pop3 user account here");
define ("POP3PASS","special pop3 user password here");
///

and edit them to match the POP3 settings you need to access your special POP3 email account: So for example:

// USER NEEDS TO SET THESE.
// Postfix will need configuring to support virtual domains with a wildcard to deliver to the account given below.
define ("POP3HOST","localhost");
define ("POP3PORT","110");
define ("POP3USER","wpmuposts");
define ("POP3PASS","notarealpassword");
///

Save the file and then upload it to the ROOT of your WPMU installation. DON’T FORGET TO REMOVE the .TXT extension!

That’s basically it, the extension is there. If you want to give it a different name, for security reasons, then feel free to.

To test it, send an email (and I’d suggest setting the wppbm-status to draft) to yourwpmulogon@posts.my-dummy.domain. Then once its arrived call:

http://my-wp.domain.here/posts_by_mail.php

You should see some diagnostic message on the screen and hopefully, fingers crossed, you’ll end up with a new post in your blog.

So all you then need to do is set up a cron job. At the moment you can’t use the PHP CLI to run this code but you can set up a cron job to to a wget on the URL. As this isn’t a silent process I don’t recommend putting a call to it into your themes, its much better to keep it controlled by cron (and that way you can route the output to a log file to keep an eye on it).

Debugging
If you think that there are problems and you want to keep checking the same email as you add debug code to the extension then you’ll want to stop it deleting emails / posting messages.

To stop it posting into your blog look for the following line (line 241):

$post_ID = wp_insert_post($post_data);

and put a # in front of it.

To stop it deleting messages on completion look for the following code (line 256 – 262):

if(!$pop3->delete($i)) {
echo ' <p>' . sprintf(__('Oops: %s'), esc_html($pop3->ERROR)) . ' </p>';
$pop3->reset();
exit;
} else {
echo ' <p>' . sprintf(__('Mission complete. Message <strong>%s</strong> deleted.'), $i) . ' </p >';
}

and comment it out.

So there you go. Please remember that is a work in progress and support for complex HTML isn’t there and you install it at your own risk. If you’ve got any suggestions on improvements, or you’ve found a bug then please let me know.

This entry was posted in Computing and tagged , , , , , . Bookmark the permalink.

24 Responses to Posting to WordPress MU by email

  1. Scot says:

    Steve

    Definitely not for the faint of heart, but certainly something of interest to many using wpmu. I’ll give it a try and report back.

    Thx

  2. Steve says:

    As I wrote it up I realised that it sounds pretty hard but really the hard part is the postfix tweaking and a lot of people running WPMU probably are up to it, or they know someone who would understand that part of it.

    Of course you could use a POP3 account anywhere, and even use a completely different domain and just get the Domain company to do the catch all for you (JTN in the UK allow you to do mail redirection on their domains and include a catch all account).

    Steve

  3. Matt says:

    Hey Steve, this is along the lines of what I’m looking for. However, is it possible for you to add a function where people can assign the post to a specific category. Maybe an admin could let them know the specific category they should be posting in? I am in desperate need to be able to post by email to a category ?

    for example
    wppbm-cat-id: 1 [default] | 2 ,3 ,4 etc?

  4. Matt says:

    http://owa.hopepres.com/wpmublogbyemailwithcat.txt

    That is a hack by Anthony Hall to allow categorys.
    Would it be of any use? It sits in the bottom of the wp-mail.php

  5. Steve says:

    I’m actually in the middle of working on that. Its balancing where the options should be stored, should they be stored as user preferences, or should they be in blog preferences. I’m leaning towards the blog owner being able to set a default category for posts by email and the default status (published or draft) and if these can be over ridden by the user emailing in.

  6. Matt says:

    oooo nice, what’s the ETA on that if you don’t mind me asking? I’ll be lurking around hanging out for that 🙂

    • Steve says:

      I’m currently working on the dashboard admin panels, allowing the blog owner to pick a default category for posts by email and also the ability to restrict which categories people can post to, and also which members of their blog can actually post by email. Then there is a “user” settings where an individual user can set their own PID for security reasons and also nominate additional email addresses which they can post from.

  7. Matt says:

    That’s very interesting, sounds like you have it all worked out lol. I’m going to RSS the comments here so hopefully I can stay updated with your progress.

  8. Steve says:

    Its just about there now, it supports categories (textual so you don’t have to remember numbers), and the blog owner can pick a default category and optional decide which other categories people can post to. Then “users” can specify an alternative source email address and a security key to stop people “hijacking” their post.

    I’m hoping to polish it off in the next day or so and then I’ll put a new post up about it.

  9. Matt says:

    Wow steve, I was not expecting progress that fast. Either me finding this post was perfect timing or you are a very clever man.

  10. Steve says:

    Actually I’m currently unemployed and I’m using stuff like this to keep my brain working, I’m about 95% of the way there on a big rewrite of the Wordbook Plugin (which allows posting of blog entries to Facebook) – its someone else’s code but I’ve added tons of additional functionality.

  11. Matt says:

    Oh that sucks, because of the GFC im assuming? Good luck with finding employment, nice to see your spending your time contributing and helping others though.
    Will postmail support something like changing wppbm to another keyword, say ‘*userkeyword*-tags:

  12. Steve says:

    It wont at the moment, but it possibly could, its just a matter of changing where it works out which blog its using and allowing it to grab the config so it knows how to handle them.

  13. Matt says:

    oooh didnt see that link, thanks very much steve!

  14. Matt says:

    Steve also, what about usernames that have spaces? what happens if my name was ‘user name’ not ‘username’?
    Can someone send an email to user name@my.dummy etc etc and the same thing will work?

  15. Steve says:

    user names can’t have spaces in them if you look. When you sign up they are taken out. So if your blog is : myblog.mydomain.com then you’d send email to myblog@whatever.domain.here

  16. Matt says:

    Okay thanks for clearing that up

  17. Matt says:

    Steve, back again.
    Normal Web hosting agreements don’t allow access to Steps 1 and 3 and also don’t support the request to make those changes. They said however I could pipe a script: “You can however pipe a script for your emails and set them up in the forwarders section of the Mail tab of your Web Hosting cpanel.”
    Can you shed some light on this?

    • Steve says:

      I have no idea how you’d do that with Cpanel.

      I know that Just The Name (a DNS registry company in the UK) support mail forwarding which features a catch all account. Which is basically what we’re doing here – creating a single account that catches anyaddress@your.domain.here and parks it into a single account. That pop3 account doesn’t have to be on your server, it could be anywhere.

  18. Joe says:

    Hi Steve,

    I’ve been working on this for a couple days now and still can’t get it to work. When I visit to http://www.my-domain.com/post_by-email.php all I get is “POP3 quit: connection does not exist”.

    I’ve checked the POP settings over and over and w/ different accounts (incl. external like Gmail), but it’s all the same.

    I’m wondering if the Postfix part (instruction #2) is crucial to the POP connection? Due to my hosting, I wasn’t able to implement that. But in my thinking, that shouldn’t matter because the email account is set up just fine w/out it.

    I’m not sure if perhaps there is a way to print a more detailed error message that would give me some direction as to where the problem lies?

    Any help would be much appreciated!!

  19. Steve says:

    The configuration in Step2 sets up the account that we then use as the target for the virtual host “catch all”

    You are using the right POP3 port for your server aren’t you?

    Does your hosting company use Cpanel and if so does it have an “Outgoing Connections Manager”? If it does you might need to configure that to allow POP3 connections to be made.

  20. Joe says:

    Thanks so much for your quick reply! It turns out that the problem has to do with connecting to the subdomain email account I created. When I pointed your plugin to my main local email address, I connected just fine!

    Thanks for all your work on this plugin!

    -Joe

  21. Joe says:

    Hi Steve it’s Joe again. Thought I’d just point out something that tripped me up for a bit – it concerns the category names:

    On the two admin pages “Post By Email : Blog Level Options” and “Post By Email : User Level options”, when it refers to the categories that one can post to, it displays their slugs (“nicenames”). This led me to think that I should include those slugs in the email after “wppbm-categories:”. However, after some investigating found that one needs to type the category names rather than slugs to get it to work.

    I went ahead and changed my copies to display the formal category names (rather than slugs) on the 2 admin pages. To avoid confusion, I’m thinking you might want to do the same in future releases. That or change the “post_to_email.php” file to where it works with the slugs rather than the category names.

    Thanks again, everything else works well.

Comments are closed.