Welcome to Geeklog, Anonymous Saturday, December 21 2024 @ 12:05 pm EST
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
What's the best way to programmatically make a new post to a given forum from outside of Geeklog?
-mono
10
16
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
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
13
13
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
Thanks!
-mono
10
12
Quote
Status: offline
Laugh
Site Admin
Admin
Registered: 09/27/05
Posts: 1470
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.
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.
12
13
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:
<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
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
15
13
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:
<input name="loginname" value="App Helper">
<input name="passwd"><br /><input type="submit" value="Login">
So I use cURL to submit the login form:
$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:
So it seems I logged in successfully - I hope...
Next, I want to emulate the Geeklog create topic form:
<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:
$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:
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
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
13
20
Quote
Status: offline
monoclast
Forum User
Junior
Registered: 07/08/06
Posts: 26
Quote by: Laugh
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. 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
-mono
14
13
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
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
13
13
Quote
Status: offline
monoclast
Forum User
Junior
Registered: 07/08/06
Posts: 26
Thanks very much, Dirk. That did the trick.
For the curious, all I had to do was instruct cURL to store cookie data in a file.
Here's the final working code:
$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!
-mono
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!
-mono
14
17
Quote
All times are EST. The time is now 12:05 pm.
- 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