Skip to content

Commit

Permalink
ссылки на отказников публикуются в телеге для их публичного обоссывания
Browse files Browse the repository at this point in the history
  • Loading branch information
s3rgeym committed Nov 19, 2024
1 parent 496e00d commit 19cc381
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 21 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

### Описание

Утилита для успешных волчат, служащая для автоматизации действий на HH.RU таких как рассылка откликов на подходящие вакансии и обновление всех резюме. Так же утилита возвращает ссылку на обсуждение работодателя в группе [Отзывы о работодателях с HH.RU](https://t.me/otzyvy_headhunter), создавая ее при необходимости. Это делается анонимно. Для этого собираются данные о работодателях и их вакансиях. Никакие персональные данные пользователя под которыми, вы авторизуетесь никуда не отправляются — только работовладельцев и их овчарок. Отправку этих данных можно отключить, но тогда вы не получите ссылку на обсуждение, а так же не сможете пожаловаться на неадекватного мудака, выкатившего отказ после "небольшого" тестового задания на недельку. Через сайты на таких жаловаться бесполезно: владелец сайта за деньги отзывы удаляет, или работовладелец его запугает и жалоб в РКН накидает, а последний всегда найдет за что сайт заблокировать. Единственное место где можно написать отзыв — это **Telegram**.
Утилита для успешных волчат, служащая для автоматизации действий на HH.RU таких как рассылка откликов на подходящие вакансии и обновление всех резюме. Но данная утилита больше чем просто спамилка отзывами, вы так же выступаете в роли тайного агента, и если в списке подходящих вакансий встречается отказ, она возвращает ссылку на обсуждение работодателя в группе [Отзывы о работодателях с HH.RU](https://t.me/otzyvy_headhunter). Там вы можете написать отзыв о работодателе и почитать чужие. Обсуждения без отзывов удаляются. Данные на сервер передаются анонимно. Для этого собираются данные о работодателях и их вакансиях. Никакие персональные данные пользователя утилиты под которыми, вы авторизуетесь никуда не отправляются — только работодателей и рекрутеров. Отправку этих данных можно отключить (флаг `--disable-telemetry`), но тогда вы не получите ссылку на обсуждение, а так же не сможете пожаловаться на неадекватного мудака, выкатившего отказ после "небольшого" тестового задания на недельку. Через сайты на таких жаловаться бесполезно: владелец сайта за деньги отзывы удаляет, или мудак его запугает и жалоб в РКН накидает, а последний всегда найдет за что сайт заблокировать. Единственное место где можно написать отзыв — это **Telegram**.

Работает с Python >= 3.10. Нужную версию Python можно поставить через
asdf/pyenv/conda и что-то еще.
Expand Down Expand Up @@ -225,7 +225,7 @@ https://hh.ru/employer/1918903
| **clear-negotiations** | Удаляет отказы и отменяет заявки, которые долго висят |
| **call-api** | Вызов произвольного метода API с выводом результата. |
| **refresh-token** | Обновляет access_token. |
| **get-employer-contacts** | Получить список контактов работодателя, даже если тот не высылал приглашения. Это премиальный функционал. Бот-пробивщик с аналогичным функционалом есть в группе. |
| **get-employer-contacts** | Получить список контактов работодателя, даже если тот не высылал приглашения. Это функционал для избранных, но в группе есть бесплатный бот с тем же функционалом. |

### Формат текста сообщений

Expand Down
28 changes: 17 additions & 11 deletions hh_applicant_tool/operations/apply_similar.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import random
import time
from collections import defaultdict
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import TextIO, Tuple

from ..api import ApiError, BadRequest
Expand Down Expand Up @@ -216,7 +216,7 @@ def _apply_similar(self) -> None:
not relations
or parse_invalid_datetime(vacancy["created_at"])
+ timedelta(days=7)
> datetime.now()
> datetime.now(tz=timezone.utc)
)
):
employer = self.api.get(f"/employers/{employer_id}")
Expand All @@ -228,23 +228,29 @@ def _apply_similar(self) -> None:
"site_url": employer.get("site_url"),
"area": employer.get("area", {}).get("name"), # город
}
if "got_rejected" in relations:
if "got_rejection" in relations:
try:
print(
"🚨 Вы получили отказ от https://hh.ru/employer/%s"
% employer_id
)
response = telemetry_client.send_telemetry(
f"/employers/{employer_id}/complaint",
employer_data,
)
print(
f"🚨 Вы получили отказ от {employer.get('name', 'какого-то ноунейма')}."
)
print(
"Ссылка для отзыва:",
response["topic_url"],
)
if "topic_url" in response:
print(
"Ссылка на обсуждение работодателя:",
response["topic_url"],
)
else:
print(
"Создание темы для обсуждения работодателя добавлено в очередь..."
)
complained_employers.add(employer_id)
except TelemetryError as ex:
logger.error(ex)
else:
elif do_apply:
telemetry_data["employers"][employer_id] = employer_data

if not do_apply:
Expand Down
34 changes: 26 additions & 8 deletions hh_applicant_tool/telemetry_client.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import os
import json
from urllib.parse import urljoin
import requests
from typing import Optional, Dict, Any
import logging
from functools import partialmethod
import os
import time
import warnings
from functools import partialmethod
from typing import Any, Dict, Optional
from urllib.parse import urljoin

import requests

warnings.filterwarnings('ignore', message='Unverified HTTPS request')
warnings.filterwarnings("ignore", message="Unverified HTTPS request")

logger = logging.getLogger(__package__)

Expand All @@ -22,6 +24,7 @@ class TelemetryClient:
"""Клиент для отправки телеметрии на сервер."""

server_address: str = "https://hh-applicant-tool.mooo.com:54157/"
default_delay: float = 0.334 # Задержка по умолчанию в секундах

def __init__(
self,
Expand All @@ -30,24 +33,36 @@ def __init__(
session: Optional[requests.Session] = None,
user_agent: str = "Mozilla/5.0 (HHApplicantTelemetry/1.0)",
proxies: dict | None = None,
delay: Optional[float] = None,
) -> None:
self.server_address = os.getenv(
"TELEMETRY_SERVER", server_address or self.server_address
)
self.session = session or requests.Session()
self.user_agent = user_agent
self.proxies = proxies
self.delay = delay if delay is not None else self.default_delay
self.last_request_time = time.monotonic() # Время последнего запроса

def request(
self,
method: str,
endpoint: str,
data: Dict[str, Any] | None = None,
**kwargs: Any
**kwargs: Any,
) -> Dict[str, Any]:
method = method.upper()
url = urljoin(self.server_address, endpoint)
has_body = method in ["POST", "PUT", "PATCH"]

# Вычисляем время, прошедшее с последнего запроса
current_time = time.monotonic()
time_since_last_request = current_time - self.last_request_time

# Если прошло меньше времени, чем задержка, ждем оставшееся время
if time_since_last_request < self.delay:
time.sleep(self.delay - time_since_last_request)

try:
response = self.session.request(
method,
Expand All @@ -58,7 +73,7 @@ def request(
json=data if has_body else None,
verify=False, # Игнорирование истекшего сертификата
**kwargs,
)
)
# response.raise_for_status()
result = response.json()
if "error" in result:
Expand All @@ -70,6 +85,9 @@ def request(
json.JSONDecodeError,
) as ex:
raise TelemetryError(str(ex)) from ex
finally:
# Обновляем время последнего запроса
self.last_request_time = time.monotonic()

get_telemetry = partialmethod(request, "GET")
send_telemetry = partialmethod(request, "POST")

0 comments on commit 19cc381

Please sign in to comment.