Every morning, has Claude pick the ten best stories logged in your news sheet, emails them to you with links, and clears the sheet.
Uses
Claude
Gmail
Google Sheets
Daily news digest from your sheet
Every morning at 08:00, the stories another workflow has been logging into your news sheet are read, the ones most worth your time are chosen by AI against the interests you describe, and one plain text email with a summary and link for each lands in your inbox. Once it has gone, the tab is cleared so tomorrow's digest starts from tomorrow's stories.
Every headline and link in the email is looked up in the sheet itself, so nothing in your inbox is invented. If the tab is empty you still get an email saying so, because that usually means whatever fills it has stopped. If the sheet cannot be read, the ranking cannot be understood or the email cannot be sent, the run stops and the sheet is left untouched, so nothing is lost. The tab is cleared only after the email has been sent, and its header row is put back so logging can carry on.
Any columns will do in the news tab, though a title, a link and a summary make for a better digest.
newsSheetUrl to blank.Set newsSheetUrl to blank.newsTab to News.Set newsTab to News.recipientEmail to blank.Set recipientEmail to blank.interests to blank.Set interests to blank.digestSize to 10.Set digestSize to 10.maxStoriesToRank to 250.Set maxStoriesToRank to 250.today.Get today's date and save it as today.dateLabel to the weekday name of today today.Set dateLabel to the weekday name of today today.sheet to nothing.Set sheet to nothing.readErrorIf a step below fails, save the error as readErrornewsSheetUrl. Save it as sheet.Read the rows of newsSheetUrl. Save it as sheet.readError.message). Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.Stop and report a problem: The news sheet could not be read (readError.message). Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.stories to sheet.rows.Set stories to sheet.rows.stories and save it as totalLogged.Count the items in stories and save it as totalLogged.totalLogged is 0If totalLogged is 0recipientEmail.Send an email to recipientEmail.
Subject: Daily news digest - nothing logged - dateLabelNo stories were logged in the '@newsTab' tab since the last digest, so there is nothing to send today. It is worth checking that whatever fills that sheet is still running.capped to false.Set capped to false.totalLogged is greater than maxStoriesToRankIf totalLogged is greater than maxStoriesToRankstories from position totalLogged minus maxStoriesToRank on and save it as stories.Take stories from position totalLogged minus maxStoriesToRank on and save it as stories.capped to true.Change capped to true.catalogue to an empty list.Set catalogue to an empty list.position to 0.Set position to 0.story in stories:For each story in stories:position.Add 1 to position.positionAdd Story position
story as a bulleted list truncated to 600 characters using ... as the ellipsis to the end of catalogue and save it as catalogue.catalogue with a blank line and save it as catalogueText.Join catalogue with a blank line and save it as catalogueText.audience to a general reader, judged by significance, novelty and usefulness.Set audience to a general reader, judged by significance, novelty and usefulness.interests isn't blankIf interests isn't blankaudience to a reader who has said they care about: interests.Change audience to a reader who has said they care about: interests.ranked to nothing.Set ranked to nothing.rankingErrorIf a step below fails, save the error as rankingErrorstories news stories logged since the last digest, each labelled 'Story' and a number, with the fields that were recorded for it. Choose the digestSize most worth reading for audience.Ask Claude: 'Below are the length of stories news stories logged since the last digest, each labelled 'Story' and a number, with the fields that were recorded for it. Choose the digestSize most worth reading for audience.
Reply with the numbers of the stories you choose and nothing else: best first, one number per line. No titles, no reasons, no headings. Never give a number that is not in the list. If fewer stories than asked for are genuinely worth the reader's time, give fewer.
Prefer stories that are significant, new rather than repeated, and useful to act on or worth knowing. When several rows report the same event, choose one of them.
The stories:
catalogueText'. Save it as ranked.
Maximum response length: 400rankingError.message). Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.Stop and report a problem: Claude could not rank today's stories (rankingError.message). Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.ranked.response_text and save it as rankingText.Trim ranked.response_text and save it as rankingText.rankingText and save it as picks.Extract all matches from rankingText and save it as picks.chosen to an empty list.Set chosen to an empty list.chosenPositions to an empty list.Set chosenPositions to an empty list.pick in picks:For each pick in picks:number to +pick.Set number to +pick.chosen is less than digestSize and number is greater than or…If the length of chosen is less than digestSize and number is greater than or…stories[number minus 1] to the end of chosen and save it as chosen.Add stories[number minus 1] to the end of chosen and save it as chosen.number to the end of chosenPositions and save it as chosenPositions.Add number to the end of chosenPositions and save it as chosenPositions.chosen is emptyIf chosen is emptyrankingText truncated to 300 characters using ... as the ellipsis Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.Stop and report a problem: Claude's ranking could not be read as a list of story numbers. It replied: rankingText truncated to 300 characters using ... as the ellipsis Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.shortlist to an empty list.Set shortlist to an empty list.rank to 0.Set rank to 0.story in chosen:For each story in chosen:rank.Add 1 to rank.rankAdd Story rank
story as a bulleted list truncated to 1500 characters using ... as the ellipsis to the end of shortlist and save it as shortlist.shortlist with a blank line and save it as shortlistText.Join shortlist with a blank line and save it as shortlistText.emailBody to blank.Set emailBody to blank.writingErrorIf a step below fails, save the error as writingErrordateLabel. Below are the the length of chosen news stories chosen for today's digest, best first, each with the fields that were logged for it (usually a title, a link and a summary, sometimes a source and a date).Ask Claude: 'Today is dateLabel. Below are the the length of chosen news stories chosen for today's digest, best first, each with the fields that were logged for it (usually a title, a link and a summary, sometimes a source and a date).
Write the email that delivers these stories. Rules you must follow:
- Plain text only. No Markdown, no HTML, no asterisks, hashes or underscores: this is sent as a plain-text email.
- Open with a one-line greeting for the day, then two or three sentences on what today's stories have in common or what stands out.
- Then the stories, numbered, in the order given. For each one: the headline on its own line, one to three sentences of summary, then the link on its own line exactly as it appears in the fields below.
- Use only what the fields below say. Do not invent facts, figures, quotes or links, and do not add stories. If a story's fields say little, say little.
- Close with one short line. Output only the body of the email: no subject line.
The stories, best first:
shortlistText'. Save it as written.
Maximum response length: 2500written.response_text and save it as emailBody.Trim written.response_text and save it as emailBody.writingError.message). Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.Stop and report a problem: Claude could not write today's digest (writingError.message). Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.emailBody is emptyIf emailBody is emptyfooter to Set footer to
---
Chosen from totalLogged stories logged in the '@newsTab' tab since the last digest.capped is yesIf capped is yesfooter to footer Only the newest maxStoriesToRank were ranked.Change footer to footer Only the newest maxStoriesToRank were ranked.sendErrorIf a step below fails, save the error as sendErrorrecipientEmail.Send an email to recipientEmail.
Subject: Daily news digest - dateLabelemailBody plus footersendError.message). Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.Stop and report a problem: The digest could not be sent (sendError.message). Nothing was sent and the sheet was left as it is, so tomorrow's digest will have today's stories to choose from as well.headerRow to an empty list.Set headerRow to an empty list.headerErrorIf a step below fails, save the error as headerErrornewsTab in newsSheetUrl. Save it as headerCells.Read row 1 of newsTab in newsSheetUrl. Save it as headerCells.headerRow to headerCells.values.Change headerRow to headerCells.values.headerError.message), so the sheet was not cleared. Clear it by hand before tomorrow's stories arrive, or tomorrow's digest will repeat today's.Stop and report a problem: The digest was sent, but the header row of the news sheet could not be read (headerError.message), so the sheet was not cleared. Clear it by hand before tomorrow's stories arrive, or tomorrow's digest will repeat today's.headerRow is emptyIf headerRow is emptyclearErrorIf a step below fails, save the error as clearErrornewsTab in newsSheetUrl.Clear the tab newsTab in newsSheetUrl.clearError.message). Clear it by hand before tomorrow's stories arrive, or tomorrow's digest will repeat today's.Stop and report a problem: The digest was sent, but the news sheet could not be cleared (clearError.message). Clear it by hand before tomorrow's stories arrive, or tomorrow's digest will repeat today's.restoreErrorIf a step below fails, save the error as restoreErrornewsTab in newsSheetUrl.Overwrite row 1 of newsTab in newsSheetUrl.restoreError.message). Put this header row back before tomorrow's stories arrive: headerRow joined by , .Stop and report a problem: The digest was sent and the news sheet was cleared, but its header row could not be written back (restoreError.message). Put this header row back before tomorrow's stories arrive: headerRow joined by , .chosen stories chosen from totalLogged and cleared the '@newsTab' tab for tomorrow.Show in the output: Sent a digest of the length of chosen stories chosen from totalLogged and cleared the '@newsTab' tab for tomorrow.