1. INDEX
- 배경: 소모임 채널을 운영하며
- 활용 기술
- Notion Database
- Typescript - 개발 및 Test 과정
1) Notion 관련 세팅하기 (DB 생성, API Key 발급)
2) Notion DB를 긁어오는 Script 작성하기 - 향후 발전 시키고 싶은 점 & 마무리
2. 배경: 소모임채널, #4_작업공간찾았또를 운영하다.
평소에 조용한 카페, 도서관, 그리고 맛있는 디저트를 찾아다니는 것을 좋아한다.
나는 중학생때 울산, 부산에서 주로 살았는데, 조용하고 한적한 카페들이 많아서 지역에 숨은 곳곳을 찾아다녔다.
어른이 되고 서울로 올라와 생활하면서 조용한 카페들을 찾기 쉽지 않다는 걸 느꼈고,
좋은 카페 정보를 찾아 공유하거나 받고 싶다는 생각이 컸다.
특히, 카페나 공간의 후기를 중요하게 여기는 편이라,
믿을 수 있는 리뷰를 기반으로 새로운 곳을 탐방하는 것이 즐거웠다.
때마침, 글또 커뮤니티에 참여하게 되면서 소모임 채널을 생성할 수 있는 기회가 생겼는데,
누구나 자유롭게 공간 정보를 공유할 수 있는 채널을 개설하였다.
이 채널의 이름은 '작업공간찾았또'라는 이름으로 현재 약 200명의 글또 멤버가 참여하고 있으며,
다양한 카페 정보가 올라오고 있다.


하지만 데이터를 보관하고 정리하는 과정에서 불편함이 있었다.
어디에 정보를 보관할까 고민하던 도중 채널에 계신 분이 Slack 캔버스를 제안 해주셨지만,
지도 URL, 카페 이름 등 하나 하나 추가해야하는게 불편하게 느껴졌다.
게다가 중간에 사라지거나 휴점을 한 카페들도 있었는데, 업데이트가 늦게 이뤄져 아쉬운 부분도 있었다.
그래서 데이터를 하나의 파일로 정리하고, Github에서 관리하는 것이 더 효율적이라는 생각이 들었다.
Github를 활용하면 업데이트 내역이 기록되어 정보의 신뢰도를 높일 수 있고,
지역별로 분류해 관리하는 것도 용이해질 것이라는 생각이 들었다.
3. 활용 기술
3.1. Notion Database
나는 이번에 조금 특별한 기술을 사용했다.
바로 Notion Database인데, 이 Notion DB의 장점은 다양한 Property를 활용하기에 매우 적합하다는 것이다.
데이터를 구조화하고 관리하기 편리할 뿐만 아니라, UI도 직관적이라 활용성이 높다.
물론 직접 백엔드를 구축하는 것도 좋은 경험이겠지만, 이번 프로젝트는 빠르게 개발하여 도입하는 것이 목표였다.
마침 Notion API 사용 경험이 있어 러닝 커브가 낮았고, 손쉽게 원하는 기능을 구현할 수 있었다.
3.2. Typescript
개발 언어로는 TypeScript를 선택했다.
현재 가장 익숙하게 다룰 수 있는 언어이기 때문에 빠르게 개발하고 유지보수하기에 적합했다.
4. 개발 및 Test 과정
4.1. Notion DB 생성하기
먼저, Notion에서 데이터를 저장할 Database를 생성했다.
Database 생성 방법은 Notion 공식 문서에 잘 나와있으니, 참고 하면 될것 같다.
Property는 아래와 같이 추가해주었다.
- Space Name (공간 이름)
- Created Date (생성 날짜)
- Last Modified Date (최근 수정 날짜)
- Location URL (위치 링크)
- Source URL (출처 링크)
그리고 Slack 캔버스에 있는 데이터 일부를 추가했다.


4.2. NotionAPI 세팅하기
Property에 있는 Data를 코드에서 활용하기 위해 API 세팅이 필요하다.
API Key를 발급하기 위해 Notion Integration 사이트에 접속해야한다.
새 API 통합 클릭 > "API 통합 이름 추가"에 API명 입력 > 저장


