How to Refresh a Policy Knowledge Collection From Front Conversations
Build a scheduled Spojit workflow that pulls resolved Front conversations, embeds them as documents into a persistent policy knowledge collection, and posts the indexed count to Slack.
What This Integration Does
Support teams build a deep well of knowledge inside Front: how refunds get approved, which exceptions are allowed, what wording an escalation should use. That knowledge lives scattered across hundreds of resolved conversations, where it is invisible to anyone trying to look up policy later. This workflow harvests those resolved conversations on a schedule, embeds them into a persistent Knowledge collection in Spojit, and keeps that collection current so future workflows (and people) can query a single, searchable record of how your team actually handles things.
A Schedule trigger runs the workflow on a cron you choose (for example, every weekday morning). Each run lists recently resolved Front conversations through the Front connector, embeds each one as a named document into the same persistent collection, and finishes by sending a Slack message with the number of documents indexed. Because each embed uses a stable File Name keyed to the conversation, re-running the workflow overwrites the matching document rather than duplicating it, so the collection stays clean across daily refreshes. The collection itself is workspace-scoped and persistent: it survives between runs and can be queried by any other workflow.
Prerequisites
- A Front connection (API token) added under Connections, with access to the inbox whose resolved conversations you want to index.
- A Slack connection added under Connections, with permission to post to your target channel.
- A persistent Knowledge collection created in advance from the Knowledge section of the sidebar (use New Collection, name it something like
support-policy, and note the fixed embedding model chosen at creation). - The exact Slack channel name or ID where the run summary should land.
Step 1: Add a Schedule trigger
Start a new workflow and set the Trigger node type to Schedule. Enter a 5-field Unix cron expression and an IANA timezone. To run at 7am on weekdays, use:
0 7 * * 1-5
Australia/Sydney
A single Schedule trigger can hold multiple schedules if you want more than one refresh window. The trigger output is { scheduledAt }; you do not need any of it downstream, since the run simply queries Front fresh each time.
Step 2: List resolved conversations from Front
Add a Connector node in Direct mode, choose the Front connector, and select the list-conversations tool. Front search filters go in the q field. To pull conversations that have been archived (resolved) recently, supply a search query such as:
{
"q": "is:archived after:{{ date.subtract }}"
}
If you prefer a simpler scope, set q to is:archived and rely on the schedule cadence to keep volumes small. Map the tool output to an output variable like conversations. The result is a paginated list; capture {{ conversations.result._pagination.next }} if you intend to walk additional pages (see Tips). For a daily refresh on a focused inbox, one page is usually enough.
Step 3: Loop over each conversation
Add a Loop node in ForEach mode and point it at the conversation list, for example {{ conversations.result._results }}. Each iteration exposes the current conversation as a loop item. Inside the loop body you will fetch the full conversation detail and embed it. Keeping the fetch inside the loop ensures you index the complete record (subject, status, tags) rather than the trimmed list entry.
Step 4: Fetch full conversation detail
Inside the loop, add a Connector node in Direct mode on the Front connector using the get-conversation tool. Map its id input to the current loop item's conversation ID, for example {{ item.id }}. Store the result in an output variable such as convo. This gives you the conversation subject, status, and tags that you will turn into a document. Optionally add a Transform node to assemble a clean plain-text body that combines the subject, tags, and a short summary line into one string for embedding.
Step 5: Embed the conversation into the collection
Still inside the loop, add a Knowledge node in Embed mode. Configure it as follows:
- Collection: pick your persistent collection (
support-policy), not Transient, so documents persist between runs. - File Name: a stable, unique name per conversation, for example
front-{{ convo.result.id }}.txt. Reusing the same name on a later run overwrites that document instead of creating a duplicate. - Document Type: choose
Plain Text(orMarkdownif you formatted the body that way). - Document Input: the base64-encoded body you want indexed. If you built a text body in the Transform step, encode it with the encoding connector
base64-encodetool first, then reference that output here. - Output Variable: name it
embedResultto capture the chunk count and metadata.
Use the same embedding model that the collection was created with; Spojit fixes that at collection creation, so you only confirm it matches. Each iteration adds (or refreshes) one document.
Step 6: Count indexed documents and notify Slack
After the loop, the number of indexed conversations equals the loop item count, for example {{ conversations.result._results.length }}. Add a Connector node in Direct mode on the Slack connector using the send-message tool. Set the channel and a templated message such as:
{
"channel": "support-ops",
"text": "Policy knowledge refresh complete. Indexed {{ conversations.result._results.length }} resolved Front conversations into the support-policy collection."
}
This gives your team a daily heartbeat confirming the refresh ran and how much it pulled in. If you would rather have Miraxa, the intelligent layer across your automation, scaffold this for you, open the Spojit chat in the designer and ask it to add a Slack Connector node in Direct mode that calls send-message with that text, then fine-tune the channel in the properties panel.
Tips
- Keep each daily window narrow with a tight
qfilter so you embed only conversations resolved since the last run; smaller batches mean faster runs and fewer AI credits spent on embedding. - To walk more than one page of results, add a Condition node that checks whether
{{ conversations.result._pagination.next }}exists, then loop thelist-conversationscall with that token passed intopage_token. - Once the collection is populated, build a second workflow with a Knowledge node in Query mode against
support-policyso agents can ask natural-language policy questions and get answers grounded in real resolved cases. - Use a stable
File Nameper conversation ID so re-runs overwrite rather than duplicate; this is what keeps the collection from ballooning over weeks of daily refreshes.
Common Pitfalls
- Timezone drift: the cron runs in the IANA timezone you set, not your browser's. A schedule of
0 7 * * 1-5inAustralia/Sydneyfires at a different UTC instant than the same cron in another zone, so confirm the zone before turning it on. - Wrong collection scope: selecting Transient in the Embed node discards everything at the end of the run. For a persistent archive you must pick the named collection you created in advance.
- Mismatched embedding models: a collection's embedding model is fixed at creation. Always embed and query the same collection with that one model, or query results degrade.
- Front search syntax: the
qfield expects Front's search grammar. If a run returns zero conversations, test the same query inside Front's search bar first to confirm the filter actually matches resolved items.
Testing
Before enabling the schedule, validate the flow on a tiny scope. Temporarily set q to a query that matches only a handful of conversations, run the workflow with the Run button, and watch the execution logs to confirm the loop iterates the expected number of times and each Knowledge Embed node reports a chunk count. Open your collection in the Knowledge section and confirm the new documents appear with status READY. Check that the Slack message posts the correct count. Once a single run looks right end to end, widen the q filter and let the Schedule trigger take over.