omnix-sopiga/docs/quick_start.md
2026-08-07 12:21:42 +07:00

8.0 KiB
Raw Permalink Blame History

Quick Start Guide

Gadai Mulia Collection Broadcast Integration


5-Minute Setup

Prerequisites

  • PostgreSQL database access
  • Sopiga API credentials (token)
  • Go 1.16+ (for worker deployment)

Step 1: Create Database Schema (2 minutes)

# Run SQL schema
psql -U postgres -h localhost -d gadai_mulia < gadai_collection_broadcast_simplified_schema.sql

Verify schema created:

\dt collection_broadcasts.*
-- Should show: sopiga_template_config, template_variable_mapping, sopiga_collar_config, broadcast_staging, etc

Step 2: Setup Sopiga Template (2 minutes)

In Sopiga UI or API:

# Create template
curl -X POST https://omnix.promas.site/api/client/template \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "template_name": "Collection Invoice",
    "channel": "waba",
    "variables": [
      {"name": "Nama", "type": "string"},
      {"name": "TotalTagihan", "type": "integer"},
      {"name": "TanggalJatuhTempo", "type": "date"}
    ]
  }'
# Response: {"data": {"id": 2}}

# Create collar
curl -X POST https://omnix.promas.site/api/client/collar \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "judul_broadcast": "Invoice May 2026",
    "template_id": 2
  }'
# Response: {"data": {"id": 70}}

Note down:

  • template_id = 2
  • collar_id = 70

Step 3: Register in Database (1 minute)

Connect to PostgreSQL:

psql -U postgres -h localhost -d gadai_mulia

Insert template:

INSERT INTO collection_broadcasts.sopiga_template_config 
  (template_name, sopiga_template_id, channel, template_type, description)
VALUES 
  ('Collection Invoice May 2026', 2, 'waba', 'utility', 'Invoice bulanan untuk collection');

Insert variable mappings (URUTAN PENTING!):

INSERT INTO collection_broadcasts.template_variable_mapping 
  (sopiga_template_id, variable_order, sopiga_variable_name, variable_type, db_field_source, is_required, example_value)
VALUES
  (2, 1, 'Nama', 'string', 'nasabah_nama', TRUE, 'Budi Santoso'),
  (2, 2, 'TotalTagihan', 'integer', 'nominal_tagihan', TRUE, '1500000'),
  (2, 3, 'TanggalJatuhTempo', 'date', 'tanggal_tempo', TRUE, '2026-06-30');

Insert collar config:

INSERT INTO collection_broadcasts.sopiga_collar_config 
  (broadcast_name, sopiga_collar_id, sopiga_template_id, status, description)
VALUES 
  ('Collection Invoices May 2026', 70, 2, 'open', 'Broadcast collar untuk collection invoice bulanan Mei 2026');

Verify setup:

SELECT * FROM collection_broadcasts.v_template_variables_ordered 
WHERE sopiga_template_id = 2;
-- Should show 3 rows with order 1, 2, 3

Step 4: Deploy Worker (1 minute)

# Build
go build -o collection_broadcast_worker collection_broadcast_worker_simplified.go

# Run with environment variables
export DB_HOST=localhost
export DB_PORT=5432
export DB_NAME=gadai_mulia
export DB_USER=postgres
export DB_PASSWORD=xxx
export SOPIGA_BASE_URL=https://omnix.promas.site
export SOPIGA_TOKEN=your_api_token

./collection_broadcast_worker
# Output: Collection Broadcast Worker started

🧪 Test It

Insert Test Record

-- Insert to broadcast_staging
INSERT INTO collection_broadcasts.broadcast_staging 
  (sopiga_collar_id, sopiga_template_id, message_payload, status)
VALUES 
  (
    70,
    2,
    '{"nasabah_nama": "Budi Santoso", "nasabah_phone": "6281234567890", "nominal_tagihan": 1500000, "tanggal_tempo": "2026-06-30", "invoice_pdf_url": "https://storage.gadai.com/invoices/inv-001.pdf"}',
    'pending'
  );

-- Check it's pending
SELECT id, status, created_at FROM collection_broadcasts.broadcast_staging WHERE status='pending';

Wait 30 seconds

Worker polls every 30 seconds. Check status:

SELECT id, status, sopiga_recipient_detail_id, dispatched_at, error_message 
FROM collection_broadcasts.broadcast_staging 
WHERE id = 1;

-- Should show: status='dispatched', sopiga_recipient_detail_id=512

Check WhatsApp Delivery

