Socket
Socket
Sign inDemoInstall

snoowrap

Package Overview
Dependencies
53
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.5.0 to 0.6.0

lib/helpers.js

11

lib/constants.js
module.exports = {
MODULE_NAME: 'snoowrap',
// SCREAMING_SNAKE_CASE MAKES EVERYTHING SEEM I'M SHOUTING AAAAAAAA
MODULE_NAME: require('../package.json').name,
ISSUE_REPORT_LINK: require('../package.json').bugs.url,
DOCS_LINK: 'https://not-an-aardvark.github.io/snoowrap/',
API_RULES_LINK: 'https://github.com/reddit/reddit/wiki/API',

@@ -19,6 +21,9 @@ USER_KEYS: ['author', 'approved_by', 'banned_by'],

KarmaList: 'KarmaList',
TrophyList: 'TrophyList'
TrophyList: 'TrophyList',
subreddit_settings: 'subreddit_settings',
modaction: 'modaction'
},
USERNAME_REGEX: /^[\w-]{1,20}$/,
REQUEST_TYPES: ['get', 'head', 'post', 'put', 'delete', 'trace', 'options', 'connect', 'patch']
MODERATOR_PERMISSIONS: ['wiki', 'posts', 'access', 'mail', 'config', 'flair'],
HTTP_VERBS: ['get', 'head', 'post', 'put', 'delete', 'trace', 'options', 'connect', 'patch']
};

@@ -0,25 +1,9 @@

// Defines the default config values. For more information on these, see the documentation for snoowrap#config()
module.exports = {
// The domain that requests should be sent to
endpoint_domain: 'reddit.com',
/* This is the minimum delay between requests, in milliseconds. Setting this to more than 1 will ensure that the
ratelimit is never reached, but it will make things run slower than necessary if only a few requests are being sent.
If this is set to zero, snoowrap will not enforce any delay between individual requests, but it will still refuse
to continue if reddit's enforced ratelimit (600 requests per 10 minutes) is exceeded. */
request_delay: 0,
/* If set to true, all requests will be queued if the ratelimit is exceeded, and then they will be executed
after the current ratelimit window expires. If false, requests will not be queued, and an error will be thrown
if the ratelimit is exceeded. */
continue_after_ratelimit_error: false,
// If set to true, snoowrap's default warnings for this instance will be suppressed.
suppress_warnings: false,
// If any of the following status codes are received on an unsuccessful request, the request will be retried.
retry_error_codes: [502, 503, 504],
/* The maximum number of times to attempt a request before giving up and throwing the error. Note that the request will
always be sent at least once. */
max_retry_attempts: 3
max_retry_attempts: 3,
suppress_warnings: false
};

@@ -0,5 +1,6 @@

