> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Salesforce Opportunities

> Use OpenAI, NextJS, and the Auth0-AI SDKs to get Salesforce opportunities

**Next.js**

Prerequisites

Before getting started, make sure you have completed the following steps:

## 1. Define the Vercel AI tool and backend API route

Create an AI tool that gets a list of opportunities from Salesforce and a backend route that uses Auth0 to get a Salesforce access token:

* When the tool calls `auth0.getAccessTokenForConnection()`, pass `sfdc` as the connection name to get a Salesforce access token.

```tsx app/api/chat/route.js wrap lines theme={null}
import { openai } from "@ai-sdk/openai";
import { streamText, tool } from "ai";
import { z } from "zod";
import { auth0 } from "@/lib/auth0";

export const maxDuration = 60;

export async function POST(req) {
  const { messages } = await req.json();

  const system = `You're a helpful AI agent that helps analyze salesforce data`;

  const response = streamText({
    model: openai("gpt-4o"),
    messages,
    system,
    maxSteps: 10,
    tools: {
      listOpportunities: tool({
        // salesforce tool call to get a list of opportunities
        description: "Get a list of opportunities from Salesforce",
        parameters: z.object({
          limit: z
            .number()
            .default(10)
            .describe("The maximum number of opportunities to return"),
        }),
        execute: async ({ limit }) => {
          const instanceUrl = process.env.SALESFORCE_INSTANCE_URL;

          const endpoint = `query/?q=${encodeURIComponent(
            `SELECT Id, Name, StageName, CloseDate FROM Opportunity LIMIT ${limit}`
          )}`;
          const url = `${instanceUrl}/services/data/v57.0/${endpoint}`;

          // call auth0 to get the access token
          const { accessToken } = await auth0.getAccessTokenForConnection({
            connection: "sfdc",
          });

          const response = await fetch(url, {
            method: "GET",
            headers: {
              Authorization: `Bearer ${accessToken}`,
              "Content-Type": "application/json",
            },
          });
          return await response.json();
        },
      }),
    },
  });
  return response.toDataStreamResponse();
}
```

## 2. Call from the frontend Chat UI

Use the `@ai-sdk/react` hook to wire up the chat component:

```tsx src/components/chat.tsx wrap lines theme={null}
"use client";
import { useChat } from "@ai-sdk/react";
export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit } = useChat();
  return (
    <div className="flex flex-col w-full max-w-3xl py-24 mx-auto stretch text-gray-100">
      {messages.map((message) => (
        <div key={message.id} className="whitespace-pre-wrap">
          {message.role === "user" ? "User: " : "AI: "}
          {message.parts.map((part, i) => {
            switch (part.type) {
              case "text":
                return <div key={`${message.id}-${i}`}>{part.text}</div>;
            }
          })}
        </div>
      ))}
      <form onSubmit={handleSubmit}>
        <input
          className="fixed bottom-0 w-full max-w-3xl p-2 mb-8 border border-zinc-300 rounded shadow-xl"
          value={input}
          placeholder="Say something..."
          onChange={handleInputChange}
        />
      </form>
    </div>
  );
}
```

## 3. Example UI

Navigate to `https://localhost:3000` to see the chat UI:

&#x20;

![Get Salesforce Opportunities Chat
UI](https://mintlify.s3.us-west-1.amazonaws.com/auth0/docs/images/ai/how-tos/get_salesforce_opportunities_chat_ui.png)

You can customize the chat UI to display structured results in tables, charts, or summaries. When the user sends a message like `Get me 2 opportunities from Salesforce`, GPT-4 interprets the request and invokes the `listOpportunities` tool, which securely calls the Salesforce API using access tokens obtained via Auth0 and returns the results.

**LangChain**

Coming soon!

**LlamaIndex**

Coming soon!

**GenKit**

Coming soon!

## Account Linking

If you're integrating with Salesforce and want users to be able to sign in using a different
method (e.g., username and password or another external provider), you need to link
these identities into a single user account. Auth0 refers to this process as
[Account Linking](https://auth0.com/docs/manage-users/user-accounts/user-account-linking)
.

Account Linking is separate from
[Connected Accounts for Token Vault](https://auth0.com/docs/secure/call-apis-on-users-behalf/token-vault/connected-accounts-for-token-vault.md)
:

<ul><li>Account Linking merges multiple Auth0 identities into one user profile for sign-in.</li>
<li>Connected Accounts for Token Vault allows that signed-in user to authorize an external
provider so Auth0 can store the provider's tokens in Token Vault.</li></ul>

If your application uses
[Organizations](https://auth0.com/docs/manage-users/organizations.md), authenticate the
user with the target organization before initiating the Connected Accounts flow. Organizations
define the session context; they do not create a shared external account for the organization.

Account Linking logic and handling varies depending on your app or agent.
You can find an example of how to implement it in a  [Next.js chatbot app](https://github.com/auth0-lab/market0/blob/main/app/api/auth/%5Bauth0%5D/route.ts#L43)
. If you have questions or are looking for best practices,
[join our Discord](http://discord.gg/XbQpZSF2Ys) and ask in the
`#auth0-for-gen-ai` channel.
