Node.js와 Supabase로 무료 성경 API 데이터 수집 자동화하기

개요

이 글에서는 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) 정보까지 확장할 수 있습니다.

관련 글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다