WikiBox
Questions answered by this recipe
- How can I post to wiki pages via email?
- How can I upload a file by sending it as an attachment in an email?
- How can I get the contents of a page (source or HTML) via email?
Description
Allow posting to and reading from PmWiki pages via email.
Hey! There's an ongoing alpha (actually probably it's up to beta by now) test going on over at www.qdk.org. If you're interested in taking part (or at least seeing what wikibox looks like in real life) feel free to check it out. You can send an email to wikibox@qdk.org with the subject "usage" to get a broad overview. Or you can go and visit http://www.qdk.org/pmwiki/pmwiki.php?n=WikiBox.WikiBox if you want to see a really quick overview of how the testing is organized, what pages are involved, etc.
Installation
- Download wikibox.phpΔ
- Download 3 dependencies: toolbox.phpΔ wikimail.phpΔ SecLayer.phpΔ
- Place all 4 files in your cookbook directory and put a section in you config.php like this:
include_once("$FarmD/cookbook/toolbox.php"); include_once("$FarmD/cookbook/SecLayer.php"); include_once("$FarmD/cookbook/wikibox.php"); include_once("$FarmD/cookbook/wikimail.php"); $wbModerator = 'moderator@localhost'; // replace this with the email address of the moderator // you can also make it an array of addresses if more than 1 # Normally this call to wmMkProfilePOP3() would be on a single line wmMkProfilePOP3('wikibox', //name of the profile - must be wikibox unless you change $wbPOP3Profile 'pop3.mydomain.com', // host where WikiBox will pick up mail 'myusername', // username WikiBox will use to pick up mail 'secret'); // password WikiBox will use to pick up mail # There are several other optional parameters you can also set in the profile, but these 3 usually suffice
Note the need to edit the moderator address from the current moderator@localhost
to whatever you will use.
- Create a page SiteAdmin.WikiBoxPageAuth giving authorization to the pages you are interested in. The following would give full permission to any files in the Test group:
all=overwrite,insert,create,read edit = overwrite, create, insert Test.*:all
- Create a page SiteAdmin.WikiBoxEmailAuth defining at least 1 email address who will be a moderator (the email address must match what will be received in the "From" field of an email from this person and the "xyz" should be replaced with the wikibox-passwd for this person, a non-vital password used to verify)
moderator@localhost:::1:0:xyz::::::
Make SURE that you replace moderator@localhost
above with the same address you used in $wbModerator above! And you might want a slightly better password than xyz, but that's up to you... :-)
- Place the markup (:wikibox PROCESS verbose=2:) on a page (optional
(:messages:)
markup on the same page). You can choose whatever page you want, but WikiBox.Check is the standard.- You can make verbose be 1 or leave it out together - it depends how much information you want.
(:messages:)
gives lots of information (probably more debugging level) whereas verbose=2 is pretty reasonable and helpful.
- You can make verbose be 1 or leave it out together - it depends how much information you want.
- Security defaults can be modified as follows (choose one of the latter 2 options if you don't like the default):
$wbControl['Write'] = array('Receive', 'UserConfirm','Moderate','Complete'); // default $wbControl['Write'] = array('Receive', 'UserConfirm','Complete'); // no moderator requirement $wbControl['Write'] = array('Receive', 'Complete'); // no moderator nor user confirmation requirement
- You can also change $wbControl['Usage'], $wbControl['Subscribe'], $wbControl['Unsubscribe'], $wbControl['Blacklist'], $wbControl['Write'], and $wbControl['Read']
- A finer degree of configuration control can be achieved by modifying the $wbRequire[] and $wbPrepFor[] arrays, but that'll have to be documented another day.
- You will want to have your WikiBox.Check page loaded on a regular basis. For this you will need some way of automatically loading a web-page on a given schedule (i.e., every 10 minutes during work hours, every hour at night and during weekends - something like that).
Cron
andwget
are tools in a linux environment which accomplish this admirably. To run the beta test at www.qdk.org I used this script (named /usr/local/bin/checkqdk and given executable privileges):
echo "Checking..." wget -N --no-cache -E "http://www.qdk.org/pmwiki/pmwiki.php?n=WikiBox.Check" >/dev/null 2>&1 #sed -n -e 's/<[^>]*>//g' -e '/WIKIBOX PROCESSING/,/WIKIBOX COMPLETE/p' pmwiki.php\?n\=WikiBox.Check.html
(The last line is useful if you are running it from the command line rather than through CRON -- if you remove the "#" at the start of that last line then it will give you a quick summary of the output of wikibox during the run.)
Then in /etc/crontab you would need entries like this:
# Every 15 minutes between 8am and 5pm Mon-Fri 0,15,30,45 8-17 * * 1-5 root /usr/local/bin/checkqdk # Every 30 minutes before 8am and after 5pm Mon-Fri 0,30 0-8,17-23 * * 1-5 root /usr/local/bin/checkqdk # Every hour on weekends 0 0-23 * * 6-7 root /usr/local/bin/checkqdk
Obviously you would need to determine what schedule worked for you.
Do note that while this cron job can be on the hosting server it by no means must be on that machine. You can run that script from a home machine, from your friend's machine that has linux on it, etc. The only requirements are (a) the machine has to keep running, (b) it has to be a machine with cron (usually linux although cygwin might have something for windows?) and (c) it has to have network access to your site (usually this means simply being connected to the internet).
Notes
Emails consist of a subject and the body of the email. For WikiBox the subject becomes a command specifying where and how the body of the email should be placed on a given page. The body of the email should be plaintext as it will be inserted into the page character-for-character as it appears in the body of the email.
Various valid initiating commands (placed in the subject) follow:
- usage
- No security or confirmation is required - a simple usage message will be returned by reply mail
- subscribe
- Security currently requires a user confirmation and a moderator confirmation
- When all security requirements have been met then the original sending email will be added to SiteAdmin.WikiBoxEmailAuth
- unsubscribe
- Security currently requires a user confirmation
- When all security requirements have been met then the original sending email will be marked as inactive in SiteAdmin.WikiBoxEmailAuth
- blacklist
- Security currently requires a user confirmation
- When all security requirements have been met then the original sending email will be marked as blacklisted in SiteAdmin.WikiBoxEmailAuth
- Write to
[[Test.Foo]]
- Overwrite
[[Test.Foo]]
- Append to
[[Test.Foo]]
- Prepend to
[[Test.Foo]]
- Insert into
[[Test.Foo]]
after /this pattern/i - Insert into
[[Test.Foo]]
before /this pattern/ - Insert into
[[Test.Foo]]
replacing /this pattern/ - Insert into
[[Test.Foo]]
instead of /this pattern/- Security for all write operations by default requires a user confirmation and a moderator confirmation
- When all security requirements have been met then the body of the email will be written to the page specified in the location indicated
- Read from
[[Test.Foo]]
ruleset=source|text|full fmt=html|text|both- Security for read operations by default requires appropriate password authentication on the initiating email
- When all security requirements have been met then the page requested will be returned by return email
- options of ruleset=x and fmt=x are optional
- ruleset=source - return the unmodified source of the page
- ruleset=text - run , (:comment:), and (:include:) rules so you get a better representation of the text of the page
- ruleset=full - fun all markup rules (Better set fmt=html)
Each write command is made up of a main command, optional filler words, a pagename, and then (if the main command was "insert") a location and a pattern.
Main Write Commands
- "Write" and "Overwrite" and "Replace" are synonyms. They will create a page if it doesn't exist or overwrite any existing content if the page already exists.
- "Append" adds the body of the email at the end of any existing text in the page (or creates the page if it doesn't exist)
- "Prepend" adds the body of the email prior to any existing text in the page (or creates the page if it doesn't exist)
- "Insert" allows the placement of the text in the email body relative to some pattern in the existing text on the page. If "Insert" is the main command then you must specify a location sub-command and a pattern
- Location Subcommand
- "after" - find the pattern and insert the text immediately following
- "before" - find the pattern and insert the text immediately prior to the pattern
- "replacing" (or, synonymously, "instead of") replaces the pattern with the body of the email
- Pattern
- The pattern can be any valid regex that preg_match would accept. Pattern modifiers (i, m, s, etc.) are valid as well.
- Patterns should be unique on the page or the text of the email body will be inserted multiple times, once for each time the pattern is matched.
- Location Subcommand
Filler words
Filler words like "on", "in", "to", "into", "at the top of", "at the bottom of", etc between the main command and the name of the page are optional and ignored. They just make the command a little more readable. Do note that the filler words are really ignored. "Insert at the top of [[Page]]
" is *not* the equivalent of "Prepend to [[Page]]
" -- the former will still require a location subcommand and a pattern and the fact that you said "at the top of" will be completely ignored.
Page
The page must be specified as [[Group.Page]]
. It is required. This is the page into which the text in the body of the email will be placed.
Email Body
Text only at the current time. I suppose it goes without saying, but markup is text, so any valid pmwiki markup can be placed in the body of the email.
If you send HTML or some other format email then only the text portion will be pulled out. If you want to format your page, put pmwiki markup in your text.
Attachments can be automatically uploaded to whatever page is being written to (only valid on a request that writes to a page). Simply follow these instructions:
- Attach the file, taking note of the exact spelling of the filename
- Include the text
wikibox-attach:FILENAME
on a line by itself in the body of your email (make sure you get the exact spelling and case of the filename). This line will not be written to the page, but it indicates that that attachment was something you intentionally wanted to upload. - Often you will want to include an "Attach:FILENAME Δ" markup as well, but this is up to you -- it keeps you from having an "orphaned" upload with no links to it...
- Assuming your wikibox account has a password (as it should) then make sure you don't forget to specify that as well
Following the examples above, here is an email you could send with an attachment named "prettypicture.jpg":
SUBJECT: write to [[Test.ShowThePicture]]
wikibox-passwd:mysecretpass wikibox-attach:prettypicture.jpg Hey! Take a look at this pretty picture! Attach:prettypicture.jpg (Everything below this line is just for fun to show the possibility that other markup can be included and written to the page -- the 1st 3 lines above, in combination with the subject and the attachment, are what are required to make uploading via attachment work.) * and ** a *** list '''boldfaced''' and ''italicized'' text [[Test.Link|+]] to put a link and any other markup I would like to do
Markup / Usage
Wikibox does nothing until the page with the appropriate markup on it is loaded. The markup used is (:wikibox:)
with possible arguments (notably (:wikibox PROCESS verbose=2:)
which would be the norm). Currently emails will be processed only when this page is loaded ("PROCESS" is a required argument). Errors will be logged to SiteAdmin.WikiBoxErrorLog - this page should be checked periodically, particularly if you are not getting expected results. If you are really having trouble you can set $DebugLevel=2
and make sure (:messages:)
markup exists on your page - then you'll need to attempt to work through the debug trace statements.
If you wish to place a signup form on a page somewhere (WikiBox.Signup is the standard and recommended) then simply create that page and place (:wikibox SIGNUP:)
as the sole markup on that page. Users will then have the capability of going there to sign up for a wikibox account (as an alternative to sending a message to the main wikibox address for your site with the subject "subscribe" and then being moderated and etc.).
Note that the authorization of the user loading the page with the (:wikibox:)
markup is irrelevant -- each email address is linked to a set of authorizations (passwords that are in memory at the time the user signed up through the form interface). Those authorizations (belonging to the email address user) will temporarily replace the authorizations of the real user who is loading the page. This makes it possible for an administrator to load the page without fear that an illicit operation might occur as well as allowing a privileged user to make changes (or request privileged reads) without requiring that the page be loaded by someone with those specific privileges.
Release Notes
- 2008-08-17 Lots of little bug fixes and improvements. We've arrived at pretty good stability. Biggest change here is mime capability and thus capability of handling attachments and receiving HTML email. Also if the user signs up using the form interface a snapshot of their current authorizations will be made and that will be used for any future read/edit operations from that email address.
- 2008-08-08 Release to keep in sync with wikimail. Other general improvements, bug fixes, etc.
- 2008-08-02 Minor release to correspond with function namechange in wikimail. Realized documentation here is 2 versions back and completely wrong :-(
- 2008-06-15 Implemented reject commands with deletion of inbox. Allow empty passwd to not be checked. Setting of expected sender for moderator.
- 2008-06-12 Completely recoded, redesigned, etc. Still only plaintext email allowed and no attachment support. Much better granularity & configurability on security, etc.
- 2008-05-18 Initial release. Only plaintext email allowed, no attachment support.
See Also
Contributors
Roadmap
- Document how to run markup via cron so people can use that. (Is it just wget?)
- Reimplement the form interface (no longer working)
- In the form go on to the next page of messages automatically instead of requiring the user to click next.
- Figure out SASL and document that.
- Allow a validation on any header element (i.e.,
$ValidHeaders['from'] = array('me@mydomain.com', 'you@yourdomain.com');
) - Allow a processing option of a few seconds each page-load (maybe once ever n seconds?) in addition to the form-based interface and the cron-based interface... This would work somewhat like the current processing of ImportText or updating the page cache.
Comments
In my config.php, the line calling wmMkProfilePOP3 seems to be problematic. My wiki goes blank and ceases to funtion (HTTP 500 Internal Server Error) when it is present. I have checked it several times and also used the lines copied directly out of this page - which, though incorrectly configured, should still produce a functional site. What could be wrong? How do I test it? DavidBessler February 27, 2009, at 08:49 AM
I figured it out. I'm using PHP5 on a standard godaddy hosting account, by the way. I turned on error reporting on my php5.ini file, and saw that php was not finding the cookbook files. I replaced the single quotes around the path names in the include_once statements in config.php with double quotes--like the rest of my include_once statements, and it worked. DavidBessler March 03, 2009, at 08:21 AM
Now I'm getting the following error: wbWriteToPage(): RetrieveAuthPage() Failure. Returning FALSE DavidBessler March 03, 2009, at 09:11 AM
Can I not use wikibox with password-protected pages? DavidBessler March 03, 2009, at 01:46 PM
Brilliant! Got it working. Now I have to work on my CRON script. This will revolutionize my journaling. I'll try to tidy up the documentation.DavidBessler
I keep getting this error with my cron script:
/home/content/a/b/c/abcusername/html/abcusername/wiki/mywikipostchecker: line 2: 1 : ambiguous redirect
(I've anonymized the path and filename) Any ideas? DavidBessler March 03, 2009, at 09:57 PM
For some reason, trying to cron the script directly yields a "file not found" error which I couldn't get past. I used the script/wget method with just:
wget "http://wiki.xxxxxxxx.com/pmwiki.php?n=WikiBox.Check"
and that is working. So now, it looks like I have the whole thing set up. Thanks so much for your help. DavidBessler March 04, 2009, at 02:32 AM
- How can I specify a remote SMTP host (with appropriate login info for it) instead of relying on a local transport? tamouse June 13, 2011, at 08:15 PM
$WikiMailSMTP
. If that doesn't work let me know and I'll look into it in more detail.
I must have messed up the config somehow. The mails being sent to the user or the moderator for action are being sent with the From: and Reply-to: set to _www@portfolio.paladin.local, which my local web server on my mac. Shouldn't this be set to the mailbox WikiBox.Check looks at instead?
Here's my config.php section:
## Adding stuff for wikibox - to allow addition of wiki pages by email ## http://www.pmwiki.org/wiki/Cookbook/WikiBox include_once("$FarmD
/cookbook/toolbox.php"); include_once("$FarmD
/cookbook/SecLayer.php"); include_once("$FarmD
/cookbook/wikibox.php"); include_once("$FarmD
/cookbook/wikimail.php"); $wbModerator = 'tamara@localhost'; // replace this with the email address of the moderator // you can also make it an array of addresses if more than 1 # Normally this call to wmMkProfilePOP3() would be on a single line wmMkProfilePOP3('wikibox', //name of the profile - must be wikibox unless you change $wbPOP3Profile 'localhost', // host where WikiBox will pick up mail 'testwiki', // username WikiBox will use to pick up mail ------); // password WikiBox will use to pick up mail
My SiteAdmin.WikiBoxEmailAuth has in it:
tamara@locahost:::1:0:--------::::::
(I'm not at all clear what the password field is for...) Nevermind, I figured it out. It goes in the message body of any pages to want to upload. tamouse June 14, 2011, at 12:49 AM
tamouse June 14, 2011, at 12:47 AM
User notes +4: If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.