Welcome to Geeklog, Anonymous Thursday, March 28 2024 @ 10:50 am EDT

Geeklog Forums

Programmatically create a new post?


Status: offline

monoclast

Forum User
Junior
Registered: 07/08/06
Posts: 26
I have a static page that uses an iframe to load an external php page into Geeklog (we use this page to accept and keep track of applications to our user group). I'd like to be able to automatically create a new post in a certain forum each time an application is submitted.

What's the best way to programmatically make a new post to a given forum from outside of Geeklog?
-mono
 Quote

Status: offline

Dirk

Site Admin
Admin
Registered: 01/12/02
Posts: 13073
Location:Stuttgart, Germany
Unfortunately, the forum doesn't support the Atom Publishing Protocol (which you could use to create new stories) - that would be the ideal solution for your problem.

You could try crafting a POST request from looking at what the forum's post editor expects. If you are using CAPTCHAs, you would also need to find a way to log in first. All that is not impossible, but somewhat laborious ...

Alternatively, you could try hacking your own API into the forum. Just make sure it can't be abused by spammers.

bye, Dirk
 Quote

Status: offline

monoclast

Forum User
Junior
Registered: 07/08/06
Posts: 26
That's what i was afraid of. I started taking a look at the forum post code, and it looks like it's do-able, but, as you indicated, messy and laborious. I guess I'll give it a shot and see if it's more effort than I want to spend!

Thanks!
-mono
 Quote

Status: offline

Laugh

Site Admin
Admin
Registered: 09/27/05
Posts: 1468
Location:Canada
I have never done this before but you could try using something like

https://addons.mozilla.org/en-US/firefox/addon/966/

