Welcome to Geeklog, Anonymous Sunday, September 01 2024 @ 12:02 am EDT
Geeklog Forums
Submit story via email
Status: offline
lfalfa
Forum User
Newbie
Registered: 04/01/04
Posts: 12
I have hacked up some PHP code that allows my users to email story submissions into geeklog. I've just gotten it up and running, and I would very much appreciate any feedback or criticism of how I'm doing it.
To use this, I have it hooked up to the email address news@livefromarlington.com, and I have a qmail rule associated with that email address that executes the script with the text of the email as stdin.
A couple of caveats:
Here's the script:
#!/usr/local/bin/php -q
<?php
include('public_html/lib-common.php');
include('public_html/submit.php');
include('Mail_Mime-1.2.1/mimeDecode.php');
require_once 'Mail/RFC822.php';
// read from stdin
$fd = fopen("php://stdin", "r");
$input = "";
while (!feof($fd)) {
$input .= fread($fd, 1024);
}
fclose($fd);
// Parse the incoming email
$decode = new Mail_mimeDecode($input, "rn");
$structure = $decode->decode(array('include_bodies' => 1));
// See if this is a real user
$rawEmail = $structure->headers['from'];
$parsedEmail = Mail_RFC822::parseAddressList ($rawEmail);
$email = $parsedEmail[0]->mailbox . "@" . $parsedEmail[0]->host;
$uid = DB_getItem($_TABLES['users'], 'uid', "email = '{$email}'");
// Whether it's a real user or not, we'll need some more
// data, either for the story submission or for the error msg
$title = $structure->headers['subject'];
// If this is a multipart message, then we have to iterate
// through the parts to find the text/plain one.
if ($structure->ctype_primary == 'text' && $structure->ctype_secondary == 'plain') {
$introtext = $structure->body;
} else {
for ($i = 0; $i < count($structure->parts); $i++) {
$aPart = $structure->parts[$i];
if ($aPart->ctype_primary == 'text' && $aPart->ctype_secondary == 'plain') {
$introtext = $aPart->body;
break;
}
}
}
if (!empty($uid)) {
$postmode = 'plaintext';
$sid = COM_makesid();
$tid = 'Admin';
DB_save($_TABLES['storysubmission'],"sid,tid,uid,title,introtext,date,postmode","{$sid},'{$tid}',{$uid},'{$title}','{$introtext}',NOW(),'{$postmode}'","");
if (isset ($_CONF['notification']) && in_array ('story', $_CONF['notification'])) {
$A['title'] = $title;
$A['postmode'] = $postmode;
$A['introtext'] = $introtext;
$A['uid'] = $uid;
$A['tid'] = $tid;
// notify the site admin of a pending submission
sendNotification ($_TABLES['storysubmission'], $A);
// send notification of acceptance
$acceptHeaders = "From: {$_CONF['site_name']} <{$_CONF['site_mail']}>rn"
. "Return-Path: {$_CONF['site_mail']}rn"
. "Content-Type: text/plain; charset=$charsetrn"
. "X-Mailer: GeekLog " . VERSION;
$acceptSubject = "Successfully processed Live From Arlington submission '$title'";
$acceptText = "Your story was successfully submitted.rn" .
"An editor will review your story for approval as soon as possible.rn" .
"Thank you for submitting your story!rnrn" .
"-Live From Arlington Staff";
@mail( $email, $acceptSubject, $acceptText, $acceptHeaders );
}
} else {
// send polite rejection notice
$rejectHeaders = "From: {$_CONF['site_name']} <{$_CONF['site_mail']}>rn"
. "Return-Path: {$_CONF['site_mail']}rn"
. "Content-Type: text/plain; charset=$charsetrn"
. "X-Mailer: GeekLog " . VERSION;
$rejectSubject = "Error processing Live From Arlington submission '$title'";
$rejectText = "Unfortunately, your story submission was not accepted.rn" .
"An emailed story submission must be sent from the email addressrn" .
"of a registered account.rnrn" .
"Please sign up for an account at:rnrn" .
" http://www.livefromarlington.com/users.php?mode=newrnrn" .
"Or please resend your message from the email address of yourrn" .
"existing account, if you have one.rnrn" .
"Sorry for the inconvenience!rnrn" .
"-Live From Arlington Staffrnrn" .
"For your convenience, your submission appears below:rnrn";
$rejectText .= "Subject: " . $title . "rn";
$rejectText .= $introtext;
@mail( $email, $rejectSubject, $rejectText, $rejectHeaders );
};
To use this, I have it hooked up to the email address news@livefromarlington.com, and I have a qmail rule associated with that email address that executes the script with the text of the email as stdin.
A couple of caveats:
- There's no security -- anyone can email something in as a submission if they know the email address of a registered user. That's why everything goes into a submission queue instead of using the logic that allows a story to be posted directly if the user has the right permission. Any ideas on how to make it more secure? Perhaps allow the user to include their password as the first line of the email?
- For now, it only handles text/plain content. I hope to add support for attached photos.
Here's the script:
Text Formatted Code
#!/usr/local/bin/php -q
<?php
include('public_html/lib-common.php');
include('public_html/submit.php');
include('Mail_Mime-1.2.1/mimeDecode.php');
require_once 'Mail/RFC822.php';
// read from stdin
$fd = fopen("php://stdin", "r");
$input = "";
while (!feof($fd)) {
$input .= fread($fd, 1024);
}
fclose($fd);
// Parse the incoming email
$decode = new Mail_mimeDecode($input, "rn");
$structure = $decode->decode(array('include_bodies' => 1));
// See if this is a real user
$rawEmail = $structure->headers['from'];
$parsedEmail = Mail_RFC822::parseAddressList ($rawEmail);
$email = $parsedEmail[0]->mailbox . "@" . $parsedEmail[0]->host;
$uid = DB_getItem($_TABLES['users'], 'uid', "email = '{$email}'");
// Whether it's a real user or not, we'll need some more
// data, either for the story submission or for the error msg
$title = $structure->headers['subject'];
// If this is a multipart message, then we have to iterate
// through the parts to find the text/plain one.
if ($structure->ctype_primary == 'text' && $structure->ctype_secondary == 'plain') {
$introtext = $structure->body;
} else {
for ($i = 0; $i < count($structure->parts); $i++) {
$aPart = $structure->parts[$i];
if ($aPart->ctype_primary == 'text' && $aPart->ctype_secondary == 'plain') {
$introtext = $aPart->body;
break;
}
}
}
if (!empty($uid)) {
$postmode = 'plaintext';
$sid = COM_makesid();
$tid = 'Admin';
DB_save($_TABLES['storysubmission'],"sid,tid,uid,title,introtext,date,postmode","{$sid},'{$tid}',{$uid},'{$title}','{$introtext}',NOW(),'{$postmode}'","");
if (isset ($_CONF['notification']) && in_array ('story', $_CONF['notification'])) {
$A['title'] = $title;
$A['postmode'] = $postmode;
$A['introtext'] = $introtext;
$A['uid'] = $uid;
$A['tid'] = $tid;
// notify the site admin of a pending submission
sendNotification ($_TABLES['storysubmission'], $A);
// send notification of acceptance
$acceptHeaders = "From: {$_CONF['site_name']} <{$_CONF['site_mail']}>rn"
. "Return-Path: {$_CONF['site_mail']}rn"
. "Content-Type: text/plain; charset=$charsetrn"
. "X-Mailer: GeekLog " . VERSION;
$acceptSubject = "Successfully processed Live From Arlington submission '$title'";
$acceptText = "Your story was successfully submitted.rn" .
"An editor will review your story for approval as soon as possible.rn" .
"Thank you for submitting your story!rnrn" .
"-Live From Arlington Staff";
@mail( $email, $acceptSubject, $acceptText, $acceptHeaders );
}
} else {
// send polite rejection notice
$rejectHeaders = "From: {$_CONF['site_name']} <{$_CONF['site_mail']}>rn"
. "Return-Path: {$_CONF['site_mail']}rn"
. "Content-Type: text/plain; charset=$charsetrn"
. "X-Mailer: GeekLog " . VERSION;
$rejectSubject = "Error processing Live From Arlington submission '$title'";
$rejectText = "Unfortunately, your story submission was not accepted.rn" .
"An emailed story submission must be sent from the email addressrn" .
"of a registered account.rnrn" .
"Please sign up for an account at:rnrn" .
" http://www.livefromarlington.com/users.php?mode=newrnrn" .
"Or please resend your message from the email address of yourrn" .
"existing account, if you have one.rnrn" .
"Sorry for the inconvenience!rnrn" .
"-Live From Arlington Staffrnrn" .
"For your convenience, your submission appears below:rnrn";
$rejectText .= "Subject: " . $title . "rn";
$rejectText .= $introtext;
@mail( $email, $rejectSubject, $rejectText, $rejectHeaders );
};
17
21
Quote
Status: offline
Norgs
Forum User
Junior
Registered: 12/16/03
Posts: 17
lfalfa, I like it.
Where are you at with this one? Did you manage to impliment some security?
Also, whats are the pre reqs for this hack? Do you have to control email for the domain? How about if I have my site hosted with someone, will it work for me?
Where are you at with this one? Did you manage to impliment some security?
Also, whats are the pre reqs for this hack? Do you have to control email for the domain? How about if I have my site hosted with someone, will it work for me?
23
17
Quote
Status: offline
johnc10
Forum User
Newbie
Registered: 02/02/05
Posts: 5
Location:UK
Hi, have you time to give an update? I'm interested in using geeklog to give users the choice to post via email (using mailman) or forum. Either one will be sent to the mailing list and posted on the forum.
15
20
Quote
Status: offline
jlawrence
Forum User
Chatty
Registered: 12/30/04
Posts: 49
Location:Plymouth, Devon, UK
One thing I don't like about that code is that it relies on your webserver to be able to receive emails - imho, webservers are exactly that, they shouldn't have open incoming port 25.
It might be possible to have something like fetchmail pull the mail in and then it gets passed to the code.
I'm working on a slightly modified version of this where the php code itself pulls from a remote pop box.
www.plymouthcricketclub.com - providing cricket for all ages in the Plymouth area.
It might be possible to have something like fetchmail pull the mail in and then it gets passed to the code.
I'm working on a slightly modified version of this where the php code itself pulls from a remote pop box.
www.plymouthcricketclub.com - providing cricket for all ages in the Plymouth area.
17
19
Quote
Status: offline
Marites
Forum User
Chatty
Registered: 02/04/04
Posts: 64
We opted for the Perl approach with security and only admin can add this way. The script was written for us and worked very well for almost 2 years now. It is rather heavyweight and requires complete access to Sendmail aliases. It also automatically splits the message for the intro and body. Sadly it was written to only work on our dedicated server so I can't add it to downloads.
Tony did write a similar script at the same time and his allows the message to be held in moderation before being added.
Tony did write a similar script at the same time and his allows the message to be held in moderation before being added.
15
15
Quote
Status: offline
johnc10
Forum User
Newbie
Registered: 02/02/05
Posts: 5
Location:UK
Quote by jlawrence: One thing I don't like about that code is that it relies on your webserver to be able to receive emails - imho, webservers are exactly that, they shouldn't have open incoming port 25.
Yes, this is what easymoblog uses and it works well.
To use publishbymail, ftp it into your geeklog website directory. You can use cpanel to set up a mail forward and enter the email address then
| /usr/bin/php -q /home/user/public_html/websitename/publishbymail.php
It works, but I was getting an error email returned eventhough the post was successful. It was due to blank lines at the end of the script, after the ending question mark ?> . Deleted them and now works fine.
I've also now found you should be able to use ~/.procmailrc instead of /etc/aliases or /etc/procmailrc, but it doesn't work on my ISP, only my own Fedora PC.
Using with procmail instead of sendmail alias:
1. don't add the forward in the alias file
2. take "#!/usr/bin/php" out of the script.php (first line)
3. add this to your procmailrc (usually /etc/procmailrc or ~/.procmailrc):
:0
* ^To.*emailpost@www.domain.org
| /usr/bin/php -q /home/user/public_html/cgi-bin/publishbymail.php
22
19
Quote
All times are EDT. The time is now 12:02 am.
- Normal Topic
- Sticky Topic
- Locked Topic
- New Post
- Sticky Topic W/ New Post
- Locked Topic W/ New Post
- View Anonymous Posts
- Able to post
- Filtered HTML Allowed
- Censored Content