Skip to content

Commit

Permalink
feat: Add Slack unintall flow
Browse files Browse the repository at this point in the history
  • Loading branch information
johnjcsmith committed Dec 28, 2024
1 parent 558bf4c commit 5472de4
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 220 deletions.
54 changes: 35 additions & 19 deletions app/app/clusters/[clusterId]/integrations/slack/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { Loading } from "@/components/loading";
import Nango from '@nangohq/frontend';
import toast from "react-hot-toast";
import { useRouter } from "next/navigation";
import { ClientInferResponses } from "@ts-rest/core";
import { contract } from "@/client/contract";

const nango = new Nango();

Expand All @@ -28,8 +30,10 @@ export default function SlackIntegration({
const { getToken } = useAuth();
const router = useRouter();
const [loading, setLoading] = useState(false);
const [sessionToken, setSessionToken] = useState<string | null>(null);
const [connectionId, setConnectionId] = useState<string | null>(null);
const [connection, setConnection] = useState<ClientInferResponses<
typeof contract.getIntegrations,
200
>["body"]["slack"] | null>(null);

const fetchConfig = useCallback(async () => {
setLoading(true);
Expand All @@ -44,19 +48,31 @@ export default function SlackIntegration({
setLoading(false);

if (response.status === 200) {
setSessionToken(response.body?.slack?.nangoSessionToken ?? null);
setConnectionId(response.body?.slack?.nangoConnectionId ?? null);
setConnection(response.body?.slack);
}

}, [clusterId, getToken]);

const onSlackConnect = async () => {
if (!sessionToken) {
const response = await client.createNangoSession({
headers: {
authorization: `Bearer ${await getToken()}`,
},
params: {
clusterId: clusterId,
},
body: {
integration: "slack",
}
});

if (response.status !== 200 || !response.body || !response.body.token) {
toast.error("Failed to connect to Slack");
return;
}

nango.openConnectUI({
sessionToken: sessionToken,
sessionToken: response.body.token,
onEvent: async (event) => {
if (event.type === "connect") {
toast.success("Connected to Slack");
Expand Down Expand Up @@ -106,21 +122,21 @@ export default function SlackIntegration({
</CardDescription>
</CardHeader>
<CardContent>
{sessionToken ? (
<div className="flex items-center gap-2">
<Button
variant="outline"
onClick={onSlackConnect}
>
Connect Slack
</Button>
</div>
) : null}
{connectionId ? (
{connection ? (
<div className="flex items-center gap-2">
<h3 className="text-gray-500">Connected ({connectionId})</h3>
<h3 className="text-gray-500">Slack Connected (Team: {connection.teamId})</h3>
</div>
) : null}
) : (
<div className="flex items-center gap-2">
<Button
variant="outline"
onClick={onSlackConnect}
>
Connect Slack
</Button>
</div>
)
}
</CardContent>
</Card>
</div>
Expand Down
30 changes: 28 additions & 2 deletions app/client/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ export const integrationSchema = z.object({
.nullable(),
slack: z
.object({
nangoSessionToken: z.string().optional().nullable(),
nangoConnectionId: z.string().optional().nullable(),
nangoConnectionId: z.string(),
botUserId: z.string(),
teamId: z.string(),
})
.optional()
.nullable(),
Expand Down Expand Up @@ -1489,6 +1490,31 @@ export const definition = {
}),
},
},
createNangoSession: {
method: "POST",
path: "/clusters/:clusterId/nango/sessions",
pathParams: z.object({
clusterId: z.string(),
}),
headers: z.object({ authorization: z.string() }),
body: z.object({
integration: z.string(),
}),
responses: {
200: z.object({
token: z.string(),
}),
},
},
createNangoEvent: {
method: "POST",
path: "/nango/events",
headers: z.object({ "x-nango-signature": z.string() }),
body: z.object({}).passthrough(),
responses: {
200: z.undefined(),
},
},
} as const;

export const contract = c.router(definition);
142 changes: 14 additions & 128 deletions control-plane/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion control-plane/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"@hyperdx/node-opentelemetry": "^0.8.1",
"@langchain/cohere": "^0.3.1",
"@langchain/langgraph": "^0.1.9",
"@openapi-contrib/openapi-schema-to-json-schema": "^5.1.0",
"@nangohq/node": "^0.48.1",
"@slack/bolt": "^4.1.1",
"@toolhouseai/sdk": "^1.0.4",
Expand Down Expand Up @@ -72,6 +71,7 @@
"devDependencies": {
"@babel/preset-env": "^7.22.10",
"@babel/preset-typescript": "^7.22.11",
"@nangohq/types": "^0.48.1",
"@types/async-retry": "^1.4.9",
"@types/jest": "^29.5.14",
"@types/jsonpath": "^0.2.4",
Expand Down
Loading

0 comments on commit 5472de4

Please sign in to comment.