From f6cc1bfc0a525ca85445b1b1812eae638090fe10 Mon Sep 17 00:00:00 2001 From: rosahaj <141790572+rosahaj@users.noreply.github.com> Date: Sat, 4 May 2024 15:14:21 +0200 Subject: [PATCH] Fix response parsing --- package.json | 1 + pnpm-lock.yaml | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ src/errors.ts | 4 +- src/index.ts | 11 +++-- src/types.d.ts | 7 +++- 5 files changed, 124 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index f9137ed..7cd0741 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "prepare": "simple-git-hooks" }, "dependencies": { + "cheerio": "1.0.0-rc.12", "ky": "^1.2.4", "undici": "^6.15.0", "xml-js": "^1.6.11" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 889872b..1cbd02c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + cheerio: + specifier: 1.0.0-rc.12 + version: 1.0.0-rc.12 ky: specifier: ^1.2.4 version: 1.2.4 @@ -1230,6 +1233,13 @@ packages: check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -1308,6 +1318,13 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -1359,6 +1376,19 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} @@ -1382,6 +1412,10 @@ packages: resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} engines: {node: '>=10.13.0'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -1779,6 +1813,9 @@ packages: hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -2208,6 +2245,12 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse5-htmlparser2-tree-adapter@7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -3886,6 +3929,25 @@ snapshots: dependencies: get-func-name: 2.0.2 + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + htmlparser2: 8.0.2 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + chokidar@3.5.3: dependencies: anymatch: 3.1.3 @@ -3965,6 +4027,16 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + cssesc@3.0.0: {} debug@3.2.7: @@ -3997,6 +4069,24 @@ snapshots: dependencies: esutils: 2.0.3 + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dotenv@16.4.5: {} eastasianwidth@0.2.0: {} @@ -4014,6 +4104,8 @@ snapshots: graceful-fs: 4.2.10 tapable: 2.2.1 + entities@4.5.0: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -4574,6 +4666,13 @@ snapshots: hosted-git-info@2.8.9: {} + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + human-signals@5.0.0: {} ignore@5.3.1: {} @@ -4989,6 +5088,15 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse5-htmlparser2-tree-adapter@7.0.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + path-exists@4.0.0: {} path-exists@5.0.0: {} diff --git a/src/errors.ts b/src/errors.ts index dd1c682..b93daa3 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -3,7 +3,7 @@ export enum ErrorCode { InvalidCredentials = 'INVALID_CREDENTIALS', InvalidFaxNumber = 'INVALID_FAX_NUMBER', InsufficientBalance = 'INSUFFICIENT_BALANCE', - InvalidDocument = 'INVALID_DOCUMENT', + FaultyDocument = 'FAULTY_DOCUMENT', InternalError = 'INTERNAL_ERROR', Other = 'OTHER', } @@ -28,7 +28,7 @@ export class SimpleFaxError extends Error { break case 'Dokument fehlerhaft': - this.code = ErrorCode.InsufficientBalance + this.code = ErrorCode.FaultyDocument break default: diff --git a/src/index.ts b/src/index.ts index 02ce423..9823e3d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,6 @@ import { js2xml } from 'xml-js' -import type { Options } from 'ky' -import ky from 'ky' import { request } from 'undici' +import * as cheerio from 'cheerio' import { SimpleFaxError } from './errors.js' import type { EnvelopeOptions } from './types.js' import template from './template.json' @@ -38,7 +37,8 @@ export async function sendFax( ): Promise { const envelope = createEnvelope(options) - const response = await request('http://longisland.simple-fax.de/soap/index.php', { + const xml = await request('https://longisland.simple-fax.de/soap/index.php', { + method: 'POST', body: envelope, headers: { 'Content-Type': 'text/xml;charset=UTF-8', @@ -46,8 +46,11 @@ export async function sendFax( }, }).then(({ body }) => body.text()) + const $ = cheerio.load(xml) + const response = $('ns4\\:sendfaxResponse').text() + // Response format: "status;message." - const [status, message] = response.trim().replace(/\.$/, '').split(';') + const [status, message] = response.trim().replace(/\..*$/, '').split(';') if (status === 'success') return message diff --git a/src/types.d.ts b/src/types.d.ts index a5656f6..3c023a3 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -29,9 +29,14 @@ export interface EnvelopeOptions { * Callback URL * * After transmission, a `GET` request with the following parameters is sent to the callback URL: - * - `faxid` + * - `faxid` (internal suid rather than the fax ID displayed in the "Versandbox") * - `status` (either "done" or "failed") * - `reason` (error message) + * - `timestamp` (unix timestamp in seconds) + * - `totpages` (number of pages) + * - `tsi` (unknown parameter) + * - `number` (recipient fax number) + * - `price` (price in `-x.xx` format) */ statusurl: string }