Skip to content

Commit

Permalink
Feat: 🚀 Tegon actions + Public access (#188)
Browse files Browse the repository at this point in the history
* Fix: local setup

* Feat: add magic login in backend
Fix: restrict action access on workspace

* Fix: local setup

* Feat: changed login UI

* Fix: login email template

* Add: openapi schema for APIs in service

* Feat: website

* Feat: added website

* Fix: squash commits

* Fix: Add attachment in slack common actions

* Feat: onboarding

* Fix: misc

* Fix: User view based on Tegon actions

---------

Co-authored-by: Manoj K <[email protected]>
  • Loading branch information
harshithmullapudi and saimanoj authored Aug 28, 2024
1 parent 21f32f3 commit e46802b
Show file tree
Hide file tree
Showing 260 changed files with 5,804 additions and 2,870 deletions.
6 changes: 4 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
VERSION=0.3.0-alpha
NODE_ENV=production
NODE_ENV=development


############# Common ###############
Expand Down Expand Up @@ -69,9 +69,10 @@ OLLAMA_HOST=http://localhost:11434

############# Frontend ###############
# Sync server url used by the frontend to connect to the websocket and server
NEXT_PUBLIC_BACKEND_URL=${BACKEND_URL}
NEXT_PUBLIC_BASE_HOST=${FRONTEND_HOST}
NEXT_PUBLIC_BACKEND_HOST=${BACKEND_HOST}
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

# You need to set your domain if self-hosted
PUBLIC_ATTACHMENT_URL=http://localhost:3000/api
Expand All @@ -85,6 +86,7 @@ TRIGGER_COMMON_ID=clyofc7dn0000o33e4sup590l

TRIGGER_TOKEN=27192e6432564f4788d55c15131bd5ac
TRIGGER_ACCESS_TOKEN=tr_pat_${TRIGGER_TOKEN}
TRIGGER_API_URL=http://localhost:3030

TRIGGER_DB=trigger
TRIGGER_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DB_HOST}/${TRIGGER_DB}
5 changes: 3 additions & 2 deletions actions/slack-common-workflows/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
},
"packageManager": "[email protected]",
"dependencies": {
"@tegonhq/sdk": "^0.1.0-beta.15",
"@tegonhq/sdk": "^0.1.3",
"@trigger.dev/sdk": "3.0.0-beta.55",
"axios": "^1.6.7",
"@trigger.dev/sdk": "3.0.0-beta.55"
"form-data": "^4.0.0"
},
"devDependencies": {
"@types/jsonwebtoken": "^9.0.6",
Expand Down
240 changes: 121 additions & 119 deletions actions/slack-common-workflows/pnpm-lock.yaml

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions actions/slack-common-workflows/triggers/comment-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export const commentSync = async (actionPayload: ActionEventPayload) => {
modelId: issueCommentId,
} = actionPayload;

const integrationDefinitionName =
integrationAccount.integrationDefinition.name;
const integrationDefinitionSlug =
integrationAccount.integrationDefinition.slug;

const issueComment = await getIssueComment({ issueCommentId });

Expand Down Expand Up @@ -77,7 +77,7 @@ export const commentSync = async (actionPayload: ActionEventPayload) => {
parentTs: message.thread_ts,
channelId: messageData.channel,
channelType: messageData.channel_type,
type: integrationDefinitionName,
type: integrationDefinitionSlug,
userDisplayName: message.username ? message.username : message.user,
};

Expand All @@ -89,4 +89,6 @@ export const commentSync = async (actionPayload: ActionEventPayload) => {
sourceData,
});
}

return null;
};
25 changes: 20 additions & 5 deletions actions/slack-common-workflows/triggers/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import {
updateIssueComment,
getLinkedComment,
getLinkedIssueBySource,
uploadAttachment,
} from '@tegonhq/sdk';

import {
convertSlackMessageToTiptapJson,
getExternalSlackUser,
getFilesBuffer,
} from '../utils';

export const slackThread = async (
Expand Down Expand Up @@ -77,19 +79,32 @@ export const slackThread = async (
parentTs: message.thread_ts,
channelId: event.channel,
channelType: event.channel_type,
type: integrationAccount.integrationDefinition.name,
type: integrationAccount.integrationDefinition.slug,
id: integrationAccount.id,
userDisplayName: message.username ? message.username : displayName,
};

const attachmentUrls: AttachmentResponse[] = [];
let attachmentUrls: AttachmentResponse[] = [];
if (message.files) {
// Get the files buffer from Slack using the integration account and message files
const filesFormData = await getFilesBuffer(
integrationAccount,
message.files,
);

// Upload the files to GCP and get the attachment URLs
attachmentUrls = await uploadAttachment(
integrationAccount.workspaceId,
filesFormData,
);
}

const tiptapMessage = convertSlackMessageToTiptapJson(
message.blocks,
attachmentUrls,
);

let linkedComment = await getLinkedComment({ sourceId: threadId });
const linkedComment = await getLinkedComment({ sourceId: threadId });
if (linkedComment) {
// If a linked comment exists, update the existing comment
logger.debug(`Updating existing comment for thread ID: ${threadId}`);
Expand All @@ -100,7 +115,7 @@ export const slackThread = async (
});
}

