Blogging without knowing…

Today I needed to setup a blog without telling its users that it’s a blog ;-)

Let me explain: a group of people need to share internal news using a kind of journal but we don’t want them to even have to think about blogging, it’s just “I’m sending news to the group” or “what happened since last time I looked”.

We could use a mailing list, but for non-geeks it might be nicer to use Movable Type (that’s what I’m used to) to archive, sort, search and otherwise organize the info. So the preferred scenario becomes: a) send mail to the journal, b) read the journal on a web page.

Problem is, blogging via email doesn’t work out of the box with Movable Type.

After looking around I found some examples of procmail to Movable Type gateways, but none was 100% ok for me. Here’s what I came up with after some fiddling, first the procmail recipe:

:0
*^TOsomewhere@yourhost.there
{
:0 fw
| /home/bdelacretaz/blog/stripmime.pl \
| /home/bdelacretaz/blogrouter/decode-headers.pl \
| /home/bdelacretaz/blog/do-post.pl
}

And here’s the Perl script that posts messages to the blog:

#!/usr/bin/perl -w
# post to Movable Type weblog, from email via procmail

use strict;
use Net::Blogger;
use Mail::Internet;

# blogger setup
my $mt = Net::Blogger->new(engine => 'movabletype');
$mt->Proxy('http://your.host.there/mt/mt-xmlrpc.cgi');
$mt->Username("email");
$mt->Password("***");
$mt->BlogId(1);

# read incoming mail
my $fh = \*STDIN;
my $msg = Mail::Internet->new($fh, 'Modify' => 0, 'MailFrom' => 'KEEP');
my @headers = @{$msg->head()->header()};
my @body = @{$msg->body()};
my $from = $msg->get('From'); chomp($from) if ($from);
my $subject = $msg->get('Subject'); chomp($subject) if ($subject);
my $cc = $msg->get('Cc'); chomp($cc) if ($cc);

my $text = "De: " . $from . "\n";

if ($cc) {
$text = $text . "Cc: " . $cc . "\n";
}

my $line = "";
foreach $line (@body) {
$text = $text . $line;
}

# post to blog
my $id = $mt->metaWeblog()->newPost(
title => $subject,
description => $text,
publish => 1
) or die $mt->LastError();

$mt->mt()->setPostCategories(
postid => $id,
categories => [{categoryId => 1}]
) or die $mt->LastError();

exit;

Cool! Like Monsieur Jourdain, these people are now blogging without knowing ;-)


Update: the above didn’t handle quoted-printable, I added the script shown below (found here with a minor correction), called after stripmime

#!/usr/bin/perl
# Script to translate quoted-printables in MIME-encoded mail messages
# Fully decodes header fields according to RFC2047
# Merges multi-line header fields into single lines

use MIME::QuotedPrint ();

undef $/; # We want to treat everything read from STDIN as one line
$input = ;
($headers, $body) = split (/\n\n/, $input, 2);

# Process the headers:
$headers =~ s/\?=\s\n/\?=\n/g; # Lines ending with an encoded-word
# have an extra space at the end. Remove it.
$headers =~ s/\n[ |\t]//g; # Merge multi-line headers into a single line.
$transheaders = '';

foreach $line (split(/\n/, $headers))
{
while ($line =~ m/=\?[^?]+\?(.)\?([^?]*)\?=/)
{
$encoding   = $1;
$txt        = $2;
$str_before = $`;
$str_after  = $';

# Base64
if ($encoding =~ /b/i)
{
require MIME::Base64;
MIME::Base64->import(decode_base64);
$txt = decode_base64($txt);
}

# QP
elsif ($encoding =~ /q/i)
{
require MIME::QuotedPrint;
MIME::QuotedPrint->import(decode_qp);
$txt = decode_qp($txt);
}

$line = $str_before . $txt . $str_after;
}
# The decode above does not do underline-to-space translation:
$line =~ tr/_/ /;
$transheaders .= $line . "\n";
}

# Process the body:
$transbody = MIME::QuotedPrint::decode($body);

# Output the combined results. We got a free \n from
# the transheaders concatenation.
print $transheaders . "\n" . $transbody;

One Response to Blogging without knowing…

  1. Morbus Iff says:

    Of interest:

    http://jeremy.zawodny.com/blog/archives/000746.html
    http://rt.cpan.org/NoAuth/Bug.html?id=2616

    Nutshell: after you assign a category to your blog entry, the entry is never rebuilt to affect that change. Editing the post (via editPost – see the URLs for an example) will rebuild the entry with the category information.

%d bloggers like this: