mirror of
https://github.com/flibusta-apps/book_bot.git
synced 2025-12-06 15:35:35 +01:00
Add book rate
This commit is contained in:
@@ -23,3 +23,5 @@ export const ENABLE_LANG_PREFIX = 'lang_on_';
|
|||||||
export const DISABLE_LANG_PREFIX = 'lang_off_';
|
export const DISABLE_LANG_PREFIX = 'lang_off_';
|
||||||
|
|
||||||
export const UPDATE_LOG_PREFIX = 'update_log_';
|
export const UPDATE_LOG_PREFIX = 'update_log_';
|
||||||
|
|
||||||
|
export const RATE_PREFIX = 'r_';
|
||||||
|
|||||||
@@ -112,6 +112,11 @@ export function formatDetailBook(book: DetailBook): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function formatDetailBookWithRating(book: DetailBook): string {
|
||||||
|
return formatDetailBook(book) + '\n\n\nОценка:';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function formatBookShort(book: AllBookTypes): string {
|
export function formatBookShort(book: AllBookTypes): string {
|
||||||
return formatBook(book, true);
|
return formatBook(book, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ import * as Messages from "./messages";
|
|||||||
import * as CallbackData from "./callback_data";
|
import * as CallbackData from "./callback_data";
|
||||||
|
|
||||||
import * as BookLibrary from "./services/book_library";
|
import * as BookLibrary from "./services/book_library";
|
||||||
|
import * as Rating from "./services/book_ratings";
|
||||||
import UsersCounter from '@/analytics/users_counter';
|
import UsersCounter from '@/analytics/users_counter';
|
||||||
import { createOrUpdateUserSettings, getUserOrDefaultLangCodes } from './services/user_settings';
|
import { createOrUpdateUserSettings, getUserOrDefaultLangCodes } from './services/user_settings';
|
||||||
import { formatBook, formatBookShort, formatAuthor, formatSequence, formatTranslator, formatDetailBook } from './format';
|
import { formatBook, formatBookShort, formatAuthor, formatSequence, formatTranslator, formatDetailBook, formatDetailBookWithRating } from './format';
|
||||||
import { getCallbackArgs, getPaginatedMessage, getPrefixWithQueryCreator, getSearchArgs, registerLanguageSettingsCallback, registerPaginationCommand, registerRandomItemCallback } from './utils';
|
import { getCallbackArgs, getPaginatedMessage, getPrefixWithQueryCreator, getSearchArgs, registerLanguageSettingsCallback, registerPaginationCommand, registerRandomItemCallback } from './utils';
|
||||||
import { getRandomKeyboard, getTextPaginationData, getUpdateLogKeyboard, getUserAllowedLangsKeyboard } from './keyboard';
|
import { getRandomKeyboard, getRatingKeyboard, getTextPaginationData, getUpdateLogKeyboard, getUserAllowedLangsKeyboard } from './keyboard';
|
||||||
import { sendFile } from './hooks/downloading';
|
import { sendFile } from './hooks/downloading';
|
||||||
import { setCommands } from './hooks/setCommands';
|
import { setCommands } from './hooks/setCommands';
|
||||||
import { isNotModifiedMessage, isReplyMessageNotFound } from './errors_utils';
|
import { isNotModifiedMessage, isReplyMessageNotFound } from './errors_utils';
|
||||||
@@ -316,15 +317,38 @@ export async function createApprovedBot(token: string, state: BotState): Promise
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bookId = ctx.message.text.split("@")[0].split('_')[2];
|
const bookIdString = ctx.message.text.split("@")[0].split('_')[2];
|
||||||
|
const bookId = parseInt(bookIdString);
|
||||||
|
|
||||||
const book = await BookLibrary.getBookById(parseInt(bookId));
|
const book = await BookLibrary.getBookById(bookId);
|
||||||
|
const keyboard = await getRatingKeyboard(ctx.message.from.id, bookId, null);
|
||||||
|
|
||||||
await ctx.reply(formatDetailBook(book), {
|
await ctx.reply(formatDetailBookWithRating(book), {
|
||||||
reply_to_message_id: ctx.message.message_id,
|
reply_to_message_id: ctx.message.message_id,
|
||||||
|
reply_markup: keyboard.reply_markup,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bot.action(new RegExp(CallbackData.RATE_PREFIX), async (ctx: Context) => {
|
||||||
|
if (!ctx.callbackQuery || !('data' in ctx.callbackQuery)) return;
|
||||||
|
|
||||||
|
const queryData = ctx.callbackQuery.data.split("_");
|
||||||
|
|
||||||
|
const userId = parseInt(queryData[1]);
|
||||||
|
const bookId = parseInt(queryData[2]);
|
||||||
|
const rate = parseInt(queryData[3]);
|
||||||
|
|
||||||
|
const rating = await Rating.set(userId, bookId, rate);
|
||||||
|
|
||||||
|
const keyboard = await getRatingKeyboard(userId, bookId, rating);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ctx.editMessageReplyMarkup(
|
||||||
|
keyboard.reply_markup
|
||||||
|
);
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
|
||||||
bot.on("message", async (ctx: Context) => {
|
bot.on("message", async (ctx: Context) => {
|
||||||
if (!ctx.message || !('text' in ctx.message)) {
|
if (!ctx.message || !('text' in ctx.message)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import { InlineKeyboardMarkup } from 'typegram';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import chunkText from 'chunk-text';
|
import chunkText from 'chunk-text';
|
||||||
|
|
||||||
import { RANDOM_BOOK, RANDOM_AUTHOR, RANDOM_SEQUENCE, ENABLE_LANG_PREFIX, DISABLE_LANG_PREFIX, UPDATE_LOG_PREFIX } from './callback_data';
|
import { RANDOM_BOOK, RANDOM_AUTHOR, RANDOM_SEQUENCE, ENABLE_LANG_PREFIX, DISABLE_LANG_PREFIX, UPDATE_LOG_PREFIX, RATE_PREFIX } from './callback_data';
|
||||||
import { getLanguages, getUserOrDefaultLangCodes } from './services/user_settings';
|
import { getLanguages, getUserOrDefaultLangCodes } from './services/user_settings';
|
||||||
|
import * as BookRating from "./services/book_ratings";
|
||||||
|
|
||||||
|
|
||||||
function getButtonLabel(delta: number, direction: 'left' | 'right'): string {
|
function getButtonLabel(delta: number, direction: 'left' | 'right'): string {
|
||||||
@@ -117,3 +118,17 @@ export async function getUserAllowedLangsKeyboard(userId: number): Promise<Marku
|
|||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getRatingKeyboard(userId: number, bookId: number, rating: BookRating.Rating | null): Promise<Markup.Markup<InlineKeyboardMarkup>> {
|
||||||
|
const bookRating = rating ? rating : await BookRating.get(userId, bookId);
|
||||||
|
|
||||||
|
const rate = bookRating ? bookRating.rate : null;
|
||||||
|
|
||||||
|
return Markup.inlineKeyboard([
|
||||||
|
[1, 2, 3, 4, 5].map((bRate) => {
|
||||||
|
const title = bRate === rate ? `⭐️ ${bRate}` : bRate.toString();
|
||||||
|
|
||||||
|
return Markup.button.callback(title, `${RATE_PREFIX}${userId}_${bookId}_${bRate}`);
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|||||||
46
src/bots/factory/bots/approved/services/book_ratings.ts
Normal file
46
src/bots/factory/bots/approved/services/book_ratings.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import got from 'got';
|
||||||
|
|
||||||
|
import env from '@/config';
|
||||||
|
|
||||||
|
|
||||||
|
export interface Rating {
|
||||||
|
id: number;
|
||||||
|
user_id: number;
|
||||||
|
book_id: number;
|
||||||
|
rate: number;
|
||||||
|
updated: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function get(userId: number, bookId: number): Promise<Rating | null> {
|
||||||
|
try {
|
||||||
|
const response = await got<Rating>(`${env.RATINGS_URL}/api/v1/ratings/${userId}/${bookId}`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': env.RATINGS_API_KEY,
|
||||||
|
},
|
||||||
|
responseType: 'json',
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.body;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function set(userId: number, bookId: number, rate: number): Promise<Rating> {
|
||||||
|
const response = await got.post<Rating>(`${env.RATINGS_URL}/api/v1/ratings`, {
|
||||||
|
json: {
|
||||||
|
"user_id": userId,
|
||||||
|
"book_id": bookId,
|
||||||
|
"rate": rate,
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
'Authorization': env.RATINGS_API_KEY,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
responseType: 'json'
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.body;
|
||||||
|
}
|
||||||
@@ -3,22 +3,35 @@ import { cleanEnv, str, num } from 'envalid';
|
|||||||
|
|
||||||
export default cleanEnv(process.env, {
|
export default cleanEnv(process.env, {
|
||||||
SENTRY_DSN: str(),
|
SENTRY_DSN: str(),
|
||||||
|
|
||||||
WEBHOOK_BASE_URL: str(),
|
WEBHOOK_BASE_URL: str(),
|
||||||
WEBHOOK_PORT: num(),
|
WEBHOOK_PORT: num(),
|
||||||
|
|
||||||
TELEGRAM_BOT_API_ROOT: str({ default: "https://api.telegram.org" }),
|
TELEGRAM_BOT_API_ROOT: str({ default: "https://api.telegram.org" }),
|
||||||
|
|
||||||
MANAGER_URL: str(),
|
MANAGER_URL: str(),
|
||||||
MANAGER_API_KEY: str(),
|
MANAGER_API_KEY: str(),
|
||||||
|
|
||||||
BOOK_SERVER_URL: str(),
|
BOOK_SERVER_URL: str(),
|
||||||
BOOK_SERVER_API_KEY: str(),
|
BOOK_SERVER_API_KEY: str(),
|
||||||
|
|
||||||
CACHE_SERVER_URL: str(),
|
CACHE_SERVER_URL: str(),
|
||||||
CACHE_SERVER_API_KEY: str(),
|
CACHE_SERVER_API_KEY: str(),
|
||||||
|
|
||||||
BUFFER_SERVER_URL: str(),
|
BUFFER_SERVER_URL: str(),
|
||||||
BUFFER_SERVER_API_KEY: str(),
|
BUFFER_SERVER_API_KEY: str(),
|
||||||
|
|
||||||
DOWNLOADER_URL: str(),
|
DOWNLOADER_URL: str(),
|
||||||
DOWNLOADER_API_KEY: str(),
|
DOWNLOADER_API_KEY: str(),
|
||||||
|
|
||||||
USER_SETTINGS_URL: str(),
|
USER_SETTINGS_URL: str(),
|
||||||
USER_SETTINGS_API_KEY: str(),
|
USER_SETTINGS_API_KEY: str(),
|
||||||
|
|
||||||
|
RATINGS_URL: str(),
|
||||||
|
RATINGS_API_KEY: str(),
|
||||||
|
|
||||||
NETWORK_IP_PREFIX: str(),
|
NETWORK_IP_PREFIX: str(),
|
||||||
|
|
||||||
REDIS_HOST: str(),
|
REDIS_HOST: str(),
|
||||||
REDIS_PORT: num(),
|
REDIS_PORT: num(),
|
||||||
REDIS_DB: num(),
|
REDIS_DB: num(),
|
||||||
|
|||||||
Reference in New Issue
Block a user