Skip to content

Repository files navigation

WhatsApp Profile Sync

CI Node.js License

WhatsApp Profile Sync is an independent integration product that turns structured WhatsApp messages—and attached photos or PDFs—into create-or-update profile operations on your backend.

It was originally built for SafeWork Global worker onboarding and is now maintained as a standalone, config-driven plugin for agencies, integrators, and product teams. No AI, OCR, or RPA.

Product WhatsApp → profile upsert connector
Origin SafeWork Global (workforce onboarding POC)
Status POC validated · production enhancements planned
Model Authorized deployment only (see licensing)

Contents: Overview · Who it's for · How it works · Setup · Access control · API contract · Commands · Troubleshooting · SafeWork preset · License


Overview

Staff and field teams already share candidate or customer details on WhatsApp. This product captures that flow in a controlled, repeatable way:

  1. A trusted sender posts a fixed template (PROFILE, WORKER, LEAD, …).
  2. The plugin parses fields deterministically and upserts by phone.
  3. Optional media slots attach photos, certificates, or PDFs.
  4. Data lands in your API—or a local store during POC.

Product-specific rules live in YAML config, not in forked code. SafeWork is one preset; CRM leads, clinic intake, or membership onboarding are others.


Who it's for

Audience Use case
Consulting / integration agencies White-label WhatsApp intake for client CRMs, HR, or marketplaces
Workforce & recruitment platforms Worker or candidate profiles from WhatsApp (SafeWork-style)
Operations teams Centre staff → server profiles without manual data entry
Product engineers Embed webhook + sync logic via npm package

Not a public self-serve SaaS today. Deployment, resale, and multi-client hosting require explicit authorization from the maintainer.


How it works

WhatsApp (allowlisted sender)
        │
        ▼
Meta Cloud API webhook
        │
        ▼
WhatsApp Profile Sync  ──► parse template + download media
        │
        ├──► Local store (POC / demo)
        └──► Your HTTP API (production)
Layer Responsibility
Ingress Meta WhatsApp Cloud API
Parsing Configured TEMPLATE + key: value lines
Identity Match on phone (configurable)
Media Caption-based slots (photo, certificate, …)
Upsert Find by phone → update; else create
Governance Sender allowlist + webhook signature verification

Access control

Access is enforced at two levels:

1. Product & deployment (commercial)

Use of this software in production, client projects, agency resale, or hosted multi-tenant offerings requires written approval from the maintainer. Cloning or deploying without authorization is not permitted.

→ See Licensing & authorized use.

2. Runtime (technical)

Only WhatsApp numbers in whatsapp.allowlist may create or update profiles:

whatsapp:
  allowlist:
    - "919549230227"   # E.164 / digits; empty = allow all (dev only)

Combine with Meta recipient allowlists in development mode. Production should always use a tight allowlist.


Setup guide

Prerequisites

  • Node.js 20+
  • Meta WhatsApp Cloud API app (developers.facebook.com)
  • HTTPS webhook URL (tunnel for local dev; reverse proxy in production)

1. Install

git clone https://github.com/Kailash-dev/whatsapp-profile-sync.git
cd whatsapp-profile-sync
npm install

2. Configure

cp config/default.example.yaml config/local.yaml
Preset Path Typical use
Generic config/default.example.yaml Any profile entity
CRM leads config/presets/crm-lead.example.yaml Sales / lead intake
SafeWork workers config/presets/safework.example.yaml Workforce onboarding

Edit config/local.yaml (gitignored). Secrets can also live in .env (see .env.example).

Minimum WhatsApp block:

whatsapp:
  verify_token: <you-invent-this>
  app_secret: <meta-app-secret>
  access_token: <meta-access-token>
  phone_number_id: "<meta-phone-number-id>"
  allowlist:
    - "91XXXXXXXXXX"

Template example:

entity: customer
templates:
  CUSTOMER:
    required: [name, phone]
    optional: [email, city]
    map:
      name: full_name
      phone: mobile
      email: email
      city: city

Staff send:

CUSTOMER
name: Priya Sharma
phone: 9876543210
email: priya@example.com
city: Pune

3. Run

CONFIG_PATH=./config/local.yaml npm run dev
  • Health: GET http://localhost:8787/health
  • Webhook: GET|POST http://localhost:8787/webhooks/whatsapp

