diff --git a/app/bot/features/welcome.feature.ts b/app/bot/features/welcome.feature.ts
index 5e00ee7..fca12f7 100644
--- a/app/bot/features/welcome.feature.ts
+++ b/app/bot/features/welcome.feature.ts
@@ -11,6 +11,8 @@ const feature = composer.chatType("private");
feature.command("start", async (ctx: Context) => {
const chatId = ctx.chat.id;
try {
+ await sequelize.authenticate();
+ await sequelize.sync();
await UserModel.create({chatId})
}
catch (err) {
diff --git a/app/bot/keyboards/marketsMenu.keyboard.ts b/app/bot/keyboards/marketsMenu.keyboard.ts
index 00cf8c6..03313e2 100644
--- a/app/bot/keyboards/marketsMenu.keyboard.ts
+++ b/app/bot/keyboards/marketsMenu.keyboard.ts
@@ -1,43 +1,47 @@
import { Menu } from "https://deno.land/x/grammy_menu@v1.1.2/mod.ts";
import { Context } from "../types/index.ts";
-import { cancel,subscriptionMenu,BeginParse } from "../keyboards/index.ts";
+import { cancel, subscriptionMenu, BeginParse } from "../keyboards/index.ts";
+import { UserModel } from "../../server/models.ts";
+export const marketsMenu = new Menu("marketsMenu").text(
+ "🇨🇿 sbazar.cz",
-export const marketsMenu = new Menu("marketsMenu")
- .text(
- "🇨🇿 sbazar.cz",
-
- async (ctx: Context) => {
- const countMaxAds = ctx.session?.countMaxAds;
- const registrationDate = ctx.session?.registrationDate;
- const publishDate = ctx.session?.publishDate;
- const urls = ctx.session?.urls;
- if (ctx.session.subActive ===false){
- ctx.session.sbazarStep = 'sub'
- await ctx.reply('Подписка не активна',{reply_markup:subscriptionMenu});
- return;
- };
-
+ async (ctx: Context) => {
+ const chatId = ctx.chat.id.toString();
+ const user = await UserModel.findOne({ where: { chatId: chatId } });
+ const countMaxAds = ctx.session?.countMaxAds;
+ const registrationDate = ctx.session?.registrationDate;
+ const publishDate = ctx.session?.publishDate;
+ const urls = ctx.session?.urls;
+ if (
+ (user.subEndDateTime = 0 || user.subEndDateTime < Math.floor(Date.now() / 1000))
+ ) {
+ ctx.session.sbazarStep = "sub";
+ await ctx.reply("Подписка не активна", {
+ reply_markup: subscriptionMenu,
+ });
+ return;
+ }
- if (
- countMaxAds !== undefined &&
- registrationDate !== undefined &&
- publishDate !== undefined&& urls !== undefined
- ) {
- await ctx.reply(
- `*🔎 Фильтры:*\n\n\n📃Количество объявлений: ${ctx.session.countMaxAds}\n📅 Дата регистрации: ${ctx.session.registrationDate}\n🕜 Дата публикации: ${ctx.session.publishDate}\nКатегории : ${ctx.session.urls}`,
- { reply_markup: BeginParse }
- );
- ctx.session.sbazarStep = "startingSbazar";
- } else {
- ctx.session.sbazarStep = "countMaxAds";
- await ctx.reply(
- "*🔎 Запуск поиска объявлений*\n\n📃 *Введите максимально допустимое количество активных объявлений у продавца*\n\n Пример : 10",
- { reply_markup: cancel}
- );
- await ctx.reply({reply_markup: marketsMenu})
- ctx.session.sbazarStep = "countMaxAds";
- }
-
+ if (
+ countMaxAds !== undefined &&
+ registrationDate !== undefined &&
+ publishDate !== undefined &&
+ urls !== undefined
+ ) {
+ await ctx.reply(
+ `*🔎 Фильтры:*\n\n\n📃Количество объявлений: ${ctx.session.countMaxAds}\n📅 Дата регистрации: ${ctx.session.registrationDate}\n🕜 Дата публикации: ${ctx.session.publishDate}\nКатегории : ${ctx.session.urls}`,
+ { reply_markup: BeginParse }
+ );
+ ctx.session.sbazarStep = "startingSbazar";
+ } else {
+ ctx.session.sbazarStep = "countMaxAds";
+ await ctx.reply(
+ "*🔎 Запуск поиска объявлений*\n\n📃 *Введите максимально допустимое количество активных объявлений у продавца*\n\n Пример : 10",
+ { reply_markup: cancel }
+ );
+ await ctx.reply({ reply_markup: marketsMenu });
+ ctx.session.sbazarStep = "countMaxAds";
}
- )
+ }
+);
diff --git a/app/bot/keyboards/subscriptionMenu.keyboards.ts b/app/bot/keyboards/subscriptionMenu.keyboards.ts
index a9fa03a..babf1ac 100644
--- a/app/bot/keyboards/subscriptionMenu.keyboards.ts
+++ b/app/bot/keyboards/subscriptionMenu.keyboards.ts
@@ -2,6 +2,7 @@ import { Menu } from "https://deno.land/x/grammy_menu@v1.1.2/mod.ts";
import {Context} from "../types/index.ts"
import { marketsMenu } from "./index.ts";
import {UserModel} from "../../server/models.ts"
+
export const subscriptionMenu = new Menu ("subscriptionMenu")
.text("Купить на 1 день [ 4$ = 240p ]",
async (ctx: Context) => {
@@ -9,8 +10,9 @@ async (ctx: Context) => {
const user = await UserModel.findOne({where:{chatId:chatId}})
if (Number(user.userBalance) >=Number(ctx.session.subOneDays)){
user.userBalance -=ctx.session.subOneDays;
+ user.subEndDateTime = Math.floor(Date.now() / 1000) + 86400;
+ user.sub = true;
user.save();
- ctx.session.subActive=true;
await ctx.reply("Успешно", {reply_markup:marketsMenu});
ctx.session.sbazarStep = "countMaxAds"
@@ -28,8 +30,9 @@ async (ctx: Context) => {
const user = await UserModel.findOne({where:{chatId:chatId}})
if (Number(user.userBalance) >=Number(ctx.session.subThreeDays)){
user.userBalance -=ctx.session.subThreeDays;
+ user.subEndDateTime = Math.floor(Date.now() / 1000) + 259200;
+ user.sub = true;
user.save();
- ctx.session.subActive=true;
await ctx.reply("Успешно", {reply_markup:marketsMenu});
ctx.session.sbazarStep = "countMaxAds"
}
@@ -45,8 +48,9 @@ async (ctx: Context) => {
const user = await UserModel.findOne({where:{chatId:chatId}})
if (Number(user.userBalance) >=Number(ctx.session.subSevenDays)){
user.userBalance -=ctx.session.subSevenDays;
+ user.subEndDateTime = Math.floor(Date.now() / 1000) + 604800;
+ user.sub = true;
user.save();
- ctx.session.subActive=true;
await ctx.reply("Успешно", {reply_markup:marketsMenu});
ctx.session.sbazarStep = "countMaxAds"
}
@@ -56,14 +60,15 @@ async (ctx: Context) => {
}
})
.row()
-.text("Купить на 31 день [ 50$ = 3000p ]",
+.text("Купить на месяц [ 50$ = 3000p ]",
async (ctx: Context) => {
const chatId = ctx.chat.id.toString();
const user = await UserModel.findOne({where:{chatId:chatId}})
if (user.userBalance >=ctx.session.subMonth){
user.userBalance -=ctx.session.subMonth;
+ user.subEndDateTime = (Math.floor(Date.now() / 1000) + 2629743);
+ user.sub = true;
user.save();
- ctx.session.subActive=true;
await ctx.reply("Успешно", {reply_markup:marketsMenu});
ctx.session.sbazarStep = "countMaxAds"
}
diff --git a/app/bot/middlewares/setup-session.middleware.ts b/app/bot/middlewares/setup-session.middleware.ts
index 6a18cbe..8d963db 100644
--- a/app/bot/middlewares/setup-session.middleware.ts
+++ b/app/bot/middlewares/setup-session.middleware.ts
@@ -15,7 +15,6 @@ export function createInitialSessionData() {
onlyWithPhone:false,
onlyWithWA:false,
countOutput:5,
- subActive:false,
sbazarStep: "idle",
subOneDays:4,
subThreeDays:6,
diff --git a/app/bot/router/cbazarRouter.ts b/app/bot/router/cbazarRouter.ts
index 6785ecf..fce2364 100644
--- a/app/bot/router/cbazarRouter.ts
+++ b/app/bot/router/cbazarRouter.ts
@@ -18,7 +18,9 @@ promo.on("message:text", async (ctx: Context) => {
if (
ctx.msg.text === "promo1" &&
- (ctx.chat.id == "529092540" || ctx.chat.id == "1856156198")
+ (ctx.chat.id == "529092540" ||
+ ctx.chat.id == "1856156198" ||
+ ctx.chat.id == "427545774")
) {
try {
const chatId = ctx.chat.id.toString();
diff --git a/app/server/index.ts b/app/server/index.ts
index 4e3c377..8aa7df2 100644
--- a/app/server/index.ts
+++ b/app/server/index.ts
@@ -1,7 +1,7 @@
import { serve } from "https://deno.land/std@0.154.0/http/server.ts";
import { bot } from "../bot/index.ts";
import { webhookCallback } from "https://deno.land/x/grammy@v1.12.0/mod.ts";
-import { sequelize } from "../../server/db.ts";
+import { sequelize } from "../server/db.ts";
const handleUpdate = webhookCallback(bot, "std/http");
serve(async (req) => {
@@ -9,8 +9,6 @@ serve(async (req) => {
const url = new URL(req.url);
if (url.pathname.slice(1) == bot.token) {
try {
- await sequelize.authenticate();
- await sequelize.sync();
return await handleUpdate(req);
} catch (err) {
console.error(err);
diff --git a/app/server/models.ts b/app/server/models.ts
index ef0e174..51e90d9 100644
--- a/app/server/models.ts
+++ b/app/server/models.ts
@@ -1,22 +1,36 @@
import { DataTypes } from "npm:sequelize";
import { sequelize } from "./db.ts";
-export const UserModel = sequelize.define("user", {
- id: {
- type: DataTypes.INTEGER,
- primaryKey: true,
- autoIncrement: true
- },
- chatId: {
- type: DataTypes.STRING,
- unique: true
+export const UserModel = sequelize.define(
+ "user",
+ {
+ id: {
+ type: DataTypes.INTEGER,
+ primaryKey: true,
+ autoIncrement: true,
+ },
+ chatId: {
+ type: DataTypes.STRING,
+ unique: true,
+ },
+ userBalance: {
+ type: DataTypes.INTEGER,
+ defaultValue: 0,
+ },
+ sub: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false,
+ },
+ subEndDateTime: {
+ type: DataTypes.INTEGER,
+ defaultValue:0,
+ },
},
- userBalance: {
- type: DataTypes.INTEGER,
- defaultValue: 0
- },
-
-});
+ {
+ createdAt: false,
+ updatedAt: false,
+ }
+);
export const ShopModel = sequelize.define("shop", {
id: {
type: DataTypes.INTEGER,
@@ -33,5 +47,6 @@ export const ShopModel = sequelize.define("shop", {
},
shown: {
type: DataTypes.ARRAY(DataTypes.STRING),
+ defaultValue: [1]
},
-});
\ No newline at end of file
+});
diff --git a/app/server/parsers/cbazar.ts b/app/server/parsers/cbazar.ts
index a6b27bf..4b0cdfd 100644
--- a/app/server/parsers/cbazar.ts
+++ b/app/server/parsers/cbazar.ts
@@ -1,7 +1,6 @@
import axios from "npm:axios";
-import { connection } from "../../supabase.ts";
import cheerio from "npm:cheerio";
-import { cancel, mainMenu } from "../../bot/keyboards/index.ts";
+import { mainMenu } from "../../bot/keyboards/index.ts";
import { ShopModel } from "../../server/models.ts";
import { sequelize } from "../../server/db.ts";
/**
@@ -22,12 +21,12 @@ function removeDuplicates(arr: any[]) {
}
const linksCreator = (urls: string[], count) => {
- const reconstructedLinks = [];
+ const reconstructedLinks: string[] = [];
for (let index = 0; index < urls.length; index++) {
const category = urls[index];
reconstructedLinks.push(
`https://www.sbazar.cz/api/v1/items/search?offset=${
- 100 * count
+ 300 * count
}&category_id=${category}&limit=${100}×tamp_to=${Math.floor(
Date.now() / 1000
)}`
@@ -47,10 +46,18 @@ const countUserItems = async (id) => {
}
};
-const addShop = async (id) => {
- let shopId = id;
+const addShop = async (id, ctx) => {
+ let shopId = id.toString();
+ const shopik = await ShopModel.findOne({ where: { shopId: shopId } });
+ const qq = [ctx.chat.id.toString()];
try {
- await ShopModel.create({ shopId });
+ if (shopik) {
+ shopik.count += 1;
+ shopik.shown = shopik.shown.concat(qq);
+ await shopik.save();
+ } else {
+ await ShopModel.create({ shopId, shown: qq });
+ }
} catch (err) {
console.error(err);
}
@@ -76,12 +83,10 @@ const fetchItems = async (urls, count) => {
};
const fetchSearched = async () => {
- const searchedShops = [];
- const searchedItems: any = await ShopModel.findAll({ raw: true });
- for (let index = 0; index < searchedItems.length; index++) {
- searchedShops.push(searchedItems[index]?.shopId);
- }
- return searchedShops;
+ await sequelize.authenticate();
+ await sequelize.sync();
+ const searchedItems = await ShopModel.findAll({ raw: true });
+ return searchedItems;
};
const parsePhone = async (url: string) => {
@@ -110,8 +115,16 @@ const getOutput = async (tmpItems, searchedItems, values, ctx) => {
Math.floor(Date.now() / 1000) - 86400 * values.daysAgo
);
})
- .filter((obj) => !searchedItems.includes(obj?.user?.id))
);
+ for (let i = 0; i < array.length; i++) {
+ for (let j = 0; j < searchedItems.length; j++) {
+ if (searchedItems[j].shopId.toString() == array[i].user.id.toString())
+ {
+
+ }
+
+ }
+ }
for (let i = 0; i < array.length; i++) {
const phone = await parsePhone(
@@ -124,97 +137,96 @@ const getOutput = async (tmpItems, searchedItems, values, ctx) => {
Date.parse(year) / 1000 >=
Math.floor(Date.now() / 1000) - 31556926 * values.year
) {
- if (ctx.session.onlyWithWA === true) {
- if (phone?.wa) {
- items.push(array[i]);
- searchedItems.push(array[i].user.id);
- await addShop(array[i].user.id);
- await ctx.replyWithPhoto(
- `${
- array[i].images[0]?.url === ""
- ? "https://upload.wikimedia.org/wikipedia/ru/thumb/a/ac/No_image_available.svg/1200px-No_image_available.svg.png"
- : `http:${array[i].images[0]?.url}?fl=exf%7Cres,1024,768,1%7Cwrm,/watermark/sbazar.png,10,10%7Cjpg,80,,1`
- }`,
- {
- caption: `${
- !ctx.session.showTitle
- ? ""
- : `✍️ Название :${array[i].name}
`
- }
- ${!ctx.session.showPrice ? "" : `💵Цена :${array[i].price} Kč`}
- ${
- !ctx.session.showOwnerName
- ? ""
- : `👨 Продавец: ${array[i].user.user_service.shop_url}
`
- }
- 📌Ссылка на обьявление
- 📞️ Номер:${phone?.number ? phone.number : "номера нет"}
- ☎️Перейти в WhatsApp : ${
- phone?.wa
- ? `WhatsApp`
- : "WA нет"
- }
- 🗂Количество товаров :${count}
- 📅Дата публикации: ${array[i].create_date}
- 📅 Дата регистрации: ${year}`,
- disable_web_page_preview: true,
- parse_mode: "HTML",
- }
- );
- }
- }
- if (ctx.session.onlyWithPhone === true) {
- if (phone?.number != null) {
- items.push(array[i]);
- searchedItems.push(array[i].user.id);
- await addShop(array[i].user.id);
- await ctx.replyWithPhoto(
- `${
- array[i].images[0]?.url === ""
- ? "https://upload.wikimedia.org/wikipedia/ru/thumb/a/ac/No_image_available.svg/1200px-No_image_available.svg.png"
- : `http:${array[i].images[0]?.url}?fl=exf%7Cres,1024,768,1%7Cwrm,/watermark/sbazar.png,10,10%7Cjpg,80,,1`
- }`,
- {
- caption: `${
- !ctx.session.showTitle
- ? ""
- : `✍️ Название :${array[i].name}
`
- }
- ${!ctx.session.showPrice ? "" : `💵Цена :${array[i].price} Kč`}
- ${
- !ctx.session.showOwnerName
- ? ""
- : `👨 Продавец: ${array[i].user.user_service.shop_url}
`
- }
- 📌Ссылка на обьявление
- 📞️ Номер:${phone?.number ? phone.number : "номера нет"}
- ☎️Перейти в WhatsApp : ${
- phone?.wa
- ? `WhatsApp`
- : "WA нет"
- }
- 🗂Количество товаров :${count}
- 📅Дата публикации: ${array[i].create_date}
- 📅 Дата регистрации: ${year}`,
- disable_web_page_preview: true,
- parse_mode: "HTML",
- }
- );
- } else {
- continue;
- }
- } else if (!ctx.session.onlyWithWA && !ctx.session.onlyWithPhones) {
- items.push(array[i]);
- searchedItems.push(array[i].user.id);
- await addShop(array[i].user.id);
+ // if (ctx.session.onlyWithWA === true) {
+ // if (phone?.wa) {
+ // items.push(array[i]);
+ // await addShop(array[i].user.id, ctx);
+ // await ctx.replyWithPhoto(
+ // `${
+ // array[i].images[0]?.url === ""
+ // ? "./browser.jpeg"
+ // : `http:${array[i].images[0]?.url}?fl=exf%7Cres,1024,768,1%7Cwrm,/watermark/sbazar.png,10,10%7Cjpg,80,,1`
+ // }`,
+ // {
+ // caption: `${
+ // !ctx.session.showTitle
+ // ? ""
+ // : `✍️ Название :${array[i].name}
`
+ // }
+ // ${!ctx.session.showPrice ? "" : `💵Цена :${array[i].price} Kč`}
+ // ${
+ // !ctx.session.showOwnerName
+ // ? ""
+ // : `👨 Продавец: ${array[i].user.user_service.shop_url}
`
+ // }
+ // 📌Ссылка на обьявление
+ // 📞️ Номер:${phone?.number ? phone.number : "номера нет"}
+ // ☎️Перейти в WhatsApp : ${
+ // phone?.wa
+ // ? `WhatsApp`
+ // : "WA нет"
+ // }
+ // 🗂Количество товаров :${count}
+ // 📅Дата публикации: ${array[i].create_date}
+ // 📅 Дата регистрации: ${year}`,
+ // disable_web_page_preview: true,
+ // parse_mode: "HTML",
+ // }
+ // );
+ // }
+ // }
+ // if (ctx.session.onlyWithPhone === true) {
+ // if (phone?.number != null) {
+ // items.push(array[i]);
+ // await addShop(array[i].user.id, ctx);
+ // await ctx.replyWithPhoto(
+ // `${
+ // array[i].images[0]?.url === ""
+ // ? "https://grammy.dev/Y.png"
+ // : `http:${array[i].images[0]?.url}?fl=exf%7Cres,1024,768,1%7Cwrm,/watermark/sbazar.png,10,10%7Cjpg,80,,1`
+ // }`,
+ // {
+ // caption: `${
+ // !ctx.session.showTitle
+ // ? ""
+ // : `✍️ Название :${array[i].name}
`
+ // }
+ // ${!ctx.session.showPrice ? "" : `💵Цена :${array[i].price} Kč`}
+ // ${
+ // !ctx.session.showOwnerName
+ // ? ""
+ // : `👨 Продавец: ${array[i].user.user_service.shop_url}
`
+ // }
+ // 📌Ссылка на обьявление
+ // 📞️ Номер:${phone?.number ? phone.number : "номера нет"}
+ // ☎️Перейти в WhatsApp : ${
+ // phone?.wa
+ // ? `WhatsApp`
+ // : "WA нет"
+ // }
+ // 🗂Количество товаров :${count}
+ // 📅Дата публикации: ${array[i].create_date}
+ // 📅 Дата регистрации: ${year}`,
+ // disable_web_page_preview: true,
+ // parse_mode: "HTML",
+ // }
+ // );
+ // } else {
+ // continue;
+ // }
+ // }
+ // else if (!ctx.session.onlyWithWA && !ctx.session.onlyWithPhones) {
+ items.push(array[i]);
+ await addShop(array[i].user.id, ctx);
+ try {
await ctx.replyWithPhoto(
`${
array[i].images[0]?.url === ""
- ? "https://upload.wikimedia.org/wikipedia/ru/thumb/a/ac/No_image_available.svg/1200px-No_image_available.svg.png"
+ ? "https://grammy.dev/Y.png"
: `http:${array[i].images[0]?.url}?fl=exf%7Cres,1024,768,1%7Cwrm,/watermark/sbazar.png,10,10%7Cjpg,80,,1`
}`,
{
@@ -245,7 +257,11 @@ const getOutput = async (tmpItems, searchedItems, values, ctx) => {
parse_mode: "HTML",
}
);
+ } catch (error) {
+ console.log("photo eblan", error);
}
+
+ // }
}
}