DokuWiki

It's better when it's simple

User Tools

Site Tools


tips:imap2wiki

Table of Contents

IMAP2wiki

Below you find a script that connects to an IMAP server, and posts the emails to the namespace that is in the subject line.

By this method it is possible to have people comment on things that appear in electronic newsletters, by just clicking on a link like mailto:dokuwikiposter@domain.com?subject=namespace:pagename

Regard this as experimental, and some work has to be done to this script, especially making it tamper proof. Authentication is not incorporated yet.

Please comment below if you use or adapt this script, I'd be glad to hear from you.

How to use

  1. adapt the configuration data below to match your IMAP account, replace the imapserver IP address with your own
  2. put the script somewhere on your server
  3. you may run it manually or have it run as a cronjob

Code

imap2wiki.php
<?
 
/**
 * IMAP2WIKI
 *
 * Usage:
 *
 * Gets email from imap account and adds it to a DokuWiki page
 * Typically used to give offline/email users possibility to comment on wiki contributions
 * Subject of email indicates namespace and pagename that will be used to add comments to
 * 
 * Tested with UTF-8 encoded subjects/content
 *
 * Todo :	authentication mechanism
 * Todo :	error checking for nasty situations:
				- subject is not valid wiki namespace
				- IMAP server does not respond
				- posting does not succeed
 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Riny <riny [at] bk [dot] ru>
 * @thanks	Andreas Gohr, Harry Fuecks, Christopher Arndt, Christopher Smith and DokuWiki community
  */
 
// SETUP
 
$host			="localhost";    // servername where your DokuWiki is
$dokuwikipath		="/dokuwiki/doku.php"; //path to your DokuWiki
$discussionprefix	= "discussion:";  //based on the discussion template of Esther Brunner
$imapuser		="itsmehoney"; //username to log in
$imappass		="youknowit"; //password to log in
 
 
// FUNCTIONS
 
    function _decodeHeader($input)    {
		// Original from RFC2047 routine from http://pear.php.net/manual/en/package.mail.mail-mime.php
		// Remove white space between encoded-words
        $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);
        // For each encoded-word...
        while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {
 
            $encoded  = $matches[1];
            $charset  = $matches[2];
            $encoding = $matches[3];
            $text     = $matches[4];
 
            switch (strtolower($encoding)) {
                case 'b':
                    $text = base64_decode($text);
                    break;
 
                case 'q':
                    $text = str_replace('_', ' ', $text);
                    preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
                    foreach($matches[1] as $value)
                        $text = str_replace('='.$value, chr(hexdec($value)), $text);
                    break;
            }
 
            $input = str_replace($encoded, $text, $input);
        }
 
        return $input;
    }
 
 
	function PostToHost($host, $path, $referer, $data_to_send,$targeturl) {
		  $fp = fsockopen($host, 80);
		  printf("Wiki found...\n");
		  fputs($fp, "POST $path HTTP/1.1\r\n");
		  fputs($fp, "Host: $host\r\n");
		  fputs($fp, "Referer: $referer\r\n");
		  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
		  fputs($fp, "Content-length: ". strlen($data_to_send) ."\r\n");
		  fputs($fp, "Connection: close\r\n\r\n");
		  fputs($fp, $data_to_send);
		  printf("Submitted to $host<br />");
			  while(!feof($fp)) {
				  $res .= fgets($fp, 128);
			  }
		  printf("Posted to $host</br>");
		  fclose($fp);
		  return $res;
	}
 
 
	function GetRaw($host,$dokuwikipath,$wikiid){
			// gets raw content (not authenticated)
			$filetoget="http://".$host.$dokuwikipath."?do=export_raw&id=$wikiid";
			return implode('',file($filetoget));	
	}
 
 
/////////////////////////////////////////////////////////////////////
 
// connect to IMAP server 82.62.3.23
 
$mailbox = imap_open("{83.62.3.23/imap:143}INBOX",$imapuser,$imappass);
 
// check mailbox
$check = imap_check($mailbox);
 
// check nr of messages
$noofmsg=$check->Nmsgs;
 
if ($noofmsg==0){
	echo "No messages to process";
}
 
// for every message in inbox
for ($index=1; $index<=$noofmsg; $index++){
	$header = imap_header($mailbox, $index);
	$mddate=$header->Date;
	$mdbody = imap_body($mailbox,$index);
	$mdid = base64_encode($id);
	$mdfrom = htmlspecialchars($header->fromaddress);
	$from=$header->from;
	$frommailhost=htmlspecialchars($from[0]->host);
	$frommailbox=htmlspecialchars($from[0]->mailbox);
	$mdfromemail=$frommailbox."@".$frommailhost;
 
	echo "<hr /><h3>Processing message $index : origin:  ".$mdfrom." at ".$mdfromemail."</h3><hr />";
	// $mdsubject = _decodeHeader($header->Subject);
	// Andi's snippet to decode base64 works fine as well...
 
	$mdsubjectb64= preg_replace('/=\?[\w\-]+?\?b\?(.*?)\?=/ie','base64_decode("\1")',$header->Subject);
	$mdsubjectURL=urlencode($mdsubjectb64);
 
	// Post to wiki, by adding timestamp and email body to existing wikitext
	$timestamp = date("Y-m-d at H:i:s");
	$title="Contribution by email from $mdfrom at $mddate";
	$wikiid=$discussionprefix.$mdsubjectURL;
 
	// get existing wikitext
	$oldwikitext=(GetRaw($host,$dokuwikipath,$wikiid));
 
	// compose new text to post to wiki
	echo $mdbody;
	$wikitext=$oldwikitext."\n\r----\n\rComment from [[$mdfromemail]] added at $timestamp\n\r----\n\r".$mdbody;
	$targeturl="http://$host$dokuwikipath?id=$wikiid";
	$data = "&id=$wikiid&wikitext=".stripslashes($wikitext)."&summary=$title&do=save";
 
	echo ("Posting..$data..$index<br/>");
 
	$x = PostToHost($host, $dokuwikipath,$_SERVER['remote_addr'],$data,$targeturl);
 
	// if posted successfully (no check yet!):
 
	imap_delete($mailbox, $index);
 
}
imap_expunge ($mailbox);
imap_close($mailbox);
 
?>

Discussion

I can't get this to work. I get the following message: Wiki found… Submitted to localhost Posted to localhost

But the wiki is not updated with the new info. Also i had to add /notls to the imap_server config to disable SSL connection.

– Check your serverlog if the connection has been made. Did you change the URL to match your domain? Standard replies are posted to the discussion namespace, have a look at that namespace.

  • Is there a way to connect to Gmail using this method? Thanks.
tips/imap2wiki.txt · Last modified: 2010-01-26 20:26 by 74.93.99.97

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki