initial commit

This commit is contained in:
vakabunga
2026-01-16 18:37:32 +03:00
commit 643eddb5fc
14 changed files with 3469 additions and 0 deletions

143
index.js Normal file
View File

@@ -0,0 +1,143 @@
function toNumberRu(s) {
if (!s) return null;
const cleaned = String(s)
.replace(/\s/g, "")
.replace(",", ".")
.replace(/[^\d.]/g, "");
const n = Number(cleaned);
console.log("toNumberRu: " + Number.isFinite(n));
return Number.isFinite(n) ? n : null;
}
function paringSms(sms) {
console.log(sms);
const raw = sms.body.message ?? "";
console.log("raw: " + raw);
const text = String(raw).replace(/\s+/g, " ").trim();
const lower = text.toLowerCase();
console.log("text: " + text);
const sender = sms.body?.sender ?? null;
console.log("sender: " + sender);
// 1) Классификация
let action = "unknown";
const rules = [
{ action: "salary", re: /зарплат/i },
{ action: "reversal", re: /(отмена|возврат)/i },
{ action: "payment", re: /(оплата|покупк)/i },
{ action: "transfer", re: /перевод/i },
{ action: "writeoff", re: /списан/i },
{ action: "income", re: /(поступлен|поступление|зачислен)/i },
];
for (const r of rules) {
if (r.re.test(lower)) {
action = r.action;
break;
}
}
console.log("action: " + action);
// 2) Баланс
const balanceRegex =
/(баланс)[:\s]*([0-9][0-9\s]*[.,]?\d{0,2})\s*(₽|руб\.?|rub|р)(?=\s|$)/i;
const balanceMatch = text.match(balanceRegex);
console.log("balanceMatch: " + balanceMatch);
const balance = balanceMatch ? toNumberRu(balanceMatch[2]) : null;
console.log("balance: " + balance);
// 3) Сумма операции
let amount = null;
const amountNearActionRegex =
/(отмена[:\s-]*оплата|отмена|списание|оплата|перевод|поступление|зарплат[аы]?)[\s:]*([0-9][0-9\s]*[.,]?\d{0,2})\s*(₽|руб\.?|rub|р)/i;
const near = text.match(amountNearActionRegex);
console.log("near: " + near);
if (near) {
amount = toNumberRu(near[2]);
console.log(amount);
} else {
const textWithoutBalance = text.replace(balanceRegex, " ");
console.log("textWithoutBalance: " + textWithoutBalance);
const amountRegex = /([0-9][0-9\s]*[.,]?\d{0,2})\s*(₽|руб\.?|rub|р)/i;
const m = textWithoutBalance.match(amountRegex);
amount = m ? toNumberRu(m[1]) : null;
console.log("m: " + m);
}
const currency = "RUB";
// 4) signedAmount
let signedAmount = amount;
if (amount != null) {
if (["payment", "transfer", "writeoff"].includes(action))
signedAmount = -Math.abs(amount);
if (["income", "salary", "reversal"].includes(action))
signedAmount = Math.abs(amount);
}
console.log({
raw_sms: raw,
sms_text: text,
sms_sender: sender,
action, // income/payment/transfer/salary/reversal/writeoff
amount,
signed_amount: signedAmount,
currency,
balance,
received_at: new Date().toISOString(),
});
return [
{
raw_sms: raw,
sms_text: text,
sms_sender: sender,
action, // income/payment/transfer/salary/reversal/writeoff
amount,
signed_amount: signedAmount,
currency,
balance,
received_at: new Date().toISOString(),
},
];
}
const input_sms = {
body: {
message:
'Оплата 980р Карта*4215 "SKURATOV COFFE Баланс 207033.86р 19:52',
sender: "VTB",
formatted_message:
'📩 *New SMS Received*\n👤 *From:* VTB\n\nОплата 980р Карта*4215 "SKURATOV COFFE Баланс 207033.86р 19:52',
contact: "",
},
};
const input_sms2 = {
body: {
formatted_message:
"📩 *New SMS Received*\n👤 *From:* VTB\n\nОплата 6800р Карта*4215 IP SHARAFETDINO Баланс 199083.86р 09:56",
contact: "",
sender: "VTB",
message:
"Оплата 6800р Карта*4215 IP SHARAFETDINO Баланс 199083.86р 09:56",
},
};
paringSms(input_sms);
// paringSms(input_sms2);