Using the Snuze object
This section discusses using Snuze to talk to Reddit's API.
Note: Snuze is in a preview release phase with limited functionality. The current version supports some common read-only actions while the overall design is being stabilized. Features like posting content and handling PMs are not yet supported. As more actions are implemented, they'll be documented here.
Contents
- Overview
- Fetching Subreddits
- Fetching Links from Subreddits
- Paging Through Listings of Links
- Fetching Accounts
- Fetching Arbitrary "Things" @todo
Overview
Working with Snuze involves three main activities:
- Creating an array of configuration parameters
- Passing that array into a
SnuzeFactory
to get aSnuze
object - Calling methods on the
Snuze
object to interact with Reddit's API
The first two steps are demonstrated in the Getting Started guide. Here's a refresher of how that looks:
<?php require_once __DIR__ . '/vendor/autoload.php'; /* Set authentication and configuration parameters */ $config = [ 'auth.client_id' => 'your-client-id-from-reddit', 'auth.client_secret' => 'your-secret-from-reddit', 'auth.username' => 'your-reddit-username', 'auth.password' => 'your-reddit-password', 'auth.user_agent' => 'php:YourAwesomeBot 1.2.3 (by /u/your-reddit-username)', ]; /* Pass the config array to a SnuzeFactory to get a Snuze object */ $snuze = (new \snuze\SnuzeFactory($config))->getSnuze();
This section assumes you've made it this far, and picks up to cover the third act, using the Snuze object to interact with Reddit.
Fetching Subreddits
To retrieve information about a subreddit, use the
Snuze::fetchSubreddit()
method. It accepts one argument, the plain name of the subreddit you want to get
data about:
/* Get a subreddit's data */ $sub = $snuze->fetchSubreddit('recipes'); /* Take a look at what came back */ var_dump($sub);
fetchSubreddit()
returns a Subreddit
object, which exposes the subreddit's attributes through its getter methods.
If the specified subreddit can't be fetched, an exception is thrown. This will happen when:
- The subreddit is private, but the authenticated API user is not subscribed to it
- The subreddit is quarantined, but the authenticated API user has not affirmatively opted in to view it
- The subreddit has been banned
If for some reason you don't know the target subreddit's name, but you do have its
"thing" fullname (e.g. t5_2qh56
), you can still get its data but you'll need to
use a different approach. See Fetching Info for Arbitrary "Things".
Fetching Links from Subreddits
To retrieve links (also called posts or submissions) from a subreddit, use
one of the Snuze::fetchLinks...()
methods. These methods return a
LinkListing
object, which is an iterable collection of
Link
objects. Reddit's API lets you get up to 100 links at a time; pagination
over larger result sets is discussed later in this document.
Each method described below corresponds to a different sort order for the returned links:
- Fetching "Hot" Links
- Fetching "New" Links
- Fetching "Rising" Links
- Fetching "Controversial" Links
- Fetching "Top" Links
- Fetching "Random" Links
Fetching "Hot" Links
When you visit a subreddit in a browser or an app, the default sort order is
usually "Hot." The Snuze::fetchLinksHot()
method lets you retrieve a subreddit's links in this sort order. Here, we fetch
the top 10 hot links from /r/Art
:
foreach ($snuze->fetchLinksHot('Art', 10) as $link) { echo 'On ' . date('Y-m-d \a\t H:i', (int) $link->getCreated()) . ' UTC, ' . "{$link->getAuthor()} posted: " . $link->getTitle() . PHP_EOL; }
On 2019-08-24 at 16:07 UTC, Namendart posted: "Mama...?", Me, Digital, 2019 On 2019-08-24 at 13:18 UTC, [deleted] posted: Insomnia, me, watercolor, 2019 ...
This example also demonstrates what happens when a user deletes their account after
posting a link. The Link::getAuthor()
method will return [deleted]
instead of a valid username.
Setting a locality code
When requesting a "Hot" link listing, you can specify an optional
locality code
to ask Reddit for links that are "Hot" among Redditors in that geographic region.
This example looks for posts in /r/aviation
that are popular in Australia. Note
that because $locality
is the 7th argument to the method, some placeholder
values must be passed for other arguments.
$ozLinks = $snuze->fetchLinksHot('aviation', 50, $after = null, $before = null, $count = null, $showAll = false, $locality = 'AU'); foreach ($ozLinks as $link) { echo 'Australians like: ' . $link->getTitle() . PHP_EOL; }
Australians like: The Red Arrows with 2 F22s and 2 F35s [3000x3609] Australians like: Two Japanese F-4s, one plain and one SPICY ...
Valid locality codes are defined here.
Fetching "New" Links
The Snuze::fetchLinksNew()
method lets you retrieve a subreddit's links in reverse chronological order, with
the most recently submitted links first. Here, we fetch the top 100 new links from /r/askscience
:
foreach ($snuze->fetchLinksNew('aSKSCieNCe', 100) as $link) { echo date('Y-m-d H:i', (int) $link->getCreated()) . ': ' . $link->getTitle() . PHP_EOL; }
2019-08-24 21:09: How do the kidneys know how much water to filter out of the blood they process? 2019-08-24 20:35: How do humans determine the location of sounds? 2019-08-24 18:44: With the Amazon fires what impact will it have on all the different wildlife there? ...
As you can see, the links get progressively older as the collection is iterated.
This example also demonstrates that the $subredditName
argument to the
Snuze::fetchLinks...()
methods is case-insensitive.
Fetching "Rising" Links
The Snuze::fetchLinksRising()
method lets you retrieve a subreddit's links sorted by upward vote momentum.
Here, we fetch the top 10 rising links from /r/Catloaf
:
foreach ($snuze->fetchLinksRising('catloaf', 10) as $link) { echo "Link ID {$link->getId()} has a score of {$link->getScore()} and " . "{$link->getNumComments()} comments" . PHP_EOL; }
Link ID cv15t8 has a score of 5 and 0 comments Link ID cutfmk has a score of 2129 and 11 comments Link ID cuuyji has a score of 453 and 4 comments ...
Also shown here are a few more of Link
's getter methods.
Fetching "Controversial" Links
The Snuze::fetchLinksControversial()
method retrieves the links in a subreddit which have seen the greatest
number of both upvotes and downvotes. Here, we fetch the current most controversial
single link from /r/ToolBand
.
foreach ($snuze->fetchLinksControversial('ToolBand', 1) as $link) { echo date('Y-m-d H:i', (int) $link->getCreated()) . ': ' . $link->getTitle() . PHP_EOL; }
2019-08-25 07:22: Deceiver!
Setting a time period
When requesting a "Controversial" link listing, you can specify an optional
time period
to widen or narrow the result set. Valid periods are 'hour', 'day', 'week',
'month', 'year', or 'all'; 'day' being the default. This example finds the most
controversial submission from /r/ToolBand
in the past year. Note that because
$period
is the 7th argument to the method, some placeholder values must be
passed for other arguments.
foreach ($snuze->fetchLinksControversial('ToolBand', 1, $after = null, $before = null, $count = null, $showAll = false, $period = 'year') as $link) { echo date('Y-m-d H:i', (int) $link->getCreated()) . ': ' . $link->getTitle() . PHP_EOL; }
2018-08-31 20:52: New Album Hits Stores Xmas 2018!
Fetching "Top" Links
The Snuze::fetchLinksTop()
method retrieves the highest scored links from a subreddit. Here, we fetch the
current top 50 links from /r/HotPeppers
:
foreach ($snuze->fetchLinksTop('HotPeppers', 50) as $link) { echo "'{$link->getTitle()}' link domain is: {$link->getDomain()}" . PHP_EOL; }
'Made some Pineapple Mango Ghost Pepper Jam' link domain is: i.redd.it 'Almost too pretty to pick' link domain is: i.redd.it 'Best looking pheno so far. Most of the others lack a tail' link domain is: i.redd.it ...
Setting a time period
When requesting a "Top" link listing, you can specify an optional
time period
to widen or narrow the result set. Valid periods are 'hour', 'day', 'week',
'month', 'year', or 'all'; 'day' being the default. This example finds the most
upvoted post from /r/HotPeppers
in the past year. Note that because
$period
is the 7th argument to the method, some placeholder values must be
passed for other arguments.
foreach ($snuze->fetchLinksTop('HotPeppers', 50, $after = null, $before = null, $count = null, $showAll = false, $period = 'year') as $link) { echo "'{$link->getTitle()}' has URL: {$link->getUrl()}" . PHP_EOL; }
'First harvest off my Carolina Reaper from Home Depot.' has URL: https://i.imgur.com/JtiGbTj.jpg
Fetching "Random" Links
The Snuze::fetchLinksRandom()
method lets you retrieve random links from a subreddit.
Here, we get 5 random submissions from /r/dogs
:
foreach ($snuze->fetchLinksRandom('dogs', 5) as $link) { echo "{$link->getAuthor()} submitted: {$link->getTitle()}" . PHP_EOL; }
wheretohides submitted: [Help] The vet said to put my dog on a grain diet Ph4zers submitted: [Help] Looking for a couch cover that is dog friendly Zeewulfeh submitted: [Vent] [Discussion] A Tale of Two Mutts ...
Under the hood, this method works differently than the others: a separate API request must be made for each random link. If you request a large number of random links, retrieving them will take some time and can run you over the API rate limit pretty quickly.
Paging Through Listings of Links
Reddit has a hard limit of 1,000 results for any collection. The API will stop returning data after 1,000 links.
The previous examples demonstrate getting a single group of links from a
subreddit's front page, sorted in various orders. Reddit's API returns a maximum
of 100 results at a time, so if you want to fetch more, you'll need to page
through the target subreddit in batches of 100. Paging over a subreddit is
accomplished by passing a couple extra arguments to the fetchLinks...()
methods:
-
$after
specifies the link ID that the next batch of results should start after; that is, you're telling the API that you've already seen all the links up through this one. -
$count
tells the API how many links you've already fetched.
The value to supply for $after
in your next request comes from the response
to your last request; you access it by calling getAfter()
on the LinkListing
object. You'll need to keep track of $count
on your own, but as you can see in
the example below, it's not hard to do.
Here's how you might get the hottest 500 links from /r/freebsd
:
/* A counter for how many links have been fetched */ $count = 0; /* Track the ID of the last link received from the API */ $after = null; while ($count < 500) { /* * Fetch the next batch of links. The first time through the loop, * $after is null and $count is 0; they get updated below. */ $links = $snuze->fetchLinksHot('freebsd', 100, $after, null, $count); /* Do something with the links */ foreach ($links as $link) { $idx = sprintf('%03d', @++$i); //For demonstration purposes only echo "{$idx}: {$link->getFullname()}: {$link->getTitle()}" . PHP_EOL; } /* * Update the value of $after by calling getAfter() on the LinkListing object. * Break if the API told us there are no more results. */ if (empty($after = $links->getAfter())) { break; } /* Update the number of links that have been seen */ $count += count($links); }
001: t3_czlppo: Dumb question about base system 002: t3_czq3hd: How to access backup drive ... 500: t3_ahku05: Firewall Syntax Error
Sometimes the API unexpectedly returns an empty listing, even when you know
there are more results. In that scenario, a loop like this will terminate
prematurely. If you've ever clicked next>
on Reddit's website only to be
greeted with "there doesn't seem to be anything here," this is the same behavior.
Fetching Accounts
Other Users' Accounts
To retrieve basic information about another user's account, call the
Snuze::fetchUser()
method. It accepts the target username as its sole argument, and returns a
UserAccount
object.
$user = $snuze->fetchUser('washingtonpost'); $created = date('Y-m-d', (int) $user->getCreated()); $gold = $user->getIsGold() ? "has" : "doesn't have"; echo "{$user->getName()} was created {$created}, has {$user->getCommentKarma()}" . " comment karma, and {$gold} gold" . PHP_EOL;
washingtonpost was created 2017-04-21, has 332613 comment karma, and has gold
Your Own Account
Reddit lets you obtain more extensive data about your own account, i.e.
the currently authenticated API user. Use the
Snuze::fetchMyAccount()
method to retrieve this information. It returns a
MyAccount
object.
$me = $snuze->fetchMyAccount(); $susp = $me->getIsSuspended() ? 'is' : "isn't"; echo "The current user {$susp} suspended, has {$me->getInboxCount()} " . "unread messages, and owns {$me->getGoldCreddits()} gold creddits" . PHP_EOL;
The current user isn't suspended, has 2 unread messages, and owns 0 gold creddits
Fetching Info for Arbitrary "Things"
Several types of entities can be fetched by ID in bulk mode. The
Snuze::fetchInfo()
method will retrieve up to 100 arbitrary subreddits, links, or comments (in any
combination thereof). It accepts an array of "thing" fullnames to identify your
targets, and returns an iterable
Listing
object.
$targets = ['t5_2qp8q', 't3_d1d3lu']; //Supply up to 100 fullnames $listing = $snuze->fetchInfo($targets); foreach ($listing as $thing) { echo "Got thing {$thing->getFullname()} of type " . get_class($thing) . PHP_EOL; }
Got thing t5_2qp8q of type snuze\Reddit\Thing\Subreddit Got thing t3_d1d3lu of type snuze\Reddit\Thing\Link
Retrieving entities in bulk with fetchInfo()
is a good strategy for reducing your
total API requests. Not only is this more efficient, it can help keep you under
the API rate limit.