Making a post to Wikia's forums using HTTParty and Ruby

217 views Asked by At

I am trying to use Ruby, along with HTTParty, to make a post to a forum on a Wikia. There is no documentation available, since the process seems to involve Wikia's internal API, so I've been attempting to use Chrome's Dev Tools to see the requests being made.

As far as I can tell, when a user attempts to post a comment to a thread on the forum, a POST request is sent to .wikia.com/wikia.php with the following parameters:

  • controller=WallExternal
  • method=replyToMessage
  • parent=(the parent thread id, eg 1036301)
  • body="the message being sent"
  • token=edittoken*

The process requires an edit token which I retrieve using the normal Mediawiki API. The problem I have run into is that I get a response of

"There seems to be a problem with your login session; this action has been canceled as a precaution against session hijacking. Go back to the previous page, reload that page and then try again."

A Google search using the error message only yields people who have had this appear when trying to login normally, which isn't the problem in this situation.

I thought the problem might be in that the headers for the user wasn't set in the request, since I don't think anonymous editors are allowed to post responses; since the Mediawiki documentation says that users that aren't logged in get an edit token of "+\", it doesn't seem to be the case.

The code I'm trying to use is:

    @api = MediaWiki::Gateway.new 'http://example.wikia.com/api.php'
    @api.login('username', 'password')
    @headers = {
      'User-Agent' => 'example',
      'Cookie' => @api.cookies.map { |k, v| "#{k}=#{v};" }.join(' ')
    }

    query = HTTParty.post('http://example.wikia.com/api.php',
      :body => {
        'action' => 'query',
        'prop' => 'info|revisions',
        'intoken' => 'edit',
        'titles' => 'Thread:2219',
        'format' => 'json'
      },
      :headers => @headers
    )

    token = JSON.parse(query.body)
    token = token["query"]["pages"]["-1"]["edittoken"]

    query = HTTParty.post('http://example.wikia.com/wikia.php',
      :body => {
        'controller' => 'WallExternal',
        'method' => 'changeThreadStatus',
        'format' => 'json',
        'msgid' => '2219',
        'newState' => 'close'
      },
      :headers => @headers
    )

Wikia is currently using Mediawiki 1.19.24, which is why the method for retrieving the edit token is the older version.

This is mainly a hobby, and I'm not very experienced. I've asked this question on a Wikia forum first, and a user advised me to come here. Thanks for any help you can provide.

1

There are 1 answers

1
max pleaner On

You're seeing an error relating to CSRF (cross site request forgery) because you're not able to use the "token" correctly.

This is probably intentional on the MediaWiki site creator's behalf. You won't be able to make the POST unless you pass along the correct token, which shows that the form is being submitted from the correct HTML page origin. This token is server-originated and you might have a hard time extracting it to use with your HTTParty requests. You could look around the DOM to maybe find some value, though.

I'd probably recommend to use Selenium as an alternative. Since this uses a proper browser instance, you won't have to deal with parsing HTML responses and crafting custom posts. Instead, you can write code to visit the wikia site, log in, and submit the 'new post' form.

Keep in mind that sometimes websites have protections to avoid being automated in this way. If you find that this happens (you aren't able to use Selenium to log in, for example), it can be helpful to place breakpoints in the selenium code, click around the browser, then move past the breakpoint to run more code.

All that being said, since there's a MediaWiki API it might be a better idea to use that interface as much as possible. I.e. there may be no need to use a HTTP client or a headless browser if the gem can accomplish your needs.