/* eslint-disable max-len */
'use strict';
let constants = require('./constants');
let errors = {
const constants = require('./constants');
module.exports = {
RateLimitError: class extends Error {

@@ -26,4 +27,17 @@ constructor(expiry_time_from_now) {

},
RateLimitWarning: time_until_reset => `Warning: ${ constants.MODULE_NAME } temporarily stopped sending requests because reddit's ratelimit was exceeded. The request you attempted to send was queued, and will be sent to reddit when the current ratelimit period expires in ${ time_until_reset } seconds.`
};
module.exports = errors;
RateLimitWarning: time_until_reset => `Warning: ${ constants.MODULE_NAME } temporarily stopped sending requests because reddit's ratelimit was exceeded. The request you attempted to send was queued, and will be sent to reddit when the current ratelimit period expires in ${ time_until_reset } seconds.`,
NoCredentialsError: class extends Error {
constructor() {
super();
this.name = 'NoCredentialsError';
this.message = `${ constants.MODULE_NAME }.errors.${ this.name }: Missing credentials passed to ${ constants.MODULE_NAME } constructor. You must pass an object containing either (a) user_agent, client_id, client_secret, and refresh_token properties, or (b) user_agent and access_token properties. For information, please read the docs at ${ constants.DOCS_LINK }.`;
}
},
MissingUserAgentError: class extends Error {
constructor() {
super();
this.name = 'MissingUserAgentError';
this.message = `${ constants.MODULE_NAME }.errors.${ this.name }: You must supply an object with the user_agent property to the snoowrap constructor. For more details on user_agent strings, please see: ${ constants.API_RULES_LINK }`;
}
}
};
{
"name": "snoowrap",
"version": "0.5.0",
"version": "0.6.0",
"license": "MIT",

@@ -8,6 +8,6 @@ "description": "A Node.js wrapper for the reddit API",

"scripts": {
"compile": "babel -d lib/ src/",
"pretest": "eslint --ignore-path .gitignore . && npm run compile",
"test": "mocha --harmony_proxies --compilers js:babel-core/register",
"prepublish": "npm run compile"
"compile": "babel -d lib/ src/ && documentation build src/snoowrap.js --shallow -o doc/ -f html",
"lint": "eslint .",
"pretest": "npm run lint && npm run compile",
"test": "mocha --harmony_proxies --compilers js:babel-core/register"
},

@@ -38,20 +38,23 @@ "repository": {

"dependencies": {
"bluebird": "^3.1.5",
"bluebird": "^3.3.1",
"harmony-reflect": "^1.4.2",
"lodash": "^4.2.0",
"moment": "^2.11.1",
"promise-chains": "^0.1.3",
"request-promise": "^2.0.0"
"lodash": "^4.5.1",
"moment": "^2.11.2",
"promise-chains": "^0.2.4",
"request-promise": "^2.0.1"
},
"devDependencies": {
"babel-cli": "^6.4.5",
"babel-core": "^6.4.5",
"babel-eslint": "^5.0.0-beta9",
"babel-plugin-transform-async-to-generator": "^6.4.6",
"babel-plugin-transform-es2015-destructuring": "^6.4.0",
"babel-plugin-transform-es2015-parameters": "^6.4.5",
"babel-cli": "^6.5.1",
"babel-core": "^6.5.2",
"babel-eslint": "^5.0.0",
"babel-plugin-transform-async-to-generator": "^6.5.0",
"babel-plugin-transform-es2015-destructuring": "^6.5.0",
"babel-plugin-transform-es2015-parameters": "^6.5.0",
"chai": "^3.5.0",
"chai-as-promised": "^5.2.0",
"dirty-chai": "^1.2.2",
"documentation": "^4.0.0-beta",
"eslint": "^2.2.0",
"eslint-plugin-babel": "^3.1.0",
"mocha": "^2.4.5"
}
}
# snoowrap
A simple Node.js wrapper for the reddit API.
A simple Node.js wrapper for the reddit API. ([Documentation](https://not-an-aardvark.github.io/snoowrap))
### To include in a project:
1. `npm install snoowrap --save`
1. (In some file): `var snoowrap = require('snoowrap');`
Note: snoowrap uses the `Proxy` object introduced in ES6. Since Node has not yet deployed this as a default feature, you will need to run your project with the `--harmony-proxies` flag. E.g. `node --harmony-proxies yourProject.js`
snoowrap is currently in development and is far from feature-complete.
### Features
* If you've used [PRAW](https://praw.readthedocs.org/en/stable/), you'll probably find a lot of snoowrap's syntax to be familiar. Aside from being written in a different language, there are a few important differences. For example, 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.
* Even though everything is asynchronous, snoowrap's objects are structured to keep the syntax as simple as possible. So the following expression:
* If you've used [PRAW](https://praw.readthedocs.org/en/stable/), you'll probably find a lot of snoowrap's syntax to be familiar. Aside from being written in a different language, there are a few important differences.
* For example, 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:

@@ -27,3 +21,3 @@ ```javascript

```
The above will return a Promise for the author's name, without having to deal with callback hell or `.then` statements. You can even chain multiple API calls together:
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:

@@ -35,46 +29,79 @@ ```javascript

```
* In a similar vein, each snoowrap object is completely independent. If you want, you can have scripts from separate accounts make requests at the same time.
* 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, the request will be queued, and then run 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 it gets an error because reddit's servers are overloaded.
* 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.
...or chain actions together with fluent syntax:
More complete documentation is in progress, and will be available sometime in the future. For now, here are a few examples of things that you can do with snoowrap.
```javascript
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 many API interactions such as authentication, ratelimiting, error correction, and HTTP requests internally, so that you can write less boilerplate code and focus more on doing what you 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](https://not-an-aardvark.github.io/snoowrap) or the [test file](https://github.com/not-an-aardvark/snoowrap/blob/master/test/snoowrap.spec.js).
### Quick example file
```javascript
'use strict';
let snoowrap = require('snoowrap');
let r = new snoowrap({
user_agent: 'Example snoowrap script',
client_id: 'put a client id here',
client_secret: 'put a client secret here',
const snoowrap = require('snoowrap');
/* Create a new snoowrap requester. If you're uncomfortable storing confidential info in your file, one solution is to
simply store it in a json file and require() it. For more information on how to get valid credentials, see here: https://github.com/not-an-aardvark/reddit-oauth-helper */
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'
});
do_example_things();
/* That's the entire setup process, now you can just make requests. I would recommend including async functions in your project
by using babel.js (or some equivalent), but this example file uses vanilla Promises for simplicity. */
async function do_example_things () {
// Get the top posts from the front page
let top_posts = r.get_hot({subreddit: 'CasualConversation'});
// Submitting a link to a subreddit
r.get_subreddit('gifs').submit_link({
title: 'Mt. Cameramanjaro',
url: 'https://i.imgur.com/n5iOc72.gifv'
});
/* `top_posts` is now a Listing. There's no need to deal with how reddit handles pagination -- snoowrap will do that internally. So now you can do something like: */
for (let i = 0; i < 30; i++) {
console.log(await top_posts[i].body); // When you retrieve a top post by index, snoowrap will fetch it and return a Promise
await top_posts[i].save(); // Save all the top posts so you can view them later
// Printing a list of the titles on the front page
r.get_hot().map(post => post.title).then(console.log);
// Replying to comments that match certain criteria
r.get_new_comments().fetch_until(500).forEach(comment => {
if (comment.body === 'ayy') {
comment.reply('lmao'); // (look at me I'm so original)
}
});
// Automating moderation tasks
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);
// (Probably overkill here, but that's none of my business and pretty much any functionality is there if you want it)
});
// snoowrap will also handle comment tree pagination for you, so you can almost just access them as if they were regular objects. In this example, it is used to moderate comments
example_post = r.get_submission('2np694');
for (let comment in (await comments.fetch_all())) { // iterate over all the top-level comments
if (comment.body.match(/bannedword1|bannedord2|bannedword3/)) {
comment.remove(); // As a moderator, remove any comments that contain selected bad words
}
}
}
// Automatically creating a stickied thread for a moderated subreddit
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');
// etc. etc.
```
For more examples of what can be done with snoowrap, take a look at the [test file](/not-an-aardvark/snoowrap/blob/master/test/snoowrap.spec.js).
---
___
### To include in a project:
1. `npm install snoowrap --save`
1. `var snoowrap = require('snoowrap');`
### To build/run the tests independently:

@@ -85,1 +112,5 @@ 1. `git clone https://github.com/not-an-aardvark/snoowrap.git`

1. `npm test`
Note: 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` flag. E.g. `node --harmony-proxies yourProject.js`
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](https://not-an-aardvark.github.io/snoowrap) for full documentation.

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc