| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- import { createSupportStorageClient } from '@/components/interfaces/Support/support-storage-client'
- import { generateAttachmentURLs } from '@/data/support/generate-attachment-urls-mutation'
- import { uuidv4 } from '@/lib/helpers'
- export const convertB64toBlob = (image: string) => {
- const contentType = 'image/png'
- const byteCharacters = atob(image.substr(`data:${contentType};base64,`.length))
- const byteArrays = []
- for (let offset = 0; offset < byteCharacters.length; offset += 1024) {
- const slice = byteCharacters.slice(offset, offset + 1024)
- const byteNumbers = new Array(slice.length)
- for (let i = 0; i < slice.length; i++) {
- byteNumbers[i] = slice.charCodeAt(i)
- }
- const byteArray = new Uint8Array(byteNumbers)
- byteArrays.push(byteArray)
- }
- const blob = new Blob(byteArrays, { type: contentType })
- return blob
- }
- type UploadAttachmentArgs = {
- image: string
- userId?: string
- }
- export const uploadAttachment = async ({ image, userId }: UploadAttachmentArgs) => {
- if (!userId) {
- console.error(
- '[FeedbackWidget > uploadAttachment] Unable to upload screenshot, missing user ID'
- )
- return undefined
- }
- const brivenClient = createSupportStorageClient()
- const blob = convertB64toBlob(image)
- const filename = `${userId}/${uuidv4()}.png`
- const options = { cacheControl: '3600' }
- const { data: file, error: uploadError } = await brivenClient.storage
- .from('feedback-attachments')
- .upload(filename, blob, options)
- if (uploadError || !file) {
- console.error('Failed to upload screenshot attachment:', uploadError)
- return undefined
- }
- const signedUrls = await generateAttachmentURLs({
- bucket: 'feedback-attachments',
- filenames: [file.path],
- })
- return signedUrls[0]
- }
- /**
- * Client-side heuristic to quickly detect obvious support requests
- * This provides immediate feedback before the AI classification completes
- */
- export function isLikelySupportRequest(text: string): boolean {
- if (!text || text.trim().length === 0) return false
- const lowerText = text.toLowerCase()
- // Common support request patterns
- const supportPatterns = [
- // Help requests
- /need help/i,
- /having trouble/i,
- /having issues/i,
- /having problems/i,
- /can you help/i,
- /could you help/i,
- /please help/i,
- /need help/i,
- /how do/i,
- /how can/i,
- /how to/i,
- /why isn't/i,
- /why doesn't/i,
- /why won't/i,
- /why can't/i,
- // Problem indicators
- /it's not working/i,
- /it doesn't work/i,
- /it won't work/i,
- /it can't work/i,
- /isn't working/i,
- /doesn't work/i,
- /won't work/i,
- /can't work/i,
- /not work/i,
- /i can't/i,
- /i cannot/i,
- /unable to/i,
- /wrong/i,
- /bad/i,
- // Bug/error indicators
- /\bbug\b/i,
- /\bbroken\b/i,
- /\berror\b/i,
- /\berrors\b/i,
- /\bfailed\b/i,
- /\bfailure\b/i,
- /\bfailing\b/i,
- /\bcrash\b/i,
- /\bcrashed\b/i,
- /\bcrashing\b/i,
- // Issue/problem keywords
- /\bissue\b/i,
- /\bissues\b/i,
- /\bproblem\b/i,
- /\bproblems\b/i,
- /\btrouble\b/i,
- /\bdifficulty\b/i,
- /\bdifficulties\b/i,
- // Support-specific phrases
- /support ticket/i,
- /contact support/i,
- /get help/i,
- /need assistance/i,
- /require assistance/i,
- /technical support/i,
- ]
- return supportPatterns.some((pattern) => pattern.test(lowerText))
- }
|