The Power of Gemini inside Trello: Building an LLM Assistant with Firebase Genkit
Source: Dev.to
In the world of project management, Trello has long been a favorite for its simplicity and visual organization. But what if your Trello cards could talk back? What if a bot could analyze a card’s details, look at its attachments, and provide intelligent updates or answers to your team’s comments?
In this article we’ll explore how to integrate Google’s Gemini 3.0 Flash model into Trello using Firebase Genkit.
Prerequisites
Before we dive in, make sure you have the following:
- A Trello account (one bot account, one regular account to issue requests from) – Trello
- A Google AI API Key – Google AI Studio
- Node.js installed – Node.js download
- A Firebase / GCP account for telemetry and deployment – Firebase
Setting Up Your Trello Power‑Up
To interact with Trello’s API you’ll need to create a Power‑Up. This gives you the API Key and Token required for authentication.
-
Go to the Trello Power‑Up Admin.
-
Click “Create a new Power‑Up” for your workspace.

-
Generate your API Key and Secret.
-
Generate a Token to allow your app to act on behalf of your user.
-
(Optional) Verify the credentials on the “Token” page.
Keep these credentials safe! You’ll need them in your .env file.
Crafting the AI Logic with Firebase Genkit
Firebase Genkit simplifies building LLM‑powered applications. We’ll define a Flow that takes a Trello card ID and a comment, fetches all relevant data, and uses Gemini to generate a response.
Defining the Schema
First, we define a structured schema for our card data. This ensures Gemini receives consistent information (checklists, comments, image attachments, etc.). The schema can be extended to include links to other projects, additional cards, and more.
export const TrelloRequestRequestInputSchema = z.object({
instructions: z.string().describe("User's instructions"),
attachments: z.array(
z.object({
url: z.string(),
caption: z.string().optional(),
})
),
details: z.string(),
comments: z.array(
z.object({
person: z.string(),
text: z.string(),
timestamp: z.string(),
})
),
checklists: z.array(
z.object({
name: z.string(),
items: z
.object({
itemName: z.string(),
completed: z.boolean(),
dueDate: z.string(),
})
.array(),
})
),
today: z.string(),
});
The Trello Flow
The core of our application is the trelloFlow. It fetches the card details using a helper function, calls the prompt, and posts the LLM’s response back to Trello as a comment.
const trelloFlow = ai.defineFlow(
{
name: "trelloFlow",
inputSchema: z.object({
trelloCardId: z.string(),
trelloComment: z.string(),
}),
// …additional metadata if needed
},
async (input) => {
// 1️⃣ Retrieve and format the card data
const formattedCard = await getFormattedTrelloCard(
input.trelloCardId,
input.trelloComment
);
// 2️⃣ Generate a response with Gemini
const output = await trelloPrompt({ inputData: formattedCard });
// 3️⃣ Post the response as a comment on the card
await trelloClient.cards.addCardComment({
id: input.trelloCardId,
text: output.output.responseText,
});
return { success: true, message: "Comment added successfully" };
}
);
Multi‑modal Capabilities: Seeing Attachments
One of Gemini’s greatest strengths is its ability to understand images. In trello_helper.ts we fetch attachments, convert them to base64 data URLs, and pass them directly to the LLM.
const formattedAttachments = await Promise.all(
attachments.map(async (attachment) => {
const response = await fetch(attachment.url, {
headers: {
Authorization: `OAuth oauth_consumer_key="${env.TRELLO_API_KEY}", oauth_token="${env.TRELLO_API_TOKEN}"`,
},
});
const arrayBuffer = await response.arrayBuffer();
const base64 = Buffer.from(arrayBuffer).toString("base64");
return {
url: `data:${attachment.mimeType};base64,${base64}`,
caption: attachment.name,
};
})
);
Designing the Prompt with Dot‑Prompt
Genkit introduces the .prompt file format, which keeps AI logic clean and separate from application code. In prompts/trello.prompt we select the Gemini 3.0 Flash model for its speed and native multi‑modal support.
The prompt uses Handlebars‑style templates to inject our structured card data. We loop over the different parts of the Trello card, but the same pattern can be reused to inject any additional context you need.
(The actual prompt file is omitted here for brevity, but it follows the standard .prompt syntax with sections for system instructions, user input, and variable interpolation.)
With the pieces above—Power‑Up credentials, a Genkit Flow, multi‑modal attachment handling, and a clean .prompt—you now have a fully functional bot that can “talk” to your Trello cards using Gemini 3.0 Flash. Deploy the code to Firebase Functions (or any Node.js environment), set the required environment variables, and watch your cards become conversational collaborators.
Connecting Trello via Webhooks
To make the bot reactive, we use Trello Webhooks. Whenever a comment is added, Trello sends a POST request to our application.
Different Express middleware is used to intercept, verify, and format the requests before they reach Genkit.
Security
We implement a middleware to verify that incoming requests actually come from Trello using HMAC‑SHA1 signatures.
export const trelloSignatureMiddleware = (
req: RequestWithAuth,
res: Response,
next: NextFunction
) => {
const signature = req.headers["x-trello-webhook"];
const secret = env.TRELLO_WEBHOOK_SECRET;
const callbackURL = env.TRELLO_CALLBACK_URL;
const body = req.rawBody ? req.rawBody.toString("utf8") : "";
const baseString = body + callbackURL;
const computedSignature = crypto
.createHmac("sha1", secret)
.update(baseString)
.digest("base64");
if (signature === computedSignature) {
next();
} else {
res.status(401).send("Unauthorized");
}
};
Registering the Webhook
Once your app is deployed (e.g., to Cloud Run), you need to tell Trello where to send its updates. Fill out your deployment URL in the .env file. A handy script is provided:
npx tsx src/register_webhook.ts
Sample output
69457XXXXXXXXXXXXXXX
Registering webhook for https://genkit-trello-{PROJECT_ID}.europe-west1.run.app/trelloFlow with board ID: 6945713XXXXXXXXXXXXXX
Seeing it in Action
After everything is set up, you can tag your bot in a Trello comment (e.g., @GeminiBot what's the status of this task?). The bot will analyze the entire card context and reply.
It can even track progress based on checklists and card descriptions!
Monitoring
If you deploy to GCP and have the Firebase project set up, the Genkit part of the dashboard provides important debug and overview information right away.
Conclusion
By combining Trello’s structured project data with Gemini’s reasoning capabilities and Firebase Genkit’s orchestration, you can create a helpful Trello assistant. Whether it’s summarizing long comment threads, analyzing attached designs, or providing quick status updates, there are many ways for this to be useful. The project is an MVP—feel free to fork it and extend it to your use‑cases.
Check out the full source code on GitHub:





