posimai-tech-events/api/events.js

93 lines
3.4 KiB
JavaScript
Raw Normal View History

/**
* Posimai Tech Events - /api/events
*
* GET /api/events?q=keyword -> Connpass APIを呼び出して整形したイベント一覧を返す
*
* Connpass API: https://connpass.com/about/api/
*/
export default async function handler(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') {
return res.status(200).end();
}
if (req.method !== 'GET') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const { q } = req.query;
// Search either specific query from UI or broad default queries for tech events
const fetchKeyword = q && q.trim().length > 0 ? q.trim() : 'IT,エンジニア,デザイン,Web,AI,アプリ';
const urlObj = new URL('https://connpass.com/api/v1/event/');
// ConnpassのOR検索仕様に合わせて keyword_or を使用する
urlObj.searchParams.append('keyword_or', fetchKeyword);
urlObj.searchParams.append('order', '2'); // 開催降順(新着イベント)
urlObj.searchParams.append('count', '50');
// Connpass APIはUser-Agentが必須
const response = await fetch(urlObj.toString(), {
headers: {
'User-Agent': 'PosimaiTechEvents/1.0 (https://posimai-tech-events.vercel.app)'
}
});
if (!response.ok) {
console.error('Connpass API Error', await response.text());
res.status(502).json({ error: 'Failed to fetch events from Connpass' });
return;
}
const data = await response.json();
// Map to Posimai Events structure
const events = (data.events || []).map(ev => {
const startStr = ev.started_at || '';
const endStr = ev.ended_at || '';
const startDate = startStr.slice(0, 10);
const startTime = startStr.slice(11, 16);
const endDate = endStr.slice(0, 10);
const endTime = endStr.slice(11, 16);
let location = ev.place || 'オンライン';
if (!ev.address && !ev.place) {
if (ev.event_url && ev.event_type === 'online') location = 'オンライン開催';
else location = '会場未定 / オンライン';
}
return {
id: String(ev.event_id),
title: ev.title,
startDate: startDate,
startTime: startTime,
endDate: endDate,
endTime: endTime,
location: location,
address: ev.address || '',
description: ev.catch || '詳細説明はリンク先をご覧ください。',
category: ev.series ? ev.series.title : 'IT/テック',
url: ev.event_url,
source: 'Connpass',
// To be enhanced: derive tags based on title/description
interestTags: [],
audienceTags: []
};
});
return res.status(200).json({
events: events,
updatedAt: new Date().toISOString(),
source: 'connpass'
});
} catch (e) {
console.error('API /events error:', e);
return res.status(500).json({ error: 'Internal Server Error' });
}
}