88 lines
3.0 KiB
TypeScript
88 lines
3.0 KiB
TypeScript
import { queryOne } from '../../../utils/db'
|
|
import { requireAuth, getCurrentUser } from '../../../utils/session'
|
|
import { getValidGoogleToken } from '../../../utils/google-token'
|
|
|
|
/**
|
|
* 구글 그룹 메시지 목록 조회
|
|
* GET /api/google-group/[id]/messages
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireAuth(event)
|
|
const groupId = parseInt(getRouterParam(event, 'id') || '0')
|
|
const queryParams = getQuery(event)
|
|
|
|
if (!groupId) {
|
|
throw createError({ statusCode: 400, message: '그룹 ID가 필요합니다.' })
|
|
}
|
|
|
|
// 그룹 정보 조회
|
|
const group = await queryOne<any>(`
|
|
SELECT group_email, group_name FROM wr_google_group WHERE group_id = $1
|
|
`, [groupId])
|
|
|
|
if (!group) {
|
|
throw createError({ statusCode: 404, message: '그룹을 찾을 수 없습니다.' })
|
|
}
|
|
|
|
// Google 토큰 확인
|
|
const accessToken = await getValidGoogleToken(user.employeeId)
|
|
if (!accessToken) {
|
|
throw createError({
|
|
statusCode: 401,
|
|
message: 'Google 계정 연결이 필요합니다.'
|
|
})
|
|
}
|
|
|
|
const maxResults = parseInt(queryParams.limit as string) || 20
|
|
const pageToken = queryParams.pageToken as string || ''
|
|
|
|
try {
|
|
// Gmail API로 그룹 메일 검색
|
|
const searchQuery = encodeURIComponent(`from:${group.group_email} OR to:${group.group_email}`)
|
|
let url = `https://gmail.googleapis.com/gmail/v1/users/me/messages?q=${searchQuery}&maxResults=${maxResults}`
|
|
if (pageToken) url += `&pageToken=${pageToken}`
|
|
|
|
const listRes = await fetch(url, {
|
|
headers: { Authorization: `Bearer ${accessToken}` }
|
|
})
|
|
|
|
if (!listRes.ok) {
|
|
throw createError({ statusCode: 500, message: 'Gmail API 오류' })
|
|
}
|
|
|
|
const listData = await listRes.json()
|
|
const messages: any[] = []
|
|
|
|
// 각 메시지 상세 정보 조회 (최대 10개)
|
|
for (const msg of (listData.messages || []).slice(0, 10)) {
|
|
const detailRes = await fetch(
|
|
`https://gmail.googleapis.com/gmail/v1/users/me/messages/${msg.id}?format=metadata&metadataHeaders=Subject&metadataHeaders=From&metadataHeaders=Date`,
|
|
{ headers: { Authorization: `Bearer ${accessToken}` } }
|
|
)
|
|
|
|
if (detailRes.ok) {
|
|
const detail = await detailRes.json()
|
|
const headers = detail.payload?.headers || []
|
|
|
|
messages.push({
|
|
messageId: msg.id,
|
|
threadId: msg.threadId,
|
|
subject: headers.find((h: any) => h.name === 'Subject')?.value || '(제목 없음)',
|
|
from: headers.find((h: any) => h.name === 'From')?.value || '',
|
|
date: headers.find((h: any) => h.name === 'Date')?.value || '',
|
|
snippet: detail.snippet || ''
|
|
})
|
|
}
|
|
}
|
|
|
|
return {
|
|
group: { groupId, groupEmail: group.group_email, groupName: group.group_name },
|
|
messages,
|
|
nextPageToken: listData.nextPageToken || null
|
|
}
|
|
|
|
} catch (e: any) {
|
|
throw createError({ statusCode: 500, message: e.message || '메시지 조회 실패' })
|
|
}
|
|
})
|