Довідник API

JavaScript
import SpamScanner from 'spamscanner';             // ESM
const SpamScanner = require('spamscanner');        // CommonJS

const scanner = new SpamScanner(options);
const result = await scanner.scan(rawMessage, scanOptions);

Створіть один сканер і використовуйте його повторно: він завантажує модель один раз і кешує відповіді DNS і мовної моделі.

Параметри#

Кожен параметр можна передати конструктору. Більшість також можна передати до scan() для одного листа; вони накладаються на параметри конструктора.

ПараметрЗа замовчуваннямЗначення
threshold5Бал, з якого лист вважається спамом
rejectThreshold15Бал, з якого action дорівнює reject
scores{}Бали для тестів: ключі налаштувань або назви тестів (тести та бали)
classifierвбудована модельClassifier, об’єкт моделі, шлях до файлу моделі або false
classifierOptions{}Параметри вбудованої моделі (див. Класифікатор)
allowedLanguages[]Коди ISO 639-1; інші мови отримують LANGUAGE_NOT_ALLOWED
phishing.cloudflaretrueЗапитувати фільтрувальні резолвери Cloudflare про хости посилань
phishing.adulttrueТакож запитувати сімейний резолвер, який блокує сайти для дорослих
phishing.maxHosts25Скільки хостів посилань перевіряти в одному листі
phishing.homograph{}brands (замінює вбудований перелік), extraBrands, allowlist (домени, які ніколи не позначаються), strictMode
dnsbl{ip: [], domain: []}Зони чорних списків DNS для IP-адреси клієнта та доменів посилань
dns{servers: null, timeout: 3000}Сервери імен для перевірок DNS (за замовчуванням системні)
attachmentstrueПеревіряти вкладення
macrostrueПозначати макроси, активні PDF і об’єкти RTF
arbitrarytrueВиконувати правила
authenticationfalsetrue або {dnsServers, timeout, mta, weights}: SPF, DKIM, DMARC, ARC
reputationfalse{allowlist, denylist, apiUrl, headers, timeout}
allowlist, denylistIP-адреси, домени або адреси; скорочення для reputation
clamavfalsetrue (стандартний сокет), {socket} або {host, port}
llmnullНалаштування мовної моделі з mode, minScore, maxScore
toxicityfalse{model, threshold = 0.7}: модель, чий classify([text]) відповідає як @tensorflow-models/toxicity
nsfwfalse{model, threshold = 0.6}: модель, чий classify(imageBuffer) відповідає як nsfwjs
maxLength100000Скільки символів тексту тіла читати
timeout10000Скільки мілісекунд дозволено на кожну мережеву перевірку
session{}Типові відомості про сеанс SMTP

scan() також приймає session:

JavaScript
await scanner.scan(raw, {
  session: {
    remoteAddress: '203.0.113.5',             // the client's IP address
    resolvedClientHostname: 'mx.example.com', // its verified reverse DNS name
    helo: 'mx.example.com',
    envelope: {
      mailFrom: {address: 'alice@example.com'},
      rcptTo: [{address: 'bob@example.org'}],
    },
  },
});

Сервер, який уже перевірив SPFSender Policy Framework: запис DNS зі списком серверів, яким дозволено надсилати пошту від імені домену., DKIMDomainKeys Identified Mail: підпис листа, який перевіряють відкритим ключем, опублікованим у DNS відправника., DMARCПолітика в DNS, яка вказує отримувачам, що робити з поштою від імені домену, коли вона не проходить вирівнювання SPF і DKIM. і ARCAuthenticated Received Chain: підписи, які передають результати автентифікації через сервери пересилання. (за допомогою mailauth), може передати свої результати як authenticationResults, і їх буде оцінено без повторної перевірки:

JavaScript
import {authenticate} from 'mailauth';

const auth = await authenticate(raw, {ip, helo, sender, mta});
await scanner.scan(raw, {authenticationResults: auth});

Методи#

МетодПовертає
scan(source, options)Результат. source — це Buffer, рядок, Uint8Array або потік для читання
scanFile(path, options)Результат для файлу листа
learn(source, 'spam' | 'ham')Навчає класифікатор на одному листі
unlearn(source, 'spam' | 'ham')Скасовує learn
saveModel(path, options)Записує класифікатор у файл (options: minCount, maxFeatures, metadata)
getClassifier()Classifier, що використовується, або null
getClassification(features)Вердикт класифікатора для ознак із getFeatures
getFeatures(mail){features, words, language, script, links, hosts, text, hidden} листа
getTokens(text, locale)Слова тексту
getTokensAndMailFromSource(source){tokens, features, mail}
parse(source){raw, mail}, де mail отримано з mailparser

У getFeatures text — це текст, який показує поштовий клієнт і з якого беруться слова, а hidden — скільки символів тексту приховує HTML.

scanner.metrics містить totalScans, averageTime і lastScanTime.

Результат#