원하는 이름으로 설정해도 좋지만,
어떤 프로젝트와 연관된 API인지 알아볼 수 있도록 적어주는 것이 좋다.
나같은 경우, geultto-space로 설정해주었다.
각 상세 옵션은 아래 이미지를 참고하면 된다.

마지막으로 Database로 돌아가 API와 연결해주었다.
우측 상단 ••• 버튼 클릭 > Connections 클릭 > 설정한 API 이름 검색 후 클릭

이렇게 하면 Notion과 관련된 준비는 끝났다.
Typescript Project 세팅은 자료가 방대해서 자세한 설명을 생략하고,
어떤 라이브러리를 설치했는지 아래에 기록해두도록 하겠다.
<shell />npm i -D typescript @types/node
tsconfig.json 파일도 생성하여 컴파일러 옵션을 지정해주었다.
<javascript />
{
"compilerOptions": {
"rootDir": "./src",
"module": "CommonJS",
"target": "ES6"
}
}
그리고 .gitignore 파일을 생성해 API Key값과 같은 환경변수 파일(.env)이 올라가지 않도록 설정했다.
4.3. Notion Database 데이터 가져오기
4.3.1. 환경 변수 세팅하기
API Key, Notion Database ID를 찾아서 .env 파일속에 넣어준다.
<javascript />
NOTION_API_KEY={발급받은 Notion API KEY}
NOTION_DATABASE_ID={Notion DB ID}
// https://www.notion.so/{notion-username}/{여기에 해당하는 부분입니다}?v={notion-unique-vlaue}&pvs=4
4.3.2. 필요한 라이브러리 설치하기
<typescript />
npm i @notionhq/client dotenv
4.3.3. package.json에 scripts에 start 명령어 실행 동작 값 넣어주기
<javascript />
"scripts": {
"start": "npx ts-node src/main.ts"
},
4.3.4. 환경 변수 값 가져오기
config.ts를 생성해 notion을 연결하고, DB ID를 가져온다.
<typescript />
import { Client } from "@notionhq/client";
import * as dotenv from "dotenv"; // npm i dotenv
dotenv.config();
export const notion = new Client({ auth: process.env.NOTION_API_KEY });
export const databaseId = process.env.NOTION_DATABASE_ID;
if (!databaseId) {
throw new Error("[ERROR] NOTION_DATABASE_ID 환경 변수가 존재하지 않습니다.");
}
4.3.5. Notion Database의 Property와 행 정보 불러오기
@notionhq/client 라이브러리를 사용해 데이터를 받아오고,
notion.databases.query를 통해 모든 Property 값을 가져왔다.
<typescript />
import { notion, databaseId } from "../config/config";
import { PageObjectResponse } from "@notionhq/client/build/src/api-endpoints";
// Notion DB Property 데이터 가져오기
export async function fetchNotionPages(): Promise<PageObjectResponse[]> {
const response = await notion.databases.query({ database_id: databaseId! });
return response.results.filter(
(result): result is PageObjectResponse => "properties" in result
);
}
그리고 가져온 값들을 가공해주었는데, 이 작업은 forEach문과 switch 문법을 활용했다.
value.type을 통해 어떤 형태의 Property냐에 따라서 조금씩 다르게 처리를 해주었다.
<typescript />
switch (value.type) {
case "title":
output = value.title.map((item) => item.plain_text).join(" ");
break;
case "date":
output = value.date?.start || "";
break;
다음으로, 받아온 데이터 값들을 가독성이 좋은 Markdown 형태로 출력해도 예뻐보이도록 내용을 구성해주었다.
그리고 Property 명이 그대로 출력되는게 좋아보이지 않아서 내 나름대로 한글 이름을 붙여주었다.
<typescript />
const spaceName = spaceData["Space Name"] || "알 수 없는 공간";
spaceTextContent += `## ${spaceName}\n`;
const desiredOrder: { [key: string]: string } = {
"Created Date": "생성 날짜",
"Last Modified Date": "최근 수정 날짜",
};
if (spaceData["Location URL"]) {
spaceTextContent += `- [📍 위치](${spaceData["Location URL"]})\n`;
}
if (spaceData["Source URL"]) {
spaceTextContent += `- [🔗 출처](${spaceData["Source URL"]})\n`;
}
마지막으로 내용이 담긴 Markdown 파일을 생성해주었다.
<typescript />
import * as fs from "fs";
import * as path from "path";
export function saveTextFiles(
folderPath: string,
fileName: string,
content: string
) {
const filePath = path.join(folderPath, fileName);
fs.writeFileSync(filePath, content, "utf8");
console.log(`파일 생성 완료: ${filePath}`);
}
이 상태에서 npm run start 명령어를 통해 실행 시켜주면,
지역 폴더 아래 카페 정보들이 모두 담긴 Markdown 파일이 생성된다!

이제 이렇게 생성된 카페 정보를 Github PR을 통해 업로드 해주면 끝이다.


5. 번외) 비 개발 직군이지만, 카페 정보를 공유해주고픈 여러분을 위해...
README.md 파일, Github Commit 모두 개발 직군에게는
익숙하지만 PM이나 디자이너 등등 다른 직군은 익숙하지 않은 경우가 대부분이다.
그래서 Tally Form을 준비했다!
작업공간찾았또
Made with Tally, the simplest way to create forms.
tally.so
구글 폼과 비슷한 친구인데,
한가지 유용한 점이 있다면 Notion과 연결하여 쓸 수 있다는 점이다.
여기에 정보를 입력해주면 자동으로 정보가 Notion DB에 기록 된다.
(비 개발 직군 분들도 아는 카페 정보가 있다면 마구 마구 공유해주세요!)
6. 발전 시키고 싶은 점 & 마무리
이렇게 Notion Database의 데이터들을 가져와서 깃허브에 업로드 해보았다.
아직 하드코딩 된 부분도 있고, 자동화가 덜 된 부분도 있지만 계속 발전 시켜보고 싶다.
Tally Form을 활용해 Notion DB에 자동으로 기록되고,
Github Action을 통해서 주기적으로 스크립트를 실행해서 관리할 수 있지 않을까 싶은데
아직 Github Action에 대한 이해도가 높지 않아서 공부를 조금 한 뒤에 적용을 시켜보려고 한다.
그리고 나중에 조금 더 시간이 많아지면
Next.js를 활용해서 하나의 페이지로 만들어보고 싶다는 생각도 있다!
(디자인 감각은 꽝이지만)
마지막으로 이 글을 빌려 소모임 채널을 열고나서 운영 될 수 있도록
정보를 마구 마구 공유해주신 분들께 정말 감사하다는 말씀을 드리고 싶다!
조만간, 채널에 있는 카페 리스트 중 한 곳을 골라 커피챗 모임을 한 번 진행할까 하는데
소소하게 이야기를 나눌 수 있는 자리를 마련해보고 싶다 :D
(곧 채널에 글을 올려보도록 하겠습니다..ㅎㅎ)
모든 카페 정보는 여기서 확인할 수 있습니다!
GitHub - azure-553/Geultto-SpaceFinder: 작업공간찾았또 채널 속 카페 데이터 파일 모음집
작업공간찾았또 채널 속 카페 데이터 파일 모음집. Contribute to azure-553/Geultto-SpaceFinder development by creating an account on GitHub.
github.com
'JavaScript' 카테고리의 다른 글
[Typescript] 고급타입 - 타입 가드와 차별 타입 (0) | 2024.02.01 |
---|---|
CSV 파일을 JSON으로 만들어서 활용하기 (0) | 2023.11.01 |
[JS] 엄격 모드(Strict Mode) (2) | 2023.08.30 |
[Node.js] node-cron을 사용해서 일정 시간 마다 특정 작업해주기 (0) | 2023.06.29 |
lodash debounce를 활용하여 성능 향상시키기 (0) | 2023.06.03 |