Files
spliit/src/app/groups/[groupId]/expenses/create-from-receipt-button-actions.ts
Mert Demir fb49fb596a Automatic category from expense title (#80)
* environment variable

* random category draft

* get category from ai

* input limit and documentation

* use watch

* use field.name

* prettier

* presigned upload, readme warning, category to string util

* prettier

* check whether feature is enabled

* use process.env

* improved prompt to return id only

* remove console.debug

* show loader

* share class name

* prettier

* use template literals

* rename format util

* prettier
2024-02-04 12:23:11 -05:00

51 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use server'
import { getCategories } from '@/lib/api'
import { env } from '@/lib/env'
import { formatCategoryForAIPrompt } from '@/lib/utils'
import OpenAI from 'openai'
import { ChatCompletionCreateParamsNonStreaming } from 'openai/resources/index.mjs'
const openai = new OpenAI({ apiKey: env.OPENAI_API_KEY })
export async function extractExpenseInformationFromImage(imageUrl: string) {
'use server'
const categories = await getCategories()
const body: ChatCompletionCreateParamsNonStreaming = {
model: 'gpt-4-vision-preview',
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: `
This image contains a receipt.
Read the total amount and store it as a non-formatted number without any other text or currency.
Then guess the category for this receipt amoung the following categories and store its ID: ${categories.map(
(category) => formatCategoryForAIPrompt(category),
)}.
Guess the expenses date and store it as yyyy-mm-dd.
Guess a title for the expense.
Return the amount, the category, the date and the title with just a comma between them, without anything else.`,
},
],
},
{
role: 'user',
content: [{ type: 'image_url', image_url: { url: imageUrl } }],
},
],
}
const completion = await openai.chat.completions.create(body)
const [amountString, categoryId, date, title] = completion.choices
.at(0)
?.message.content?.split(',') ?? [null, null, null, null]
return { amount: Number(amountString), categoryId, date, title }
}
export type ReceiptExtractedInfo = Awaited<
ReturnType<typeof extractExpenseInformationFromImage>
>