Build an integration card
This tutorial will show how to build a Salesforce card in your frontend web app for customers to connect their Salesforce account to your application using Supaglue.
Prerequisites
This tutorial assumes you have gone through Supaglue's Quickstart and will use the following technologies:
- Typescript
- Nextjs 13
- Tailwind css
Oauth 2.0 (Embedded Links)
In this first example, we will connect to Salesforce, which uses Oauth 2.0 as its authentication method.
Build a Nextjs IntegrationCard component
// components/IntegrationCard.jsx
const IntegrationCard = ({
icon,
provider,
description,
to,
cta = 'Connect',
}: {
icon: ReactNode,
provider: string,
description: string,
to: string,
cta?: string,
}) => (
<div className="mb-4 p-6 max-w-sm flex flex-col border rounded-md border-slate-200 border-solid items-start">
<img src={icon} className="w-auto h-9" />
<div className="font-semibold mt-4">{provider}</div>
<div className="text-xs mt-2">{description}</div>
<div
onClick={() => {
window.location.href = to;
}}
className="border-solid font-semibold cursor-pointer hover:bg-slate-100 mt-6 px-4 py-2 border border-slate-300 rounded-md text-xs"
>
{cta}
</div>
</div>
);
Generate the Embedded Link
To use the IntegrationCard
component, we will need to generate the Embedded Link to provide as the to
prop.
The Embedded Link lets customers securely connect their Provider account using Supaglue's Managed Authentication.
applicationId:
Obtain your Supaglue applicationId
by visiting the Management Portal and clicking on the upper left corner, then "Copy ID".
customerId: Your application's customer id.
providerName: View the list of provider names here.
returnUrl: You likely want your customers to return to your application after authenticating.
// SettingsPage.jsx
// applicationId: 8473e5ad-ffe7-45db-bbfd-ebc638f5f8c9
// customerId: 001
// providerName: salesforce
// returnUrl: https://supaglue.com
<IntegrationCard
icon="/img/salesforce.svg"
provider="Salesforce"
description="Sync your leads to and from Salesforce"
to="#"
/>
Checking for an existing connection
In the example above, we display "Connect" as the CTA. To check for existing connections to show a different CTA, such as "Disconnect" or "Reconnect" call the Connections Management API in a Nextjs Server Component.
You will need a Supaglue API key to call the Management API. You can obtain one by following these steps.
// fetch_active_connections.jsx
export async function fetchActiveConnection(providerName) {
const connections = await fetch(`https://api.supaglue.io/mgmt/v2/customers/${CUSTOMER_ID}/connections`, {
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.NEXT_PUBLIC_SUPAGLUE_API_KEY,
},
});
const activeConnection = connections.find((connection) => connection.provider_name === providerName);
return activeConnection;
}
Use activeConnection
when using IntegrationCard
:
<IntegrationCard
icon="/img/salesforce.svg"
provider="Salesforce"
description="Sync your leads to and from Salesforce"
to="https://api.supaglue.io/oauth/connect?applicationId=8473e5ad-ffe7-45db-bbfd-ebc638f5f8c9&customerId=001&providerName=saleforce&returnUrl=https://supaglue.com"
cta={activeConnection ? 'Connect' : 'Reconnect'}
/>
API key
Authenticating with an API key requires your customer to input their API key.
const ApiKeyIntegrationCard = ({ icon, provider, description, to, customerId }) => {
return (
<div className="mb-4 p-6 max-w-sm flex flex-col border rounded-md border-slate-200 border-solid items-start">
<img src={icon} style={{ width: 'auto', height: '36px' }} />
<div className="font-semibold mt-4">{provider}</div>
<div className="text-xs mt-2">{description}</div>
<div className="mt-4 w-full gap-2 mt-2">
<label htmlFor="apiKey" className="block text-sm font-medium leading-6 text-gray-900">
API key
</label>
<input
type="password"
name="apiKey"
id="apiKey"
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
placeholder="JdPcdo76t01KCW3JA9jvfhcaZ6KA7IkP1GOFk+"
/>
</div>
<div
className="border-solid font-semibold cursor-pointer hover:bg-slate-100 mt-6 px-4 py-2 border border-slate-300 rounded-md text-xs"
onClick={async () => {
await fetch(YOUR_BACKEND_API, {
method: 'POST',
body: JSON.stringify({
provide_name: 'apollo',
category: 'engagement',
api_key: YOUR_CUSTOMERS_API_KEY,
}),
});
}}
>
Connect
</div>
</div>
);
};
Due to CORS issues, authenticating using API keys requires you to call your backend to call Supaglue's Management API.
Access keys
Authenticating with access keys requires your customer to input two pieces of information: an access key id and secret access key.
export const AccessKeyIntegrationCard = ({ icon, provider, description, to, customerId }) => {
return (
<div className="mb-4 p-6 max-w-sm flex flex-col border rounded-md border-slate-200 border-solid items-start">
<img src={icon} style={{ width: 'auto', height: '36px' }} />
<div className="font-semibold mt-4">{provider}</div>
<div className="text-xs mt-2">{description}</div>
<div className="w-full gap-2 mt-2">
<label htmlFor="email" className="block text-sm font-medium leading-6 text-gray-900">
Access Key ID
</label>
<input
type="text"
name="keyId"
id="keyId"
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
placeholder="JdPcdo76t01KCW3JA9jvfhcaZ6KA7IkP1GOFk+"
/>
</div>
<div className="w-full gap-2 mt-2">
<label htmlFor="email" className="block text-sm font-medium leading-6 text-gray-900">
Secret Access Key
</label>
<input
type="password"
name="keySecret"
id="keySecret"
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
placeholder="9v+/+HzsY6x4xhRqwqdPGUYQoNeEJ4F79"
/>
</div>
<div
className="border-solid font-semibold cursor-pointer hover:bg-slate-100 mt-6 px-4 py-2 border border-slate-300 rounded-md text-xs"
onClick={async () => {
await fetch(YOUR_BACKEND_API, {
method: 'POST',
body: JSON.stringify({
provide_name: 'gong',
category: 'engagement',
key_id: YOUR_CUSTOMERS_ACCESS_KEY_ID,
key_secret: YOUR_CUSTOMERS_SECRET_ACCESS_KEY,
}),
});
}}
>
Connect
</div>
</div>
);
};
Due to CORS issues, authenticating using access keys requires you to call your backend to call Supaglue's Management API.