개요
이 글에서는 https://bible.helloao.org의 무료 성경 API에서 번역 목록과 각 번역의 책 정보를 수집하여 Supabase(PostgreSQL)에 자동 저장하는 방법을 정리합니다. Node.js 기반으로 구성하며 .env
, 스케줄링, 중복 처리까지 실용적으로 다룹니다.
1단계: Supabase 테이블 구조 만들기
📌 bible_translations 테이블
create table bible_translations (
id text primary key,
name text,
website text,
license_url text,
license_notes text,
short_name text,
english_name text,
language text,
text_direction text,
sha256 text,
available_formats jsonb,
list_of_books_api_link text,
number_of_books integer,
total_number_of_chapters integer,
total_number_of_verses integer,
language_name text,
language_english_name text
);
📌 bible_books 테이블
create table bible_books (
id serial primary key,
translation_id text references bible_translations(id),
book_id text,
name text,
common_name text,
title text,
book_order integer,
number_of_chapters integer,
total_number_of_verses integer,
sha256 text,
first_chapter_api_link text,
last_chapter_api_link text
);
📌 중복 방지 제약조건 추가
ALTER TABLE bible_books
ADD CONSTRAINT uniq_translation_book UNIQUE (translation_id, book_id);
2단계: Node.js 환경 설정
npm init -y
npm install axios @supabase/supabase-js dotenv node-cron
.env
파일 생성:
SUPABASE_URL=https://<your-project-id>.supabase.co
SUPABASE_SERVICE_KEY=your-service-role-key
3단계: 번역 목록 가져오기 (syncTranslations.js)
require('dotenv').config();
const axios = require('axios');
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_SERVICE_KEY
);
async function syncBibleTranslations() {
const response = await axios.get('https://bible.helloao.org/api/available_translations.json');
const translations = response.data.translations;
for (const item of translations) {
await supabase
.from('bible_translations')
.upsert({
id: item.id,
name: item.name,
website: item.website,
license_url: item.licenseUrl,
license_notes: item.licenseNotes,
short_name: item.shortName,
english_name: item.englishName,
language: item.language,
text_direction: item.textDirection,
sha256: item.sha256,
available_formats: item.availableFormats,
list_of_books_api_link: item.listOfBooksApiLink,
number_of_books: item.numberOfBooks,
total_number_of_chapters: item.totalNumberOfChapters,
total_number_of_verses: item.totalNumberOfVerses,
language_name: item.languageName,
language_english_name: item.languageEnglishName,
}, { onConflict: 'id' });
}
console.log('📖 번역 정보 동기화 완료');
}
syncBibleTranslations();
4단계: 각 번역의 책 정보 저장 (syncBooks.js)
require('dotenv').config();
const axios = require('axios');
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_SERVICE_KEY
);
async function syncBooks() {
const { data: translations } = await supabase
.from('bible_translations')
.select('id');
for (const translation of translations) {
const url = `https://bible.helloao.org/api/${translation.id}/books.json`;
try {
const res = await axios.get(url);
const books = res.data.books;
for (const book of books) {
await supabase
.from('bible_books')
.upsert({
translation_id: translation.id,
book_id: book.id,
name: book.name,
common_name: book.commonName,
title: book.title,
book_order: book.order,
number_of_chapters: book.numberOfChapters,
total_number_of_verses: book.totalNumberOfVerses,
sha256: book.sha256,
first_chapter_api_link: book.firstChapterApiLink,
last_chapter_api_link: book.lastChapterApiLink
}, { onConflict: 'translation_id,book_id' });
}
console.log(`✅ ${translation.id} 책 정보 동기화 완료`);
} catch (err) {
console.error(`❌ ${translation.id} 실패: ${err.message}`);
}
}
}
syncBooks();
5단계: 자동 스케줄링 설정 (선택)
const cron = require('node-cron');
// 매일 새벽 3시에 동기화
cron.schedule('0 3 * * *', () => {
console.log('⏰ 스케줄 실행 시작');
syncBibleTranslations();
syncBooks();
});
node syncBooks.js
로도 수동 실행 가능
마무리
- Supabase와 Node.js를 활용하면 별도 서버 없이도 성경 데이터를 안전하게 저장하고 관리할 수 있습니다.
- 이후에는 각 책의 장(
chapter
)과 절(verse
) 정보까지 확장할 수 있습니다.