auths
objectSearch for new HN stories with these keywords in the title (case-insensitive)
Slack channel to send stories to
return
or this.key = 'value'
, pass input data to your code viaparams
, and maintain state across executions with$checkpoint.async
(event, steps, params, auths) => {
}
const axios = require('axios')
const allSettled = require('promise.allsettled')
const get = require("lodash.get")
const { WebClient } = require('@slack/web-api')
// Keywords are comma-separated, so we convert into an array
const { keywords, channel } = params
var KEYWORDS = keywords.split(",").map(k => k.trim())
const HN_BASE_URL = "https://hacker-news.firebaseio.com/v0/"
// Fetch all top HN stories, filtering by keywords,
const topStories = (await axios.get(`${HN_BASE_URL}/topstories.json`)).data
if (!topStories) {
$end("No top stories found")
}
const responses = await allSettled(
topStories.map(topStory =>
axios.get(`${HN_BASE_URL}/item/${topStory}.json`)
)
)
// Pull previously-posted stories from this.$checkpoint.
// See https://docs.pipedream.com/workflows/steps/code/#step-level-state-this-checkpoint
const previouslyPostedStories = get(this, '$checkpoint', [])
const matchingStories = []
for (response of responses) {
const story = response.value.data
for (keyword of KEYWORDS) {
const re = new RegExp(keyword, 'gi')
if (story.title.match(re) && !previouslyPostedStories.includes(story.id)) {
console.log(`MATCHING TITLE: ${story.title}`)
matchingStories.push(story)
}
}
}
if (!matchingStories.length) {
$end("No new stories matching keywords")
}
// Send to Slack
const web = new WebClient(auths.slack.token)
for (story of matchingStories) {
const storyURL = story.url ? story.url : `https://news.ycombinator.com/item?id=${story.id}`
const text = `New Story on HN matching your keywords: <${storyURL}|${story.title}> (<https://news.ycombinator.com/item?id=${story.id}|comments>)`
await web.chat.postMessage({
channel,
text,
})
}
// Finally, store the processed stories in state so we don't process them next time
this.$checkpoint = previouslyPostedStories.concat(matchingStories.map(s => s.id))