{"id":48441867,"url":"https://github.com/cjj/business-card-extractor","last_synced_at":"2026-04-06T16:00:59.788Z","repository":{"id":322690541,"uuid":"1063606602","full_name":"cjj/business-card-extractor","owner":"cjj","description":"Extract business card data into a template for import to Google Workspace Contacts ","archived":false,"fork":false,"pushed_at":"2026-03-24T04:10:14.000Z","size":598,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-25T05:16:09.481Z","etag":null,"topics":["contacts","google","linkedin","openai-api"],"latest_commit_sha":null,"homepage":"https://agilito.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cjj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-24T21:32:20.000Z","updated_at":"2026-03-24T04:10:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cjj/business-card-extractor","commit_stats":null,"previous_names":["cjj/business-card-extractor"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cjj/business-card-extractor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjj%2Fbusiness-card-extractor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjj%2Fbusiness-card-extractor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjj%2Fbusiness-card-extractor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjj%2Fbusiness-card-extractor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cjj","download_url":"https://codeload.github.com/cjj/business-card-extractor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjj%2Fbusiness-card-extractor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31479006,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T14:34:32.243Z","status":"ssl_error","status_checked_at":"2026-04-06T14:34:31.723Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["contacts","google","linkedin","openai-api"],"created_at":"2026-04-06T16:00:43.409Z","updated_at":"2026-04-06T16:00:59.777Z","avatar_url":"https://github.com/cjj.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Business Card Contact Extractor\n\nA **Node.js / Next.js** web application that lets you upload photos of business cards, automatically extracts contact information, searches for a LinkedIn profile, and exports the results to a CSV file ready for import into Google Contacts.\n\n## Features\n\n- **Image upload** (multiple JPG/PNG files at once)\n- **Data extraction** using either:\n  - **AI Vision** (OpenAI GPT‑4o) for high‑accuracy extraction, **or**\n  - **OCR** (Tesseract.js) with advanced regex parsing\n- **LinkedIn profile search** – generates a LinkedIn search URL for each contact\n- **CSV export** compatible with Google Contacts import template\n- Fully responsive UI built with Tailwind CSS and Radix UI components\n\n## Prerequisites\n\n**For Local Development:**\n- Node.js (v18 or later) and npm (or yarn/pnpm) installed\n\n**For Docker:**\n- Docker and Docker Compose installed\n\n**For AI Vision Mode:**\n- An OpenAI API key (required for AI Vision mode). You can obtain one at https://platform.openai.com/api-keys.\n\n## Setup\n\n1. **Clone the repository**\n   ```bash\n   git clone https://github.com/cjj/business-card-extractor\n   cd business-card-extractor\n   ```\n2. **Install dependencies**\n   ```bash\n   npm install   # or `yarn` / `pnpm install`\n   ```\n3. **Configure environment variables**\n   Copy the example file and configure your API key:\n   ```bash\n   cp .env.example .env.local\n   ```\n   Then edit `.env.local` and add your OpenAI API key:\n   ```env\n   OPENAI_API_KEY=your-openai-api-key   # required for AI Vision mode\n   ```\n   The API key is optional if you plan to use OCR-only mode.\n\n## Running the Application Locally\n\nStart the development server:\n```bash\nnpm run dev   # or `yarn dev` / `pnpm dev`\n```\nThe app will be available at **http://localhost:3000**.\n\n### Using the UI\n1. Click **Select Images** to choose one or more business‑card photos.\n2. Toggle the **AI Vision** switch to choose between AI (recommended) or OCR extraction.\n3. Press **Extract** – the app will process each image, fetch a LinkedIn search link, and display the results in a table.\n4. Click **Download CSV** to export all contacts. You should be able to use this file directly to import into Google Contacts. \n\n## API Endpoints\n\n- `POST /api/extract` – extracts contact data using OpenAI GPT‑4o (requires `OPENAI_API_KEY`).\n- `POST /api/extract-ocr` – extracts contact data using Tesseract OCR with custom parsing.\n- `POST /api/linkedin-search` – returns a LinkedIn search URL for a given name and company.\n\n## Running with Docker\n\nAlternatively, you can run the application using Docker and Docker Compose. The Docker setup uses an optimized production build with Next.js standalone mode for minimal image size (~300MB) and fast startup.\n\n### Prerequisites\n- Docker and Docker Compose installed\n- `.env.local` file configured (see Setup section above)\n\n### Quick Start\n\n1.  **Build and run the container:**\n    ```bash\n    docker-compose up -d --build\n    ```\n\n2.  **Access the application:**\n    - Open your browser to **http://localhost:3000**\n\n### Managing the Container\n\n**View logs:**\n```bash\ndocker logs business-card-extractor-app-1\n```\n\n**Stop the application:**\n```bash\ndocker-compose down\n```\n\n**Rebuild after code changes:**\n```bash\ndocker-compose up -d --build\n```\n\n### Notes\n- The container uses a non-root user for enhanced security\n- Environment variables are loaded from `.env.local` at runtime\n- OCR mode works without an API key; AI Vision mode requires `OPENAI_API_KEY`\n- The production build uses multi-stage Docker builds for optimization\n\n## Building for Production\n\n```bash\nnpm run build   # creates an optimized production build\nnpm start       # runs the production server\n```\n\n## Development \u0026 CI Notes\n\n### CI/Build Pipeline\nThe GitHub Actions CI workflow runs the following checks in order:\n1. **Lint** - `npm run lint`\n2. **TypeScript check** - `npx tsc --noEmit`\n3. **Tests** - `npm test`\n4. **Build** - `npm run build`\n\n**Important:** All commands must pass for CI to succeed. If you add new scripts or modify the build process, ensure they're compatible with the CI workflow in `.github/workflows/ci.yml`.\n\n### Google Contacts CSV Format\nThe application exports contact data in Google Contacts CSV import format with these fields:\n- **Name fields:** `Name`, `Given Name`, `Family Name`\n- **Contact fields:** `E-mail 1 - Type/Value`, `Phone 1 - Type/Value`\n- **Address fields:** `Address 1 - Type/Formatted/Street/City/Region/Postal Code/Country`\n- **Organization fields:** `Organization 1 - Name/Title`\n- **Website fields:** `Website 1 - Type/Value`\n\n**Note:** LinkedIn Profile is displayed in the UI but intentionally excluded from CSV export.\n\n### Recent Changes\n- **2026-03-23:** Security patches: Next.js 15.5.9 → 15.5.14 (HTTP smuggling, DoS fixes), plus transitive dependency updates for `tar`, `flatted`, `minimatch`, `ajv`, `lodash`, and `qs`\n- **2025-12-13:** Updated to Google Contacts official CSV format (changed from `First Name`/`Last Name` to `Given Name`/`Family Name`)\n- **2025-12-13:** Security patches: Next.js 15.5.3 → 15.5.9, Node.js 20 → 22 (Dockerfile)\n- **2025-12-13:** Added placeholder test script to satisfy CI requirements\n\n## License\n\nThis project is open‑source and available under the MIT License.\n\n---\n\n*Built with Next.js 15.5.14, Tailwind CSS, Radix UI, OpenAI, and Tesseract.js.*","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjj%2Fbusiness-card-extractor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcjj%2Fbusiness-card-extractor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjj%2Fbusiness-card-extractor/lists"}