snoowrap
A simple Node.js wrapper for the reddit API. (Documentation)
Features
snoowrap supports every API endpoint, and provides a simple interface to access each of them. The method to get a user profile is just get_user()
, and the method to upvote something is just upvote()
. There's no need to look up REST endpoints or deal with low-level HTTP requests.
If you've used PRAW, you'll probably find a lot of snoowrap's syntax to be familiar. However, aside from being written in a different language, there are a few important differences:
- Unlike PRAW, snoowrap is non-blocking; all API calls are async and return bluebird Promises. This means that you can handle asynchronous events however you want, and you can use snoowrap as part of a larger process without it holding everything back.
- Each snoowrap object is completely independent. If you want, you can have scripts from separate accounts make requests at the same time.
snoowrap's objects are structured to keep the syntax as simple as possible. So the following expression:
r.get_submission('2np694').body
...will return a Promise. So will this one:
r.get_submission('2np694').author.name
The above will return a Promise for the author's name, without having to deal with callback hell or .then
statements. You can chain multiple API calls together:
r.get_submission('2np694').subreddit.get_moderators()[0].name
...or chain actions together with fluent syntax:
r.get_subreddit('snoowrap')
.submit_selfpost({title: 'Discussion Thread', text: 'Hello! This is a thread'})
.sticky()
.distinguish()
.ignore_reports()
.assign_flair({text: 'Exciting Flair Text', css_class: 'modpost'})
snoowrap handles all API interactions such as authentication, ratelimiting, error correction, and HTTP requests under the hood. That way, you can write less boilerplate code and focus more on doing what you actually want to do.
- After you provide a token once, snoowrap will refresh it on its own from then on -- you won't have to worry about authentication again.
- snoowrap uses lazy objects, so it never fetches more than it needs to.
- snoowrap has built-in ratelimit protection. If you hit reddit's ratelimit, you can choose to queue the request, and then run it after the current ratelimit period runs out. That way you won't lose a request if you go a bit too fast.
- snoowrap will retry its request a few times if reddit returns an error due to its servers being overloaded.
For more examples of what can be done with snoowrap, take a look at the documentation or the test file.
Simple example file
'use strict';
const snoowrap = require('snoowrap');
const r = new snoowrap({
client_id: 'put your client id here',
client_secret: 'put your client secret here',
refresh_token: 'put your refresh token here'
});
r.get_subreddit('gifs').submit_link({
title: 'Mt. Cameramanjaro',
url: 'https://i.imgur.com/n5iOc72.gifv'
});
r.get_hot().map(post => post.title).then(console.log);
r.get_new_comments().fetch_until(500).forEach(comment => {
if (comment.body === 'ayy') {
comment.reply('lmao');
}
});
r.get_subreddit('some_subreddit_name').get_modqueue({limit: 100}).filter(/some-removal-condition/.test).forEach(flaggedItem => {
flaggedItem.remove();
flaggedItem.subreddit.ban_user(flaggedItem.author);
});
r.get_subreddit('some_subreddit_name')
.create_selfpost({title: 'Daily thread', text: 'Discuss things here'})
.sticky()
.distinguish()
.approve()
.assign_flair({text: 'Daily Thread flair text', css_class: 'daily-thread'})
.reply('This is a comment that appears on that daily thread');
r.get_subreddit('AskReddit').get_wiki_page('bestof').content_md.then(console.log);
Live threads
Reddit's live threads are different from most other content, in that messages are distributed through websockets instead of a RESTful API. snoowrap fully supports this protocol under the hood, and it represents the content stream as an EventEmitter. For example, the following code will stream all livethread updates to the console as they appear:
r.get_livethread('whrdxo8dg9n0').stream.on('update', console.log);
For more information, see snoowrap's LiveThread documentation page.
Important note regarding ES6
snoowrap uses the Proxy
object introduced in ES6. Since this is not yet included in Node by default, you will need to run your project with the --harmony-proxies
runtime flag, e.g. node --harmony-proxies yourProject.js
. With regard to running code in browsers, as of February 2016 the only browsers that support Proxies are Chrome 49+ and Microsoft Edge.
If you can't use that node flag for some reason, or your code is running in a non-supporting browser, snoowrap will still function. However, method chaining as described above won't work, so your syntax will need to be a bit heavier.
For example:
r.get_submission('47v7tm').comments[0].upvote();
r.get_submission('47v7tm').fetch().get('comments').get(0).call('upvote');
To include in a project
npm install snoowrap --save
var snoowrap = require('snoowrap');
To build/run the tests independently
git clone https://github.com/not-an-aardvark/snoowrap.git
cd snoowrap
npm install
npm test
snoowrap is currently in active development; while it provides shortcuts for a large number of API endpoints, it is not yet feature-complete. See here for full documentation.