Reads the pages you name each morning, keeps only the lines matching your brief, and posts them to Slack with their source.

UsesClaudeJina AISlack

Digest the sources you watch into Slack

Every morning at 08:00, each page you have named, a vendor's changelog, a regulator's notices page, a competitor's blog, is read, and only the lines that match what you care about are kept. Those lines are posted to one Slack channel, each with the address it came from.

Every line posted is quoted from the page word for word: a suggested line that does not appear on the page is dropped and counted, never posted. No summary, ranking or opinion is added, so the judgement stays yours. Exactly one message is posted per run, including on days when nothing matched, so silence is never ambiguous. A page that cannot be read is reported by its host name only, never by the full address, in case it carries a key, and each run is bounded in how many sources it reads and lines it posts.

You need the page addresses to watch, a short brief of what matters to you, and a Slack channel. There is no memory between runs, so a page that says the same thing tomorrow is quoted again.

ScheduleRun every day at 08:00.Run every day at 08:00.
ValuesSet sourceUrls to blank.Set sourceUrls to blank.
ValuesSet readerBrief to blank.Set readerBrief to blank.
ValuesSet slackChannelId to blank.Set slackChannelId to blank.
ValuesSet maxSourcesPerRun to 8.Set maxSourcesPerRun to 8.
ValuesSet maxLinesPerRun to 12.Set maxLinesPerRun to 12.
TextSplit sourceUrls by , and save it as sources.Split sourceUrls by , and save it as sources.
ValuesSet keptLines to an empty list.Set keptLines to an empty list.
ValuesSet sourcesRead to 0.Set sourcesRead to 0.
ValuesSet sourcesSkipped to 0.Set sourcesSkipped to 0.
ValuesSet linesRejected to 0.Set linesRejected to 0.
Decisions & LoopsFor each source in sources:For each source in sources:
TextTrim source and save it as sourceUrl.Trim source and save it as sourceUrl.
Decisions & LoopsIf sourceUrl is emptyIf sourceUrl is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf the length of keptLines is greater than or equal to maxLinesPerRun multiplied…If the length of keptLines is greater than or equal to maxLinesPerRun multiplied…
Yes
Decisions & LoopsStop repeating.Stop repeating.
No
No steps
Decisions & LoopsIf sourcesRead is greater than or equal to maxSourcesPerRun multiplied by 1If sourcesRead is greater than or equal to maxSourcesPerRun multiplied by 1
Yes
Decisions & LoopsStop repeating.Stop repeating.
No
No steps
Decisions & LoopsIf sourceUrl doesn't start with http (ignoring case)If sourceUrl doesn't start with http (ignoring case)
Yes
ValuesAdd 1 to sourcesSkipped.Add 1 to sourcesSkipped.
ValuesShow in the output: One entry in 'sourceUrls' is not a web address starting with http, so it was skipped..Show in the output: One entry in 'sourceUrls' is not a web address starting with http, so it was skipped..
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ValuesAdd 1 to sourcesRead.Add 1 to sourcesRead.
ListsGet the first item of sourceUrl with https:// replaced by with http:// replaced by split by / and save it as sourceHost.Get the first item of sourceUrl with https:// replaced by with http:// replaced by split by / and save it as sourceHost.
ValuesSet pageText to blank.Set pageText to blank.
ValuesSet pageTitle to blank.Set pageTitle to blank.
Decisions & LoopsIf a step below fails, save the error as readErrorIf a step below fails, save the error as readError
Try
Jina AIJina AIRead the page at sourceUrl with Jina. Save it as page.Read the page at sourceUrl with Jina. Save it as page.
TextTrim page.content and save it as pageText.Trim page.content and save it as pageText.
TextTrim page.title and save it as pageTitle.Trim page.title and save it as pageTitle.
On error
TextReplace sourceUrl with the source address in readError.message and save it as readNote.Replace sourceUrl with the source address in readError.message and save it as readNote.
Decisions & LoopsIf readNote contains :// (ignoring case)If readNote contains :// (ignoring case)
Yes
ValuesChange readNote to the page could not be read.Change readNote to the page could not be read.
No
No steps
ValuesShow in the output: Could not read sourceHost: readNote.Show in the output: Could not read sourceHost: readNote.
Decisions & LoopsIf the length of pageText is less than 200If the length of pageText is less than 200
Yes
ValuesAdd 1 to sourcesSkipped.Add 1 to sourcesSkipped.
ValuesShow in the output: There was not enough readable text at sourceHost to filter this run.Show in the output: There was not enough readable text at sourceHost to filter this run.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ValuesSet promptIntro to You are filtering one web page for one reader.Set promptIntro to You are filtering one web page for one reader. The reader cares about: readerBrief .
ValuesSet prompt to promptIntroReturn at most three lines from the page that match what the reader cares about. Copy each line word for word from the page. Do not summarise it, rewrite it, translate it, rank it, or add any judgement, conclusion or opinion of your own. Separate the lines with |||. If nothing on the page matches, reply with the single word NONE and nothing else.Set prompt to promptIntroReturn at most three lines from the page that match what the reader cares about. Copy each line word for word from the page. Do not summarise it, rewrite it, translate it, rank it, or add any judgement, conclusion or opinion of your own. Separate the lines with |||. If nothing on the page matches, reply with the single word NONE and nothing else. Page title: pageTitle Page text: pageText truncated to 4000 characters.
ValuesSet answerText to blank.Set answerText to blank.
Decisions & LoopsIf a step below fails, save the error as filterErrorIf a step below fails, save the error as filterError
Try
TextTrim the response text from the Claude “Ask Claude” step and save it as answerText.Trim the response text from the Claude “Ask Claude” step and save it as answerText.
On error
ValuesShow in the output: The filter step did not answer for sourceHost this run, so nothing from it was posted.Show in the output: The filter step did not answer for sourceHost this run, so nothing from it was posted.
Decisions & LoopsIf answerText is emptyIf answerText is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsFor each suggestedLine in answerText split by |||:For each suggestedLine in answerText split by |||:
TextTrim suggestedLine and save it as candidateLine.Trim suggestedLine and save it as candidateLine.
Decisions & LoopsIf candidateLine is emptyIf candidateLine is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf candidateLine in lowercase is noneIf candidateLine in lowercase is none
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf the length of keptLines is greater than or equal to maxLinesPerRun multiplied…If the length of keptLines is greater than or equal to maxLinesPerRun multiplied…
Yes
Decisions & LoopsStop repeating.Stop repeating.
No
No steps
Decisions & LoopsIf pageText doesn't contain candidateLine (ignoring case)If pageText doesn't contain candidateLine (ignoring case)
Yes
ValuesAdd 1 to linesRejected.Add 1 to linesRejected.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ListsAdd - candidateLine truncated to 300 charactersAdd - candidateLine truncated to 300 characters sourceUrl to the end of keptLines and save it as keptLines.
ValuesSet digestHeader to From the sources you follow - read sourcesRead of them this run.Set digestHeader to From the sources you follow - read sourcesRead of them this run.
ValuesSet messageText to digestHeaderSet messageText to digestHeader Nothing on those pages matched your brief this run.
Decisions & LoopsIf keptLines isn't emptyIf keptLines isn't empty
Yes
ValuesChange messageText to digestHeaderChange messageText to digestHeader keptLines joined by a new line Every line above is quoted from the page it links to.
No
No steps
ValuesSet footer to blank.Set footer to blank.
Decisions & LoopsIf sourcesSkipped is greater than 0If sourcesSkipped is greater than 0
Yes
ValuesChange footer to Change footer to sourcesSkipped source(s) could not be read or had too little text to use.
No
No steps
Decisions & LoopsIf linesRejected is greater than 0If linesRejected is greater than 0
Yes
ValuesChange footer to footerChange footer to footer linesRejected suggested line(s) were dropped because they did not appear on the page word for word.
No
No steps
SlackSlackSend a message to slackChannelId.Send a message to slackChannelId.messageText plus footer truncated to 3500 characters
ValuesShow in the output: Posted the length of keptLines line(s) to Slack from sourcesRead source(s).Show in the output: Posted the length of keptLines line(s) to Slack from sourcesRead source(s).