Treat 0098 SOAP positive SendSMSResult as success

This commit is contained in:
2026-05-25 15:50:32 +03:30
parent 27bd903e9d
commit 26c3e02d6f
2 changed files with 23 additions and 20 deletions
+5 -2
View File
@@ -51,9 +51,12 @@ for (const mobile of targets) {
const body = await res.text(); const body = await res.text();
const match = body.match(/<SendSMSResult[^>]*>([^<]*)<\/SendSMSResult>/i); const match = body.match(/<SendSMSResult[^>]*>([^<]*)<\/SendSMSResult>/i);
const code = match?.[1]?.trim() ?? '?'; const code = match?.[1]?.trim() ?? '?';
const n = Number(code);
const ok = Number.isFinite(n) ? n >= 0 : false;
const status = ok ? 'OK (accepted by 0098)' : 'FAILED';
console.log(`mobile=${mobile} http=${res.status} RESULT=${code}`); console.log(`mobile=${mobile} http=${res.status} RESULT=${code} ${status}`);
if (code !== '0') { if (!ok) {
console.log(body.slice(0, 400)); console.log(body.slice(0, 400));
} }
} }
+18 -18
View File
@@ -7,20 +7,9 @@ const SMS_0098_LINK_URL = 'http://www.0098sms.com/sendsmslink.aspx';
/** Official 0098 SOAP API (works when link endpoint is down). */ /** Official 0098 SOAP API (works when link endpoint is down). */
const SMS_0098_SOAP_URL = 'https://webservice.0098sms.com/service.asmx'; const SMS_0098_SOAP_URL = 'https://webservice.0098sms.com/service.asmx';
const SMS_0098_ERROR_CODES: Record<string, string> = { /** SOAP SendSMSResult: 0 or positive = accepted (often SMS part count); negative = error. */
'1': 'invalid phone number', const SMS_0098_SOAP_ERROR_CODES: Record<string, string> = {
'2': 'no phone number', '-22': 'invalid mobile number format',
'3': 'no sender',
'4': 'no text',
'5': 'no username',
'6': 'no password',
'7': 'no domain',
'8': 'invalid license',
'9': 'insufficient SMS credit',
'10': 'no link for this number',
'11': 'no license for link access',
'12': 'wrong username or password',
'13': 'invalid characters in message text',
}; };
export type SmsSendResult = { export type SmsSendResult = {
@@ -142,12 +131,12 @@ export class SmsService {
} }
const code = this.parseSoapResultCode(body); const code = this.parseSoapResultCode(body);
if (code === '0') { if (this.is0098SoapSuccess(code)) {
return { ok: true, transport: 'soap' }; return { ok: true, transport: 'soap' };
} }
const reason = const reason =
SMS_0098_ERROR_CODES[code ?? ''] ?? SMS_0098_SOAP_ERROR_CODES[code ?? ''] ??
(code ? `provider code ${code}` : 'unknown SOAP response'); (code ? `provider code ${code}` : 'unknown SOAP response');
this.logger.warn( this.logger.warn(
`SOAP rejected to=${this.maskPhone(to)} code=${code ?? '?'} body=${body.slice(0, 200)}`, `SOAP rejected to=${this.maskPhone(to)} code=${code ?? '?'} body=${body.slice(0, 200)}`,
@@ -208,6 +197,17 @@ export class SmsService {
} }
} }
private is0098SoapSuccess(code: string | null): boolean {
if (code == null || code === '') {
return false;
}
const n = Number(code);
if (Number.isFinite(n)) {
return n >= 0;
}
return false;
}
private parseSoapResultCode(xml: string): string | null { private parseSoapResultCode(xml: string): string | null {
const match = const match =
xml.match(/<SendSMSResult[^>]*>([^<]*)<\/SendSMSResult>/i) ?? xml.match(/<SendSMSResult[^>]*>([^<]*)<\/SendSMSResult>/i) ??
@@ -234,8 +234,8 @@ export class SmsService {
return false; return false;
} }
const code = body.trim(); const code = body.trim();
if (/^\d+$/.test(code) && code !== '0') { if (/^-?\d+$/.test(code)) {
return false; return Number(code) >= 0;
} }
return true; return true;
} }