Contact Support

    Guides

    More guides
    Build an email agent with Langbase & Unified

    Build an email agent with Langbase & Unified

    Mar 06 20259 min read

    In this guide, you will build an AI-powered email agent with Langbase SDK, using the Unified.to messaging API as a tool call to fetch emails from Gmail accounts.

    Let’s get started!

    Step #0Prerequisites

    Before you begin, go ahead and create a free personal account on Langbase and Unified.to.

    Step #1Setup your project

    Create a new directory for your project and navigate to it.

    1mkdir email-agent && cd email-agent

    Step #2Initialize the project

    Initialize Node.js project and create an email-agent.ts file.

    1npm init -y && touch email-agent.ts

    Step #3Install dependencies

    You will use the Langbase SDK to connect to the AI agent pipes, dotenv to manage environment variables and Unified SDK to fetch emails. Install them with:

    1npm i langbase dotenv @unified-api/typescript-sdk

    Build your own AI agent Pipe

    Pipe is an AI agent available as a serverless API.

    Build your own AI agent Pipe

    Step #4Get Langbase and Unified API key

    Every request you send to Langbase needs an API key. To generate your Langbase API key follow these steps.

    Create an .env file in the root of your project and add your Langbase API key.

    1// Replace xxxxxxxxx with your Langbase API key. 2LANGBASE_API_KEY=xxxxxxxxx

    You also need the Unified API key to work with its messaging API. Follow this quickstart guide to learn more about how you can generate one. Once you have the key, add it to the '.env' file.

    1LANGBASE_API_KEY=xxxxxxxxx 2UNIFIED_API_KEY=xxxxxxxxx

    Step #5Add LLM API keys

    If you have set up LLM API keys in your profile, the pipe agent will automatically use them. If not, navigate to the LLM API keys page and add keys for different providers like OpenAI, TogetherAI, Anthropic, etc.

    Step #6Fork the AI agent pipe

    On Langbase, fork this public email agent pipe. This agent pipe analyzes user prompts to fetch emails, process them, and respond accordingly. If the user asks any question other than emails, it responds back with a predefined message.

    The pipe agent contains the following tool definition. The agent calls the tool when the user provides a prompt like fetch the latest email from my inbox. The tool uses Unified API to fetch the latest email from the user's Gmail account.

    1{ 2 "type": "function", 3 "function": { 4 "name": "fetchEmails", 5 "description": "Fetch number of emails from user inbox.", 6 "parameters": { 7 "type": "object", 8 "required": ["num"], 9 "properties": { 10 "num": { 11 "type": "string", 12 "description": "The number of emails to fetch from the user inbox. Default value is 1." 13 } 14 } 15 } 16 } 17}

    Step #7Setup Unified OAuth 2 credentials for Gmail

    To access Google services such as Gmail with the Unified API, you will need to generate and retrieve your OAuth 2 credentials in the Google Cloud Console.

    You can follow this guide to quickly set it up.

    Step #8Create Gmail connection

    Lastly, navigate to the “Connections” inside the Unified dashboard and create a new Gmail connection.

    Unified connections image

    Step #9Setting up the email agent

    In this step, you will call the forked email agent pipe to analyze user prompts. To fetch emails from a user's inbox using Langbase, we'll break this process into two steps. Go ahead and add the following code to your email-agent.ts file:

    1import 'dotenv/config'; 2import { Langbase, Tools } from 'langbase'; 3 4// Initialize Langbase SDK 5const langbase = new Langbase({ 6 apiKey: process.env.LANGBASE_API_KEY! 7}); 8 9// Tool definition to fetch emails from user inbox 10const fetchEmailToolDefinition: Tools = { 11 type: 'function', 12 function: { 13 name: 'fetchEmails', 14 description: 'Fetch number of emails from user inbox.', 15 parameters: { 16 type: 'object', 17 required: ['num'], 18 properties: { 19 num: { 20 type: 'string', 21 description: 22 'The number of emails to fetch from the user inbox. Default value is 1.' 23 } 24 } 25 } 26 } 27};

    Here's whats happening in the above code:

    • Initialize the Langbase SDK with an API key from the environment variables.
    • Define the fetchEmailToolDefinition object that contains the tool definition to fetch emails from the user's inbox.

    Now, let's implement the email agent and handle the response stream. For that add the following code in the same email-agent.ts file:

    1import { Langbase, Tools, getRunner, getToolsFromRunStream } from 'langbase'; 2 3async function userEmailAgent(prompt: string) { 4 // Call the email agent pipe 5 const { stream } = await langbase.pipes.run({ 6 stream: true, 7 name: 'email-agent', 8 messages: [ 9 { 10 role: 'system', 11 content: `You are an AI email agent that fetches emails from user inbox. 12 If user asks anything other than fetching emails, 13 you should respond that you can only process prompts related to emails.` 14 }, 15 { 16 role: 'user', 17 content: prompt 18 } 19 ], 20 tools: [fetchEmailToolDefinition] 21 }); 22 23 // Split the stream into two parts to check for tool calls and print on screen 24 const [streamForTools, streamForResponse] = stream.tee(); 25 const toolCalls = await getToolsFromRunStream(streamForTools); 26 27 // Check if any tool calls are present 28 const hasToolCalls = toolCalls.length > 0; 29 30 // If tool calls are present, handle them 31 if (hasToolCalls) { 32 // Handle tool calls (to be implemented) 33 } else { 34 // If no tool calls are present, get the runner and listen for content 35 const runner = getRunner(streamForResponse); 36 runner.on('content', content => { 37 process.stdout.write(content); 38 }); 39 } 40} 41 42// Execute the email agent with a test prompt 43(async () => { 44 const userPrompt = 'Fetch latest email from my inbox.'; 45 await userEmailAgent(userPrompt); 46})();

    Let's take a look at what is happening in this code:

    • Define userEmailAgent, which sends a request to the Langbase agent with a system prompt and user input.
    • Split the response stream into two:
      • One checks if tool calls exist.
      • The other prints the response on the screen if no tools are needed.
    • If a tool call is detected, it will be handled in the next step. Otherwise, you will print the stream on the console.
    • Define an immediately invoked function expression (IIFE) where you have called userEmailAgent function. This will call the function when you run the file.

    Step #10Implement tool calls

    Now you will handle the case when agent pipes make a tool call. Go ahead and add the following code in email-agent.ts file:

    1import { Langbase, Tools, getRunner, getToolsFromRunStream } from 'langbase'; 2import { UnifiedTo } from '@unified-api/typescript-sdk'; 3import 'dotenv/config'; 4 5// Initialize Langbase SDK 6const langbase = new Langbase({ 7 apiKey: process.env.LANGBASE_API_KEY! 8}); 9 10// Initialize Unified API SDK 11const unified = new UnifiedTo({ 12 security: { 13 jwt: process.env.UNIFIED_API_KEY! 14 } 15}); 16 17// Function to fetch emails from user inbox 18async function fetchEmails(args: { num: string }) { 19 const num = args.num || '1'; 20 21 // use unified messaging API to fetch x number of emails 22 const emails = await unified.messaging.listMessagingMessages({ 23 connectionId: 'REPLACE_WITH_CONNECTION_ID', 24 channelId: 'inbox', 25 limit: parseInt(num) 26 }); 27 28 for (const email of emails) { 29 const emailContent = email.message; 30 console.log('Email:', emailContent); 31 } 32} 33 34// All tools available in the agent 35const allTools: Record<string, Function> = { 36 fetchEmails 37}; 38 39// Tool definition to fetch emails from user inbox 40const fetchEmailToolDefinition: Tools = { 41 type: 'function', 42 function: { 43 name: 'fetchEmails', 44 description: 'Fetch number of emails from user inbox.', 45 parameters: { 46 type: 'object', 47 required: ['num'], 48 properties: { 49 num: { 50 type: 'string', 51 description: 52 'The number of emails to fetch from the user inbox. Default value is 1.' 53 } 54 } 55 } 56 } 57}; 58 59async function userEmailAgent(prompt: string) { 60 // Call the email agent pipe 61 const { stream } = await langbase.pipes.run({ 62 stream: true, 63 name: 'email-agent', 64 messages: [ 65 { 66 role: 'system', 67 content: `You are an AI email agent that fetches emails from user inbox. 68 If user asks anything other than fetching emails, 69 you should respond that you can only process prompts related to emails.` 70 }, 71 { 72 role: 'user', 73 content: prompt 74 } 75 ], 76 tools: [fetchEmailToolDefinition] 77 }); 78 79 // Split the stream into two parts to check for tool calls and print on screen 80 const [streamForTools, streamForResponse] = stream.tee(); 81 const toolCalls = await getToolsFromRunStream(streamForTools); 82 83 // Check if any tool calls are present 84 const hasToolCalls = toolCalls.length > 0; 85 86 // If tool calls are present, handle them 87 if (hasToolCalls) { 88 toolCalls.map(async tool => { 89 const fnName = tool.function.name; 90 const fnArgs = JSON.parse(tool.function.arguments); 91 92 if (allTools[fnName]) { 93 await allTools[fnName](fnArgs); 94 } else { 95 console.error(`Function "${fnName}" not found.`); 96 } 97 }); 98 } else { 99 // If no tool calls are present, get the runner and listen for content 100 const runner = getRunner(streamForResponse); 101 runner.on('content', content => { 102 process.stdout.write(content); 103 }); 104 } 105} 106 107(async () => { 108 const userPrompt = 'Fetch latest email from my inbox.'; 109 await userEmailAgent(userPrompt); 110})();

    Let's take a look at the above code:

    • Initialize the Unified API SDK with the API key from the environment variables.
    • Define a fetchEmails function that takes a num as an argument. The num defines how many emails the function needs to fetch and uses Unified SDK to fetch emails.
    • fetchEmails function then logs the email content on the console
    • Create an object that contains the fetchEmails function tool.
    • Inside userEmailAgent function, map over the tools array to call every tool the agent called.

    You can find the connection id inside connections in the Unified dashboard.

    Step #11Run the agent

    Run the email agent by running the following command in terminal:

    1npx tsx email-agent.ts

    You should see the response in your terminal. Here’s an example output you’ll see in the console:

    1Hi folks, 2 3I just wanted to share how impressed I am with the service I received yesterday! 4The product worked perfectly, and customer support was incredibly helpful and efficient. 5 6Great job to the team! 7John.

    This is how you can build an AI email agent using Langbase pipe agents and Unified messaging API.

    Next steps

    We have also written a guide to help you build a fully functional AI email response generator workflow. This composable multi-agent AI workflow takes user email, analyzes its sentiment, summarizes it, decides whether to respond, and generates the response email if needed.

    You can pass the emails you get from the above pipe agent we created through this composable multi-agent AI email agent workflow and generate response emails as well.

    Build your own composable multi-agent email AI workflow

    This composable multi-agent workflow analyzes, summarizes, and responds to emails when needed.

    Build your own composable multi-agent email AI workflow