Every morning, turns the news logged in your sheet into LinkedIn post ideas for your area of interest, emails them, and clears the sheet.

UsesClaudeGmailGoogle Sheets

Get LinkedIn post ideas from the news in your sheet

Every morning at 08:00, the stories another workflow has been logging into your news sheet are read, the ones with the most to offer someone who posts about your area of interest are chosen by AI, and one plain text email lands in your inbox with a post idea for each: a hook, an angle, talking points, a suggested format and the source link. Once it has gone, the tab is cleared so tomorrow's ideas come from tomorrow's news.

Every headline and link in the email is looked up in the sheet itself, so nothing in your inbox is invented, and the ideas are prompts to write from in your own voice rather than finished posts. If the tab holds nothing usable 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 better ideas.

ScheduleRun every day at 08:00.Run every day at 08:00.
ValuesSet newsSheetUrl to blank.Set newsSheetUrl to blank.
ValuesSet newsTab to News.Set newsTab to News.
ValuesSet recipientEmail to blank.Set recipientEmail to blank.
ValuesSet areaOfInterest to blank.Set areaOfInterest to blank.
ValuesSet ideasPerEmail to 5.Set ideasPerEmail to 5.
ValuesSet maxStoriesToRank to 250.Set maxStoriesToRank to 250.
TextTrim areaOfInterest and save it as interest.Trim areaOfInterest and save it as interest.
Dates & TimesGet today's date and save it as today.Get today's date and save it as today.
ValuesSet dateLabel to the weekday name of today today.Set dateLabel to the weekday name of today today.
ValuesSet sheet to nothing.Set sheet to nothing.
Decisions & LoopsIf a step below fails, save the error as readErrorIf a step below fails, save the error as readError
Try
Google SheetsGoogle SheetsRead the rows of newsSheetUrl. Save it as sheet.Read the rows of newsSheetUrl. Save it as sheet.
On error
Decisions & LoopsStop 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 email 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 email will have today's stories to choose from as well.
ListsCount the items in sheet.rows and save it as totalLogged.Count the items in sheet.rows and save it as totalLogged.
ListsKeep each item in sheet.rows where the first match in item as text isn't empty and save it as stories.Keep each item in sheet.rows where the first match in item as text isn't empty and save it as stories.
ListsCount the items in stories and save it as usable.Count the items in stories and save it as usable.
Decisions & LoopsIf usable is 0If usable is 0
Yes
GmailGmailSend an email to recipientEmail.Send an email to recipientEmail. Subject: LinkedIn content ideas - nothing logged - dateLabelNo stories were logged in the '@newsTab' tab since the last email, so there are no content ideas today. It is worth checking that whatever fills that sheet is still running.
Decisions & LoopsFinish the run: The news sheet held nothing usable; sent a note saying so instead of ideas.Finish the run: The news sheet held nothing usable; sent a note saying so instead of ideas.
No
No steps
ValuesSet capped to false.Set capped to false.
Decisions & LoopsIf usable is greater than maxStoriesToRankIf usable is greater than maxStoriesToRank
Yes
ListsTake stories from position usable minus maxStoriesToRank on and save it as stories.Take stories from position usable minus maxStoriesToRank on and save it as stories.
ValuesChange capped to true.Change capped to true.
No
No steps
ValuesSet catalogue to an empty list.Set catalogue to an empty list.
ValuesSet position to 0.Set position to 0.
Decisions & LoopsFor each story in stories:For each story in stories:
ValuesAdd 1 to position.Add 1 to position.
ListsAdd Story 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.
TextJoin catalogue with a blank line and save it as catalogueText.Join catalogue with a blank line and save it as catalogueText.
ValuesSet ranked to nothing.Set ranked to nothing.
Decisions & LoopsIf a step below fails, save the error as rankingErrorIf a step below fails, save the error as rankingError
Try
ClaudeClaudeAsk Claude: 'You help someone who posts on LinkedIn about: interest.Ask Claude: 'You help someone who posts on LinkedIn about: interest. Below are the length of stories news stories logged since their last email, each labelled 'Story' and a number, with the fields that were recorded for it. Choose the ideasPerEmail that would make the best LinkedIn posts for them: stories their audience would care about, that give them something to say in their own area, and that are new rather than repeated. 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 genuinely suit their area, give fewer. When several rows report the same event, choose one of them. The stories: catalogueText'. Save it as ranked. Maximum response length: 400
On error
Decisions & LoopsStop 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 email 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 email will have today's stories to choose from as well.
TextTrim ranked.response_text and save it as rankingText.Trim ranked.response_text and save it as rankingText.
TextExtract all matches from rankingText and save it as picks.Extract all matches from rankingText and save it as picks.
ValuesSet chosen to an empty list.Set chosen to an empty list.
ValuesSet chosenPositions to an empty list.Set chosenPositions to an empty list.
Decisions & LoopsFor each pick in picks:For each pick in picks:
ValuesSet number to +pick.Set number to +pick.
Decisions & LoopsIf the length of chosen is less than ideasPerEmail and number is greater than or…If the length of chosen is less than ideasPerEmail and number is greater than or…
Yes
ListsAdd 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.
ListsAdd number to the end of chosenPositions and save it as chosenPositions.Add number to the end of chosenPositions and save it as chosenPositions.
No
No steps
Decisions & LoopsIf chosen is emptyIf chosen is empty
Yes
Decisions & LoopsStop 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 email 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 email will have today's stories to choose from as well.
No
No steps
ValuesSet shortlist to an empty list.Set shortlist to an empty list.
ValuesSet rank to 0.Set rank to 0.
Decisions & LoopsFor each story in chosen:For each story in chosen:
ValuesAdd 1 to rank.Add 1 to rank.
ListsAdd Story 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.
TextJoin shortlist with a blank line and save it as shortlistText.Join shortlist with a blank line and save it as shortlistText.
ValuesSet emailBody to blank.Set emailBody to blank.
Decisions & LoopsIf a step below fails, save the error as writingErrorIf a step below fails, save the error as writingError
Try
ClaudeClaudeAsk Claude: 'Today is dateLabel. You are writing for someone who posts on LinkedIn about: interest.Ask Claude: 'Today is dateLabel. You are writing for someone who posts on LinkedIn about: interest. Below are the the length of chosen news stories chosen as today's raw material, 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 turns each story into one LinkedIn post idea. 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 one or two sentences on the thread running through today's stories. - Then the ideas, numbered, in the order given. For each one give, on separate lines: Hook - the opening line the post could start with, written in their voice and specific to their area; Angle - one or two sentences on the take they could bring to it and why their audience would care; Talking points - two or three short lines drawn only from the story's fields; Format - one suggestion such as a short opinion, a numbered list, a personal story or a question to the audience; Source - 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, keep its idea short. - 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: 3000
TextTrim written.response_text and save it as emailBody.Trim written.response_text and save it as emailBody.
On error
Decisions & LoopsStop and report a problem: Claude could not write today's content ideas (writingError.message). Nothing was sent and the sheet was left as it is, so tomorrow's email will have today's stories to choose from as well.Stop and report a problem: Claude could not write today's content ideas (writingError.message). Nothing was sent and the sheet was left as it is, so tomorrow's email will have today's stories to choose from as well.
Decisions & LoopsIf emailBody is emptyIf emailBody is empty
Yes
Decisions & LoopsStop and report a problem: Claude returned an empty email. Nothing was sent and the sheet was left as it is, so tomorrow's email will have today's stories to choose from as well.Stop and report a problem: Claude returned an empty email. Nothing was sent and the sheet was left as it is, so tomorrow's email will have today's stories to choose from as well.
No
No steps
ValuesSet footer to Set footer to --- Chosen from usable stories logged in the '@newsTab' tab since the last email, for someone posting about: interest.
Decisions & LoopsIf capped is yesIf capped is yes
Yes
ValuesChange footer to footer Only the newest maxStoriesToRank were ranked.Change footer to footer Only the newest maxStoriesToRank were ranked.
No
No steps
Decisions & LoopsIf a step below fails, save the error as sendErrorIf a step below fails, save the error as sendError
Try
GmailGmailSend an email to recipientEmail.Send an email to recipientEmail. Subject: LinkedIn content ideas - dateLabelemailBody plus footer
On error
Decisions & LoopsStop and report a problem: The content ideas could not be sent (sendError.message). Nothing was sent and the sheet was left as it is, so tomorrow's email will have today's stories to choose from as well.Stop and report a problem: The content ideas could not be sent (sendError.message). Nothing was sent and the sheet was left as it is, so tomorrow's email will have today's stories to choose from as well.
ValuesSet headerRow to an empty list.Set headerRow to an empty list.
Decisions & LoopsIf a step below fails, save the error as headerErrorIf a step below fails, save the error as headerError
Try
Google SheetsGoogle SheetsRead row 1 of newsTab in newsSheetUrl. Save it as headerCells.Read row 1 of newsTab in newsSheetUrl. Save it as headerCells.
ValuesChange headerRow to headerCells.values.Change headerRow to headerCells.values.
On error
Decisions & LoopsStop and report a problem: The content ideas were 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 email will repeat today's.Stop and report a problem: The content ideas were 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 email will repeat today's.
Decisions & LoopsIf headerRow is emptyIf headerRow is empty
Yes
Decisions & LoopsStop and report a problem: The content ideas were sent, but the first row of the news sheet is empty, so there is no header to put back after clearing. The sheet was left as it is: clear it by hand before tomorrow's stories arrive, or tomorrow's email will repeat today's.Stop and report a problem: The content ideas were sent, but the first row of the news sheet is empty, so there is no header to put back after clearing. The sheet was left as it is: clear it by hand before tomorrow's stories arrive, or tomorrow's email will repeat today's.
No
No steps
Decisions & LoopsIf a step below fails, save the error as clearErrorIf a step below fails, save the error as clearError
Try
Google SheetsGoogle SheetsClear the tab newsTab in newsSheetUrl.Clear the tab newsTab in newsSheetUrl.
On error
Decisions & LoopsStop and report a problem: The content ideas were sent, but the news sheet could not be cleared (clearError.message). Clear it by hand before tomorrow's stories arrive, or tomorrow's email will repeat today's.Stop and report a problem: The content ideas were sent, but the news sheet could not be cleared (clearError.message). Clear it by hand before tomorrow's stories arrive, or tomorrow's email will repeat today's.
Decisions & LoopsIf a step below fails, save the error as restoreErrorIf a step below fails, save the error as restoreError
Try
Google SheetsGoogle SheetsOverwrite row 1 of newsTab in newsSheetUrl.Overwrite row 1 of newsTab in newsSheetUrl.
On error
Decisions & LoopsStop and report a problem: The content ideas were sent, but although the news sheet was cleared, its header row could not be written back (restoreError.message). Put this header row back before tomorrow's stories arrive: headerRow joined by , .Stop and report a problem: The content ideas were sent, but although the news sheet was cleared, its header row could not be written back (restoreError.message). Put this header row back before tomorrow's stories arrive: headerRow joined by , .
ValuesShow in the output: Sent the length of chosen LinkedIn content ideas chosen from usable stories and cleared the '@newsTab' tab for tomorrow.Show in the output: Sent the length of chosen LinkedIn content ideas chosen from usable stories and cleared the '@newsTab' tab for tomorrow.