Skip to main content

Code-Native Agentic Flows

In this video we add two agentic flows to existing code-native Dropbox and Slack integrations, giving our built-in chat bot the ability to fetch files from our customers' Dropbox accounts, and send notifications to our customers' Slack workspaces.

For additional information on building code-native agentic flows, see Code-Native Agentic Flows.

Code built in the video can be referenced below:

dropbox/searchAndFetchFiles.ts
import { flow } from "@prismatic-io/spectral";
import { createDropboxClient } from "../dropboxClient";

interface Match {
metadata: {
metadata: {
name: string;
path_display: string;
};
};
}

interface ResponseItem {
name: string;
path_display: string;
presigned_url: string;
}

export const searchAndFetchFiles = flow({
name: "Search and Fetch Files from Dropbox",
description:
"Search for files in Dropbox and return a presigned URL for each matching file",
isAgentFlow: true,
isSynchronous: true,
stableKey: "searchAndFetchFiles",
schemas: {
invoke: {
$schema: "https://json-schema.org/draft/2020-12/schema",
title: "search-and-fetch-files",
$comment:
"Search for files in Dropbox by file name. Returns a list of files that match including a presigned URL for each file.",
type: "object",
properties: {
filename: {
type: "string",
description:
"The name of the file to search for in Dropbox. This can be a partial or full file name.",
},
folder: {
type: "string",
description:
"The folder path in Dropbox to search for files. If not provided, the root folder will be searched.",
},
},
required: ["filename"],
},
},
onExecution: async (context, { onTrigger }) => {
const { filename, folder } = onTrigger.results.body.data as {
filename: string;
folder?: string;
};
if (!filename) {
throw new Error("Filename is required to search for files in Dropbox.");
}

const dbxClient = createDropboxClient(
context.configVars["Dropbox Connection"],
);

const searchResponse = await dbxClient.post<{ matches: Match[] }>(
"/files/search_v2",
{
query: filename,
options: {
path: folder || "",
},
},
);

const files: ResponseItem[] = [];

for (const match of searchResponse.data.matches) {
const tempLinkResponse = await dbxClient.post<{ link: string }>(
"/files/get_temporary_link",
{
path: match.metadata.metadata.path_display,
},
);
files.push({
name: match.metadata.metadata.name,
path_display: match.metadata.metadata.path_display,
presigned_url: tempLinkResponse.data.link,
});
}

return { data: files };
},
});