Fetches each video transcript you list, summarises the whole thing section by section with AI, and logs it to a sheet.
Uses
Google Sheets
OpenAI
Summarise long videos from their transcripts
Give it a list of transcript links, one per line with an optional title, and run it whenever you have a batch of videos to get through. Each transcript is fetched, cut into sections along its own line breaks and read section by section by the AI, which notes the actual claims in each part. Those notes are then written up as one summary in the style you describe, with key points underneath, so the end of a long talk is covered too.
You end up with a 'Video summaries' tab in your Google Sheet holding one row per video: date, title, transcript link, word count, sections covered, summary and key points. The tab is created on the first run and added to after that, never overwritten. A transcript that cannot be fetched or comes back empty is reported and skipped while the rest go through, and a very long one is capped at a set number of sections, with the row saying how many were read.
Transcripts must be reachable by link; the video itself cannot be read.
transcriptLinks to blank.Set transcriptLinks to blank.reportSheetUrl to blank.Set reportSheetUrl to blank.summaryStyle to One tight paragraph in plain English for someone who has not seen the video, naming the speaker's actual claims rather than the topics they touched on..Set summaryStyle to One tight paragraph in plain English for someone who has not seen the video, naming the speaker's actual claims rather than the topics they touched on..reportTabName to Video summaries.Set reportTabName to Video summaries.charactersPerSection to 8000.Set charactersPerSection to 8000.maxSectionsPerVideo to 10.Set maxSectionsPerVideo to 10.summaryModel to gpt-5.4-mini.Set summaryModel to gpt-5.4-mini.tabIsNew to false.Set tabIsNew to false.createTabErrorIf a step below fails, save the error as createTabErrorreportTabName in reportSheetUrl.Create the tab reportTabName in reportSheetUrl.tabIsNew to true.Change tabIsNew to true.createTabError.message).Show in the output: The '@reportTabName' tab is already there, so this run adds to it. (createTabError.message).tabIsNew is yesIf tabIsNew is yesreportTabName in reportSheetUrl.Add a row to reportTabName in reportSheetUrl.transcriptLinks by a new line and save it as transcriptEntries.Split transcriptLinks by a new line and save it as transcriptEntries.videosSummarised to 0.Set videosSummarised to 0.transcriptEntry in transcriptEntries:For each transcriptEntry in transcriptEntries:transcriptEntry and save it as entryText.Trim transcriptEntry and save it as entryText.entryText is emptyIf entryText is emptyentryText by | and save it as entryParts.Split entryText by | and save it as entryParts.entryParts and save it as transcriptUrl.Trim the last item of entryParts and save it as transcriptUrl.entryParts and save it as videoLabel.Trim the first item of entryParts and save it as videoLabel.transcriptUrl is emptyIf transcriptUrl is emptyvideoLabel is emptyIf videoLabel is emptyvideoLabel to transcriptUrl.Change videoLabel to transcriptUrl.transcriptText to blank.Set transcriptText to blank.transcriptReached to false.Set transcriptReached to false.fetchErrorIf a step below fails, save the error as fetchErrortranscriptUrl and save it as response.Fetch transcriptUrl and save it as response.transcriptReached to response.ok.Change transcriptReached to response.ok.response.body and save it as transcriptText.Trim response.body and save it as transcriptText.transcriptUrl - fetchError.message.Show in the output: Could not open the transcript at transcriptUrl - fetchError.message.transcriptReached isn't yes or transcriptText is emptyIf transcriptReached isn't yes or transcriptText is emptytranscriptUrl, so nothing was summarised for videoLabel.Show in the output: No transcript text came back from transcriptUrl, so nothing was summarised for videoLabel.transcriptText and save it as transcriptWords.Count the words in transcriptText and save it as transcriptWords.transcriptText by a new line and save it as transcriptLines.Split transcriptText by a new line and save it as transcriptLines.sections.Start an empty list and save it as sections.currentSection to blank.Set currentSection to blank.transcriptLine in transcriptLines:For each transcriptLine in transcriptLines:currentSection plus the length of transcriptLine plus 1 is…If the length of currentSection plus the length of transcriptLine plus 1 is…currentSection to the end of sections and save it as sections.Add currentSection to the end of sections and save it as sections.currentSection to blank.Change currentSection to blank.currentSection to currentSection@transcriptLineChange currentSection to currentSection@transcriptLine
.currentSection isn't blankIf currentSection isn't blankcurrentSection to the end of sections and save it as sections.Add currentSection to the end of sections and save it as sections.sections is greater than maxSectionsPerVideoIf the length of sections is greater than maxSectionsPerVideovideoLabel is the length of sections as text sections long, so only the first maxSectionsPerVideo as text were summarised. Raise 'maxSectionsPerVideo' to cover the whole thing.Show in the output: The transcript for videoLabel is the length of sections as text sections long, so only the first maxSectionsPerVideo as text were summarised. Raise 'maxSectionsPerVideo' to cover the whole thing.sectionNotes.Start an empty list and save it as sectionNotes.sectionsRead to 0.Set sectionsRead to 0.section in sections:For each section in sections:sectionsRead is greater than or equal to maxSectionsPerVideoIf sectionsRead is greater than or equal to maxSectionsPerVideosectionsRead.Add 1 to sectionsRead.section to charactersPerSection characters (keeping words whole) and save it as sectionText.Shorten section to charactersPerSection characters (keeping words whole) and save it as sectionText.sectionErrorIf a step below fails, save the error as sectionErrorvideoLabel
Part sectionsRead as text of the length of sections as text of the transcript:
sectionText'. Save it as sectionReply.sectionReply.response_text and save it as sectionNote.Trim sectionReply.response_text and save it as sectionNote.sectionNote isn't empty and sectionNote is not noneIf sectionNote isn't empty and sectionNote is not nonesectionNote to the end of sectionNotes and save it as sectionNotes.Add sectionNote to the end of sectionNotes and save it as sectionNotes.sectionsRead as text of videoLabel - sectionError.message.Show in the output: Could not read part sectionsRead as text of videoLabel - sectionError.message.sectionNotes is emptyIf sectionNotes is emptyvideoLabel, so no row was written for it.Show in the output: Nothing usable came back for videoLabel, so no row was written for it.sectionNotes with a blank line and save it as combinedNotes.Join sectionNotes with a blank line and save it as combinedNotes.sectionsUsed to the length of sectionNotes as text of the length of sections as text.Set sectionsUsed to the length of sectionNotes as text of the length of sections as text.summaryText to blank.Set summaryText to blank.keyPoints to blank.Set keyPoints to blank.summaryErrorIf a step below fails, save the error as summaryErrorsummaryStyle
Then write a line containing exactly KEY POINTS: and, under it, the points a reader should take away, one per line starting with a dash. Add no other headings, and never mention the notes or the transcript.
Video: videoLabel
Notes taken across the transcript, in order:
combinedNotes'. Save it as finalReply.finalReply.response_text and save it as answer.Trim finalReply.response_text and save it as answer.answer by KEY POINTS: and save it as answerParts.Split answer by KEY POINTS: and save it as answerParts.answerParts and save it as summaryText.Trim the first item of answerParts and save it as summaryText.answerParts is greater than 1If the length of answerParts is greater than 1answerParts and save it as keyPoints.Trim the last item of answerParts and save it as keyPoints.videoLabel - summaryError.message.Show in the output: Could not summarise videoLabel - summaryError.message.summaryText is emptyIf summaryText is emptyvideoLabel, so no row was written for it.Show in the output: No summary came back for videoLabel, so no row was written for it.writeErrorIf a step below fails, save the error as writeErrorreportTabName in reportSheetUrl.Add a row to reportTabName in reportSheetUrl.videosSummarised.Add 1 to videosSummarised.videoLabel to the sheet - writeError.message.Show in the output: Could not add the summary for videoLabel to the sheet - writeError.message.videosSummarised as text video(s) into the '@reportTabName' tab.Show in the output: Summarised videosSummarised as text video(s) into the '@reportTabName' tab.