to capture what post data is needed to create a forum post in the forum and then use curl (http://php.net/manual/en/ref.curl.php) when the application is submitted on your other website to post the data to the forum.

Tom

One of the Geeklog Core Developers.
 Quote

Status: offline

monoclast

Forum User
Junior
Registered: 07/08/06
Posts: 26
From what I've learned so far, these are the parameters I would need to send:

Text Formatted Code
<form action="http://somewhere.org/blog/forum/createtopic.php" method="POST" name="forumpost">
<input type="hidden" name="forum" value="7">
<input type="hidden" name="id" value="0">
<input type="hidden" name="modedit" value="0">
<input type="hidden" name="method" value="newtopic">
<input type="hidden" name="editpost" value="">
<input type="hidden" name="editpid" value="">
<input type="hidden" name="editid" value="">
<input type="hidden" name="page" value="0">
<input type="hidden" name="name" value="username making post">
<input type="text" name="subject" value="subject of post">
<textarea name="comment">content of post</textarea>
<input type="checkbox" name="notify">
<input type="hidden" name="postmode" value="text">
<input type="submit" name="submit" value="Submit">


The tricky part will be establishing a valid login session.

I'm thinking of creating a basic user account to be used only for this purpose. The account will have very restricted permissions, in the interest of security. I'll need to figure out how to log in as that user, and then call createtopic.php such that the post is made by that logged-in user.

Any tips regarding that would be much appreciated!
-mono
 Quote

Status: offline

monoclast

Forum User
Junior
Registered: 07/08/06
Posts: 26
I'm having some trouble figuring out a way to establish a login session that is persistent enough to let me post. I figured i would try using PHP's cURL functions to log in, and then post the form to create a post.

First I created a new Geeklog user account called "App Helper".

Next, I want to first emulate the Geeklog login form:

Text Formatted Code
<form action="http://mysite.com/blog/users.php" method="post" style="margin-top:5px;margin-bottom:5px;">
<input name="loginname" value="App Helper">
<input name="passwd"><br /><input type="submit" value="Login">


So I use cURL to submit the login form:

Text Formatted Code
// create form data

$post_data = array ();
$post_data['loginname']    = 'App Helper';
$post_data['passwd']    = 'password';
$post_data['submit']    = 'Login';

foreach ($post_data as $key => $value)
{
        $post_items[] = $key . '=' . $value;
}
$post_string = implode ('&', $post_items);

log_event ("post_string: $post_string");

// create a cURL connection

$curl_connection = curl_init ();

// set cURL options

curl_setopt ($curl_connection, CURLOPT_URL, 'http://mysite.com/blog/users.php');
curl_setopt ($curl_connection, CURLOPT_POSTFIELDS, $post_string);

curl_setopt ($curl_connection, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt ($curl_connection, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt ($curl_connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($curl_connection, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl_connection, CURLOPT_POST, true);

// execute the post

$result = curl_exec ($curl_connection);


At this point, $result contains:

Text Formatted Code
<html><head><meta http-equiv="refresh" content="0; URL=http://mysite.com/blog/index.php"></head></html>


So it seems I logged in successfully - I hope...

Next, I want to emulate the Geeklog create topic form:

Text Formatted Code
<form action="http://mysite.com/blog/forum/createtopic.php" method="POST" name="forumpost">
<input type="hidden" name="forum" value="7">
<input type="hidden" name="id" value="0">
<input type="hidden" name="modedit" value="0">
<input type="hidden" name="method" value="newtopic">
<input type="hidden" name="editpost" value="">
<input type="hidden" name="editpid" value="">
<input type="hidden" name="editid" value="">
<input type="hidden" name="page" value="0">
<input type="hidden" name="name" value="App Helper">
<input type="text" name="subject" value="subject of post">
<textarea name="comment">content of post</textarea>
<input type="checkbox" name="notify">
<input type="hidden" name="postmode" value="text">
<input type="submit" name="submit" value="Submit">


So, without closing the cURL connection, I make another post:

Text Formatted Code
// create form data

$post_data = array ();
$post_items = array ();

$post_data['forum']            = '7';
$post_data['id']            = '0';
$post_data['modedit']    = '0';
$post_data['method']    = 'newtopic';
$post_data['editpost']    = '';
$post_data['editpid']    = '';
$post_data['editid']    = '';
$post_data['page']            = '0';
$post_data['name']            = 'App Helper';
$post_data['subject']    = 'subject of post';
$post_data['comment']    = 'content of post';
$post_data['notify']    = '';
$post_data['postmode']    = 'text';
$post_data['submit']    = 'Submit';

foreach ($post_data as $key => $value)
{
        $post_items[] = $key . '=' . $value;
}
$post_string = implode ('&', $post_items);

log_event ("post_string: $post_string");

// create a cURL connection

$curl_connection = curl_init ();

// set cURL options

curl_setopt ($curl_connection, CURLOPT_URL, 'http://mysite.com/blog/forum/createtopic.php');
curl_setopt ($curl_connection, CURLOPT_POSTFIELDS, $post_string);

curl_setopt ($curl_connection, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt ($curl_connection, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt ($curl_connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($curl_connection, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl_connection, CURLOPT_POST, true);

// execute the post

$result = curl_exec ($curl_connection);


Unfortunately, at this point, $result contains a full Geeklog web page with the standard access denied message:

Text Formatted Code
<h2>ACCESS ERROR</h2><br><p style="padding-left:10px;">Access to this forum is restricted.<br>It may be that you are not a member of this web site, and are attempting to access a members-only forum. You must register an account to access content on this web site.<br>If you feel this is incorrect, contact the site administrator.<p />


Any ideas on how I might be able to make this work the way I want? Or am I barking up the wrong tree?
-mono
 Quote

Status: offline

Laugh

Site Admin
Admin
Registered: 09/27/05
Posts: 1468
Location:Canada
Did you try posting a topic as an anonymous user (to a forum topic that they have access too) to make sure that part of your code works?

Tom
One of the Geeklog Core Developers.
 Quote

Status: offline

monoclast

Forum User
Junior
Registered: 07/08/06
Posts: 26
Quote by: Laugh

Did you try posting a topic as an anonymous user (to a forum topic that they have access too) to make sure that part of your code works?

Tom

Well I don't allow anonymous access to any pages on this site. So even if the posting part works, I still need to log in.
-mono
 Quote

Status: offline

Dirk

Site Admin
Admin
Registered: 01/12/02
Posts: 13073
Location:Stuttgart, Germany
One word: Cookies.

When you log into Geeklog, it sends you a session cookie, which the browser is supposed to send with all future requests during that session.

Actaully, I would try to fake that bit: Log into the site as the bot user. Get the content of the permanent cookie (ignore the session cookie) and send that with each request. Not entirely sure if you can get away with it, and it would expire eventually, but worth a try ...

bye, Dirk
 Quote

Status: offline

monoclast

Forum User
Junior
Registered: 07/08/06
Posts: 26
Thanks very much, Dirk. That did the trick. Smile

For the curious, all I had to do was instruct cURL to store cookie data in a file.

Here's the final working code:

Text Formatted Code
// create a cookie jar

$cookie_filename = 'cookie_jar.txt';
$file = fopen ($cookie_filename, "w");
fclose ($file);

// initialize cURL

$connection = curl_init ();

curl_setopt ($connection, CURLOPT_COOKIEJAR, $cookie_filename);
curl_setopt ($connection, CURLOPT_COOKIEFILE, $cookie_filename);
curl_setopt ($connection, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt ($connection, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt ($connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($connection, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($connection, CURLOPT_POST, true);

// log in to the web log as "App Helper"

$post_data = array ();
$post_items = array ();

$post_data['loginname']    = 'App Helper';
$post_data['passwd']    = 'password';
$post_data['submit']    = 'Login';

foreach ($post_data as $key => $value)
{
        $post_items[] = $key . '=' . $value;
}
$post_string = implode ('&', $post_items);
       
curl_setopt ($connection, CURLOPT_URL, 'http://mysite.com/blog/users.php');
curl_setopt ($connection, CURLOPT_POSTFIELDS, $post_string);

$result = curl_exec ($connection);
if ($result !== false)
{
        // login succeeded
       
        // create a new post in the "Recruiting" forum
       
        $post_data = array ();
        $post_items = array ();
       
        $post_data['forum']    = '7';
        $post_data['id']    = '0';
        $post_data['modedit']    = '0';
        $post_data['method']    = 'newtopic';
        $post_data['editpost']    = '';
        $post_data['editpid']    = '';
        $post_data['editid']    = '';
        $post_data['page']    = '0';
        $post_data['name']    = 'App Helper';
        $post_data['subject']    = 'subject of post';
        $post_data['comment']    = 'content of post';
        $post_data['notify']    = '';
        $post_data['postmode']    = 'text';
        $post_data['submit']    = 'Submit';
       
        foreach ($post_data as $key => $value)
        {
                $post_items[] = $key . '=' . $value;
        }
        $post_string = implode ('&', $post_items);
       
        curl_setopt ($connection, CURLOPT_URL, 'http://mysite.com/blog/forum/createtopic.php');
        curl_setopt ($connection, CURLOPT_POSTFIELDS, $post_string);
       
        $result = curl_exec ($connection);
        if ($result === false)
        {
                // post creation failed
               
                log_event ("ERROR: curl_exec (create post) returned FALSE");
        }
}
else
{
        // login failed
       
        log_event ("ERROR: curl_exec (log in) returned FALSE");
}


Enjoy!

Thanks again, Dirk. You are the man! Smile
-mono
 Quote

Status: offline

Laugh

Site Admin
Admin
Registered: 09/27/05
Posts: 1468
Location:Canada
Glad it worked out, thanks for keeping us posted.

Tom
One of the Geeklog Core Developers.
 Quote

All times are EDT. The time is now 10:50 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