After 5 minutes, check sync job:

SELECT id, status, last_status_from_sopiga, delivered_at
FROM collection_broadcasts.broadcast_staging
WHERE id = 1;

-- Should show: status='delivered', delivered_at=<timestamp>

📊 Monitor

Check Delivery Rate

SELECT * FROM collection_broadcasts.v_delivery_rate_24h;
-- delivery_rate_percent should be > 95%

Check Failed Records

SELECT * FROM collection_broadcasts.v_failed_records_24h;
-- Should be empty or < 5%

Check Collar Summary

SELECT * FROM collection_broadcasts.v_collar_summary;
-- See totals per collar, delivery rates

Add New Template (5 minutes)

When Sopiga template changes (e.g., add NoKontrak field):

1. Create in Sopiga

# template_id = 3, collar_id = 71

2. Register in Database

-- Template
INSERT INTO sopiga_template_config (template_name, sopiga_template_id, ...)
VALUES ('Collection Invoice Extended', 3, ...);

-- Variables (URUTAN PENTING!)
INSERT INTO template_variable_mapping 
  (sopiga_template_id, variable_order, sopiga_variable_name, variable_type, db_field_source, is_required)
VALUES
  (3, 1, 'Nama', 'string', 'nasabah_nama', TRUE),
  (3, 2, 'NoKontrak', 'string', 'contract_no', TRUE),            NEW
  (3, 3, 'TotalTagihan', 'integer', 'nominal_tagihan', TRUE),
  (3, 4, 'TanggalJatuhTempo', 'date', 'tanggal_tempo', TRUE);

-- Collar
INSERT INTO sopiga_collar_config (broadcast_name, sopiga_collar_id, sopiga_template_id, status)
VALUES ('Collection Invoices June 2026', 71, 3, 'open');

3. NO code redeploy needed

Worker automatically picks up new template on next poll.


🚀 Gadai Service Integration

How Gadai calls this:

import "database/sql"
import "encoding/json"

db, _ := sql.Open("postgres", "postgres://user:pass@localhost/gadai_mulia")

payload := map[string]interface{}{
  "nasabah_nama": "Budi Santoso",
  "nasabah_phone": "6281234567890",
  "nominal_tagihan": 1500000.0,
  "tanggal_tempo": "2026-06-30",
  "invoice_pdf_url": "https://storage.gadai.com/invoices/inv-001.pdf",
  "contract_no": "GAD-2026-001",
}

payloadJSON, _ := json.Marshal(payload)

db.Exec(`
  INSERT INTO collection_broadcasts.broadcast_staging 
    (sopiga_collar_id, sopiga_template_id, message_payload, status)
  VALUES ($1, $2, $3, 'pending')
`, 70, 2, payloadJSON)

// Done! Worker picks it up automatically

🐛 Troubleshooting

"Message format wrong"

→ Check template variable order matches Sopiga:

SELECT variable_order, sopiga_variable_name FROM template_variable_mapping 
WHERE sopiga_template_id=2 ORDER BY variable_order;

"Record stuck in pending"

→ Check worker logs:

# Look for errors in stdout/stderr
# Check DB connection
psql -U postgres -h localhost -d gadai_mulia -c "SELECT 1;"

"Sopiga API errors"

→ Check token and URL:

curl -X GET https://omnix.promas.site/api/client/collar/list \
  -H "Authorization: Bearer YOUR_TOKEN"

Checklist

  • Schema created
  • Sopiga template created (note template_id)
  • Sopiga collar created (note collar_id)
  • Database populated with template_id, collar_id
  • Variable mappings inserted (check order!)
  • Worker deployed and running
  • Test record inserted
  • Record moved to 'dispatched' after 30s
  • Record moved to 'delivered' after 5 min
  • WhatsApp message received on test phone

📞 Quick Reference

Database:

  • Schema: collection_broadcasts
  • Main table: broadcast_staging
  • Config tables: sopiga_template_config, template_variable_mapping, sopiga_collar_config

Sopiga URLs:

  • Base: https://omnix.promas.site
  • Create template: POST /api/client/template
  • Create collar: POST /api/client/collar
  • Add recipient: POST /api/client/collar/add-recipient
  • Get recipient detail: GET /api/client/collar/add-recipient/{id}/detail

Worker:

  • Poll interval: 30 seconds (pending records)
  • Status sync: 5 minutes (delivery status)
  • Max retries: 3 (exponential backoff: 1s, 2s, 4s)

Ready to go! 🚀