JavaScript
{
  isSpam: true,
  score: 16.25,
  threshold: 5,
  rejectThreshold: 15,
  action: 'reject',                       // 'accept', 'tag' or 'reject'
  message: 'Spam (BAYES_999, PHISHING_LOOKALIKE_DOMAIN, DECEPTIVE_LINK, FROM_NAME_BRAND)',
  tests: [
    {name: 'BAYES_999', score: 6.25, description: 'Classifier spam probability 99.9%'},
    {name: 'PHISHING_LOOKALIKE_DOMAIN', score: 5, description: '"paypa1-secure.top" imitates paypal by swapping characters'},
    // ...
  ],
  results: {
    classification: {probability, category, spam, ham, clues, coverage},
    phishing: [],        // lookalike domains, deceptive links, Cloudflare and URIBL findings
    uncheckedHosts: 0,   // link hosts beyond phishing.maxHosts, not looked up
    attachments: [],     // every attachment finding
    executables: [],     // the executable findings among them
    macros: [],          // macros, active PDFs, RTF objects
    viruses: [],         // ClamAV findings: {filename, virus: [names], message}
    arbitrary: [],       // rules strong enough to mark spam alone
    obfuscation: {invisible, mixed, styled},
    authentication: null, // mailauth's results with a score, when checked
    reputation: null,
    dnsbl: [],           // {zone, value} for each listing
    language: {language, script, notAllowed},
    llm: null,           // the language model's verdict, when asked
    toxicity: [],
    nsfw: [],
    idnHomographAttack: {detected, domains, riskScore},
  },
  links: ['http://paypa1-secure.top/login'],
  language: 'en',
  tokens: ['dear', 'customer', /* ... */],
  mail: {/* the parsed message, from mailparser */},
  version: '7.0.0',
  metrics: {totalTime: 42},
}

Знахідки в phishing, attachments, executables, macros, viruses і arbitrary — це об’єкти з type і message. String(finding) повертає повідомлення.

Експорти#

JavaScript
import SpamScanner, {
  Classifier, getFeatures, segmentWords, detectLanguage,
  LLMClassifier, PROVIDERS, RECOMMENDED_MODELS, CLASSIFIER_MODELS,
  DEFAULT_SCORES, scoreResults, spamHeaders, rewriteMessage,
  loadModel, saveModel, defaultModelPath, loadDefaultModel,
  train, evaluate, readExamples,
  MilterServer, createHttpServer, createTcpServer, createSpamdServer,
  DEFAULTS, VERSION,
} from 'spamscanner';

import ArfParser from 'spamscanner/arf';

Класифікатор#

JavaScript
const classifier = new Classifier({spamCutoff: 0.99, hamCutoff: 0.2});
classifier.learn(getFeatures(mail).features, 'spam');
classifier.classify(features); // {probability, category, spam, ham, clues, coverage}
ПараметрЗа замовчуваннямЗначення
strength, unknown0.45, 0.5s і x Робінсона: наскільки сильно рідкісні ознаки зсуваються до 0,5
minDistance0.1Ознаки, ближчі до 0,5, ніж це значення, ігноруються
maxClues150Скільки найсильніших ознак поєднується для одного листа
hamCutoff, spamCutoff0.2, 0.99Межі діапазону unsure
minLanguageExamples, languageShare1000, 0.02Скільки листів кожного класу потрібно в мові для повної впевненості
languagePriortrueЗважувати слова відносно лічильників їхньої власної мови

Також доступні merge(other), toJSON(options), Classifier.fromJSON(json), size і entries().

Навчання#

JavaScript
import {train, evaluate, saveModel} from 'spamscanner';

const {classifier, spam, ham} = await train({
  spam: ['/mail/Junk'],
  ham: ['/mail/Archive', '/mail/archive.mbox'],
  datasets: [{file: 'extra.csv', textColumn: 'body', labelColumn: 'kind'}],
});
saveModel(classifier, 'model.json');

evaluate(classifier, examples) приймає елементи {label, features} або readExamples(sources), яка читає ті самі джерела, що й train, і повертає лічильники, точність, повноту, F1, правильність, а також частки хибнопозитивних, хибнонегативних і невизначених результатів.

Сервери#

JavaScript
import SpamScanner, {MilterServer, createHttpServer, createSpamdServer} from 'spamscanner';

const scanner = new SpamScanner({authentication: true});
const milter = new MilterServer(scanner, {reject: true, rejectCode: 451, subjectTag: '[SPAM]'});
milter.on('scan', ({session, result}) => console.log(session.remoteAddress, result.score));
await milter.listen(7831);

createHttpServer(scanner, {token: process.env.SPAMSCANNER_TOKEN}).listen(7832, '127.0.0.1');
createSpamdServer(scanner).listen(783, '127.0.0.1');

Звіти ARF#

spamscanner/arf читає й записує звіти про зловживання (RFC 5965) — формат, у якому поштові провайдери повідомляють про скарги на спам:

JavaScript
import ArfParser from 'spamscanner/arf';

const report = await ArfParser.parse(rawReport);
console.log(report.feedbackType, report.sourceIp, report.originalHeaders.subject);

const raw = ArfParser.create({
  feedbackType: 'abuse', userAgent: 'MyService/1.0',
  from: 'abuse@example.com', to: 'fbl@example.net',
  originalMessage, sourceIp: '192.0.2.1',
});

ArfParser.tryParse() повертає null замість винятку для листів, які не є звітами, а isArfMessage(mail) перевіряє розібраний лист.

Редагувати цю сторінку на GitHub · Markdown ·