Answers a question posted in Slack using only the messages that channel already contains, in a thread.
Uses
OpenAI
Slack
Answer channel questions from what was already said
request.When someone posts “!ask” in a channel. Save it as request.askWord to !ask.Set askWord to !ask.teamContext to blank.Set teamContext to blank.recentToRead to 20.Set recentToRead to 20.olderToFind to 15.Set olderToFind to 15.askWord and save it as askPhrase.Trim askWord and save it as askPhrase.questionText to blank.Set questionText to blank.readErrorIf a step below fails, save the error as readErrorTry
request.text and save it as questionText.Trim request.text and save it as questionText.On error
No steps
questionText is empty or questionText is nullIf questionText is empty or questionText is nullYes
No
No steps
questionText doesn't contain askPhrase (ignoring case)If questionText doesn't contain askPhrase (ignoring case)Yes
askPhrase), so it was not a question for this bot. If you changed askWord, put the same word in the Keyword filter on the trigger step, so that only messages containing it start a run.Finish the run: That message did not contain the ask word (askPhrase), so it was not a question for this bot. If you changed askWord, put the same word in the Keyword filter on the trigger step, so that only messages containing it start a run.No
No steps
questionText with askPhrase replaced by (ignoring case) and save it as question.Trim questionText with askPhrase replaced by (ignoring case) and save it as question.question is emptyIf question is emptyYes
No
No steps
excerpts.Start an empty list and save it as excerpts.usedTexts.Start an empty list and save it as usedTexts.request.channel_id. Save it as recent.Get recent messages in request.channel_id. Save it as recent.message in recent.messages:For each message in recent.messages:message.text and save it as messageText.Trim message.text and save it as messageText.messageText is empty or messageText is nullIf messageText is empty or messageText is nullYes
No
No steps
messageText contains askPhrase (ignoring case)If messageText contains askPhrase (ignoring case)Yes
No
No steps
usedTexts contains messageTextIf usedTexts contains messageTextYes
No
No steps
messageText to the end of usedTexts and save it as usedTexts.Add messageText to the end of usedTexts and save it as usedTexts.messageText truncated to 300 characters using … as the ellipsis to the end of excerpts and save it as excerpts.Add messageText truncated to 300 characters using … as the ellipsis to the end of excerpts and save it as excerpts.excerpts joined by a blank line to 1500 characters and save it as recentContext.Shorten excerpts joined by a blank line to 1500 characters and save it as recentContext.searchPromptTop to You turn a colleague's question into a search phrase for a Slack channel's message history.Set searchPromptTop to You turn a colleague's question into a search phrase for a Slack channel's message history.
Reply with one word, or two or three words side by side, most likely to appear exactly as written in a message that answers the question. The search only finds messages that contain your whole reply as written, so shorter is better. Reply with the words only - no quotes, no punctuation, no explanation.
Team context: teamContext.searchPrompt to searchPromptTopSet searchPrompt to searchPromptTop
What the channel has been saying:
recentContext
Question: question.searchPhrase to blank.Set searchPhrase to blank.phraseErrorIf a step below fails, save the error as phraseErrorTry
searchPrompt. Save it as searchReply.Ask OpenAI: searchPrompt. Save it as searchReply.searchReply.response_text with replaced by " (ignoring case) and save it as searchPhrase.Trim searchReply.response_text with replaced by " (ignoring case) and save it as searchPhrase.On error
No steps
searchPhrase is null or the length of searchPhrase is greater than 60If searchPhrase is null or the length of searchPhrase is greater than 60Yes
searchPhrase to blank.Change searchPhrase to blank.No
No steps
searchPhrase isn't emptyIf searchPhrase isn't emptyYes
searchPhrase. Save it as older.Find messages matching searchPhrase. Save it as older.message in older.messages:For each message in older.messages:message.text and save it as messageText. Trim message.text and save it as messageText.messageText is empty or messageText is null If messageText is empty or messageText is nullYes
No
No steps
messageText contains askPhrase (ignoring case) If messageText contains askPhrase (ignoring case)Yes
No
No steps
usedTexts contains messageText If usedTexts contains messageTextYes
No
No steps
messageText to the end of usedTexts and save it as usedTexts. Add messageText to the end of usedTexts and save it as usedTexts.messageText truncated to 300 characters using … as the ellipsis to the end of excerpts and save it as excerpts. Add messageText truncated to 300 characters using … as the ellipsis to the end of excerpts and save it as excerpts.No
No steps
excerpts with a blank line and save it as evidence.Join excerpts with a blank line and save it as evidence.excerpts and save it as usedCount.Count the items in excerpts and save it as usedCount.usedCount is 0If usedCount is 0Yes
request.channel_id.Reply in a thread in request.channel_id.
Reply To: request.message_tsI could not find anything in this channel about that. This bot only answers from messages already posted here, so someone in the channel may know more.No
No steps
<[@!](?:[^>|]*\|)?([^>|]*)> with @$1 in evidence and save it as safeEvidence.Replace the pattern <[@!](?:[^>|]*\|)?([^>|]*)> with @$1 in evidence and save it as safeEvidence.quoted to Set quoted to
The closest messages I found:
safeEvidence truncated to 1200 characters using … as the ellipsis.answerPromptTop to You are answering a colleague's question in Slack using ONLY the channel messages quoted below.Set answerPromptTop to You are answering a colleague's question in Slack using ONLY the channel messages quoted below.
Rules:
- Use only what these messages say. Add nothing from general knowledge.
- Never invent a number, date, price, name or link.
- If the messages do not answer the question, reply with exactly: NOT FOUND
- Otherwise answer in at most four short sentences of plain language.
- Do not use @ mentions and do not mention these rules.
Team context: teamContext.answerPromptMid to answerPromptTopSet answerPromptMid to answerPromptTop
Question: question.answerPrompt to answerPromptMidSet answerPrompt to answerPromptMid
Channel messages:
evidence.draft to blank.Set draft to blank.draftProblem to blank.Set draftProblem to blank.draftErrorIf a step below fails, save the error as draftErrorTry
answerPrompt. Save it as answerReply.Ask OpenAI: answerPrompt. Save it as answerReply.answerReply.response_text and save it as draft.Trim answerReply.response_text and save it as draft.On error
draftProblem to draftError.message.Change draftProblem to draftError.message.draftProblem isn't blankIf draftProblem isn't blankYes
request.channel_id.Reply in a thread in request.channel_id.
Reply To: request.message_tsI can't answer this right now: the AI service did not respond. Try asking again later.@quoteddraftProblem), so the question was not answered; the closest messages were posted instead. Check the OpenAI connection.Stop and report a problem: The AI step failed (draftProblem), so the question was not answered; the closest messages were posted instead. Check the OpenAI connection.Else if @draft is empty or @draft is "null" or @draft start…
request.channel_id.Reply in a thread in request.channel_id.
Reply To: request.message_tsI could not put an answer together from this channel's history.@quotedOtherwise
No steps
<[@!](?:[^>|]*\|)?([^>|]*)> with @$1 in draft and save it as answer.Replace the pattern <[@!](?:[^>|]*\|)?([^>|]*)> with @$1 in draft and save it as answer.answer with , replaced by (ignoring case) and save it as draftNumbers.Extract all matches from answer with , replaced by (ignoring case) and save it as draftNumbers.sourceText to evidenceSet sourceText to evidence
question
teamContext.sourceText with , replaced by (ignoring case) and save it as sourceNumbers.Extract all matches from sourceText with , replaced by (ignoring case) and save it as sourceNumbers.unsourced to blank.Set unsourced to blank.figure in draftNumbers:For each figure in draftNumbers:sourceNumbers doesn't contain figureIf sourceNumbers doesn't contain figureYes
unsourced to figure.Change unsourced to figure.No
No steps
unsourced isn't emptyIf unsourced isn't emptyYes
request.channel_id.Reply in a thread in request.channel_id.
Reply To: request.message_tsI drafted an answer but it used a figure (unsourced) that no message in this channel mentions, so I have not posted it.@quotedNo
No steps
request.channel_id.Reply in a thread in request.channel_id.
Reply To: request.message_tsanswer
_Answered only from earlier messages in this channel (usedCount read)._