Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Posting a comment to Reddit API with NodeJs Request module

So I'm building a pretty silly bot for a fellow Redditor. And it needs to log in, then post a comment. The Reddit documentation is fairly sparse, IMHO, so I'm hoping that someone can show me where I'm going wrong.

As I understand it, I need to post to https://ssl.reddit.com/api/login, retrieve a cookie and then send that cookie, along with the provided modhash to https://api.reddit.com/api/comment. But I keep getting a 403 statusCode when I follow these steps. I'm sure there's something silly that I'm missing, but I can't seem to tell what it is.

Relevant code:

var request = require('request')
  , modhash;

request.defaults({jar:true});

function login () {
  var options = {
      url     : 'https://ssl.reddit.com/api/login?api_type=json&user=USERNAME&passwd=PASSWORD&rem=true',
      headers : {
        'User-Agent' : 'fooBot/0.1 by USERNAME'
      },
      method  : 'POST'
  };

  request(options, function (err, res, body) {
    if (err) {
      console.log(err.json.errors);
      return;
    } else {
      var parsedBody = JSON.parse(body);
      modhash = body.json.data.modhash;
    }
  });
}

function postComment () {
  var parentId = 't1_cf9k3wa'
    , options = {
        url : 'https://api.reddit.com/api/comment?api_type=json&text=foobar&thing_id=' + parentId,
        headers : {
            'User-Agent' : 'fooBot/0.1 by USERNAME',
            'X-Modhash'  : modhash
          },
        methods : 'POST'
      };
  request(options, function (err, res, body) {
    if (err) {
      console.log(err);
      return;
    } else {
      // this blows up
    }
  });
}
like image 248
joeLepper Avatar asked Oct 02 '22 15:10

joeLepper


1 Answers

So I've solved the problem, though not to my satisfaction. A working version of what I posted this weekend is below. There were a number of things that I was doing wrong.

  • As noted by gotnull above, I had fat-fingered method as methods.
  • For whatever reason request's cookie jar was not working for me. I had to handle the cookie manually as illustrated by the code.
  • api.reddit.com doesn't handle https so I had to send the request to post a comment to https://en.reddit.com/

I'm still unhappy with the way that this works, because it limits the length of my message by having it in the URI. From what I understand I need to have the message in the POSTDATA but I haven't been able to coax request into doing that for me.

My initial problem is solved, but I'll need to open a second question for this when I re-visit the bot.

var request  = require('request')
  , argv     = require('yargs').argv
  , modhash
  , cookie;

function login () {
  var options = {
      url     : 'https://ssl.reddit.com/api/login?api_type=json&user=' + argv.user + '&passwd=' + argv.pass + '&rem=True',
      headers : {
        'User-Agent' : 'fooBot/0.1 by USERNAME',
      },
      method  : 'POST'
  };

  request(options, function (err, res, body) {
    if (err) {
      console.log('LOGIN ERROR:');
      console.log(err.json.errors);
      return;
    } else {
      var parsedBody = JSON.parse(body);
      modhash = parsedBody.json.data.modhash;
      cookie  = parsedBody.json.data.cookie;
    }
  });
}

function postComment (parentId) {
  var text     = 'message message message.'
    , options  = {
        url      : 'https://en.reddit.com/api/comment?api_type=json&text=' + encodeURIComponent(text) + '&thing_id=' + parentId,
        headers  : {
            'User-Agent' : 'fooBot/0.1 by USERNAME',
            'X-Modhash'  : modhash,
            'Cookie'     : 'reddit_session=' + encodeURIComponent(cookie)
          },
        method : 'POST'      };

  request(options, function (err, res, body) {
    if (err) {
      console.log('COMMENT POST ERROR:');
      console.log(err.stack);
      return;
    } else {
      console.log('// ------ //');
      console.log(body);
      console.log('// ------ //');
    }
  });
}
like image 101
joeLepper Avatar answered Oct 05 '22 12:10

joeLepper