141 lines
4.1 KiB
TypeScript
141 lines
4.1 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { getEvents } from '@/lib/analytics';
|
|
import { ApiResponse } from '@/lib/types';
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(request.url);
|
|
|
|
// Get required parameters
|
|
const slug = searchParams.get('slug');
|
|
const domain = searchParams.get('domain');
|
|
|
|
// If slug or domain is missing, return an error
|
|
if (!slug || !domain) {
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: 'Missing required parameters: slug and domain are required'
|
|
}, { status: 400 });
|
|
}
|
|
|
|
// Construct the shortUrl from domain and slug
|
|
const shortUrl = `https://${domain}/${slug}`;
|
|
|
|
// Log the request for debugging
|
|
console.log('Activities API received parameters:', {
|
|
slug,
|
|
domain,
|
|
shortUrl
|
|
});
|
|
|
|
// Set default page size and page
|
|
const page = parseInt(searchParams.get('page') || '1');
|
|
const pageSize = parseInt(searchParams.get('pageSize') || '50');
|
|
|
|
// Optional date range parameters
|
|
const startTime = searchParams.get('startTime') || undefined;
|
|
const endTime = searchParams.get('endTime') || undefined;
|
|
|
|
// Get events for the specified shortUrl
|
|
const { events, total } = await getEvents({
|
|
linkSlug: slug,
|
|
page,
|
|
pageSize,
|
|
startTime,
|
|
endTime,
|
|
sortBy: 'event_time',
|
|
sortOrder: 'desc'
|
|
});
|
|
|
|
// Process the events to extract useful information
|
|
const processedEvents = events.map(event => {
|
|
// Parse JSON strings to objects safely
|
|
let eventAttributes: Record<string, unknown> = {};
|
|
|
|
try {
|
|
if (typeof event.event_attributes === 'string') {
|
|
eventAttributes = JSON.parse(event.event_attributes);
|
|
} else if (typeof event.event_attributes === 'object') {
|
|
eventAttributes = event.event_attributes;
|
|
}
|
|
} catch {
|
|
// Keep default empty object if parsing fails
|
|
}
|
|
|
|
// Extract tags
|
|
let tags: string[] = [];
|
|
|
|
try {
|
|
if (typeof event.link_tags === 'string') {
|
|
const parsedTags = JSON.parse(event.link_tags);
|
|
if (Array.isArray(parsedTags)) {
|
|
tags = parsedTags;
|
|
}
|
|
} else if (Array.isArray(event.link_tags)) {
|
|
tags = event.link_tags;
|
|
}
|
|
} catch {
|
|
// If parsing fails, keep tags as empty array
|
|
}
|
|
|
|
// Return a simplified event object
|
|
return {
|
|
id: event.event_id,
|
|
type: event.event_type,
|
|
time: event.event_time,
|
|
visitor: {
|
|
id: event.visitor_id,
|
|
ipAddress: event.ip_address,
|
|
userAgent: eventAttributes.user_agent as string || null,
|
|
referrer: eventAttributes.referrer as string || null
|
|
},
|
|
device: {
|
|
type: event.device_type,
|
|
browser: event.browser,
|
|
os: event.os
|
|
},
|
|
location: {
|
|
country: event.country,
|
|
city: event.city
|
|
},
|
|
link: {
|
|
id: event.link_id,
|
|
slug: event.link_slug,
|
|
originalUrl: event.link_original_url,
|
|
label: event.link_label,
|
|
tags
|
|
},
|
|
utm: {
|
|
source: eventAttributes.utm_source as string || null,
|
|
medium: eventAttributes.utm_medium as string || null,
|
|
campaign: eventAttributes.utm_campaign as string || null,
|
|
term: eventAttributes.utm_term as string || null,
|
|
content: eventAttributes.utm_content as string || null
|
|
}
|
|
};
|
|
});
|
|
|
|
// Return processed events
|
|
const response: ApiResponse<typeof processedEvents> = {
|
|
success: true,
|
|
data: processedEvents,
|
|
meta: {
|
|
total,
|
|
page,
|
|
pageSize
|
|
}
|
|
};
|
|
|
|
return NextResponse.json(response);
|
|
} catch (error) {
|
|
console.error('Error retrieving activities:', error);
|
|
|
|
const response: ApiResponse<null> = {
|
|
success: false,
|
|
data: null,
|
|
error: error instanceof Error ? error.message : 'An error occurred while retrieving activities'
|
|
};
|
|
|
|
return NextResponse.json(response, { status: 500 });
|
|
}
|
|
}
|