Lin / frontend /src /services /postService.js
Zelyanoth's picture
fff
25f22bf
raw
history blame
7.46 kB
import apiClient from './apiClient';
class PostService {
/**
* Get all posts for the current user
* @param {Object} params - Query parameters
* @param {boolean} params.published - Filter by published status
* @returns {Promise} Promise that resolves to the posts data
*/
async getAll(params = {}) {
try {
const response = await apiClient.get('/posts', { params });
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log('πŸ“ [Post] Retrieved posts:', response.data);
}
return response;
} catch (error) {
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.error('πŸ“ [Post] Get posts error:', error.response?.data || error.message);
}
throw error;
}
}
/**
* Generate a new post using AI asynchronously
* @returns {Promise} Promise that resolves to the generated post content
*/
async generate() {
try {
// Step 1: Start the generation process and get job ID
const startResponse = await apiClient.post('/posts/generate', {});
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log('πŸ“ [Post] AI post generation started:', startResponse.data);
}
const jobId = startResponse.data.job_id;
// Step 2: Poll for the result
const generatedContent = await this.pollForJobResult(jobId);
// Ensure we return a default value if content is null/undefined
const finalContent = generatedContent !== undefined && generatedContent !== null ? generatedContent : "Generated content will appear here...";
return { data: { success: true, content: finalContent } };
} catch (error) {
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.error('πŸ“ [Post] Generate post error:', error.response?.data || error.message);
}
throw error;
}
}
/**
* Poll for job result
* @param {string} jobId - Job ID to poll
* @returns {Promise} Promise that resolves to the generated content
*/
async pollForJobResult(jobId) {
const pollInterval = 6000; // 6 seconds to match backend logs
const maxAttempts = 60; // 6 minutes (60 * 6 seconds = 360 seconds)
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
const response = await apiClient.get(`/posts/jobs/${jobId}`);
const jobData = response.data;
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log(`πŸ“ [Post] Job status check ${attempt}/${maxAttempts}:`, jobData);
}
switch (jobData.status) {
case 'completed':
// Log the raw job data for debugging
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log('πŸ“ [Post] Raw job data:', jobData);
}
// Extract content, handling cases where it might be a list
let content = jobData.content;
// If content is an array, take the first element
if (Array.isArray(content)) {
content = content[0] || '';
}
// Ensure we return the content even if it's an empty string
return content !== undefined ? content : '';
case 'failed':
throw new Error(jobData.error || 'Job failed');
case 'processing':
case 'pending':
// Wait before next poll
await new Promise(resolve => setTimeout(resolve, pollInterval));
break;
default:
throw new Error(`Unknown job status: ${jobData.status}`);
}
} catch (error) {
if (error.response?.status === 404) {
throw new Error('Job not found');
}
throw error;
}
}
// If we've reached here, we've exceeded the max attempts
throw new Error('Job polling timed out after 6 minutes. Please check back later.');
}
/**
* Create a new post
* @param {Object} postData - Post data
* @param {string} postData.social_account_id - Social account ID
* @param {string} postData.text_content - Post text content
* @param {string} [postData.image_content_url] - Image URL (optional)
* @param {string} [postData.scheduled_at] - Scheduled time (optional)
* @returns {Promise} Promise that resolves to the create post response
*/
async create(postData) {
try {
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log('πŸ“ [Post] Creating post with data:', postData);
}
const response = await apiClient.post('/posts', {
social_account_id: postData.social_account_id,
text_content: postData.text_content,
image_content_url: postData.image_content_url,
scheduled_at: postData.scheduled_at
});
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log('πŸ“ [Post] Post created:', response.data);
}
return response;
} catch (error) {
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.error('πŸ“ [Post] Create post error:', error.response?.data || error.message);
console.error('πŸ“ [Post] Error details:', {
status: error.response?.status,
statusText: error.response?.statusText,
headers: error.response?.headers,
data: error.response?.data
});
}
throw error;
}
}
/**
* Publish a post directly to social media
* @param {Object} publishData - Publish data
* @param {string} publishData.social_account_id - Social account ID
* @param {string} publishData.text_content - Post text content
* @returns {Promise} Promise that resolves to the publish post response
*/
async publishDirect(publishData) {
try {
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log('πŸ“ [Post] Publishing post directly to social media with data:', publishData);
}
const response = await apiClient.post('/posts/publish-direct', publishData);
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log('πŸ“ [Post] Post published directly:', response.data);
}
return response;
} catch (error) {
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.error('πŸ“ [Post] Publish post directly error:', error.response?.data || error.message);
console.error('πŸ“ [Post] Error details:', {
status: error.response?.status,
statusText: error.response?.statusText,
headers: error.response?.headers,
data: error.response?.data
});
}
throw error;
}
}
/**
* Delete a post
* @param {string} postId - Post ID
* @returns {Promise} Promise that resolves to the delete post response
*/
async delete(postId) {
try {
const response = await apiClient.delete(`/posts/${postId}`);
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.log('πŸ“ [Post] Post deleted:', response.data);
}
return response;
} catch (error) {
if (import.meta.env.VITE_NODE_ENV === 'development') {
console.error('πŸ“ [Post] Delete post error:', error.response?.data || error.message);
}
throw error;
}
}
}
export default new PostService();