-
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #414 from sfrunza13/issue-410-sf
issue410 on first click searchbar shows top 5 subreddits by popularity
- Loading branch information
Showing
2 changed files
with
140 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import type {NextRequest} from 'next/server' | ||
|
||
export const config = { | ||
runtime: 'experimental-edge' | ||
} | ||
|
||
/** | ||
* Popular Subreddit Reddit API. | ||
* | ||
* @example | ||
* /api/preSearch?limit=5 | ||
* | ||
* @see https://www.reddit.com/dev/api#GET_subreddits_{where} | ||
* @see https://nextjs.org/docs/api-routes/edge-api-routes | ||
* @see https://nextjs.org/docs/api-reference/edge-runtime | ||
*/ | ||
export default async function search(req: NextRequest) { | ||
// Parse and sanitize query params from request. | ||
const limit = req.nextUrl.searchParams.get('limit') || '5' | ||
|
||
try { | ||
// Generate random device ID. | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues | ||
const array = new Uint32Array(24) | ||
const deviceId = self.crypto.getRandomValues(array) | ||
|
||
// Try and fetch a new access token. | ||
const tokenResponse = await fetch( | ||
`https://www.reddit.com/api/v1/access_token?grant_type=client_credentials&device_id=${deviceId}`, | ||
{ | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json charset=UTF-8', | ||
'User-Agent': 'reddit-image-viewer/* by Greg Rickaby', | ||
Authorization: `Basic ${btoa( | ||
`${process.env.REDDIT_CLIENT_ID}:${process.env.REDDIT_CLIENT_SECRET}` | ||
)}` | ||
} | ||
} | ||
) | ||
|
||
// Bad response? Bail... | ||
if (tokenResponse.status != 200) { | ||
return new Response( | ||
JSON.stringify({ | ||
error: `${tokenResponse.statusText}` | ||
}), | ||
{ | ||
status: tokenResponse.status, | ||
statusText: tokenResponse.statusText | ||
} | ||
) | ||
} | ||
|
||
// Get the access token. | ||
const token = await tokenResponse.json() | ||
|
||
// Issue with token? Bail... | ||
if (token.error) { | ||
return new Response( | ||
JSON.stringify({ | ||
error: token.error | ||
}), | ||
{ | ||
status: token.status, | ||
statusText: token.statusText | ||
} | ||
) | ||
} | ||
|
||
// Attempt to fetch subreddits. | ||
const response = await fetch( | ||
`https://oauth.reddit.com/subreddits/popular?limit=${limit}`, | ||
{ | ||
headers: { | ||
authorization: `Bearer ${token.access_token}` | ||
} | ||
} | ||
) | ||
|
||
// No response? Bail... | ||
if (response.status != 200) { | ||
return new Response( | ||
JSON.stringify({ | ||
error: `${response.statusText}` | ||
}), | ||
{ | ||
status: response.status, | ||
statusText: response.statusText | ||
} | ||
) | ||
} | ||
|
||
// Parse the response. | ||
const subs = await response.json() | ||
|
||
// No data in the response? Bail... | ||
if (!subs.data && !subs.data.children.length) { | ||
return new Response( | ||
JSON.stringify({ | ||
error: `No data returned from Reddit.` | ||
}), | ||
{ | ||
status: 400, | ||
statusText: 'Bad Request' | ||
} | ||
) | ||
} | ||
|
||
// Filter uneeded data to keep the payload small. | ||
const filtered = subs.data.children.map( | ||
(sub: {data: {over18?: string; url?: string; display_name?: string}}) => { | ||
return { | ||
over_18: sub.data.over18 ? true : false, | ||
url: sub.data.url ? sub.data.url : '', | ||
value: sub.data.display_name ? sub.data.display_name : '' | ||
} | ||
} | ||
) | ||
|
||
// Send the response. | ||
return new Response(JSON.stringify(filtered), { | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'Cache-Control': 'public, s-maxage=1, stale-while-revalidate=59' | ||
}, | ||
status: 200, | ||
statusText: 'OK' | ||
}) | ||
} catch (error) { | ||
// Issue? Leave a message and bail. | ||
console.error(error) | ||
return new Response(JSON.stringify({error: `${error}`}), { | ||
status: 500, | ||
statusText: 'Internal Server Error' | ||
}) | ||
} | ||
} |
756af7c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
reddit-image-viewer – ./
reddit-image-viewer.vercel.app
reddit-image-viewer-git-main-gregrickaby.vercel.app
reddit-image-viewer-gregrickaby.vercel.app