노션을 단순 메모장으로만 쓰고 있다면 50%만 활용하는 것입니다. 개발자라면 노션 API와 자동화를 통해 진정한 두 번째 뇌를 만들 수 있습니다.
노션 API 시작하기
Integration 생성
- 노션 개발자 페이지 접속
- "New integration" 클릭
- 이름 설정 및 권한 선택
- API 키 복사
# 환경 변수 설정
export NOTION_API_KEY="secret_..."
export NOTION_DATABASE_ID="..."
기본 연결 테스트
import { Client } from '@notionhq/client';
const notion = new Client({ auth: process.env.NOTION_API_KEY });
// 데이터베이스 조회
const response = await notion.databases.query({
database_id: process.env.NOTION_DATABASE_ID,
});
console.log(response.results);
실전 자동화 1: GitHub 이슈 동기화
GitHub 이슈가 생성되면 자동으로 노션 태스크로 추가합니다.
아키텍처
구현
// github-notion-sync.ts
import { Octokit } from '@octokit/rest';
import { Client } from '@notionhq/client';
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
const notion = new Client({ auth: process.env.NOTION_API_KEY });
async function syncIssueToNotion(issue: GitHubIssue) {
// 이미 존재하는지 확인
const existing = await notion.databases.query({
database_id: TASK_DB_ID,
filter: {
property: 'GitHub Issue',
url: { equals: issue.html_url },
},
});
if (existing.results.length > 0) {
// 업데이트
await notion.pages.update({
page_id: existing.results[0].id,
properties: {
'Status': { select: { name: mapStatus(issue.state) } },
'Title': { title: [{ text: { content: issue.title } }] },
},
});
} else {
// 새로 생성
await notion.pages.create({
parent: { database_id: TASK_DB_ID },
properties: {
'Title': { title: [{ text: { content: issue.title } }] },
'GitHub Issue': { url: issue.html_url },
'Status': { select: { name: 'To Do' } },
'Labels': {
multi_select: issue.labels.map(l => ({ name: l.name })),
},
'Assignee': {
people: issue.assignees.map(a => ({ id: getUserId(a.login) })),
},
},
});
}
}
// Webhook 핸들러 (Express)
app.post('/webhook/github', async (req, res) => {
const { action, issue } = req.body;
if (['opened', 'edited', 'closed'].includes(action)) {
await syncIssueToNotion(issue);
}
res.status(200).send('OK');
});
실전 자동화 2: 일일 리포트 생성
매일 아침 전날 작업 내용을 자동으로 정리합니다.
// daily-report.ts
import { Client } from '@notionhq/client';
import OpenAI from 'openai';
const notion = new Client({ auth: process.env.NOTION_API_KEY });
const openai = new OpenAI();
async function generateDailyReport() {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
// 어제 완료된 태스크 조회
const tasks = await notion.databases.query({
database_id: TASK_DB_ID,
filter: {
and: [
{ property: 'Status', select: { equals: 'Done' } },
{ property: 'Completed', date: { equals: yesterday.toISOString().split('T')[0] } },
],
},
});
// AI로 요약 생성
const taskList = tasks.results.map(t => getTitle(t)).join('\n');
const summary = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'system',
content: '당신은 일일 업무 리포트를 작성하는 어시스턴트입니다.',
},
{
role: 'user',
content: `다음 완료된 작업들을 바탕으로 간결한 일일 리포트를 작성해주세요:\n${taskList}`,
},
],
});
// 노션에 리포트 페이지 생성
await notion.pages.create({
parent: { database_id: REPORTS_DB_ID },
properties: {
'Title': {
title: [{ text: { content: `일일 리포트 - ${yesterday.toLocaleDateString('ko')}` } }],
},
'Date': { date: { start: yesterday.toISOString() } },
},
children: [
{
type: 'heading_2',
heading_2: { rich_text: [{ text: { content: '완료 작업' } }] },
},
{
type: 'bulleted_list_item',
bulleted_list_item: {
rich_text: tasks.results.map(t => ({
text: { content: getTitle(t) + '\n' },
})),
},
},
{
type: 'heading_2',
heading_2: { rich_text: [{ text: { content: 'AI 요약' } }] },
},
{
type: 'paragraph',
paragraph: {
rich_text: [{ text: { content: summary.choices[0].message.content } }],
},
},
],
});
}
// 매일 아침 9시 실행 (cron)
// 0 9 * * * node daily-report.js
실전 자동화 3: 콘텐츠 아이디어 수집
웹에서 발견한 아이디어를 자동으로 노션에 저장합니다.
Chrome Extension
// background.js
chrome.contextMenus.create({
id: 'save-to-notion',
title: 'Save to Notion',
contexts: ['selection', 'link'],
});
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
const content = info.selectionText || info.linkUrl;
await fetch('https://your-api.com/notion/quick-save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
content,
url: tab.url,
title: tab.title,
}),
});
});
서버 API
// quick-save.ts
app.post('/notion/quick-save', async (req, res) => {
const { content, url, title } = req.body;
// AI로 카테고리 분류
const category = await classifyContent(content);
await notion.pages.create({
parent: { database_id: IDEAS_DB_ID },
properties: {
'Title': { title: [{ text: { content: title || content.slice(0, 50) } }] },
'Source URL': { url },
'Category': { select: { name: category } },
'Status': { select: { name: 'Inbox' } },
},
children: [
{
type: 'quote',
quote: { rich_text: [{ text: { content } }] },
},
],
});
res.json({ success: true });
});
실전 자동화 4: 슬랙 알림 연동
노션 데이터베이스 변경 시 슬랙으로 알림을 보냅니다.
// notion-slack-notify.ts
import { WebClient } from '@slack/web-api';
const slack = new WebClient(process.env.SLACK_TOKEN);
async function checkAndNotify() {
// 최근 10분 내 변경된 항목
const recentChanges = await notion.databases.query({
database_id: TASK_DB_ID,
filter: {
property: 'Last edited time',
date: {
after: new Date(Date.now() - 10 * 60 * 1000).toISOString(),
},
},
});
for (const page of recentChanges.results) {
const status = getStatus(page);
const title = getTitle(page);
const assignee = getAssignee(page);
if (status === 'Done') {
await slack.chat.postMessage({
channel: '#dev-updates',
text: `✅ *${title}* 완료됨 (@${assignee})`,
unfurl_links: false,
});
}
if (status === 'Blocked') {
await slack.chat.postMessage({
channel: '#dev-alerts',
text: `🚨 *${title}* 블로커 발생! (@${assignee})`,
unfurl_links: false,
});
}
}
}
// 10분마다 실행
setInterval(checkAndNotify, 10 * 60 * 1000);
노코드 대안: Make (Integromat)
코드 없이 자동화하려면 Make를 활용할 수 있습니다.
가능한 자동화
- Gmail → Notion: 중요 이메일 자동 저장
- Calendar → Notion: 미팅 일정 동기화
- Notion → Slack: 상태 변경 알림
- RSS → Notion: 블로그 구독 자동 저장
설정 예시
- Make 계정 생성
- Notion 모듈 추가 → Integration 연결
- 트리거 설정 (스케줄 또는 웹훅)
- 액션 정의
보안 고려사항
// API 키 보호
// .env 파일 사용, 절대 커밋하지 않음
NOTION_API_KEY=secret_...
// 접근 권한 최소화
// Integration에 필요한 페이지만 공유
// 웹훅 검증
function verifyWebhook(req: Request): boolean {
const signature = req.headers['x-signature'];
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(JSON.stringify(req.body))
.digest('hex');
return signature === expected;
}
마치며
노션 자동화를 통해 얻을 수 있는 것:
- 시간 절약: 반복 작업 자동화
- 정보 중앙화: 여러 소스의 정보를 한 곳에
- 팀 협업 강화: 실시간 동기화 및 알림
- 데이터 기반 의사결정: 자동 리포트 생성
시작은 작게, 하나의 자동화부터 구축해보세요. 점점 확장하다 보면 어느새 노션이 당신의 두 번째 뇌가 되어 있을 것입니다.