mirror of
https://github.com/tiennm99/store-scraper-bot-java.git
synced 2026-05-15 11:53:02 +00:00
Refactor bot client and add group management commands
Replaced ScoreScrapeBotTelegramClient with StoreScrapeBotTelegramClient and updated related references. Added BaseStoreScraperBotCommand for command error handling. Implemented AddGroupCommand and GetGroupCommand for managing allowed groups via admin commands. Improved CouchbaseUtil to ensure scope and collection creation. Updated logging configuration and environment example. Minor model and repository adjustments for initialization and group handling.
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
||||
# cp .env.example .env
|
||||
|
||||
# Couchbase configuration
|
||||
COUCHBASE_CONNECTION_STRING=localhost:8091
|
||||
COUCHBASE_CONNECTION_STRING=couchbase://localhost
|
||||
COUCHBASE_USERNAME=admin
|
||||
COUCHBASE_PASSWORD=your_password_here
|
||||
COUCHBASE_BUCKET_NAME=store_scraper
|
||||
|
||||
@@ -23,7 +23,6 @@ configurations {
|
||||
dependencies {
|
||||
annotationProcessor("org.projectlombok:lombok:1.18.36")
|
||||
implementation("com.couchbase.client:java-client:3.4.11")
|
||||
implementation("com.lmax:disruptor:4.0.0")
|
||||
implementation("org.apache.logging.log4j:log4j-1.2-api:2.24.3")
|
||||
implementation("org.apache.logging.log4j:log4j-core:2.24.3")
|
||||
implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.24.3")
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.miti99.storescraperbot;
|
||||
|
||||
import com.miti99.storescraperbot.bot.StoreScrapeBot;
|
||||
import com.miti99.storescraperbot.config.Config;
|
||||
import com.miti99.storescraperbot.repository.AdminRepository;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication;
|
||||
|
||||
@@ -9,6 +10,8 @@ import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication;
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
AdminRepository.INSTANCE.init();
|
||||
|
||||
try (var botsApplication = new TelegramBotsLongPollingApplication()) {
|
||||
botsApplication.registerBot(Config.TELEGRAM_BOT_TOKEN, StoreScrapeBot.INSTANCE);
|
||||
log.info("StoreScrapeBot successfully started!");
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.miti99.storescraperbot.bot;
|
||||
|
||||
import com.miti99.storescraperbot.config.Config;
|
||||
import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient;
|
||||
|
||||
public class ScoreScrapeBotTelegramClient extends OkHttpTelegramClient {
|
||||
public static final ScoreScrapeBotTelegramClient INSTANCE = new ScoreScrapeBotTelegramClient();
|
||||
|
||||
public ScoreScrapeBotTelegramClient() {
|
||||
super(Config.TELEGRAM_BOT_TOKEN);
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,10 @@ package com.miti99.storescraperbot.bot;
|
||||
import com.miti99.storescraperbot.bot.command.AddGroupCommand;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.telegram.telegrambots.extensions.bots.commandbot.CommandLongPollingTelegramBot;
|
||||
import org.telegram.telegrambots.meta.api.methods.commands.SetMyCommands;
|
||||
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
|
||||
import org.telegram.telegrambots.meta.api.objects.Update;
|
||||
import org.telegram.telegrambots.meta.api.objects.commands.BotCommand;
|
||||
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
|
||||
|
||||
@Log4j2
|
||||
@@ -12,8 +14,22 @@ public class StoreScrapeBot extends CommandLongPollingTelegramBot {
|
||||
public static final StoreScrapeBot INSTANCE = new StoreScrapeBot();
|
||||
|
||||
StoreScrapeBot() {
|
||||
super(ScoreScrapeBotTelegramClient.INSTANCE, true, ScoreScrapeBotUsernameSupplier.INSTANCE);
|
||||
super(StoreScrapeBotTelegramClient.INSTANCE, true, StoreScrapeBotUsernameSupplier.INSTANCE);
|
||||
register(AddGroupCommand.INSTANCE);
|
||||
setMyCommands();
|
||||
}
|
||||
|
||||
private void setMyCommands() {
|
||||
try {
|
||||
var commands =
|
||||
getRegisteredCommands().stream()
|
||||
.map(cmd -> new BotCommand(cmd.getCommandIdentifier(), cmd.getDescription()))
|
||||
.toList();
|
||||
var setMyCommands = SetMyCommands.builder().commands(commands).build();
|
||||
StoreScrapeBotTelegramClient.INSTANCE.execute(setMyCommands);
|
||||
} catch (TelegramApiException e) {
|
||||
log.error("register error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.miti99.storescraperbot.bot;
|
||||
|
||||
import com.miti99.storescraperbot.config.Config;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient;
|
||||
import org.telegram.telegrambots.meta.api.methods.ParseMode;
|
||||
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
|
||||
|
||||
@Log4j2
|
||||
public class StoreScrapeBotTelegramClient extends OkHttpTelegramClient {
|
||||
public static final StoreScrapeBotTelegramClient INSTANCE = new StoreScrapeBotTelegramClient();
|
||||
|
||||
public StoreScrapeBotTelegramClient() {
|
||||
super(Config.TELEGRAM_BOT_TOKEN);
|
||||
}
|
||||
|
||||
public void sendMessage(long chatId, String text) {
|
||||
try {
|
||||
var sendMessage =
|
||||
SendMessage.builder().parseMode(ParseMode.HTML).chatId(chatId).text(text).build();
|
||||
execute(sendMessage);
|
||||
} catch (Exception e) {
|
||||
log.error("sendMessage error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessage(long chatId, int threadId, String text) {
|
||||
try {
|
||||
var sendMessage =
|
||||
SendMessage.builder()
|
||||
.parseMode(ParseMode.HTML)
|
||||
.chatId(chatId)
|
||||
.messageThreadId(threadId)
|
||||
.text(text)
|
||||
.build();
|
||||
execute(sendMessage);
|
||||
} catch (Exception e) {
|
||||
log.error("sendMessage error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -3,9 +3,9 @@ package com.miti99.storescraperbot.bot;
|
||||
import com.miti99.storescraperbot.config.Config;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ScoreScrapeBotUsernameSupplier implements Supplier<String> {
|
||||
public static final ScoreScrapeBotUsernameSupplier INSTANCE =
|
||||
new ScoreScrapeBotUsernameSupplier();
|
||||
public class StoreScrapeBotUsernameSupplier implements Supplier<String> {
|
||||
public static final StoreScrapeBotUsernameSupplier INSTANCE =
|
||||
new StoreScrapeBotUsernameSupplier();
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
@@ -1,23 +1,48 @@
|
||||
package com.miti99.storescraperbot.bot.command;
|
||||
|
||||
import com.miti99.storescraperbot.bot.StoreScrapeBotTelegramClient;
|
||||
import com.miti99.storescraperbot.config.Config;
|
||||
import org.telegram.telegrambots.extensions.bots.commandbot.commands.BotCommand;
|
||||
import com.miti99.storescraperbot.repository.AdminRepository;
|
||||
import org.telegram.telegrambots.meta.api.objects.User;
|
||||
import org.telegram.telegrambots.meta.api.objects.chat.Chat;
|
||||
import org.telegram.telegrambots.meta.generics.TelegramClient;
|
||||
|
||||
public class AddGroupCommand extends BotCommand {
|
||||
public class AddGroupCommand extends BaseStoreScraperBotCommand {
|
||||
public static final AddGroupCommand INSTANCE = new AddGroupCommand();
|
||||
|
||||
AddGroupCommand() {
|
||||
super("addgroup", "Thêm group vào list group cho phép sử dụng bot");
|
||||
super("addgroup", "<groupId>. Thêm group vào list group cho phép sử dụng bot");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(TelegramClient telegramClient, User user, Chat chat, String[] arguments) {
|
||||
if (!Config.ADMIN_IDS.contains(user.getId()) ) {
|
||||
protected void executeCommand(
|
||||
TelegramClient telegramClient, User user, Chat chat, String[] arguments) {
|
||||
if (!Config.ADMIN_IDS.contains(user.getId())) {
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "You are not admin");
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
|
||||
if (arguments.length != 1) {
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Invalid arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
long groupId;
|
||||
try {
|
||||
groupId = Long.parseLong(arguments[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Invalid groupId");
|
||||
return;
|
||||
}
|
||||
|
||||
var admin = AdminRepository.INSTANCE.load();
|
||||
if (admin.getGroups().contains(groupId)) {
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Group is already added");
|
||||
return;
|
||||
}
|
||||
|
||||
admin.getGroups().add(groupId);
|
||||
AdminRepository.INSTANCE.save(admin);
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Group added successfully");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.miti99.storescraperbot.bot.command;
|
||||
|
||||
import com.miti99.storescraperbot.bot.StoreScrapeBotTelegramClient;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.telegram.telegrambots.extensions.bots.commandbot.commands.BotCommand;
|
||||
import org.telegram.telegrambots.meta.api.objects.User;
|
||||
import org.telegram.telegrambots.meta.api.objects.chat.Chat;
|
||||
import org.telegram.telegrambots.meta.generics.TelegramClient;
|
||||
|
||||
@Log4j2
|
||||
public abstract class BaseStoreScraperBotCommand extends BotCommand {
|
||||
|
||||
public BaseStoreScraperBotCommand(String commandIdentifier, String description) {
|
||||
super(commandIdentifier, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(TelegramClient telegramClient, User user, Chat chat, String[] arguments) {
|
||||
try {
|
||||
executeCommand(telegramClient, user, chat, arguments);
|
||||
} catch (Exception e) {
|
||||
log.error("execute error", e);
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void executeCommand(
|
||||
TelegramClient telegramClient, User user, Chat chat, String[] arguments);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.miti99.storescraperbot.bot.command;
|
||||
|
||||
import com.miti99.storescraperbot.bot.StoreScrapeBotTelegramClient;
|
||||
import com.miti99.storescraperbot.config.Config;
|
||||
import com.miti99.storescraperbot.repository.AdminRepository;
|
||||
import org.telegram.telegrambots.meta.api.objects.User;
|
||||
import org.telegram.telegrambots.meta.api.objects.chat.Chat;
|
||||
import org.telegram.telegrambots.meta.generics.TelegramClient;
|
||||
|
||||
public class GetGroupCommand extends BaseStoreScraperBotCommand {
|
||||
public static final GetGroupCommand INSTANCE = new GetGroupCommand();
|
||||
|
||||
GetGroupCommand() {
|
||||
super("getgroup", "Lấy danh sách group được phép sử dụng bot hiện tại");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executeCommand(
|
||||
TelegramClient telegramClient, User user, Chat chat, String[] arguments) {
|
||||
if (!Config.ADMIN_IDS.contains(user.getId())) {
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "You are not admin");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.length != 0) {
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Invalid arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var admin = AdminRepository.INSTANCE.load();
|
||||
var groups = admin.getGroups();
|
||||
var sb = new StringBuilder();
|
||||
sb.append("<b>Groups:</b>/n");
|
||||
for (var groupId : groups) {
|
||||
sb.append("- ").append(groupId).append("\n");
|
||||
}
|
||||
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), sb.toString());
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,10 @@ package com.miti99.storescraperbot.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
public abstract class AbstractModel<K> {
|
||||
|
||||
@JsonProperty("class")
|
||||
protected String clazz = getClass().getSimpleName();
|
||||
|
||||
@Setter protected K key;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.miti99.storescraperbot.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
@@ -8,5 +9,5 @@ import lombok.Setter;
|
||||
@Getter
|
||||
@Setter
|
||||
public class Admin extends AbstractModel<String> {
|
||||
List<Long> groups;
|
||||
List<Long> groups = new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
|
||||
protected AbstractRepository(String collectionName) {
|
||||
this.collectionName = collectionName.toLowerCase();
|
||||
CouchbaseUtil.createCollection(scopeName, collectionName);
|
||||
}
|
||||
|
||||
public Collection collection() {
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.miti99.storescraperbot.model.Admin;
|
||||
* Đây là repository chỉ chứa 1 key duy nhất, key là "" (rỗng)
|
||||
*/
|
||||
public class AdminRepository extends AbstractRepository<String, Admin> {
|
||||
private static final AdminRepository INSTANCE = new AdminRepository();
|
||||
public static final AdminRepository INSTANCE = new AdminRepository();
|
||||
|
||||
protected AdminRepository() {
|
||||
super("admin");
|
||||
|
||||
@@ -8,8 +8,12 @@ import static com.miti99.storescraperbot.config.Config.COUCHBASE_USERNAME;
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.ClusterOptions;
|
||||
import com.couchbase.client.java.manager.collection.CollectionSpec;
|
||||
import com.miti99.storescraperbot.config.Config;
|
||||
import java.time.Duration;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
@Log4j2
|
||||
public class CouchbaseUtil {
|
||||
public static final Cluster CLUSTER;
|
||||
public static final Bucket BUCKET;
|
||||
@@ -24,4 +28,54 @@ public class CouchbaseUtil {
|
||||
BUCKET = CLUSTER.bucket(COUCHBASE_BUCKET_NAME);
|
||||
BUCKET.waitUntilReady(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
public static void createScope(String scopeName) {
|
||||
var collectionManager = BUCKET.collections();
|
||||
try {
|
||||
boolean scopeExists =
|
||||
collectionManager.getAllScopes().stream().anyMatch(s -> s.name().equals(scopeName));
|
||||
|
||||
if (!scopeExists) {
|
||||
collectionManager.createScope(scopeName);
|
||||
log.info("Scope created: {}", scopeName);
|
||||
} else {
|
||||
log.info("Scope existed: {}", scopeName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("createScope error - scopeName: '{}'", scopeName, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void createCollection(String scopeName, String collectionName) {
|
||||
var collectionManager = BUCKET.collections();
|
||||
try {
|
||||
var scopeSpecOpt =
|
||||
collectionManager.getAllScopes().stream()
|
||||
.filter(s -> s.name().equals(scopeName))
|
||||
.findFirst();
|
||||
if (scopeSpecOpt.isEmpty()) {
|
||||
createScope(scopeName);
|
||||
createCollection(scopeName, collectionName);
|
||||
return;
|
||||
}
|
||||
|
||||
var scopeSpec = scopeSpecOpt.get();
|
||||
boolean collectionExists =
|
||||
scopeSpec.collections().stream().anyMatch(c -> c.name().equals(collectionName));
|
||||
|
||||
if (!collectionExists) {
|
||||
var spec = CollectionSpec.create(collectionName, scopeName);
|
||||
collectionManager.createCollection(spec);
|
||||
log.info("Collection created: {} in {}", collectionName, scopeName);
|
||||
} else {
|
||||
log.info("Collection existed: {} in {}", collectionName, scopeName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"createCollection error - collectionName: '{}', scopeName: '{}'",
|
||||
collectionName,
|
||||
scopeName,
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<AsyncRoot level="warn">
|
||||
<Root level="${env:LOG_LEVEL:-debug}">
|
||||
<AppenderRef ref="ConsoleAppender"/>
|
||||
</AsyncRoot>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
||||
Reference in New Issue
Block a user