4. Connect Meta

  1. Create app → WhatsApp → Integrate with API.
  2. Step 1. Try it out — token, phone number ID, add test recipients.
  3. Tunnel locally: cloudflared tunnel --url http://localhost:8787
  4. Webhook → Callback URL: https://<host>/webhooks/whatsapp, verify token = config value.
  5. Subscribe webhook field messages.
  6. Subscribe app to WABA: POST /v21.0/{WABA_ID}/subscribed_apps

5. Verify

Message the business/test number from the WhatsApp app (not Meta's "Send message" demo):

CUSTOMER
name: Test User
phone: 9000000001

Offline:

npm run parse:demo
npm run test:e2e

Backend API contract

When api.enabled: true:

Action Method Path Notes
Find GET find_path ({phone}) Return object with id, or empty / 404
Create POST create_path Body: mapped fields + phone + source: "whatsapp"
Update PATCH update_path ({id}) Body: mapped fields
Upload POST multipart upload_path ({id}) slot, field, file

Default auth: Authorization: Bearer <token> (configurable).


Development commands

Command Description
npm run dev Webhook server with hot reload
npm start Run compiled server
npm run build Compile src/dist/
npm run typecheck Typecheck src/ + scripts/
npm run parse:demo Offline parse + storage demo
npm run test:e2e Offline webhook e2e suite

Embed as a library

import { loadConfig, ProfileSyncService, startServer } from "whatsapp-profile-sync";

const config = loadConfig("./config/local.yaml");
startServer(config);

// or embed:
const sync = new ProfileSyncService(config);
await sync.handleMessage(incomingMessage);

Authorized npm distribution and commercial embedding are subject to the same licensing terms.


SafeWork Global (reference deployment)

SafeWork Global was the first production intent for this product: staff and centres send worker details on WhatsApp; the platform upserts worker profiles and documents.

cp config/presets/safework.example.yaml config/local.yaml
CONFIG_PATH=./config/local.yaml npm run dev
Item Value
Entity worker
Template WORKER
Media slots passport_photo, trade_certificate, resume, …

SafeWork remains a reference customer and preset, not the owner of the product. The core plugin is entity-agnostic.


Message & media reference

Text

<TEMPLATE>
field: value

Media caption — must match a configured slot:

certificate

or document:certificate. Full template text can appear in a media caption to create + attach in one message.


Troubleshooting

Issue Fix
Webhook verify fails URL must include /webhooks/whatsapp; token must match config
Inbound messages ignored Subscribe messages; subscribe app to WABA; keep tunnel + server running
#131030 recipient error Add number in Meta test recipients + allowlist
invalid_signature Meta sends signed payloads when app_secret is set
Token expired Refresh from Meta API setup or use System User token
Unauthorized sender Number not in whatsapp.allowlist

Security checklist

  • Tight whatsapp.allowlist in production
  • Secrets in env, not git (config/local.yaml is gitignored)
  • HTTPS webhook only
  • HMAC signature verification enabled (real app_secret)
  • Authorized deployment agreement for client / agency use

Project structure

config/
  default.example.yaml
  presets/              # safework, crm-lead, …
src/                    # product-agnostic core
scripts/                # parse-demo, webhook-e2e

Roadmap (post-POC)

Planned enhancements for agency and production use:

  • Managed hosting and stable webhook URLs
  • Multi-tenant config per client
  • Long-lived Meta token / Business verification playbook
  • Admin audit UI and deployment tooling
  • Commercial support tiers for integrators

POC scope is complete; contact the maintainer for production rollout.


Licensing & authorized use

Copyright © 2026 Kailash-dev. All rights reserved.

This repository documents a validated proof of concept. The software is not open for unauthorized commercial use, redistribution, resale, or client deployment without written permission from the maintainer.

Permitted Requires authorization
Reviewing this repo with maintainer approval Production deployment for a client
POC / evaluation agreed in writing Agency resale or white-label offering
SafeWork Global reference deployment Multi-tenant hosted service
Contributions by invitation Publishing forks as competing products

To request a license (agency, integrator, or enterprise deployment):

  • Open an issue on GitHub describing your use case, or
  • Contact via SafeWork Global for workforce-related deployments.

Unauthorized use may violate applicable copyright and contract law.

Technical details: LICENSE


Contributing

Contributions are welcome by invitation or after maintainer approval. See CONTRIBUTING.md.

About

Generic WhatsApp → profile sync plugin. Config-driven templates & media for workers, leads, or any entity — no AI.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages