Reads a company filing you supply and writes notes on what it says - segments, risks, management commentary - into a Google Doc.

UsesGoogle DocsOpenAI

Write research notes from a company filing

Give it a company filing, as a link to a Google Doc or as pasted text, along with the company's name, and run it whenever you want a first pass on the document. For each topic you choose, such as segment performance, stated risks or the outlook management gives, the AI writes notes on what the filing says: its statements in its own words, the figures it gives with the period each covers, what it does not say, and two things worth checking.

The notes are added to a Google Doc of your choice under a heading carrying the company's name and the date, so the document becomes a running record across quarters and nothing already in it is overwritten. They are not investment advice and say so: no recommendation, rating or price target, only what the filing itself states. Each block says how much of the filing was read out of how much, marked 'cut short' when a long report was not read to the end, and a topic not covered in the part read is listed as not covered rather than invented. If the AI gives no notes for a topic, the block names it and the run is marked as failed.

You need Google Docs and OpenAI connected, and the company's name, the filing and the link of your notes document filled in. Filings usually come as PDFs or web pages: copy the text into a Google Doc and give it that link, or paste the sections you want straight in.

ValuesSet companyName to blank.Set companyName to blank.
ValuesSet filingSource to blank.Set filingSource to blank.
ValuesSet notesDocumentLink to blank.Set notesDocumentLink to blank.
ValuesSet topics to:Set topics to:Segment performance Stated risks Management commentary and outlook
ValuesSet maxFilingCharacters to 200000.Set maxFilingCharacters to 200000.
ListsGet the last item of notesDocumentLink split by /d/ and save it as notesLinkTail.Get the last item of notesDocumentLink split by /d/ and save it as notesLinkTail.
ListsGet the first item of notesLinkTail split by / and save it as notesDocumentId.Get the first item of notesLinkTail split by / and save it as notesDocumentId.
Decisions & LoopsIf notesDocumentId is emptyIf notesDocumentId is empty
Yes
Decisions & LoopsStop and report a problem: No document id could be read out of the link in the 'notesDocumentLink' step. It should look like https://docs.google.com/document/d/1AbCdEf/edit.Stop and report a problem: No document id could be read out of the link in the 'notesDocumentLink' step. It should look like https://docs.google.com/document/d/1AbCdEf/edit.
No
No steps
ValuesSet filingText to blank.Set filingText to blank.
ValuesSet sourceLabel to blank.Set sourceLabel to blank.
Decisions & LoopsIf filingSource starts with httpIf filingSource starts with http
Yes
Decisions & LoopsIf filingSource doesn't contain /d/If filingSource doesn't contain /d/
Yes
Decisions & LoopsStop and report a problem: The 'filingSource' step holds a link, but not a link to a Google Doc, and the workflow cannot open PDFs or web pages. Open the filing, select all, copy, paste it into a new Google Doc and put that Doc's link (it looks like https://docs.google.com/document/d/1AbCdEf/edit) into 'filingSource', or paste the sections you need straight into the step.Stop and report a problem: The 'filingSource' step holds a link, but not a link to a Google Doc, and the workflow cannot open PDFs or web pages. Open the filing, select all, copy, paste it into a new Google Doc and put that Doc's link (it looks like https://docs.google.com/document/d/1AbCdEf/edit) into 'filingSource', or paste the sections you need straight into the step.
No
No steps
ListsGet the last item of filingSource split by /d/ and save it as filingLinkTail.Get the last item of filingSource split by /d/ and save it as filingLinkTail.
ListsGet the first item of filingLinkTail split by / and save it as filingDocumentId.Get the first item of filingLinkTail split by / and save it as filingDocumentId.
Decisions & LoopsIf filingDocumentId is emptyIf filingDocumentId is empty
Yes
Decisions & LoopsStop and report a problem: No document id could be read out of the link in the 'filingSource' step. It should look like https://docs.google.com/document/d/1AbCdEf/edit.Stop and report a problem: No document id could be read out of the link in the 'filingSource' step. It should look like https://docs.google.com/document/d/1AbCdEf/edit.
No
No steps
ValuesChange sourceLabel to filingSource.Change sourceLabel to filingSource.
Decisions & LoopsIf a step below fails, save the error as readErrorIf a step below fails, save the error as readError
Try
Google DocsGoogle DocsRead filingDocumentId. Save it as filingDocument.Read filingDocumentId. Save it as filingDocument.
TextTrim filingDocument.text and save it as filingText.Trim filingDocument.text and save it as filingText.
On error
ValuesShow in the output: Could not read the filing document: readError as text.Show in the output: Could not read the filing document: readError as text.
No
ValuesChange sourceLabel to text pasted into the 'filingSource' step.Change sourceLabel to text pasted into the 'filingSource' step.
TextTrim filingSource and save it as filingText.Trim filingSource and save it as filingText.
Decisions & LoopsIf filingText is emptyIf filingText is empty
Yes
Decisions & LoopsStop and report a problem: There was no filing text to read, so no notes were written. Check that the 'filingSource' step holds the filing, and that the connected Google account can open it if it is a link.Stop and report a problem: There was no filing text to read, so no notes were written. Check that the 'filingSource' step holds the filing, and that the connected Google account can open it if it is a link.
No
No steps
TextShorten filingText to maxFilingCharacters characters and save it as filingExtract.Shorten filingText to maxFilingCharacters characters and save it as filingExtract.
TextCount the characters in filingText and save it as filingLength.Count the characters in filingText and save it as filingLength.
TextCount the characters in filingExtract and save it as readLength.Count the characters in filingExtract and save it as readLength.
MathFormat filingLength as a number with thousands separators with 0 decimal places and save it as filingCount.Format filingLength as a number with thousands separators with 0 decimal places and save it as filingCount.
MathFormat readLength as a number with thousands separators with 0 decimal places and save it as readCount.Format readLength as a number with thousands separators with 0 decimal places and save it as readCount.
TextBuild the text Read all @filingCount characters of the filing. and save it as readLine.Build the text Read all @filingCount characters of the filing. and save it as readLine.
Decisions & LoopsIf readLength is less than filingLengthIf readLength is less than filingLength
Yes
TextBuild the text Read @readCount of @filingCount characters of the filing (cut short: the rest was not read; paste the sections you need, such as Risk Factors or Management's D... and save it as readLine.Build the text Read @readCount of @filingCount characters of the filing (cut short: the rest was not read; paste the sections you need, such as Risk Factors or Management's D... and save it as readLine.
No
No steps
TextSplit topics by a new line and save it as topicList.Split topics by a new line and save it as topicList.
ValuesSet sections to an empty list.Set sections to an empty list.
ValuesSet topicsWithoutNotes to an empty list.Set topicsWithoutNotes to an empty list.
ValuesSet topicsNotCovered to an empty list.Set topicsNotCovered to an empty list.
ValuesSet topicsWithNotes to an empty list.Set topicsWithNotes to an empty list.
ValuesSet aiProblem to blank.Set aiProblem to blank.
Decisions & LoopsFor each topicLine in topicList:For each topicLine in topicList:
TextTrim topicLine and save it as topic.Trim topicLine and save it as topic.
Decisions & LoopsIf topic is emptyIf topic is empty
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ValuesSet notes to blank.Set notes to blank.
ValuesSet covered to blank.Set covered to blank.
Decisions & LoopsIf a step below fails, save the error as notesErrorIf a step below fails, save the error as notesError
Try
AI AgentRun an AI agent: Company: companyName Topic: topic Filing extract: filingExtract and save it as topicReading.Run an AI agent: Company: companyName Topic: topic Filing extract: filingExtract and save it as topicReading.
ValuesChange covered to topicReading.output.covered.Change covered to topicReading.output.covered.
TextTrim topicReading.output.notes and save it as notes.Trim topicReading.output.notes and save it as notes.
On error
ValuesChange aiProblem to notesError.message.Change aiProblem to notesError.message.
Decisions & LoopsIf covered is noIf covered is no
Yes
ListsAdd topic to the end of topicsNotCovered and save it as topicsNotCovered.Add topic to the end of topicsNotCovered and save it as topicsNotCovered.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf covered is not yes or notes is emptyIf covered is not yes or notes is empty
Yes
ListsAdd topic to the end of topicsWithoutNotes and save it as topicsWithoutNotes.Add topic to the end of topicsWithoutNotes and save it as topicsWithoutNotes.
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
ListsAdd topicAdd topic notes to the end of sections and save it as sections.
ListsAdd topic to the end of topicsWithNotes and save it as topicsWithNotes.Add topic to the end of topicsWithNotes and save it as topicsWithNotes.
TextJoin topicsNotCovered with , and save it as notCoveredList.Join topicsNotCovered with , and save it as notCoveredList.
TextJoin topicsWithoutNotes with , and save it as withoutNotesList.Join topicsWithoutNotes with , and save it as withoutNotesList.
Decisions & LoopsIf sections is emptyIf sections is empty
Yes
Decisions & LoopsIf topicsWithoutNotes isn't emptyIf topicsWithoutNotes isn't empty
Yes
Decisions & LoopsStop and report a problem: No notes came back for withoutNotesList, so nothing was added to the notes document. Check that the OpenAI connection is working, then run it again. aiProblem.Stop and report a problem: No notes came back for withoutNotesList, so nothing was added to the notes document. Check that the OpenAI connection is working, then run it again. aiProblem.
No
No steps
Decisions & LoopsStop and report a problem: None of the topics (notCoveredList) is covered in the part of the filing that was read, so nothing was added to the notes document. readLine Check the topics in the 'topics' step, or give it the part of the filing that covers them.Stop and report a problem: None of the topics (notCoveredList) is covered in the part of the filing that was read, so nothing was added to the notes document. readLine Check the topics in the 'topics' step, or give it the part of the filing that covers them.
No
No steps
TextJoin sections with a blank line and save it as notesText.Join sections with a blank line and save it as notesText.
ValuesSet notCoveredLine to blank.Set notCoveredLine to blank.
Decisions & LoopsIf topicsNotCovered isn't emptyIf topicsNotCovered isn't empty
Yes
ValuesChange notCoveredLine to Change notCoveredLine to Not covered in the part of the filing that was read: notCoveredList.
No
No steps
ValuesSet failedLine to blank.Set failedLine to blank.
Decisions & LoopsIf topicsWithoutNotes isn't emptyIf topicsWithoutNotes isn't empty
Yes
TextBuild the text No notes came back for: @withoutNotesList (the AI step did not answer; run it again with just these in 'topics') and save it as failedLine.Build the text No notes came back for: @withoutNotesList (the AI step did not answer; run it again with just these in 'topics') and save it as failedLine.
No
No steps
Google DocsGoogle DocsAdd the heading '@companyName - filing research notes - today's date' to notesDocumentId.Add the heading '@companyName - filing research notes - today's date' to notesDocumentId.
Google DocsGoogle DocsAdd text to notesDocumentId.Add text to notesDocumentId.notesText Source: sourceLabel readLine@notCoveredLine@failedLine These notes describe what the filing says. They are not investment advice - there is no recommendation, rating, price target or view on the company in them - and every figure should be checked against the fili...
TextJoin topicsWithNotes with , and save it as withNotesList.Join topicsWithNotes with , and save it as withNotesList.
Decisions & LoopsIf topicsWithoutNotes isn't emptyIf topicsWithoutNotes isn't empty
Yes
Decisions & LoopsStop and report a problem: Notes on withNotesList were added to the notes document, but no notes came back for withoutNotesList. Run it again with just those in the 'topics' step. aiProblem.Stop and report a problem: Notes on withNotesList were added to the notes document, but no notes came back for withoutNotesList. Run it again with just those in the 'topics' step. aiProblem.
No
No steps
ValuesSet notCoveredNote to blank.Set notCoveredNote to blank.
Decisions & LoopsIf topicsNotCovered isn't emptyIf topicsNotCovered isn't empty
Yes
TextBuild the text Not covered in the part that was read: @notCoveredList. and save it as notCoveredNote.Build the text Not covered in the part that was read: @notCoveredList. and save it as notCoveredNote.
No
No steps
Decisions & LoopsFinish the run: Added notes on withNotesList to the notes document. readLine@notCoveredNote.Finish the run: Added notes on withNotesList to the notes document. readLine@notCoveredNote.