# πŸ“š Unofficial Goodreads Book Search API [![npm version](https://badge.fury.io/js/szbk-goodreads-search-book.svg)](https://badge.fury.io/js/szbk-goodreads-search-book) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Node.js Version](https://img.shields.io/badge/node-%3E%3D14.0.0-brightgreen)](https://nodejs.org/) [![Build Status](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com/szbk/goodreads-book-search) πŸ” **A powerful Node.js library that enables you to retrieve comprehensive book information from Goodreads using only an ISBN number - no API key required!** This library intelligently analyzes Goodreads' HTML structure and returns detailed book information in a clean JSON format. Built with modern asynchronous JavaScript patterns and comprehensive error handling. --- ## ✨ Key Features - πŸ”‘ **No API Key Required** - Search Goodreads without authentication - πŸ“– **Comprehensive Data** - Extract detailed book information including: - πŸ“• Title & cover image - ✍️ Author details with profile links - 🌍 Translator information - πŸ“ Full book descriptions - πŸ“„ Page count - ⭐ Goodreads ratings - 🏷️ Genre classifications - πŸ“… Publication dates - πŸš€ **Modern JavaScript** - Promise-based asynchronous operations - πŸ›‘οΈ **Error Resilient** - Comprehensive error handling and validation - ⚑ **Performance Optimized** - Configurable request delays and timeouts - πŸ§ͺ **Well Tested** - Complete test suite with Mocha and Chai - πŸ“Š **CI/CD Ready** - Jenkins integration with automated testing - πŸ”§ **Easy Configuration** - Simple, intuitive API --- ## 🎯 Prerequisites - **Node.js** v14 or higher - **NPM** (usually comes with Node.js) - **Internet connection** (for Goodreads access) - **Basic JavaScript knowledge** (async/await patterns) --- ## πŸ“¦ Installation ```bash # Install via npm npm install szbk-goodreads-search-book # Or using yarn yarn add szbk-goodreads-search-book ``` --- ## πŸš€ Quick Start ### Basic Usage ```javascript const GoodreadsBookSearch = require("szbk-goodreads-search-book"); async function searchBook() { try { const BookSearch = new GoodreadsBookSearch(); const bookDetails = await BookSearch.getBookDetails("9944824453"); console.log("πŸ“š Book Found:", bookDetails); } catch (error) { console.error("❌ Error:", error.message); } } searchBook(); ``` ### Example Output ```json { "title": "DΓΆvmeli Adam", "thumbImage": "https://images.gr-assets.com/books/1348616986m/8631735.jpg", "authorName": { "author": { "name": "Peter V. Brett", "profileLink": "/author/show/306789.Peter_V_Brett" }, "translators": ["Γ‡evirmen AdΔ± 1", "Γ‡evirmen AdΔ± 2"] }, "description": "Kitap aΓ§Δ±klamasΔ± burada yer alΔ±r. KapsamlΔ± kitap ΓΆzeti...", "page": "640", "isbn": "9944824453", "date": "01 Sept 2008", "rate": "4.3", "genres": ["Fantasy", "Adventure", "Action"] } ``` --- ## πŸ“– Advanced Usage ### Error Handling Best Practices ```javascript const GoodreadsBookSearch = require("szbk-goodreads-search-book"); async function robustBookSearch(isbn) { const BookSearch = new GoodreadsBookSearch(); try { const bookDetails = await BookSearch.getBookDetails(isbn); // Validate the response if (!bookDetails.title) { throw new Error("Book title not found"); } return bookDetails; } catch (error) { // Handle different error types if (error.message.includes("Detay bilgisi bulunamadΔ±")) { console.log("πŸ“­ Book not found for ISBN:", isbn); } else if (error.message.includes("timeout")) { console.log("⏰ Request timeout. Please try again."); } else { console.log("❌ Unexpected error:", error.message); } return null; } } // Usage robustBookSearch("9944824453").then(book => { if (book) { console.log("βœ… Successfully retrieved:", book.title); } }); ``` ### Multiple Book Search ```javascript async function searchMultipleBooks(isbnList) { const BookSearch = new GoodreadsBookSearch(); const results = []; for (const isbn of isbnList) { try { console.log(`πŸ” Searching for ISBN: ${isbn}`); const bookDetails = await BookSearch.getBookDetails(isbn); results.push({ isbn, success: true, data: bookDetails }); } catch (error) { results.push({ isbn, success: false, error: error.message }); } // Add delay between requests to be respectful await new Promise(resolve => setTimeout(resolve, 3000)); } return results; } // Example usage const isbnList = ["9944824453", "863173540X", "9780547928227"]; searchMultipleBooks(isbnList).then(results => { console.log("πŸ“Š Search Results:", results); }); ``` --- ## πŸ—οΈ Architecture & Project Structure ``` szbk-goodreads-search-book/ β”œβ”€β”€ πŸ“ lib/ # Core library files β”‚ β”œβ”€β”€ πŸ“„ index.js # Main GoodreadsBookSearch class β”‚ └── πŸ“„ module.js # Data extraction and parsing logic β”œβ”€β”€ πŸ“ config/ # Configuration files β”‚ └── πŸ“„ index.js # Application configuration β”œβ”€β”€ πŸ“ test/ # Test suite β”‚ └── πŸ“„ index.js # Integration tests β”œβ”€β”€ πŸ“„ index.js # Library entry point β”œβ”€β”€ πŸ“„ package.json # Dependencies and metadata β”œβ”€β”€ πŸ“„ package-lock.json # Locked dependencies β”œβ”€β”€ πŸ“„ Jenkinsfile # CI/CD pipeline configuration β”œβ”€β”€ πŸ“„ mocha-report-config.json # Test reporting configuration └── πŸ“„ README.md # This documentation ``` ### Core Components - **`GoodreadsBookSearch` Class**: Main interface for book searches - **HTML Parser**: Uses Cheerio for robust HTML parsing - **Data Extraction**: Specialized methods for different book metadata - **Error Handling**: Comprehensive error catching and user-friendly messages - **Configuration**: Centralized settings for timeouts, headers, and URLs --- ## βš™οΈ Configuration Options The library includes built-in configuration that you can modify: ```javascript // Default configuration in config/index.js { goodreadsBaseUrl: "https://www.goodreads.com/search?q=", headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..." }, fetchTimeout: 2000 // Delay between requests in milliseconds } ``` --- ## πŸ§ͺ Testing ### Run All Tests ```bash # Install dependencies first npm install # Run the test suite npm test ``` ### Test Coverage The test suite includes: - βœ… ISBN validation - βœ… Title extraction accuracy - βœ… Publication date parsing - βœ… Page count verification - βœ… Error handling scenarios - βœ… Integration testing with live Goodreads data ### Sample Test Output ``` 🧠 Goodreads Book Search Integration Test βœ“ Is the ISBN "9944824453" πŸ”₯ (1500ms) βœ“ Is the book title "DΓΆvmeli Adam" πŸš€ (1200ms) βœ“ Is the book's publication date "1 September 2008" ⏰ (1100ms) βœ“ Is the page count "640" πŸ“‹ (1300ms) 4 passing (5s) ``` --- ## πŸ“š API Reference ### GoodreadsBookSearch Class #### Constructor ```javascript const BookSearch = new GoodreadsBookSearch(); ``` #### Methods ##### `getBookDetails(isbn)` Searches for a book using its ISBN number. **Parameters:** - `isbn` (string): The ISBN number to search for **Returns:** - `Promise`: Book details object **Example:** ```javascript const details = await BookSearch.getBookDetails("9944824453"); ``` ### Response Object Structure ```typescript interface BookDetails { title: string; // Book title thumbImage: string; // Cover image URL authorName: { author?: { name: string; // Author name profileLink: string; // Goodreads profile URL }; translators?: string[]; // Translator names array }; description: string; // Book description page: string; // Page count as string isbn: string; // ISBN number date: string; // Publication date (DD MMM YYYY) rate: string; // Goodreads rating genres: string[]; // Array of genre tags } ``` --- ## πŸ”„ Integration Examples ### Express.js Integration ```javascript const express = require('express'); const GoodreadsBookSearch = require('szbk-goodreads-search-book'); const app = express(); app.use(express.json()); const BookSearch = new GoodreadsBookSearch(); // API endpoint for book search app.get('/api/books/:isbn', async (req, res) => { try { const { isbn } = req.params; if (!isbn || isbn.length < 10) { return res.status(400).json({ error: 'Invalid ISBN provided' }); } const bookDetails = await BookSearch.getBookDetails(isbn); res.json({ success: true, data: bookDetails }); } catch (error) { res.status(404).json({ success: false, error: error.message }); } }); app.listen(3000, () => { console.log('πŸ“š Book search API running on port 3000'); }); ``` ### React Integration ```jsx import React, { useState } from 'react'; const GoodreadsBookSearch = require('szbk-goodreads-search-book'); function BookSearchApp() { const [isbn, setIsbn] = useState(''); const [book, setBook] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const searchBook = async () => { if (!isbn) return; setLoading(true); setError(''); try { const BookSearch = new GoodreadsBookSearch(); const bookDetails = await BookSearch.getBookDetails(isbn); setBook(bookDetails); } catch (err) { setError(err.message); } finally { setLoading(false); } }; return (
setIsbn(e.target.value)} placeholder="Enter ISBN..." /> {error &&

{error}

} {book && (

{book.title}

Author: {book.authorName?.author?.name}

Rating: {book.rate}/5

{book.title}
)}
); } ``` --- ## πŸš€ Deployment & CI/CD ### Jenkins Integration This project includes a pre-configured Jenkinsfile for automated testing: - **Automated Triggers**: Runs every 6 hours - **Smart Dependencies**: Only runs `npm install` when package.json changes - **Test Reporting**: Generates JUnit XML reports - **Slack Integration**: Sends build notifications to Slack channels - **Cleanup**: Automatically removes old test reports ### Jenkins Pipeline Features ```groovy // Key features of the Jenkins pipeline - Cron scheduling (H */6 * * *) - Node.js 22.13.0 support - Conditional dependency installation - Automated test execution - Test result publishing - Slack notifications for success/failure ``` --- ## πŸ”§ Development ### Local Development Setup ```bash # Clone the repository git clone https://github.com/szbk/goodreads-book-search.git cd goodreads-book-search # Install dependencies npm install # Run tests in development mode npm test # Start development (if applicable) npm run dev ``` ### Contributing Guidelines 1. 🍴 Fork the repository 2. 🌿 Create a feature branch (`git checkout -b feature/amazing-feature`) 3. πŸ“ Make your changes with proper testing 4. βœ… Ensure all tests pass 5. πŸ“€ Commit your changes (`git commit -m 'Add amazing feature'`) 6. πŸ“€ Push to the branch (`git push origin feature/amazing-feature`) 7. πŸ”ƒ Open a Pull Request --- ## πŸ› οΈ Dependencies ### Production Dependencies | Package | Version | Purpose | |---------|---------|---------| | `axios` | ^1.6.8 | HTTP client for web requests | | `cheerio` | ^1.0.0-rc.12 | HTML parsing and DOM manipulation | | `@google/generative-ai` | ^0.8.0 | AI integration for enhanced descriptions | | `dotenv` | ^16.4.5 | Environment variable management | ### Development Dependencies | Package | Version | Purpose | |---------|---------|---------| | `mocha` | ^11.0.1 | Test framework | | `chai` | ^5.1.2 | Assertion library | | `mocha-junit-reporter` | ^2.2.1 | JUnit XML test reporting | | `mocha-multi-reporters` | ^1.5.1 | Multiple test reporters support | --- ## ❓ FAQ ### Q: Do I need a Goodreads API key? **A:** No! This library works by analyzing Goodreads' public HTML structure, so no API key is required. ### Q: Is this library officially supported by Goodreads? **A:** No, this is an unofficial library. Use responsibly and in accordance with Goodreads' terms of service. ### Q: What happens if Goodreads changes their HTML structure? **A:** The library may need updates to work with new HTML structures. Report issues if you encounter problems. ### Q: Can I use this in a commercial application? **A:** Yes, under the MIT license. However, ensure compliance with Goodreads' terms of service. ### Q: How can I avoid rate limiting? **A:** The library includes a built-in 2-second delay between requests. You can modify this in the config file if needed. --- ## πŸ”’ Legal & Disclaimer - This is an **unofficial** library and is not affiliated with Goodreads - Use responsibly and in accordance with Goodreads' terms of service - The library is provided "as-is" without warranties - Users are responsible for ensuring compliance with applicable laws and terms --- ## πŸ“„ License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ``` MIT License Copyright (c) 2024 szbk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. ``` --- ## 🀝 Support & Community - **GitHub Issues**: [Report bugs and request features](https://github.com/szbk/goodreads-book-search/issues) - **GitHub Discussions**: [Community discussions and questions](https://github.com/szbk/goodreads-book-search/discussions) - **NPM Page**: [Package information and version history](https://www.npmjs.com/package/szbk-goodreads-search-book) --- ## πŸ“Š Version History ### v1.1.2 (Current) - ✨ Enhanced HTML parsing stability - πŸ›‘οΈ Improved error handling - πŸ“ Better documentation ### v1.1.0 - πŸ”§ Added configurable timeouts - πŸ§ͺ Enhanced test coverage - πŸš€ Performance improvements ### v1.0.0 - πŸŽ‰ Initial release - πŸ“š Core Goodreads search functionality - πŸ” ISBN-based book lookup --- ## πŸ™ Acknowledgments - **Goodreads** - For providing an amazing book database platform - **Cheerio** - Excellent HTML parsing library - **Axios** - Reliable HTTP client - **Mocha & Chai** - Great testing framework - The open-source community for inspiration and tools ---
**⭐ If this project helped you, please give it a star on GitHub!** Made with ❀️ by [szbk](https://github.com/szbk)