D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Всех приветствую, это моя четвертая статья, и возможно она с слишком кликабельным названием, но все же свою функцию оно выполняет -> расширение предупреждает пользователя в диалоге о том, что на собеседника есть открытая жалоба.
Это мой первый опыт в написании расширений, ранее я никогда этим не занимался и до сих пор не совсем обладаю опытом и нужными знаниями, эта статья нацелена для таких же как и я новичков в сфере написания браузерных расширений.
ДИСКЛЕЙМЕР: укажу все недоработки в шапке, чтобы ниже не оставалось ни у кого вопросов.
КАК РАСШИРЕНИЕ ВЫГЛЯДИТ НА ДАННЫЙ МОМЕНТ (момент написания статьи, 29.12.2024 14:18 МСК)
ЕСЛИ НА СОБЕСЕДНИКА ЕСТЬ НАПИСАННЫЕ ЖАЛОБЫ:
Спойлер: скриншот
ЕСЛИ НА СОБЕСЕДНИКА НЕТ НАПИСАННЫХ ЖАЛОБ:
Спойлер: скриншот
Приступим к написанию самого расширения.
Наверное каждый сталкивался с ситуацией, когда связывался с каким-нибудь человеком на форуме, а оказывается, на него был написан блек. Вы этого не посмотрели, либо при просмотре ветки с жалобами не заметили, и попались на недобросовестного пользователя. Это расширение поможет с этим и теперь не придется мониторить раздел с жалобами самостоятельно. Если на пользователя есть открытые жалобы - расширение нам скажет об этом. Писать наше расширение мы будем на JavaScript без использования дополнительных фреймворков.
Структура проекта:
JSON: Скопировать в буфер обмена
JavaScript: Скопировать в буфер обмена
Функция isConversationPage()
JavaScript: Скопировать в буфер обмена
JavaScript: Скопировать в буфер обмена
JavaScript: Скопировать в буфер обмена
JavaScript: Скопировать в буфер обмена
JavaScript: Скопировать в буфер обмена
CSS: Скопировать в буфер обмена
этот HTML-код создает простой интерфейс для попапа, который открывается при нажатии на иконку расширения.
HTML: Скопировать в буфер обмена
Установка расширения:
Заключение:
Как я ранее сказал, то это мой первый опыт в написании расширений, и как мне кажется, получилось довольно неплохо. Если эта статья вызовет интерес у читателей, то я с великим удовольствием буду ждать фидбека о том, что можно улучшить и доработать, а так же решение моей проблемы с невозможностью исправить поиск закрытых жалоб и их отображения в баннере (чтобы закрытые блеки не отображались в ЛС). На данный момент я параллельно работаю над еще одним расширениям по заметкам для пользователей, но на данный момент оно дается сложней к написанию, чем этот проект. Всем читателям заранее большое спасибо, надеюсь, эта статья была для вас интересна.
Авторство: AGN
Специально для форума https://xss.is/
Это мой первый опыт в написании расширений, ранее я никогда этим не занимался и до сих пор не совсем обладаю опытом и нужными знаниями, эта статья нацелена для таких же как и я новичков в сфере написания браузерных расширений.
ДИСКЛЕЙМЕР: укажу все недоработки в шапке, чтобы ниже не оставалось ни у кого вопросов.
- пароль к архиву с расширением ниже: xss.is
- я не реализовал поиск уже закрытых жалоб, чтобы они не показывались в диалоге (я не понял как это правильно сделать, мои методы с поиском классов structItem-status или blockStatus-messag не сработали) ;
- я не реализовал поддержку английского языка ;
- я не совсем уверен, что эта версия расширения работает именно так, как нужно. выкладываю эту статью и эту версию с целью собрать фидбэк и доработать это расширение до идеального состояния, ибо моего опыта и знаний не хватило для этого. пожалуйста, не кидайтесь камнями.
- я не реализовал поддержку темной темы.
- реализовать поиск уже закрытых жалоб, чтобы они не показывались в диалоге как активный блек ;
- добавить поддержку английского языка (корректная работа на английской раскладке форума) ;
- сделать предупреждение более "ярким", чтобы оно попадало сразу в глаза. возможен перенос этого блока ;
- найти и исправить все (или максимально возможное количество) баги, которые присутствуют в этой версии расширения ;
- адаптировать расширение к темной теме форума ;
КАК РАСШИРЕНИЕ ВЫГЛЯДИТ НА ДАННЫЙ МОМЕНТ (момент написания статьи, 29.12.2024 14:18 МСК)
ЕСЛИ НА СОБЕСЕДНИКА ЕСТЬ НАПИСАННЫЕ ЖАЛОБЫ:
Спойлер: скриншот

ЕСЛИ НА СОБЕСЕДНИКА НЕТ НАПИСАННЫХ ЖАЛОБ:
Спойлер: скриншот

