* Uploads files to Slack and returns the uploaded file IDs
( files: any[], accessToken: string, requestId: string, logger: Logger, ownerUserId: string )
| 71 | * Uploads files to Slack and returns the uploaded file IDs |
| 72 | */ |
| 73 | async function uploadFilesToSlack( |
| 74 | files: any[], |
| 75 | accessToken: string, |
| 76 | requestId: string, |
| 77 | logger: Logger, |
| 78 | ownerUserId: string |
| 79 | ): Promise<{ fileIds: string[]; files: ToolFileData[] }> { |
| 80 | const userFiles = processFilesToUserFiles(files, requestId, logger) |
| 81 | const uploadedFileIds: string[] = [] |
| 82 | const uploadedFiles: ToolFileData[] = [] |
| 83 | |
| 84 | for (const userFile of userFiles) { |
| 85 | logger.info(`[${requestId}] Uploading file: ${userFile.name}`) |
| 86 | |
| 87 | const hasAccess = await verifyFileAccess(userFile.key, ownerUserId) |
| 88 | if (!hasAccess) { |
| 89 | throw new FileAccessDeniedError() |
| 90 | } |
| 91 | |
| 92 | const { buffer, contentType } = await downloadServableFileFromStorage( |
| 93 | userFile, |
| 94 | requestId, |
| 95 | logger |
| 96 | ) |
| 97 | |
| 98 | const getUrlResponse = await fetch('https://slack.com/api/files.getUploadURLExternal', { |
| 99 | method: 'POST', |
| 100 | headers: { |
| 101 | 'Content-Type': 'application/x-www-form-urlencoded', |
| 102 | Authorization: `Bearer ${accessToken}`, |
| 103 | }, |
| 104 | body: new URLSearchParams({ |
| 105 | filename: userFile.name, |
| 106 | length: buffer.length.toString(), |
| 107 | }), |
| 108 | }) |
| 109 | |
| 110 | const urlData = await getUrlResponse.json() |
| 111 | |
| 112 | if (!urlData.ok) { |
| 113 | logger.error(`[${requestId}] Failed to get upload URL:`, urlData.error) |
| 114 | continue |
| 115 | } |
| 116 | |
| 117 | logger.info(`[${requestId}] Got upload URL for ${userFile.name}, file_id: ${urlData.file_id}`) |
| 118 | |
| 119 | const uploadResponse = await secureFetchWithValidation( |
| 120 | urlData.upload_url, |
| 121 | { |
| 122 | method: 'POST', |
| 123 | body: buffer, |
| 124 | }, |
| 125 | 'uploadUrl' |
| 126 | ) |
| 127 | |
| 128 | if (!uploadResponse.ok) { |
| 129 | logger.error(`[${requestId}] Failed to upload file data: ${uploadResponse.status}`) |
| 130 | continue |
no test coverage detected