UNPKG

tw-voucher

Version:

Redeem อั่งเปา True Money Wallet ด้วย Node.js

207 lines (181 loc) 5.71 kB
import retry from "./retry"; export type BahtAmount = string; export type MobileNumber = string; export type ProfilePicURL = string | null; export type Timestamp = number; export type VoucherCode = string; export interface TicketInfo { mobile: MobileNumber; update_date: Timestamp; amount_baht: BahtAmount; full_name: string; profile_pic: ProfilePicURL; } export interface VoucherData { voucher_id: string; amount_baht: BahtAmount; redeemed_amount_baht: BahtAmount; member: number; status: string; link: VoucherCode; detail: string; expire_date: Timestamp; type: string; redeemed: number; available: number; } export interface Voucher { status: { message: string; code: string; }; data: { voucher: VoucherData; owner_profile: { full_name: string; }; redeemer_profile: { mobile_number: MobileNumber; }; my_ticket: TicketInfo; tickets: TicketInfo[]; }; } export interface simplifiedVoucher { owner_full_name: string; amount: number; code: VoucherCode; } /** * @typedef {string} BahtAmount * @typedef {string} MobileNumber * @typedef {string | null} ProfilePicURL * @typedef {number} Timestamp * @typedef {string} VoucherCode */ /** * @typedef {Object} TicketInfo * @property {MobileNumber} mobile * @property {Timestamp} update_date * @property {BahtAmount} amount_baht * @property {string} full_name * @property {ProfilePicURL} profile_pic */ /** * @typedef {Object} VoucherData * @property {string} voucher_id * @property {BahtAmount} amount_baht * @property {BahtAmount} redeemed_amount_baht * @property {number} member * @property {string} status * @property {VoucherCode} link * @property {string} detail * @property {Timestamp} expire_date * @property {string} type * @property {number} redeemed * @property {number} available */ /** * @typedef {Object} Voucher * @property {{ message: string, code: string }} status * @property {{ * voucher: VoucherData, * owner_profile: { full_name: string }, * redeemer_profile: { mobile_number: MobileNumber }, * my_ticket: TicketInfo, * tickets: TicketInfo[] * }} data */ /** * @typedef {Object} simplifiedVoucher * @property {string} owner_full_name * @property {number} amount * @property {VoucherCode} code */ enum Invalid { NUMBER = "INVALID_NUMBER", VOUCHER = "INVALID_VOUCHER", } function fetchFailedMessage(response: Response): string { return `Network Error: ${response.status} ${response.statusText}`; } async function sendAPIRequest( mobile: MobileNumber, voucher_hash: string ): Promise<Voucher> { const response = await fetch( `https://gift.truemoney.com/campaign/vouchers/${voucher_hash}/redeem`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ mobile, voucher_hash, }), } ); if (!response.ok) throw new Error(fetchFailedMessage(response)); return response.json(); } /** * ส่งคำขอไปยัง API เพื่อใช้ซองอั่งเปา * * @param {string} mobileNumber - หมายเลขบัญชี TrueMoney Wallet * @param {string} voucherLink - ลิงก์หรือโค้ดซองอั่งเปา * @returns {Promise<Voucher>} Promise ที่คืนข้อมูล Voucher * * @example * // ใช้ร่วมกับ @type เพื่อให้มี auto-complete * /** @type {import("tw-voucher").Voucher} *\/ * const result = await redeemVoucher("0382149845", "0197a3ca6ecb7b4aa07632f832159fc982S"); * console.log(result.data.voucher.voucher_id); */ async function redeemVoucher( mobileNumber: MobileNumber, voucherLink: string ): Promise<Voucher> { mobileNumber = mobileNumber.toString().trim(); if (mobileNumber.length === 0 || mobileNumber.match(/\D/)) { throw Error(Invalid.NUMBER); } //link: https://gift.truemoney.com/campaign/?v=0197a3ca6ecb7b4aa07632f832159fc982S const parts: string[] = voucherLink.toString().split("v="); const part: string = parts[1] || parts[0]; const matchedPart: RegExpMatchArray | null = part.match(/[0-9A-Za-z]{35}/); if (!matchedPart) throw Error(Invalid.VOUCHER); const voucherCode: string = matchedPart[0]; try { const jsonResponse = await retry(() => sendAPIRequest(mobileNumber, voucherCode) ); if (jsonResponse.status.code === "SUCCESS") { return jsonResponse; } throw Error(jsonResponse.status.code); } catch (error) { throw error; } } /** * ย่อการตอบกลับจาก API เพื่อให้ใช้งานง่ายขึ้น * * @param {Voucher} voucher - ผลลัพธ์สุดท้ายที่ได้จาก redeemVoucher * @returns {simplifiedVoucher} ข้อมูล Voucher แบบย่อ * * @example * const response = await redeemVoucher("0382149845", "0197a3ca6ecb7b4aa07632f832159fc982S"); * * // ใช้ร่วมกับ @type เพื่อให้มี auto-complete * /** @type {import("tw-voucher").simplifiedVoucher} *\/ * const result = simplify(response); * console.log(result.owner_full_name); */ export function simplify(voucher: Voucher): simplifiedVoucher { const { data } = voucher; return { owner_full_name: data.owner_profile.full_name, amount: Number(data.my_ticket.amount_baht), code: data.voucher.link, }; } export default redeemVoucher;