linkedComment = {
const linkedCommentMetadata = {
url: threadId,
sourceId: threadId,
sourceData: sourceMetadata,
Expand All @@ -111,6 +126,6 @@ export const slackThread = async (
body: tiptapMessage,
parentId,
sourceMetadata,
linkCommentMetadata: linkedComment,
linkCommentMetadata: linkedCommentMetadata,
});
};
27 changes: 23 additions & 4 deletions actions/slack-common-workflows/triggers/triage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
logger,
getLinkedIssueBySource,
getWorkflowsByTeam,
uploadAttachment,
} from '@tegonhq/sdk';

import { slackIssueCreate } from './issue-create';
Expand All @@ -19,6 +20,7 @@ import {
import {
convertSlackMessageToTiptapJson,
getExternalSlackUser,
getFilesBuffer,
getSlackMessage,
getStateId,
sendEphemeralMessage,
Expand Down Expand Up @@ -87,10 +89,11 @@ export const slackTriage = async (
// Check if the thread is already linked to an existing issue
const [linkedIssue, workflowStates] = await Promise.all([
getLinkedIssueBySource({ sourceId }),
// (await axios.get(`/api/v1/linked_issues/source?sourceId=${sourceId}`)).data,
getWorkflowsByTeam({ teamId }),
]);

// If the thread is already linked to an issue, send an ephemeral message and return
// // If the thread is already linked to an issue, send an ephemeral message and return
if (linkedIssue) {
await sendEphemeralMessage(
integrationAccount,
Expand Down Expand Up @@ -128,14 +131,28 @@ export const slackTriage = async (
// Create source metadata object
const sourceMetadata = {
id: integrationAccount.id,
type: integrationAccount.integrationDefinition.name,
type: integrationAccount.integrationDefinition.slug,
subType: 'Thread',
channelId: sessionData.channelId,
userDisplayName: slackUsername,
};

const attachmentUrls: AttachmentResponse[] = [];
let attachmentUrls: AttachmentResponse[] = [];
// add Attachments
if (slackMessageResponse.messages[0].files) {
// Get the files buffer from Slack using the integration account and message files
const filesFormData = await getFilesBuffer(
integrationAccount,
slackMessageResponse.messages[0].files,
);
filesFormData.append('sourceMetadata', JSON.stringify(sourceMetadata));

// Upload the files to GCP and get the attachment URLs
attachmentUrls = await uploadAttachment(
integrationAccount.workspaceId,
filesFormData,
);
}

// Convert the Slack message blocks to Tiptap JSON format, including the attachment URLs
const description = convertSlackMessageToTiptapJson(
Expand All @@ -147,10 +164,12 @@ export const slackTriage = async (
url: `https://${sessionData.slackTeamDomain}.slack.com/archives/${sessionData.channelId}/p${mainTs.replace('.', '')}`,
sourceId,
sourceData: {
type: integrationAccount.integrationDefinition.name,
type: integrationAccount.integrationDefinition.slug,
channelId: sessionData.channelId,
parentTs: mainTs,
title: `Slack message from: ${slackUsername}`,
slackTeamDomain: sessionData.slackTeamDomain,
userDisplayName: slackUsername,
},
createdById: userId,
};
Expand Down
45 changes: 45 additions & 0 deletions actions/slack-common-workflows/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
} from '@tegonhq/sdk';

import axios from 'axios';
import fs from 'fs';
import FormData from 'form-data';

import { SlackBlock, SlackElement, SlashCommandSessionRecord } from './types';

Expand Down Expand Up @@ -201,6 +203,49 @@ export async function getSlackTeamInfo(slackTeamId: string, apiKey: string) {
return response.data;
}

/**
* Retrieves the files buffer from Slack.
* @param integrationAccount The integration account with relations.
* @param files The array of files from the Slack event body.
* @returns Formdata with files.
*/
export async function getFilesBuffer(
integrationAccount: IntegrationAccount,
files: EventBody[],
) {
const formData = new FormData();

// Retrieve the files buffer for each file
await Promise.all(
files.map(async (file) => {
const response = await axios.get(file.url_private, {
...getSlackHeaders(integrationAccount),
responseType: 'stream',
});

const tempFilePath = `/tmp/${file.name}`;
const writeStream = fs.createWriteStream(tempFilePath);

await new Promise((resolve, reject) => {
response.data.pipe(writeStream);
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});

formData.append('files', fs.createReadStream(tempFilePath));

return tempFilePath;
}),
);

// Clean up the temporary files after the request is complete
// tempFilePaths.forEach((filePath) => {
// fs.unlinkSync(filePath);
// });

return formData;
}

/// ******************* Tip tap utils *******************//////

export function convertSlackMessageToTiptapJson(
Expand Down
2 changes: 1 addition & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"prisma:studio": "prisma studio",
"generate": "prisma generate",
"db:init-resources": "pnpm run migrate:dev && pnpm run generate",
"create-resources": "node scripts/createUserWorkspaceTeam",
"deploy-trigger-tasks": "npx trigger.dev@beta deploy --self-hosted",
"trigger-dev": "npx trigger.dev@beta dev -a http://localhost:3030"
},
Expand Down Expand Up @@ -99,6 +98,7 @@
"openai": "^4.28.4",
"passport": "0.7.0",
"passport-jwt": "4.0.1",
"passwordless": "link:supertokens-node/recipe/passwordless",
"pg": "^8.12.0",
"pg-logical-replication": "^2.0.3",
"prisma": "5.17.0",
Expand Down
Loading

0 comments on commit e46802b

Please sign in to comment.