Skip to content

Commit 3ceabbb

Browse files
committed
fix more bugbot comments
1 parent a65f3b8 commit 3ceabbb

File tree

7 files changed

+348
-503
lines changed

7 files changed

+348
-503
lines changed

apps/sim/app/api/tools/microsoft_teams/write_channel/route.ts

Lines changed: 12 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ import { checkInternalAuth } from '@/lib/auth/hybrid'
55
import { secureFetchWithValidation } from '@/lib/core/security/input-validation.server'
66
import { generateRequestId } from '@/lib/core/utils/request'
77
import { RawFileInputArraySchema } from '@/lib/uploads/utils/file-schemas'
8-
import { processFilesToUserFiles } from '@/lib/uploads/utils/file-utils'
9-
import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server'
10-
import type {
11-
GraphApiErrorResponse,
12-
GraphChatMessage,
13-
GraphDriveItem,
14-
} from '@/tools/microsoft_teams/types'
15-
import { resolveMentionsForChannel, type TeamsMention } from '@/tools/microsoft_teams/utils'
8+
import type { GraphApiErrorResponse, GraphChatMessage } from '@/tools/microsoft_teams/types'
9+
import {
10+
resolveMentionsForChannel,
11+
type TeamsMention,
12+
uploadFilesForTeamsMessage,
13+
} from '@/tools/microsoft_teams/utils'
1614

1715
export const dynamic = 'force-dynamic'
1816

@@ -60,130 +58,12 @@ export async function POST(request: NextRequest) {
6058
fileCount: validatedData.files?.length || 0,
6159
})
6260

63-
const attachments: any[] = []
64-
const filesOutput: Array<{
65-
name: string
66-
mimeType: string
67-
data: string
68-
size: number
69-
}> = []
70-
if (validatedData.files && validatedData.files.length > 0) {
71-
const rawFiles = validatedData.files
72-
logger.info(`[${requestId}] Processing ${rawFiles.length} file(s) for upload to OneDrive`)
73-
74-
const userFiles = processFilesToUserFiles(rawFiles, requestId, logger)
75-
76-
for (const file of userFiles) {
77-
try {
78-
// Microsoft Graph API limits direct uploads to 4MB
79-
const maxSize = 4 * 1024 * 1024
80-
if (file.size > maxSize) {
81-
const sizeMB = (file.size / (1024 * 1024)).toFixed(2)
82-
logger.error(
83-
`[${requestId}] File ${file.name} is ${sizeMB}MB, exceeds 4MB limit for direct upload`
84-
)
85-
throw new Error(
86-
`File "${file.name}" (${sizeMB}MB) exceeds the 4MB limit for Teams attachments. Use smaller files or upload to SharePoint/OneDrive first.`
87-
)
88-
}
89-
90-
logger.info(`[${requestId}] Uploading file to Teams: ${file.name} (${file.size} bytes)`)
91-
92-
const buffer = await downloadFileFromStorage(file, requestId, logger)
93-
filesOutput.push({
94-
name: file.name,
95-
mimeType: file.type || 'application/octet-stream',
96-
data: buffer.toString('base64'),
97-
size: buffer.length,
98-
})
99-
100-
const uploadUrl =
101-
'https://graph.microsoft.com/v1.0/me/drive/root:/TeamsAttachments/' +
102-
encodeURIComponent(file.name) +
103-
':/content'
104-
105-
logger.info(`[${requestId}] Uploading to Teams: ${uploadUrl}`)
106-
107-
const uploadResponse = await secureFetchWithValidation(
108-
uploadUrl,
109-
{
110-
method: 'PUT',
111-
headers: {
112-
Authorization: `Bearer ${validatedData.accessToken}`,
113-
'Content-Type': file.type || 'application/octet-stream',
114-
},
115-
body: buffer,
116-
},
117-
'uploadUrl'
118-
)
119-
120-
if (!uploadResponse.ok) {
121-
const errorData = (await uploadResponse
122-
.json()
123-
.catch(() => ({}))) as GraphApiErrorResponse
124-
logger.error(`[${requestId}] Teams upload failed:`, errorData)
125-
throw new Error(
126-
`Failed to upload file to Teams: ${errorData.error?.message || 'Unknown error'}`
127-
)
128-
}
129-
130-
const uploadedFile = (await uploadResponse.json()) as GraphDriveItem
131-
logger.info(`[${requestId}] File uploaded to Teams successfully`, {
132-
id: uploadedFile.id,
133-
webUrl: uploadedFile.webUrl,
134-
})
135-
136-
const fileDetailsUrl = `https://graph.microsoft.com/v1.0/me/drive/items/${uploadedFile.id}?$select=id,name,webDavUrl,eTag,size`
137-
138-
const fileDetailsResponse = await secureFetchWithValidation(
139-
fileDetailsUrl,
140-
{
141-
method: 'GET',
142-
headers: {
143-
Authorization: `Bearer ${validatedData.accessToken}`,
144-
},
145-
},
146-
'fileDetailsUrl'
147-
)
148-
149-
if (!fileDetailsResponse.ok) {
150-
const errorData = (await fileDetailsResponse
151-
.json()
152-
.catch(() => ({}))) as GraphApiErrorResponse
153-
logger.error(`[${requestId}] Failed to get file details:`, errorData)
154-
throw new Error(
155-
`Failed to get file details: ${errorData.error?.message || 'Unknown error'}`
156-
)
157-
}
158-
159-
const fileDetails = (await fileDetailsResponse.json()) as GraphDriveItem
160-
logger.info(`[${requestId}] Got file details`, {
161-
webDavUrl: fileDetails.webDavUrl,
162-
eTag: fileDetails.eTag,
163-
})
164-
165-
const attachmentId = fileDetails.eTag?.match(/\{([a-f0-9-]+)\}/i)?.[1] || fileDetails.id
166-
167-
attachments.push({
168-
id: attachmentId,
169-
contentType: 'reference',
170-
contentUrl: fileDetails.webDavUrl,
171-
name: file.name,
172-
})
173-
174-
logger.info(`[${requestId}] Created attachment reference for ${file.name}`)
175-
} catch (error) {
176-
logger.error(`[${requestId}] Failed to process file ${file.name}:`, error)
177-
throw new Error(
178-
`Failed to process file "${file.name}": ${error instanceof Error ? error.message : 'Unknown error'}`
179-
)
180-
}
181-
}
182-
183-
logger.info(
184-
`[${requestId}] All ${attachments.length} file(s) uploaded and attachment references created`
185-
)
186-
}
61+
const { attachments, filesOutput } = await uploadFilesForTeamsMessage({
62+
rawFiles: validatedData.files || [],
63+
accessToken: validatedData.accessToken,
64+
requestId,
65+
logger,
66+
})
18767

