Обнаружение спама
Обнаружение спама Discuse классифицирует текст как спам или не спам и возвращает оценку уверенности. Отправьте текст на POST https://api.discuse.com/api/v2/check с включённым check_spam и получите вердикт из results.spamfinder. Это помогает выявлять рекламный спам, мошеннические сообщения и сгенерированный ботами шум, который простые фильтры по ключевым словам часто пропускают.
Что выявляет обнаружение спама?
Модель обучена на массовых паттернах, которые обходят блок-листы:
- Рекламный спам и нежелательная реклама
- Мошеннические и фишинговые сообщения
- Сгенерированный ботами и скопированный контент
Она возвращает один label (например, spam или ham) и оценку confidence, чтобы вы могли сами выбрать нужную строгость.
Как запустить проверку на спам?
curl -X POST https://api.discuse.com/api/v2/check \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": {
"text": "CONGRATULATIONS! You won $10,000! Click here to claim: bit.ly/fake"
},
"settings": {
"check_spam": true
}
}'
Формат ответа
{
"has_violations": true,
"cached": false,
"message": "Spam content detected",
"results": {
"hits": true,
"spamfinder": {
"text": "CONGRATULATIONS! You won $10,000! Click here to claim: bit.ly/fake",
"label": "spam",
"confidence": 0.97,
"is_spam": true,
"hit": true
}
},
"usage": {
"api_requests_used": 8,
"api_requests_limit": 5000,
"api_requests_remaining": 4992
}
}
Какие поля возвращает результат проверки на спам?
| Поле | Тип | Значение |
|---|---|---|
text |
string | Текст, который был классифицирован |
label |
string | Классификация модели (например, spam, ham) |
confidence |
number | Уверенность модели в метке (0.0–1.0) |
is_spam |
bool | Сырой вердикт модели — label == spam, без учёта порога |
hit |
bool | Решение с учётом порога — is_spam И confidence ≥ порога спама вашего проекта |
is_spam и hit
is_spam — это сырой вердикт: модель пометила текст как спам независимо от своей уверенности. hit дополнительно требует, чтобы уверенность превышала настроенный в вашем проекте порог спама. Основывайте действия модерации на hit, а не на is_spam, чтобы метка спама с низкой уверенностью не приводила к наказанию за пограничное сообщение.
Как интерпретировать оценку уверенности?
confidence показывает, насколько модель уверена в своём label:
- 0.0 – 0.3: очень низкая — скорее всего, текст допустим.
- 0.3 – 0.5: низкая — пограничный случай.
- 0.5 – 0.7: средняя — подозрительно.
- 0.7 – 0.9: высокая — с большой вероятностью спам.
- 0.9 – 1.0: очень высокая — почти наверняка спам.
Рекомендуемые пороги
Настройте порог спама в проекте в соответствии с допустимым уровнем риска на вашей платформе:
const SPAM_THRESHOLDS = {
strict: 0.5, // professional platforms, financial services
standard: 0.7, // social media, forums
permissive: 0.85 // creative platforms, open communities
};
Сценарии использования
Разделы комментариев
async function moderateComment(comment) {
const result = await checkSpam(comment.text);
const spam = result.results.spamfinder;
if (spam.hit) {
if (spam.confidence > 0.9) {
return { action: 'reject', reason: 'spam_detected' };
}
return { action: 'review', reason: 'possible_spam' };
}
return { action: 'approve' };
}
Регистрация пользователей
def validate_registration(user_data):
bio = user_data.get('bio')
if bio:
result = check_spam(bio)
if result['results']['spamfinder']['hit']:
return {'approved': False, 'reason': 'Spam content detected in profile'}
return {'approved': True}
Платформы обмена сообщениями
async function filterMessage(message, sender) {
const result = await checkSpam(message.text);
const spam = result.results.spamfinder;
if (spam.hit) {
await incrementSpamCount(sender.id);
const spamCount = await getSpamCount(sender.id);
if (spamCount > 3) {
await banUser(sender.id, 'repeated_spam');
}
return { delivered: false, reason: 'Message filtered as spam' };
}
return { delivered: true };
}
Сочетание с другими проверками
Запускайте проверку на спам вместе с анализом тональности и определением языка в одном запросе:
{
"content": {
"text": "Check out this amazing deal! Click here: example.com/offer"
},
"settings": {
"check_spam": true,
"check_sentiment": true,
"check_language": true
}
}
В ответе будут одновременно доступны results.spamfinder, results.sentiment и results.language.
Рекомендации
Используйте градуированные реакции
Вместо бинарного решения блокировать/разрешить выбирайте действие в зависимости от уверенности:
function handleSpamResult(spam) {
if (!spam.hit) return 'allow';
if (spam.confidence > 0.95) return 'silent_delete';
if (spam.confidence > 0.8) return 'block_notify';
if (spam.confidence > 0.6) return 'flag_for_review';
return 'apply_friction';
}
Отслеживайте повторных нарушителей
async function assessUser(userId, spam) {
if (spam.hit) {
await incrementUserSpamScore(userId, spam.confidence);
}
const userScore = await getUserSpamScore(userId);
if (userScore > 10.0) await autoSuspendUser(userId);
else if (userScore > 5.0) await flagForManualReview(userId);
}
Добавляйте надёжных пользователей в белый список
Пропускайте проверку на спам для верифицированных аккаунтов или аккаунтов с высоким уровнем доверия, чтобы снизить число ложных срабатываний и экономить квоту:
function shouldCheckSpam(user) {
if (user.isVerified) return false;
if (user.trustScore > 0.9) return false;
return true;
}
Лимиты использования
Обнаружение спама расходует квоту анализа тональности:
| Тариф | Анализов в месяц | Примечания |
|---|---|---|
| Basic | 1,000 | Включает спам + тональность |
| Gold | 5,000 | Включает спам + тональность |
| Platinum | 15,000 | Включает спам + тональность |
| Ultimate | 30,000 | Включает спам + тональность |
Кэшированные ответы не расходуют вашу квоту.
Примеры интеграции
Middleware для Express.js
const spamFilter = async (req, res, next) => {
if (req.body.text) {
const result = await checkSpam(req.body.text);
if (result.results.spamfinder.hit) {
return res.status(400).json({
error: 'spam_detected',
message: 'Your message was flagged as spam'
});
}
}
next();
};
app.post('/api/comments', spamFilter, createComment);
Python Flask
from functools import wraps
from flask import request, jsonify
def spam_filter(f):
@wraps(f)
def decorated(*args, **kwargs):
text = request.json.get('text')
if text:
result = check_spam(text)
if result['results']['spamfinder']['hit']:
return jsonify({
'error': 'spam_detected',
'message': 'Your message was flagged as spam'
}), 400
return f(*args, **kwargs)
return decorated
@app.route('/api/comments', methods=['POST'])
@spam_filter
def create_comment():
pass
Следующие шаги
- Анализ текста - объедините спам с оценкой тональности
- Определение языка - определяйте язык контента и применяйте языковые правила
- Краткое руководство - получите свой первый API-ключ