From 1efa565b587b6083d66468bd7fb072f9aa17250e Mon Sep 17 00:00:00 2001 From: Henit Chobisa Date: Fri, 2 May 2025 14:16:22 +0530 Subject: [PATCH] [SILO-201] fix: created proper type for issue link entity data #3104 --- packages/etl/src/slack/types/base.ts | 9 ++++++ .../slack/worker/handlers/view-submission.ts | 30 ++++++++++++++----- .../handle-comment-webhook.ts | 7 +++-- .../handle-issue-webhook.ts | 5 ++-- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/packages/etl/src/slack/types/base.ts b/packages/etl/src/slack/types/base.ts index 24c2fef4f8..3e1f0aa0d5 100644 --- a/packages/etl/src/slack/types/base.ts +++ b/packages/etl/src/slack/types/base.ts @@ -21,6 +21,15 @@ export type TSlackMetadata = { incoming_webhook: Incomingwebhook; is_enterprise_install: boolean; }; + +export type TSlackIssueEntityData = { + channel: string; + message: { + ts: string; + team: string; + }; +}; + export type Incomingwebhook = { url: string; channel: string; diff --git a/silo/src/apps/slack/worker/handlers/view-submission.ts b/silo/src/apps/slack/worker/handlers/view-submission.ts index 4e880d1cc6..c9319951bb 100644 --- a/silo/src/apps/slack/worker/handlers/view-submission.ts +++ b/silo/src/apps/slack/worker/handlers/view-submission.ts @@ -1,5 +1,5 @@ import { E_INTEGRATION_KEYS } from "@plane/etl/core"; -import { TViewSubmissionPayload } from "@plane/etl/slack"; +import { TSlackIssueEntityData, TViewSubmissionPayload } from "@plane/etl/slack"; import { CONSTANTS } from "@/helpers/constants"; import { logger } from "@/logger"; import { getAPIClient } from "@/services/client"; @@ -69,17 +69,23 @@ export const handleLinkWorkItemViewSubmission = async ( if (workspaceEntityConnection.length > 0) { // We need to update the view in order to show that the selected issue is already linked to a thread const existingLink = workspaceEntityConnection[0]; - const entityData = existingLink.entity_data as any; - const channelName = entityData?.channel?.name || "a channel"; - const threadLink = `https://${data.team.domain}.slack.com/archives/${entityData?.channel?.id}/p${existingLink.entity_id}`; + const entityData = existingLink.entity_data as TSlackIssueEntityData; + const threadLink = `https://${data.team.domain}.slack.com/archives/${entityData.channel}/p${existingLink.entity_id}`; const issueLink = `${env.APP_BASE_URL}/${linkWorkItemValues.workspaceSlug}/browse/${issue.project.identifier}-${issue.sequence_id}`; // Create rich error message with links - const errorMessage = createIssueErrorBlocks(issue, channelName, threadLink, issueLink); + const errorMessage = createIssueErrorBlocks(issue, entityData.channel, threadLink, issueLink); const updatedModal = createLinkIssueModalView(metadata.entityPayload); updatedModal.blocks = [...errorMessage.blocks, ...updatedModal.blocks]; const res = await slackService.openModal(data.trigger_id, updatedModal); } else { + const messageTs = metadata.entityPayload.message?.ts; + + if (!messageTs) { + logger.error("No message ts found in entity payload"); + return; + } + const title = "Connected to Slack thread"; const link = `https://${data.team.domain}.slack.com/archives/${metadata.entityPayload.channel.id}/p${metadata.entityPayload.message?.ts}`; @@ -103,6 +109,14 @@ export const handleLinkWorkItemViewSubmission = async ( link ); + const entityData: TSlackIssueEntityData = { + channel: metadata.entityPayload.channel.id, + message: { + ts: messageTs, + team: data.team.id, + }, + }; + const createEntityConnection = apiClient.workspaceEntityConnection.createWorkspaceEntityConnection({ // Main workspace connection workspace_connection_id: details.workspaceConnection.id, @@ -114,8 +128,8 @@ export const handleLinkWorkItemViewSubmission = async ( // Entity identifiers entity_type: E_INTEGRATION_KEYS.SLACK, - entity_id: metadata.entityPayload.message?.ts || "", - entity_data: metadata.entityPayload, + entity_id: messageTs, + entity_data: entityData, entity_slug: issue.id, }); @@ -440,7 +454,7 @@ export const createIssueErrorBlocks = ( type: "section", text: { type: "mrkdwn", - text: `:warning: The work item *<${issueLink}|[${issue.project.identifier}-${issue.sequence_id}] ${issue.name}>* is already linked to another conversation in #${channelName}.`, + text: `:warning: The work item *<${issueLink}|[${issue.project.identifier}-${issue.sequence_id}] ${issue.name}>* is already linked to another conversation in <#${channelName}>.`, }, }, { diff --git a/silo/src/apps/slack/worker/plane-webhook-handlers/handle-comment-webhook.ts b/silo/src/apps/slack/worker/plane-webhook-handlers/handle-comment-webhook.ts index 14b0106c2e..de51ba51e5 100644 --- a/silo/src/apps/slack/worker/plane-webhook-handlers/handle-comment-webhook.ts +++ b/silo/src/apps/slack/worker/plane-webhook-handlers/handle-comment-webhook.ts @@ -1,4 +1,4 @@ -import { SlackMessageResponse } from "@plane/etl/slack"; +import { TSlackIssueEntityData } from "@plane/etl/slack"; import { WebhookIssueCommentPayload } from "@plane/sdk"; import { getAPIClient } from "@/services/client"; import { getConnectionDetailsForIssue } from "../../helpers/connection-details"; @@ -37,8 +37,9 @@ const handleCommentSync = async (payload: WebhookIssueCommentPayload) => { const { entityConnection, slackService } = details; - const slackData = entityConnection.entity_data as SlackMessageResponse; - const channel = typeof slackData.channel === "string" ? slackData.channel : slackData.channel?.["id"]; + const slackData = entityConnection.entity_data as TSlackIssueEntityData; + + const channel = slackData.channel; const response = await slackService.sendThreadMessage( channel, diff --git a/silo/src/apps/slack/worker/plane-webhook-handlers/handle-issue-webhook.ts b/silo/src/apps/slack/worker/plane-webhook-handlers/handle-issue-webhook.ts index 9308bca385..739fb3bfb4 100644 --- a/silo/src/apps/slack/worker/plane-webhook-handlers/handle-issue-webhook.ts +++ b/silo/src/apps/slack/worker/plane-webhook-handlers/handle-issue-webhook.ts @@ -2,6 +2,7 @@ import { Store } from "@/worker/base"; import { PlaneWebhookPayload } from "@plane/sdk"; import { getConnectionDetailsForIssue } from "../../helpers/connection-details"; import { ActivityForSlack, PlaneActivityWithTimestamp } from "../../types/types"; +import { TSlackIssueEntityData } from "@plane/etl/slack"; const ignoredFieldUpdates = ["description", "attachment"]; @@ -25,9 +26,9 @@ export const handleIssueWebhook = async (payload: PlaneWebhookPayload) => { const { slackService, entityConnection } = details; const message = createSlackBlocksFromActivity(activities); - const entityData = entityConnection.entity_data as any; + const entityData = entityConnection.entity_data as TSlackIssueEntityData; - const channel = entityData.channel || entityData.channel.id; + const channel = entityData.channel; const messageTs = entityData.message.ts; if (message.length === 0) {