Conversation
| console.error("discard_publish_draft error", error), | ||
| ), | ||
| ); | ||
| slackBot.command("/publish", async ({ command, ack, client }) => { |
There was a problem hiding this comment.
The command accepts any channel ID and doesn't verify if its a DM or multi-person DM or a channel. The
command can be run in any channel and the LLM will read the entire chat history, and only one person has to consent. can we reject the command in non-Dm conversations?
| return `${dmChannelId}:${previewTs}`; | ||
| } | ||
|
|
||
| async function getPublishedByDM(dmChannelId, db) { |
There was a problem hiding this comment.
Publishing is treated as one-time per Slack DM channel, rather than one-time per donut round. If 2 people are paired again after several cycle, /publish says their old donut was already published. Could we scope idempotency to a pairing/round or prompt timestamp instead?
|
@lsha0730 Could you also add documentation for this feature either in a separate README or a notion page? Please also include required env vars, slack permissions and commands, firestore config, and details of the dokploy configuration. Can you also clarify the handoff plan so this feature doesn’t depend on your personal account or access in the future? |
User flow
After each weekly pairing, DinuBot posts a Publish donut 🍩 button in the new group DM.
/publishslack command./publish <context>to limit the LLM's context to a specified value.@DinuBotto request a revisionNew commands:
/publish— starts the normal consent and DM-history flow./publish <custom context>— generates a draft from the supplied text instead of the DM history./set-timezone— opens a modal for configuring the club timezone./set-donut-roster-max <positive integer>— updates the maximum roster size.Maintainer requirements
New environment configuration:
OPENAI_API_KEY— required for publishing.OPENAI_MODEL— optional; defaults togpt-5.6-luna.PUBLISH_CHANNEL_ID— required public channel for published donuts.ALL_MEMBERS_CHANNEL— required pairing/member channel, replacing the previouschannelIDconfiguration.The Slack app must also register the new slash commands and have the permissions needed to read the pairing DMs and post/update messages in the configured public channel.
Publishing requires the club timezone and roster maximum to be configured in Firestore. The
InternalProjects/DinuBotdocument now stores:clubTimezonedonutRosterMaxThe publish feature uses two subcollections beneath that document:
pendings— temporary draft previews awaiting approval or discard.publishes— published meetup records, including Slack message references, details, and roster state.The Slack SDK was upgraded to Bolt 4 / Web API 7 to resolve the Socket Mode disconnect issue. Node.js 18 or newer is required.
Code structure
src/publish/workflows.jscoordinates the draft, review, and publish lifecycle.src/publish/handlers/contains Slack command, action, modal, and event handlers.src/publish/llm/encapsulates prompts, structured-output schemas, and OpenAI calls.src/publish/slack/contains Block Kit presentation, conversation access, and Slack message operations.src/publish/repository.jsowns Firestore validation, persistence, and transactional roster updates.src/publish/drafts.jsconstructs the deterministic final announcement from the LLM’s structured details.index.jsintegrates the publish module with the existing pairing application.