Tutorial: Call DamCorp WhatsApp API from a Minimal Go main.go
This guide shows the smallest practical Go program for sending one WhatsApp template message directly to DamCorp.
Important: HISv3 normally does not call DamCorp directly from domain services.
HISv3 builds a MessageBody, publishes it to RabbitMQ, and an external
WhatsappPublisherConsumer performs the HTTP call. Use this direct sample only for
learning, local experiments, or a standalone integration.
What the HISv3 repo tells us
| File | What to copy from it |
|---|---|
common-go-modules/pkg/whatsapp/dto/damcorpapi.go |
Direct DamCorp JSON body shape. |
common-go-modules/pkg/whatsapp/dto/whatsapp.go |
Template, component, parameter fields. |
his-backend/internal/service/whatsappmanager/template/template.go |
Template parameter order. |
his-backend/internal/service/whatsappmanager/enum/templatemessage.go |
Template names. |
The simplest text-only template in HISv3 is:
phkg_sendpatientregistration_id_beta_v1
Its body parameters are built in BuildEncounterPatientRegistration:
- Patient name
- Identity number
- Patient name again
- Gender display
- Birth date
- Counter name
- Location floor
Prerequisites
- DamCorp API token.
- Recipient phone number in international format, for example
628123456789. - The WhatsApp template must already exist and be approved in DamCorp.
- The parameter count and order must match the template.
Minimal main.go
Create a new scratch folder outside the HISv3 repo:
mkdir dampcorp-go-sample
cd dampcorp-go-sample
go mod init example.com/dampcorp-go-sample
Create main.go:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
)
func main() {
token := os.Getenv("DAMPCORP_TOKEN")
to := os.Getenv("DAMPCORP_TO")
if token == "" || to == "" {
log.Fatal("set DAMPCORP_TOKEN and DAMPCORP_TO first")
}
payload := map[string]any{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": to,
"type": "template",
"template": map[string]any{
"name": "phkg_sendpatientregistration_id_beta_v1",
"language": map[string]string{
"code": "id",
},
"components": []map[string]any{
{
"type": "body",
"parameters": []map[string]string{
{"type": "text", "text": "Budi Santoso"},
{"type": "text", "text": "3173000000000001"},
{"type": "text", "text": "Budi Santoso"},
{"type": "text", "text": "Laki-laki"},
{"type": "text", "text": "2-1-1990"},
{"type": "text", "text": "counter aktivasi pasien"},
{"type": "text", "text": "Lantai 1"},
},
},
},
},
}
body, err := json.Marshal(payload)
if err != nil {
log.Fatal(err)
}
req, err := http.NewRequest(
http.MethodPost,
"https://waba.damcorp.id/v2/messages",
bytes.NewReader(body),
)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
client := &http.Client{Timeout: 15 * time.Second}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
log.Fatalf("DamCorp error: status=%d body=%s", resp.StatusCode, respBody)
}
fmt.Printf("DamCorp success: status=%d body=%s\n", resp.StatusCode, respBody)
}
Run it:
export DAMPCORP_TOKEN='your-damcorp-token'
export DAMPCORP_TO='628123456789'
go run .
Payload sent by the sample
The Go program sends this shape:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "628123456789",
"type": "template",
"template": {
"name": "phkg_sendpatientregistration_id_beta_v1",
"language": { "code": "id" },
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Budi Santoso" },
{ "type": "text", "text": "3173000000000001" },
{ "type": "text", "text": "Budi Santoso" },
{ "type": "text", "text": "Laki-laki" },
{ "type": "text", "text": "2-1-1990" },
{ "type": "text", "text": "counter aktivasi pasien" },
{ "type": "text", "text": "Lantai 1" }
]
}
]
}
}
How this maps to HISv3
In HISv3, the same message is created by:
body, err := svc.whatsappMgrSvc.BuildEncounterPatientRegistration(
patientInfo,
"Lantai 1",
hospitalName,
"628123456789",
)
if err != nil {
return err
}
return svc.notificationService.SendWhatsapp(body)
That path publishes to RabbitMQ instead of calling https://waba.damcorp.id/v2/messages
directly.
Related wiki pages
- WhatsApp DamCorp Integration — HISv3 async flow via RabbitMQ.
Common mistakes
- Do not use
0812...; use62812.... - Do not change parameter order unless the DamCorp template is changed too.
- Do not send the HISv3
MessageBodywrapper directly to DamCorp. - Keep the token in an environment variable or secret manager, never in source code.