Приступим к написанию самого расширения.
Наверное каждый сталкивался с ситуацией, когда связывался с каким-нибудь человеком на форуме, а оказывается, на него был написан блек. Вы этого не посмотрели, либо при просмотре ветки с жалобами не заметили, и попались на недобросовестного пользователя. Это расширение поможет с этим и теперь не придется мониторить раздел с жалобами самостоятельно. Если на пользователя есть открытые жалобы - расширение нам скажет об этом. Писать наше расширение мы будем на JavaScript без использования дополнительных фреймворков.
Структура проекта:

- images: папка с логотипами для расширения.
- background.js: скрипт для оповещения в консоли разработчика о том, что расширение корректно установлено.
- contents.js: основная логика расширения.
- popup.html: скрипт для функций при нажатии на иконку расширения в браузере
- styles.css: стили расширения.
JSON: Скопировать в буфер обмена
Код:
{
"manifest_version": 3,
"name": "ScammersController",
"version": "0.1",
"description": "Расширение помогает наблюдать за скамерами. Написал AGN, специально для XSS.is.",
"permissions": [
"activeTab"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["https://xss.is/conversations/*"],
"js": ["content.js"]
}
],
"icons": {
"16": "images/icon16.png",
"48": "images/icon48.png",
"128": "images/icon128.png"
}
}
- manifest_version: указывает на использование версии.
- name: название расширения.
- version: версия расширения.
- description: описание расширения.
- permissions: разрешение activeTab позволяет расширению взаимодействовать с текущей активной вкладкой браузера.
- background: ссылка на фоновый скрипт, который использует сервис (background.js).
- content_scripts: указывает, что скрипт content.js будет выполняться на страницах форума, где URL включает /conversations/ (иными словами - в диалогах пользователей)
- icons: путь к иконкам расширения для разных размеров.
JavaScript: Скопировать в буфер обмена
Код:
chrome.runtime.onInstalled.addListener(() => {
console.log("Extension installed!");
});
- скрипт выполняется при установке или обновлении расширения. когда расширение устанавливается, срабатывает событие onInstalled, и выводится сообщение в консоль браузера о том, что расширение установлено.
Функция isConversationPage()
JavaScript: Скопировать в буфер обмена
Код:
function isConversationPage() {
return window.location.href.includes('conversations');
}
- эта функция проверяет, находимся ли мы на странице личных сообщений (переписки) на форуме..
для этого она использует свойство window.location.href, которое содержит текущий URL страницы, и проверяет, включает ли этот URL подстроку conversations. если подстрока присутствует, то функция возвращает true, что означает, что мы на странице переписки.
JavaScript: Скопировать в буфер обмена
Код:
function getOtherUsernameFromConversation() {
const participantElements = document.querySelectorAll('.block-body .contentRow-main .username');
if (participantElements.length > 1) {
const otherUsername = participantElements[1].innerText.trim();
console.log('Other Username:', otherUsername);
return otherUsername;
}
console.log('No other username found!');
return null;
}
- функция извлекает имя собеседника из страницы личного сообщения.
- сначала она находит все элементы с классом .username в блоке переписки. эти элементы содержат имена участников.
- если на странице больше одного участника (должен быть второй элемент в списке участников), функция возвращает имя второго участника (собеседника).
- если собеседник не найден (например, мы не находим второго пользователя), выводится сообщение об ошибке, и возвращается null.
JavaScript: Скопировать в буфер обмена
Код:
async function fetchComplaints(username) {
const complaints = [];
const response = await fetch("https://xss.is/forums/82/");
const pageText = await response.text();
console.log('Page Text:', pageText.substring(0, 1000));
const regex = new RegExp(`<a href="\\/threads\\/([0-9]+)\\/.*?">${username}.*?<\/a>`, "g");
let match;
while ((match = regex.exec(pageText)) !== null) {
const threadId = match[1];
const url = `https://xss.is/threads/${threadId}/`;
const hasLockIcon = pageText.includes(`<a href="/threads/${threadId}/">`) && pageText.includes('<i class="structItem-status structItem-status--locked" aria-hidden="true" title="Закрыто"></i>');
const hasClosedMessage = pageText.includes(`<a href="/threads/${threadId}/"`) && pageText.includes('Закрыто для дальнейших ответов');
if (hasLockIcon || hasClosedMessage) {
console.log(`Тема с ID ${threadId} закрыта, пропускаем...`);
continue;
}
const title = match[2] || "Ссылка на блек";
complaints.push({ url, title });
}
console.log('Complaints:', complaints);
return complaints;
}
- эта функция собирает жалобы на пользователя на форуме с помощью запросов.
- сначала она запрашивает страницу форума с помощью fetch(), получает текст страницы и извлекает из нее все упоминания заданного пользователя.
- для извлечения жалоб используется регулярное выражение, которое находит все ссылки, содержащие имя пользователя. регулярное выражение ищет темы форума, где упоминается имя пользователя.
- далее проверяется, не закрыта ли тема (с помощью наличия иконки замка или сообщения о закрытой теме). если тема закрыта, она пропускается (почему-то этот метод не срабатывает)
- в список жалоб добавляется URL темы и ее заголовок.
- функция возвращает массив объектов с жалобами, содержащими ссылку и заголовок темы.
JavaScript: Скопировать в буфер обмена
Код:
function createComplaintWarning(complaints) {
if (complaints.length === 0) return;
const warningBlock = document.createElement('div');
warningBlock.className = 'block';
const warningContent = `
<div class="block-container">
<h3 class="block-minorHeader" style="font-size: 16px; font-weight: bold; color: #34495E;">ВНИМАНИЕ! НА ПОЛЬЗОВАТЕЛЯ ОТКРЫТ БЛЕК!</h3>
<div class="block-body block-row block-row--minor">
<p>На пользователя, с кем вы ведете диалог, открыт блек:</p>
<ul class="block-body">
${complaints.map(complaint => `
<li class="block-row" style="padding: 5px 0;">
<a href="${complaint.url}" class="username" style="color: #34495E; text-decoration: none;" target="_blank">${complaint.title}</a>
</li>
`).join('')}
</ul>
</div>
</div>
`;
warningBlock.innerHTML = warningContent;
const sidebar = document.querySelector('.p-body-sidebar');
if (sidebar) {
sidebar.appendChild(warningBlock);
}
}
- эта функция создает и отображает предупреждение о том, что на пользователя, с которым ведется переписка, есть жалобы на форуме. если список жалоб пуст, то функция ничего не делает.
- если жалобы есть, она создает новый HTML-блок, который содержит заголовок и список жалоб, каждую из которых представляет собой ссылку на тему форума. этот блок вставляется в боковую панель страницы личного сообщения (элемент .p-body-sidebar), чтобы пользователь мог увидеть предупреждение.
JavaScript: Скопировать в буфер обмена
Код:
if (isConversationPage()) {
const otherUsername = getOtherUsernameFromConversation();
if (otherUsername) {
fetchComplaints(otherUsername).then(complaints => {
if (complaints.length > 0) {
createComplaintWarning(complaints);
} else {
console.log('Нет открытых жалоб на этого пользователя.');
}
}).catch((error) => {
console.error('Ошибка при получении жалоб:', error);
});
}
}
- этот фрагмент кода выполняется, если мы находимся на странице личного сообщения (проверка через isConversationPage()).
- извлекается имя собеседника через getOtherUsernameFromConversation().
- если имя собеседника найдено, выполняется запрос к форуму через fetchComplaints() для получения жалоб.
- если жалобы найдены, вызывается функция createComplaintWarning() для отображения предупреждения.
- в случае ошибки при запросе жалоб выводится сообщение об ошибке в консоль.
CSS: Скопировать в буфер обмена
Код:
.block {
background-color: #fff3cd;
border: 1px solid #ffeeba;
padding: 10px;
margin-top: 20px;
border-radius: 5px;
}
.block-container {
padding: 15px;
}
.block-minorHeader {
font-size: 18px;
font-weight: bold;
color: #856404;
}
.block-body {
padding: 15px;
}
.block-row {
padding: 5px 0;
}
.username {
color: #007aff;
text-decoration: none;
}
.username:hover {
text-decoration: underline;
}
- .block — отвечает за внешний вид контейнера с предупреждением, включая фон, границу, отступы.
- .block-minorHeader — стили для заголовка предупреждения.
- .block-body — стили для основного содержимого блока.
- .username — стили для ссылок на темы жалоб.
этот HTML-код создает простой интерфейс для попапа, который открывается при нажатии на иконку расширения.
HTML: Скопировать в буфер обмена
Код:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Forum Complaints Notifier</title>
<style>
body {
font-family: Arial, sans-serif;
padding: 10px;
max-width: 200px;
}
button {
padding: 10px;
font-size: 14px;
background-color: #007aff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #005bb5;
}
</style>
</head>
<body>
<h3>Forum Complaints Notifier</h3>
<button id="toggleNotifications">Toggle Notifications</button>
<script>
document.getElementById('toggleNotifications').addEventListener('click', () => {
alert("This feature will be implemented soon.");
});
</script>
</body>
</html>
Установка расширения:
- Пишем расширение сами основываясь на эту статью либо скачиваем уже готовый проект ниже.
- Переходим по ссылке chrome://extensions/ в вашем браузере и включаем режим разработчика.
Спойлер: скриншот
- Нажимаем на кнопку "Загрузить распакованное расширение"
Спойлер: скриншот
- Выбираем папку с нашим расширением и загружаем ее.
- Обновляем страницу с форумом и проверяем, работает ли расширение. Для этого достаточно перейти в диалог с пользователем, на которого есть открытая жалоба.
Заключение:
Как я ранее сказал, то это мой первый опыт в написании расширений, и как мне кажется, получилось довольно неплохо. Если эта статья вызовет интерес у читателей, то я с великим удовольствием буду ждать фидбека о том, что можно улучшить и доработать, а так же решение моей проблемы с невозможностью исправить поиск закрытых жалоб и их отображения в баннере (чтобы закрытые блеки не отображались в ЛС). На данный момент я параллельно работаю над еще одним расширениям по заметкам для пользователей, но на данный момент оно дается сложней к написанию, чем этот проект. Всем читателям заранее большое спасибо, надеюсь, эта статья была для вас интересна.
Авторство: AGN
Специально для форума https://xss.is/