saas-starter-kit
saas-starter-kit copied to clipboard
OpenAI API integration
OpenAI API integration will be useful to get them deployed into the SaaS Solution built on top of this starter kit
@rambalachandran What do you mean by integration for doing what ?
You can create a chat OpenAI integration with those steps
- [ ] understand the structure of
boxyhq/saas-starter-kit
- [ ] create file
pages\teams\[slug]\openai.tsx
- [ ] create file
pages\api\openai.ts
- [ ] add to next.config.js
, env: { OPENAI_API_SECRET_KEY: process.env.OPENAI_API_SECRET_KEY,},
- [ ] add OPENAI_API_SECRET_KEY to .env
- [ ] add new
MenuItem
tocomponents\shared\shell\TeamNavigation.tsx
- [ ] adapt the solution to your app by enhancing source code and adding your stuff
File content
pages\teams[slug]\openai.tsx
import axios from 'axios';
import { useTranslation } from 'next-i18next';
import React, { useCallback, useEffect, useRef, useState } from 'react';
type HistoryItem = {
role: 'user' | 'assistant';
content: string;
};
const handleMessageSubmit = async (
message: string,
setLoading: React.Dispatch<React.SetStateAction<boolean>>,
setHistory: React.Dispatch<React.SetStateAction<HistoryItem[]>>,
setMessage: React.Dispatch<React.SetStateAction<string>>
) => {
setLoading(true);
try {
const { data } = await axios.post('/api/openai', { prompt: message });
setHistory((oldHistory) => [
...oldHistory,
{ role: 'user', content: message },
{ role: 'assistant', content: data.message },
]);
setMessage('');
} catch (error) {
alert('An error occurred');
} finally {
setLoading(false);
}
};
const OpenAIChat: React.FC = () => {
const { t } = useTranslation('common');
const [message, setMessage] = useState('');
const [history, setHistory] = useState<HistoryItem[]>([]);
const [loading, setLoading] = useState(false);
const callbackRef = useRef<() => void>();
useEffect(() => {
callbackRef.current = () => {
handleMessageSubmit(message, setLoading, setHistory, setMessage);
};
});
const handleInputChange = useCallback(
(event) => setMessage(event.target.value),
[]
);
const handleFormSubmit = useCallback((event) => {
event.preventDefault();
callbackRef.current && callbackRef.current();
}, []);
return (
<div className="container mx-auto py-4 px-4">
<ul>
{history.map((item, index) => (
<li
key={`history-item-${index}`}
className="my-2 p-2 rounded bg-gray-200 dark:bg-gray-700"
>
<strong>{item.role}:</strong> {item.content}
</li>
))}
</ul>
<form
onSubmit={handleFormSubmit}
className="mt-4 flex items-center justify-between"
>
<input
type="text"
value={message}
onChange={handleInputChange}
disabled={loading}
className="flex-1 border p-2 rounded mr-2"
/>
<button
type="submit"
className="btn bg-blue-500 text-white px-4 py-2 rounded"
>
{t('Send')}
</button>
</form>
</div>
);
};
export default OpenAIChat;
pages\api\openai.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { OpenAI } from 'openai';
const apiKey = process.env.OPENAI_API_SECRET_KEY;
if (!apiKey) {
throw new Error(
'OPENAI_API_SECRET_KEY must be declared in your environment variables'
);
}
const openai = new OpenAI({
apiKey: apiKey,
});
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === 'POST') {
const { prompt } = req.body;
try {
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{
role: 'system',
content: 'You are chatting with Assistant.',
},
{
role: 'user',
content: prompt,
},
],
});
const extractedResponseMessage = response.choices[0].message.content;
return res.status(200).json({ message: extractedResponseMessage });
} catch (error) {
console.error('Error:', error);
return res
.status(500)
.json({ error: 'Failed to fetch response from OpenAI.' });
}
} else {
return res
.status(405)
.json({ error: 'Method not allowed. Please use POST.' });
}
}
Results
Thank you for the detailed response. This appears sufficient for now. I will close the ticket