18868
let messageContent = validatedData.content
18969
let contentType: 'text' | 'html' = 'text'

apps/sim/app/api/tools/microsoft_teams/write_chat/route.ts

Lines changed: 12 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ import { checkInternalAuth } from '@/lib/auth/hybrid'
55
import { secureFetchWithValidation } from '@/lib/core/security/input-validation.server'
66
import { generateRequestId } from '@/lib/core/utils/request'
77
import { RawFileInputArraySchema } from '@/lib/uploads/utils/file-schemas'
8-
import { processFilesToUserFiles } from '@/lib/uploads/utils/file-utils'
9-
import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server'
10-
import type {
11-
GraphApiErrorResponse,
12-
GraphChatMessage,
13-
GraphDriveItem,
14-
} from '@/tools/microsoft_teams/types'
15-
import { resolveMentionsForChat, type TeamsMention } from '@/tools/microsoft_teams/utils'
8+
import type { GraphApiErrorResponse, GraphChatMessage } from '@/tools/microsoft_teams/types'
9+
import {
10+
resolveMentionsForChat,
11+
type TeamsMention,
12+
uploadFilesForTeamsMessage,
13+
} from '@/tools/microsoft_teams/utils'
1614

1715
export const dynamic = 'force-dynamic'
1816

@@ -58,130 +56,12 @@ export async function POST(request: NextRequest) {
5856
fileCount: validatedData.files?.length || 0,
5957
})
6058

