A basic web server

This tutorial shows you a minimal example of a web server that can use composio

Install dependencies

using bun for this example, it is super convenient for rapid prototyping.

$bun install @composio/core@next openai hono

Please set the following environment variables:

$# .env
>COMPOSIO_API_KEY=your_api_key
>OPENAI_API_KEY=your_api_key

The full source code is available here.

In this tutorial, we will create an auth config, initiate a connection, and send an email.

Setup

Basic scaffolding for the server.

Setup
1import { Hono } from 'hono';
2import { Composio } from '@composio/core';
3import OpenAI from 'openai';
4
5const app = new Hono();
6
7// reads COMPOSIO_API_KEY from the environment variables
8// uses OpenAI by default
9const composio = new Composio();

Auth Configs

These are configurations for tools that control how they are authorized, the scopes and permissions they have. You can learn more about them here.

For this example, we will create a basic GMAIL auth config.

You are recommend to store these config ids, so that you can reuse them later.

Auth Configs
1// this should be made once and stored in a database
2// const authConfigId = (await composio.authConfigs.create('GMAIL')).id;
3const authConfigId = 'ac_DUMMY';

Initiating a connection

Connections are your users authorizing your tools.

Here we start the connection process, once your user uses the redirectUrl from the response, they will be redirected to the auth flow. Once they have authorized the connection, you can use the id to get and execute the tools as the user.

Initiating a connection
1app.post('/create-connection', async c => {
2 const { userId } = await c.req.json();
3
4 const connection = await composio.connectedAccounts.initiate(userId, authConfigId);
5
6 return c.json({
7 id: connection.id,
8 // for the user to authorize the connection
9 redirectUrl: connection.redirectUrl,
10 });
11});

You can test your server by running bun run index.ts and then running the following command:

$curl -X POST http://localhost:3000/create-connection \
>-H "Content-Type: application/json" \
>-d '{"userId": "123"}'

Sending an email

Now let’s send that email.

Sending an email
1app.post('/send-email', async c => {
2 const { userId, feedback, overwrite_email } = await c.req.json();
3
4 const tools = await composio.tools.get(userId, {
5 toolkits: ['GMAIL'],
6 });
7
8 const completion = await openai.chat.completions.create({
9 model: 'gpt-4o',
10 messages: [
11 {
12 role: 'system',
13 content:
14 'Send the composio team feedback about their product at feedback@composio.dev, parse the user feedback and send an email from their account, if they provide an email address, use that, otherwise sent it to feedback@composio.dev',
15 },
16 {
17 role: 'user',
18 content: `
19 User feedback: ${feedback}
20 Overwrite email: ${overwrite_email}
21 `,
22 },
23 ],
24 tools,
25 tool_choice: 'auto',
26 });
27
28 const result = await composio.provider.handleToolCalls(userId, completion);
29
30 return c.json({ completion, result });
31});

Using the id from the connection, we can now send an email.

$curl -X POST http://localhost:3000/send-email \
>-H "Content-Type: application/json" \
>-d '{"userId": "123", "feedback": "These docs are great!"}'

Full Code

You can see the full code here.

What just happened?

Well first - we created an instance of our gmail tool with our default auth config, then our user authorized that tool with their account and some permissions.

Then we used that gmail tool by giving it to OpenAI’s gpt-4o. The model composed the email and sent it correctly formatted to the composio team.

What’s next?

This is a fairly basic example, but you can do a lot more with our sdk.

Recommended further reading: