@byteindev/truemoney-voucher
v1.1.1
Published
Zero-dependency client for the Truemoney-Voucher REST APIs (Go / NestJS / FastAPI ports) — redeem TrueMoney gift vouchers from npm, pnpm, bun, yarn or the browser
Maintainers
Readme
Truemoney-Voucher (npm)
ไคลเอนต์แบบ zero-dependency สำหรับ REST APIs ของ Truemoney-Voucher — แลกรับ TrueMoney gift voucher จาก npm, pnpm, bun, yarn หรือเบราว์เซอร์
English - ไทย
ไคลเอนต์แบบ zero-dependency สำหรับตระกูล API Truemoney-Voucher — มี backend สามตัวที่ใช้ HTTP contract เดียวกัน และไคลเอนต์เลือกตัวที่เร็วที่สุดให้อัตโนมัติ:
| Provider | Backend | ที่อยู่ |
| --- | --- | --- |
| auto (ค่าเริ่มต้น) | probe ทั้งสามตัว ใช้ตัว healthy ที่เร็วที่สุด | failover อัตโนมัติเมื่อ network error |
| go | Go (uTLS HelloFirefox_148 + HTTP/2 framer) | https://truemoney-voucher-go.vercel.app |
| nestjs | NestJS (cycletls Firefox 148 fingerprint) | https://truemoney-voucher-nestjs.vercel.app |
| fastapi | FastAPI (curl_cffi Firefox 147 fingerprint) | https://truemoney-voucher-fastapi.vercel.app |
ความสามารถ
| ความสามารถ | รายละเอียด |
| ----------- | ----------- |
| แลกรับโค้ด | Client.redeem(code, mobile) — ใส่โค้ดตรงๆ หรือลิงก์เต็ม gift.truemoney.com ก็ได้ |
| Auto provider | ค่าเริ่มต้น 'auto' — probe ทุก backend แล้วใช้ตัว healthy ที่เร็วสุด พร้อม failover เมื่อ network error |
| Static API | import { Client } — ไม่ต้องสร้าง instance ไม่ต้อง config แค่ await Client.redeem(...) |
| Zero dependencies | ไม่มี install scripts, ไม่มี native binaries, ไม่มี runtime deps — มีทั้ง ESM + CJS + types |
| รันได้ทุกที่ | Node.js >= 18, Bun, Deno, เบราว์เซอร์ — อะไรก็ได้ที่มี fetch |
| Error แบบมี type | TruemoneyApiError, TruemoneyTimeoutError, TruemoneyError พร้อมเข้าถึง envelope ได้ |
เริ่มต้นใช้งาน
ติดตั้งด้วย package manager ตัวไหนก็ได้:
npm install @byteindev/truemoney-voucher
# หรือ
pnpm add @byteindev/truemoney-voucher
# หรือ
yarn add @byteindev/truemoney-voucher
# หรือ
bun add @byteindev/truemoney-voucherไม่ต้องตั้งค่าอะไร — Client คือ static wrapper พร้อมใช้ ครอบ instance ที่ config แบบ auto ให้แล้ว:
import { Client } from '@byteindev/truemoney-voucher';
// auto: probe backend สามตัวที่โฮสต์อยู่ แล้วใช้ตัว healthy ที่เร็วที่สุด
const result = await Client.redeem('12345678901234', '0812345678');
console.log(result.status.code); // เช่น "VOUCHER_NOT_FOUND", "TARGET_USER_REDEEMED"
// ตรวจว่า service ยังทำงานอยู่:
const alive = await Client.status();
// ข้อมูลบริการ:
const info = await Client.info();เลือก provider เอง (หรือใช้ deployment ของตัวเอง)
import { createClient } from '@byteindev/truemoney-voucher';
// เลือก backend ตัวใดตัวหนึ่งจากสามตัวที่โฮสต์อยู่:
const client = createClient({ provider: 'nestjs' }); // 'go' | 'nestjs' | 'fastapi'
// หรือใช้ base URL ของตัวเอง (ชนะ `provider` เสมอ):
const custom = createClient({
baseUrl: 'https://api.example.com',
timeoutMs: 15_000,
});
// `Client.configure()` สร้าง instance ใหม่ด้วยวิธีเดียวกัน:
Client.configure({ provider: 'fastapi' });API Reference
Static Client (ไม่ต้องสร้าง instance)
| Method | คำอธิบาย |
| --- | --- |
| Client.redeem(code, mobile) | แลกรับโค้ดตรงๆ หรือ campaign URL เต็ม ผ่าน backend healthy ที่เร็วที่สุด |
| Client.status() | true เมื่อมี backend อย่างน้อยหนึ่งตัวตอบ 2xx ที่ /status |
| Client.info() | service info + routes ของ backend ที่เลือก |
| Client.configure(options?) | แทนที่ instance ร่วม (ค่าเริ่มต้น auto) |
createClient(options?) => TruemoneyClient
| ตัวเลือก | Type | ค่าเริ่มต้น | คำอธิบาย |
| --- | --- | --- | --- |
| provider | 'auto' \| 'go' \| 'nestjs' \| 'fastapi' | 'auto' | backend ที่จะเรียก — 'auto' probe แล้วเลือกตัว healthy ที่เร็วสุด |
| baseUrl | string | URL ของ provider | base URL เต็ม (ชนะ provider) |
| timeoutMs | number | 30_000 | หมดเวลา per-request |
| fetch | typeof fetch | global | fetch แบบกำหนดเอง (ทดสอบ, proxy) |
| userAgent | string | truemoney-voucher/1.1.0 | header User-Agent |
| headers | Record<string, string> | — | header เพิ่มเติมในทุก request |
Auto provider
- ใน request แรก (หรือเมื่อ cache 60 วินาทีหมดอายุ) backend ทั้งสามจะถูก probe พร้อมกัน (
GET /status, probe timeout 3 วินาที) และจัดอันดับตาม latency redeem,status()และinfo()ไปที่ backend healthy ที่เร็วที่สุด — การจัดอันดับ cache ไว้ 60 วินาที- ถ้า redeem ล้มเหลวด้วย network error ไคลเอนต์ลอง backend healthy ตัวถัดไปอัตโนมัติ — validation error (
TruemoneyApiError) ไม่ trigger failover เพราะ redeem ใช้ครั้งเดียว ย้อนไม่ได้ failover แล้วก็ไม่ซ้ำ — กรณีแย่สุดแค่TARGET_USER_REDEEMED client.explicitBaseUrlคืน base URL ของ backend ที่เลือกแบบชัดเจน (undefinedสำหรับ auto)
client.redeem(code, mobile) => Promise<RedeemResult>
รับโค้ดตรงๆ หรือ ลิงก์เต็ม campaign URL (percent-encode ลงใน path —
backend รักษา %2F ไว้ ตรงกับ CLI ต้นฉบับ)
- สำเร็จ →
{ ok: true, status: { message, code }, data }เมื่อ upstream call สำเร็จ - ผิดพลาด → throw
TruemoneyApiErrorสำหรับ validation/routing errors ({ code, message }envelope หรือ error body แบบ Spring ที่ normalize ให้แล้ว)
client.status() => Promise<boolean>
true เมื่อได้ 2xx, false เมื่ออื่นๆ — ไม่ throw เด็ดขาด ปลอดภัยสำหรับ uptime checks
โหมด auto: true เมื่อมี backend อย่างน้อยหนึ่งตัว healthy
client.info() => Promise<ServiceInfo>
ชื่อ service, เวอร์ชันที่ deploy (ถ้ามีการ expose), และรายการ routes
Errors
| Error | เมื่อเกิด |
| --- | --- |
| TruemoneyApiError | API ตอบ { code, message } (validation 400, not found 404, …) หรือ error body แบบ Spring — เปิดดู status, code, envelope ได้ |
| TruemoneyTimeoutError | ไม่มีการตอบกลับภายใน timeoutMs |
| TruemoneyError | network ล้มเหลว, response ไม่ใช่ JSON, envelope แปลกๆ |
ทุก error สืบทอดจาก TruemoneyError:
import { TruemoneyApiError } from '@byteindev/truemoney-voucher';
try {
await Client.redeem(code, mobile);
} catch (err) {
if (err instanceof TruemoneyApiError) {
console.log(err.code, err.message); // 400 "Bad Request"
}
}TrueMoney status codes
เมื่อ upstream call สำเร็จ result.status.code จะมีคำตอบของ TrueMoney:
| Code | ความหมาย |
| ---- | -------- |
| SUCCESS | รับเงินสำเร็จ |
| TARGET_USER_REDEEMED | คุณแลกโค้ดนี้ไปแล้ว |
| VOUCHER_OUT_OF_STOCK | คนอื่นแลกไปแล้ว |
| VOUCHER_EXPIRED | วอเล็ต voucher หมดอายุแล้ว |
| VOUCHER_NOT_FOUND | ไม่พบโค้ดในระบบ |
| CANNOT_GET_OWN_VOUCHER | แลกโค้ดของตัวเองไม่ได้ |
| TARGET_USER_NOT_FOUND | ไม่พบเบอร์โทรศัพท์ในระบบ |
| INTERNAL_ERROR | ไม่พบโค้ด หรือ URL ผิด |
เบราว์เซอร์
ไม่ต้อง build — package มีทั้ง ESM + CJS พร้อม TypeScript types:
<script type="module">
import { Client } from 'https://esm.sh/@byteindev/truemoney-voucher';
document.body.textContent = JSON.stringify(await Client.info());
</script>การทดสอบ
npm test # unit tests (client, errors, providers) — offline
npm run test:live # ตรวจกับ backend ที่โฮสต์อยู่ทั้งสามตัวแบบ realชุดเทสต์แบบ live รัน status/info และตรวจ invalid voucher กับ Vercel
deployments ทั้งสามตัว บวก upstream call จริง — ยืนยันแล้วบน npm, pnpm 11
และ Bun 1.3
Contributing
ยินดีรับ contribution! กรุณา:
- เปิด issue ก่อนสำหรับการเปลี่ยนแปลงใหญ่ๆ
- รักษา
npm run typecheckและnpm testให้เขียวเสมอ - เพิ่ม
VERSIONในsrc/version.tsพร้อมกับpackage.json
ข้อควรทราบ
สำหรับการศึกษาหรือที่ผู้ให้บริการอนุญาตเท่านั้น การแลกโค้ดย้อนกลับไม่ได้ และอยู่ภายใต้ข้อกำหนดการใช้งานของ TrueMoney โค้ด voucher เทียบเท่าเงินสด — อย่า log โค้ดเต็ม
License
Licensed under the MIT License © 2026 ByteInDev