61-
const attachments: any[] = []
62-
const filesOutput: Array<{
63-
name: string
64-
mimeType: string
65-
data: string
66-
size: number
67-
}> = []
68-
if (validatedData.files && validatedData.files.length > 0) {
69-
const rawFiles = validatedData.files
70-
logger.info(`[${requestId}] Processing ${rawFiles.length} file(s) for upload to Teams`)
71-
72-
const userFiles = processFilesToUserFiles(rawFiles, requestId, logger)
73-
74-
for (const file of userFiles) {
75-
try {
76-
// Microsoft Graph API limits direct uploads to 4MB
77-
const maxSize = 4 * 1024 * 1024
78-
if (file.size > maxSize) {
79-
const sizeMB = (file.size / (1024 * 1024)).toFixed(2)
80-
logger.error(
81-
`[${requestId}] File ${file.name} is ${sizeMB}MB, exceeds 4MB limit for direct upload`
82-
)
83-
throw new Error(
84-
`File "${file.name}" (${sizeMB}MB) exceeds the 4MB limit for Teams attachments. Use smaller files or upload to SharePoint/OneDrive first.`
85-
)
86-
}
87-
88-
logger.info(`[${requestId}] Uploading file to Teams: ${file.name} (${file.size} bytes)`)
89-
90-
const buffer = await downloadFileFromStorage(file, requestId, logger)
91-
filesOutput.push({
92-
name: file.name,
93-
mimeType: file.type || 'application/octet-stream',
94-
data: buffer.toString('base64'),
95-
size: buffer.length,
96-
})
97-
98-
const uploadUrl =
99-
'https://graph.microsoft.com/v1.0/me/drive/root:/TeamsAttachments/' +
100-
encodeURIComponent(file.name) +
101-
':/content'
102-
103-
logger.info(`[${requestId}] Uploading to Teams: ${uploadUrl}`)
104-
105-
const uploadResponse = await secureFetchWithValidation(
106-
uploadUrl,
107-
{
108-
method: 'PUT',
109-
headers: {
110-
Authorization: `Bearer ${validatedData.accessToken}`,
111-
'Content-Type': file.type || 'application/octet-stream',
112-
},
113-
body: buffer,
114-
},
115-
'uploadUrl'
116-
)
117-
118-
if (!uploadResponse.ok) {
119-
const errorData = (await uploadResponse
120-
.json()
121-
.catch(() => ({}))) as GraphApiErrorResponse
122-
logger.error(`[${requestId}] Teams upload failed:`, errorData)
123-
throw new Error(
124-
`Failed to upload file to Teams: ${errorData.error?.message || 'Unknown error'}`
125-
)
126-
}
127-
128-
const uploadedFile = (await uploadResponse.json()) as GraphDriveItem
129-
logger.info(`[${requestId}] File uploaded to Teams successfully`, {
130-
id: uploadedFile.id,
131-
webUrl: uploadedFile.webUrl,
132-
})
133-
134-
const fileDetailsUrl = `https://graph.microsoft.com/v1.0/me/drive/items/${uploadedFile.id}?$select=id,name,webDavUrl,eTag,size`
135-
136-
const fileDetailsResponse = await secureFetchWithValidation(
137-
fileDetailsUrl,
138-
{
139-
method: 'GET',
140-
headers: {
141-
Authorization: `Bearer ${validatedData.accessToken}`,
142-
},
143-
},
144-
'fileDetailsUrl'
145-
)
146-
147-
if (!fileDetailsResponse.ok) {
148-
const errorData = (await fileDetailsResponse
149-
.json()
150-
.catch(() => ({}))) as GraphApiErrorResponse
151-
logger.error(`[${requestId}] Failed to get file details:`, errorData)
152-
throw new Error(
153-
`Failed to get file details: ${errorData.error?.message || 'Unknown error'}`
154-
)
155-
}
156-
157-
const fileDetails = (await fileDetailsResponse.json()) as GraphDriveItem
158-
logger.info(`[${requestId}] Got file details`, {
159-
webDavUrl: fileDetails.webDavUrl,
160-
eTag: fileDetails.eTag,
161-
})
162-
163-
const attachmentId = fileDetails.eTag?.match(/\{([a-f0-9-]+)\}/i)?.[1] || fileDetails.id
164-
165-
attachments.push({
166-
id: attachmentId,
167-
contentType: 'reference',
168-
contentUrl: fileDetails.webDavUrl,
169-
name: file.name,
170-
})
171-
172-
logger.info(`[${requestId}] Created attachment reference for ${file.name}`)
173-
} catch (error) {
174-
logger.error(`[${requestId}] Failed to process file ${file.name}:`, error)
175-
throw new Error(
176-
`Failed to process file "${file.name}": ${error instanceof Error ? error.message : 'Unknown error'}`
177-
)
178-
}
179-
}
180-
181-
logger.info(
182-
`[${requestId}] All ${attachments.length} file(s) uploaded and attachment references created`
183-
)
184-
}
59+
const { attachments, filesOutput } = await uploadFilesForTeamsMessage({
60+
rawFiles: validatedData.files || [],
61+
accessToken: validatedData.accessToken,
62+
requestId,
63+
logger,
64+
})
18565

18666
let messageContent = validatedData.content
18767
let contentType: 'text' | 'html' = 'text'

0 commit comments

Comments
 (0)