Created
December 30, 2025 11:12
-
-
Save hokage-shuriken/c9ce0669b3d09fa7d9873b3e2c60b780 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const BASE_URL = 'https://memealerts.com/api'; | |
| class MemeAlertsClient { | |
| /** | |
| * @param {string} token - Bearer JWT токен | |
| */ | |
| constructor(token) { | |
| if (!token) { | |
| throw new Error('Token is required'); | |
| } | |
| this.token = token; | |
| } | |
| /** | |
| * @private | |
| */ | |
| async _request(endpoint, body) { | |
| const response = await fetch(`${BASE_URL}${endpoint}`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${this.token}`, | |
| }, | |
| body: JSON.stringify(body), | |
| }); | |
| const data = await response.json().catch(() => null); | |
| if (!response.ok) { | |
| const message = data?.message || data?.error || `HTTP ${response.status}`; | |
| throw new Error(message); | |
| } | |
| return data; | |
| } | |
| /** | |
| * Получить список саппортеров с пагинацией | |
| * @param {object} options | |
| * @param {number} [options.limit=20] - количество на страницу | |
| * @param {number} [options.skip=0] - сколько пропустить | |
| * @param {string} [options.query=''] - поисковый запрос | |
| * @returns {Promise<{data: object[], total: number}>} | |
| */ | |
| async getSupporters({ limit = 20, skip = 0, query = '' } = {}) { | |
| return this._request('/supporters', { | |
| limit, | |
| skip, | |
| query, | |
| filters: [], | |
| }); | |
| } | |
| /** | |
| * Найти саппортера по имени (точное или частичное совпадение) | |
| * @param {string} username - имя для поиска | |
| * @param {object} options | |
| * @param {boolean} [options.exact=true] - точное совпадение имени | |
| * @returns {Promise<object|null>} - саппортер или null | |
| */ | |
| async findSupporter(username, { exact = true } = {}) { | |
| const normalizedSearch = username.toLowerCase(); | |
| let skip = 0; | |
| const limit = 50; | |
| while (true) { | |
| const { data, total } = await this.getSupporters({ limit, skip, query: username }); | |
| for (const supporter of data) { | |
| const name = supporter.supporterName?.toLowerCase(); | |
| if (exact) { | |
| if (name === normalizedSearch) return supporter; | |
| } else { | |
| if (name?.includes(normalizedSearch)) return supporter; | |
| } | |
| } | |
| skip += limit; | |
| if (skip >= total || data.length === 0) { | |
| return null; | |
| } | |
| } | |
| } | |
| /** | |
| * Начислить мемкоины пользователю | |
| * @param {string} userId - ID получателя | |
| * @param {string} streamerId - ID стримера (владельца канала) | |
| * @param {number} value - количество мемкоинов | |
| * @returns {Promise<object>} | |
| */ | |
| async giveBonus(userId, streamerId, value) { | |
| if (!userId) throw new Error('userId is required'); | |
| if (!streamerId) throw new Error('streamerId is required'); | |
| if (typeof value !== 'number' || value <= 0) { | |
| throw new Error('value must be a positive number'); | |
| } | |
| return this._request('/user/give-bonus', { | |
| userId, | |
| streamerId, | |
| value, | |
| }); | |
| } | |
| } | |
| module.exports = { MemeAlertsClient }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment