2023-09-02 17:21:00 +00:00
|
|
|
const { ApolloClient, InMemoryCache, HttpLink, gql } = require('@apollo/client')
|
|
|
|
|
|
|
|
const ITEMS = gql`
|
|
|
|
query items ($sort: String, $when: String, $sub: String) {
|
|
|
|
items (sort: $sort, when: $when, sub: $sub) {
|
|
|
|
cursor
|
|
|
|
items {
|
|
|
|
id
|
|
|
|
title
|
|
|
|
url
|
|
|
|
ncomments
|
|
|
|
sats
|
|
|
|
company
|
|
|
|
maxBid
|
|
|
|
status
|
|
|
|
location
|
|
|
|
remote
|
|
|
|
boost
|
|
|
|
user {
|
|
|
|
id
|
|
|
|
name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`
|
|
|
|
|
2024-03-23 17:23:31 +00:00
|
|
|
const TOP_COWBOYS = gql`
|
|
|
|
query TopCowboys($cursor: String) {
|
|
|
|
topCowboys(cursor: $cursor) {
|
|
|
|
users {
|
|
|
|
name
|
|
|
|
optional {
|
|
|
|
streak
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cursor
|
|
|
|
}
|
|
|
|
}`
|
|
|
|
|
|
|
|
const TOP_USERS = gql`
|
|
|
|
query TopUsers($cursor: String, $when: String, $from: String, $to: String, $by: String, ) {
|
|
|
|
topUsers(cursor: $cursor, when: $when, from: $from, to: $to, by: $by) {
|
|
|
|
users {
|
|
|
|
name
|
|
|
|
optional {
|
|
|
|
stacked(when: $when, from: $from, to: $to)
|
|
|
|
spent(when: $when, from: $from, to: $to)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cursor
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`
|
|
|
|
|
2023-09-02 17:21:00 +00:00
|
|
|
const client = new ApolloClient({
|
|
|
|
link: new HttpLink({ uri: 'https://stacker.news/api/graphql' }),
|
|
|
|
cache: new InMemoryCache()
|
|
|
|
})
|
|
|
|
|
|
|
|
const abbrNum = n => {
|
2023-10-28 23:28:13 +00:00
|
|
|
if (n < 1e3) return n
|
|
|
|
if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(1) + 'k'
|
2023-09-02 17:21:00 +00:00
|
|
|
if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(1) + 'm'
|
|
|
|
if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(1) + 'b'
|
|
|
|
if (n >= 1e12) return +(n / 1e12).toFixed(1) + 't'
|
|
|
|
}
|
|
|
|
|
2024-06-22 20:23:15 +00:00
|
|
|
const SEARCH = gql`
|
|
|
|
query Search($q: String, $sort: String, $what: String, $when: String) {
|
|
|
|
search(q: $q, sort: $sort, what: $what, when: $when) {
|
|
|
|
items {
|
|
|
|
id
|
|
|
|
title
|
|
|
|
bountyPaidTo
|
2023-10-28 23:28:13 +00:00
|
|
|
}
|
2024-06-22 20:23:15 +00:00
|
|
|
}
|
|
|
|
}`
|
2023-10-28 23:28:13 +00:00
|
|
|
|
2024-06-22 20:23:15 +00:00
|
|
|
async function bountyWinner (q) {
|
2023-10-28 23:28:13 +00:00
|
|
|
const WINNER = gql`
|
|
|
|
query Item($id: ID!) {
|
|
|
|
item(id: $id) {
|
|
|
|
text
|
|
|
|
sats
|
|
|
|
imgproxyUrls
|
|
|
|
user {
|
|
|
|
name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`
|
|
|
|
|
|
|
|
const bounty = await client.query({
|
2024-06-22 20:23:15 +00:00
|
|
|
query: SEARCH,
|
2024-09-14 18:44:57 +00:00
|
|
|
variables: { q: `${q} @sn`, sort: 'recent', what: 'posts', when: 'week' }
|
2023-10-28 23:28:13 +00:00
|
|
|
})
|
|
|
|
|
2024-01-07 17:00:11 +00:00
|
|
|
const items = bounty.data.search.items.filter(i => i.bountyPaidTo?.length > 0)
|
|
|
|
if (items.length === 0) return
|
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
try {
|
|
|
|
const item = await client.query({
|
|
|
|
query: WINNER,
|
2024-01-07 17:00:11 +00:00
|
|
|
variables: { id: items[0].bountyPaidTo[0] }
|
2023-12-17 19:20:22 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
const winner = { ...item.data.item, image: Object.values(item.data.item.imgproxyUrls)[0]?.['640w'] }
|
2023-10-28 23:28:13 +00:00
|
|
|
|
2024-01-07 17:00:11 +00:00
|
|
|
return { bounty: items[0].id, winner }
|
2023-12-17 19:20:22 +00:00
|
|
|
} catch (e) {
|
2023-10-28 23:28:13 +00:00
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
}
|
2023-10-28 23:28:13 +00:00
|
|
|
}
|
|
|
|
|
2024-03-23 17:23:31 +00:00
|
|
|
async function getTopUsers ({ by, cowboys = false, includeHidden = false, count = 5, when = 'week' } = {}) {
|
|
|
|
const accum = []
|
|
|
|
let cursor = ''
|
|
|
|
try {
|
|
|
|
while (accum.length < count) {
|
|
|
|
let variables = {
|
|
|
|
cursor
|
|
|
|
}
|
|
|
|
if (!cowboys) {
|
|
|
|
variables = {
|
|
|
|
...variables,
|
|
|
|
by,
|
|
|
|
when
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const result = await client.query({
|
|
|
|
query: cowboys ? TOP_COWBOYS : TOP_USERS,
|
|
|
|
variables
|
|
|
|
})
|
|
|
|
cursor = result.data[cowboys ? 'topCowboys' : 'topUsers'].cursor
|
2024-08-31 19:04:49 +00:00
|
|
|
accum.push(...result.data[cowboys ? 'topCowboys' : 'topUsers'].users.filter(user => includeHidden ? true : !!user).filter(user => user.name !== 'k00b'))
|
2024-03-23 17:23:31 +00:00
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
return accum.slice(0, count)
|
|
|
|
}
|
|
|
|
|
2023-09-02 17:21:00 +00:00
|
|
|
async function main () {
|
2023-11-11 22:18:40 +00:00
|
|
|
const { quote } = await import('../lib/md.js')
|
|
|
|
|
2023-09-02 17:21:00 +00:00
|
|
|
const top = await client.query({
|
|
|
|
query: ITEMS,
|
|
|
|
variables: { sort: 'top', when: 'week' }
|
|
|
|
})
|
|
|
|
|
|
|
|
const meta = await client.query({
|
|
|
|
query: ITEMS,
|
|
|
|
variables: { sort: 'top', when: 'week', sub: 'meta' }
|
|
|
|
})
|
|
|
|
|
|
|
|
const jobs = await client.query({
|
|
|
|
query: ITEMS,
|
|
|
|
variables: { sub: 'jobs' }
|
|
|
|
})
|
|
|
|
|
2024-08-31 19:04:49 +00:00
|
|
|
// const thisDay = await client.query({
|
|
|
|
// query: SEARCH,
|
|
|
|
// variables: { q: 'This Day in Stacker News @Undisciplined', sort: 'recent', what: 'posts', when: 'week' }
|
|
|
|
// })
|
2024-06-22 20:23:15 +00:00
|
|
|
|
2024-01-21 19:23:52 +00:00
|
|
|
const topMeme = await bountyWinner('meme monday')
|
2023-10-28 23:28:13 +00:00
|
|
|
const topFact = await bountyWinner('fun fact')
|
|
|
|
|
2024-03-23 17:23:31 +00:00
|
|
|
const topCowboys = await getTopUsers({ cowboys: true })
|
|
|
|
const topStackers = await getTopUsers({ by: 'stacking' })
|
|
|
|
const topSpenders = await getTopUsers({ by: 'spent' })
|
|
|
|
|
2023-09-02 17:21:00 +00:00
|
|
|
process.stdout.write(
|
|
|
|
`Happy Sat-urday Stackers,
|
|
|
|
|
|
|
|
Have a great weekend!
|
|
|
|
|
|
|
|
##### Top Posts
|
2024-08-31 19:04:49 +00:00
|
|
|
${top.data.items.items.map((item, i) =>
|
2024-04-21 19:12:18 +00:00
|
|
|
`${i + 1}. [${item.title}](https://stacker.news/items/${item.id})
|
|
|
|
- ${abbrNum(item.sats)} sats${item.boost ? ` \\ ${abbrNum(item.boost)} boost` : ''} \\ ${item.ncomments} comments \\ [@${item.user.name}](https://stacker.news/${item.user.name})\n`).join('')}
|
2023-09-02 17:21:00 +00:00
|
|
|
|
|
|
|
##### Don't miss
|
2023-09-03 16:59:55 +00:00
|
|
|
${top.data.items.items.map((item, i) =>
|
2023-09-02 17:21:00 +00:00
|
|
|
`- [${item.title}](https://stacker.news/items/${item.id})\n`).join('')}
|
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
[**all of this week's top posts**](https://stacker.news/top/posts/week)
|
|
|
|
|
|
|
|
-------
|
|
|
|
|
2023-09-02 17:21:00 +00:00
|
|
|
##### Top meta
|
|
|
|
${meta.data.items.items.slice(0, 10).map((item, i) =>
|
|
|
|
`- [${item.title}](https://stacker.news/items/${item.id})\n`).join('')}
|
|
|
|
|
2024-06-22 20:23:15 +00:00
|
|
|
[**all meta**](https://stacker.news/~meta/top/posts/week)
|
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
-------
|
|
|
|
|
|
|
|
##### Top Monday meme \\ ${abbrNum(topMeme?.winner.sats)} sats \\ [@${topMeme?.winner.user.name}](https://stacker.news/${topMeme?.winner.user.name})
|
|
|
|
![](${topMeme?.winner.image})
|
2023-09-02 17:21:00 +00:00
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
[**all monday memes**](https://stacker.news/items/${topMeme?.bounty})
|
2023-10-28 23:28:13 +00:00
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
------
|
2023-10-28 23:28:13 +00:00
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
##### Top Friday fun fact \\ ${abbrNum(topFact?.winner.sats)} sats \\ [@${topFact?.winner.user.name}](https://stacker.news/${topFact?.winner.user.name})
|
2024-01-21 19:23:52 +00:00
|
|
|
${topFact && quote(topFact?.winner.text)}
|
2023-10-28 23:28:13 +00:00
|
|
|
|
2024-01-21 19:23:52 +00:00
|
|
|
[**all friday fun facts**](https://stacker.news/items/${topFact?.bounty})
|
2023-10-28 23:28:13 +00:00
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
------
|
|
|
|
|
2024-03-23 17:23:31 +00:00
|
|
|
##### Top Stackers
|
|
|
|
${topStackers.map((user, i) =>
|
|
|
|
`${i + 1}. [@${user.name}](https://stacker.news/${user.name}): ${abbrNum(user.optional.stacked)} sats stacked`
|
|
|
|
).join('\n')}
|
|
|
|
|
|
|
|
------
|
|
|
|
|
|
|
|
##### Top Spenders
|
|
|
|
${topSpenders.map((user, i) =>
|
|
|
|
`${i + 1}. [@${user.name}](https://stacker.news/${user.name}): ${abbrNum(user.optional.spent)} sats spent`
|
|
|
|
).join('\n')}
|
|
|
|
|
|
|
|
------
|
|
|
|
|
|
|
|
##### Top Cowboys
|
|
|
|
${topCowboys.map((user, i) =>
|
|
|
|
`${i + 1}. [@${user.name}](https://stacker.news/${user.name}): ${user.optional.streak} days`
|
|
|
|
).join('\n')}
|
|
|
|
|
|
|
|
------
|
|
|
|
|
2023-09-02 17:21:00 +00:00
|
|
|
##### Promoted jobs
|
|
|
|
${jobs.data.items.items.filter(i => i.maxBid > 0 && i.status === 'ACTIVE').slice(0, 5).map((item, i) =>
|
|
|
|
`${i + 1}. [${item.title.trim()} \\ ${item.company} \\ ${item.location}${item.remote ? ' or Remote' : ''}](https://stacker.news/items/${item.id})\n`).join('')}
|
|
|
|
|
|
|
|
[**all jobs**](https://stacker.news/~jobs)
|
|
|
|
|
2023-12-17 19:20:22 +00:00
|
|
|
------
|
|
|
|
|
2023-09-02 17:21:00 +00:00
|
|
|
Yeehaw,
|
|
|
|
Keyan
|
|
|
|
A guy who works on Stacker News
|
|
|
|
|
2024-01-07 16:43:00 +00:00
|
|
|
[Watch](https://www.youtube.com/@stackernews/live) or [Listen](https://www.fountain.fm/show/Mg1AWuvkeZSFhsJZ3BW2) to SN's top stories every week.
|
|
|
|
|
|
|
|
Get this newsletter sent to your email inbox by signing up [here](https://mail.stacker.news/subscription/form).`)
|
2023-09-02 17:21:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
main()
|