с чат GPT накатал бота телеграмм, в него можно писать, отправлять файлы, медиа.
Основной функционал
- Обработка сообщений пользователей:
- Пользователи могут отправлять сообщения боту.
- Сообщения от пользователей пересылаются администратору.
- Бот отвечает пользователям, информируя их о том, что их сообщение было отправлено администратору.
- Обработка сообщений администратора:
- Администратор может отправлять команды боту.
- Администратор может управлять пользователями (блокировка, разблокировка).
- Администратор может рассылать сообщения всем пользователям.
- Блокировка и разблокировка пользователей:
- Администратор может блокировать и разблокировать пользователей.
- Заблокированные пользователи не могут отправлять сообщения бот.
- Обработка callback-запросов:
- Администратор может блокировать, отвечать на сообщения или удалять сообщения через inline-кнопки.
- Рассылка сообщений:
- Администратор может отправлять одно сообщение всем пользователям.(Тут вроде не работает фикция)
- Логирование действий:
- Бот ведет лог сообщений и действий в базе данных.
Команды для администратора
- /banlist
- Описание: Отправляет список всех заблокированных пользователей администратору.
- Результат: Бот возвращает сообщение с перечислением всех заблокированных пользователей или уведомление, если заблокированных пользователей нет.
- /chat
- Описание: Переводит бота в режим рассылки сообщений.
- Результат: Администратор получает запрос на ввод сообщения, которое будет разослано всем пользователям.
- /unban
- Описание: Переводит бота в режим разблокировки пользователей.
- Результат: Администратор получает запрос на ввод ID пользователя для разблокировки. После ввода ID пользователь будет разблокирован.
Логирование
- Логирование сообщений: Все сообщения пользователей и администратора сохраняются в базе данных.
- Логирование действий: Действия, такие как блокировка пользователей, также сохраняются в базе данных.
- если кто-то допилит до идеала буду рад)
Код:
package main
import (
"fmt"
"log"
"strconv"
"strings"
"time"
"github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/tidwall/buntdb"
)
var (
botToken = "ТОКЕН"
adminChatID = int64(64834138) // ID администратора
dbFile = "bot_logs.db" // Файл базы данных
replyingTo = make(map[int64]int64) // Контекст ответа: админ -> пользователь
broadcastMode = false // Режим рассылки
unbanMode = false // Режим разблокировки
)
func main() {
bot, err := tgbotapi.NewBotAPI(botToken)
if err != nil {
log.Panic(err)
}
// Открытие или создание базы данных
db, err := buntdb.Open(dbFile)
if err != nil {
log.Fatal(err)
}
defer db.Close()
log.Printf("Authorized on account %s", bot.Self.UserName)
u := tgbotapi.NewUpdate(0)
u.Timeout = 60
updates := bot.GetUpdatesChan(u)
for update := range updates {
if update.Message != nil {
if update.Message.From.ID == adminChatID {
handleAdminMessage(bot, update, db)
} else {
handleUserMessage(bot, update, db)
}
}
if update.CallbackQuery != nil {
handleCallback(bot, update.CallbackQuery, db)
}
}
}
// Обработка сообщений от пользователей
func handleUserMessage(bot *tgbotapi.BotAPI, update tgbotapi.Update, db *buntdb.DB) {
userID := update.Message.From.ID
userMessage := update.Message.Text
chatID := update.Message.Chat.ID
if isUserBlocked(db, userID) {
return
}
logMessage(db, userID, userMessage, "User")
forwardMessageToAdmin(bot, update, adminChatID, userID)
response := tgbotapi.NewMessage(chatID, "Ваше сообщение отправлено администратору.")
bot.Send(response)
}
// Обработка сообщений от администратора
func handleAdminMessage(bot *tgbotapi.BotAPI, update tgbotapi.Update, db *buntdb.DB) {
adminID := update.Message.From.ID
message := update.Message.Text
if userID, ok := replyingTo[adminID]; ok {
replyToUser(bot, userID, message)
delete(replyingTo, adminID)
return
}
switch message {
case "/banlist":
sendBanList(bot, adminID, db)
case "/chat":
broadcastMode = true
msg := tgbotapi.NewMessage(adminID, "Введите сообщение для рассылки всем пользователям.")
bot.Send(msg)
case "/unban":
unbanMode = true
msg := tgbotapi.NewMessage(adminID, "Введите ID пользователя для разблокировки.")
bot.Send(msg)
default:
if broadcastMode {
broadcastMessage(bot, message, db)
broadcastMode = false
}
if unbanMode {
userID, err := strconv.ParseInt(message, 10, 64)
if err != nil {
msg := tgbotapi.NewMessage(adminID, "Некорректный ID пользователя.")
bot.Send(msg)
return
}
unblockUser(db, userID)
msg := tgbotapi.NewMessage(adminID, fmt.Sprintf("Пользователь %d разблокирован.", userID))
bot.Send(msg)
unbanMode = false
} else {
msg := tgbotapi.NewMessage(adminID, "Используйте кнопки для управления.")
bot.Send(msg)
}
}
}
// Обработка callback-запросов
func handleCallback(bot *tgbotapi.BotAPI, callback *tgbotapi.CallbackQuery, db *buntdb.DB) {
data := strings.Split(callback.Data, ":")
action := data[0]
userID, _ := strconv.ParseInt(data[1], 10, 64)
switch action {
case "block":
blockUser(bot, userID, callback, db)
case "reply":
prepareReply(bot, userID, callback)
case "delete":
deleteMessage(bot, callback)
}
}
// Блокировка пользователя
func blockUser(bot *tgbotapi.BotAPI, userID int64, callback *tgbotapi.CallbackQuery, db *buntdb.DB) {
logAction(db, "Blocked", userID)
msg := tgbotapi.NewMessage(callback.Message.Chat.ID, fmt.Sprintf("Пользователь %d заблокирован.", userID))
bot.Send(msg)
}
// Разблокировка пользователя
func unblockUser(db *buntdb.DB, userID int64) {
db.Update(func(tx *buntdb.Tx) error {
tx.Delete(fmt.Sprintf("blocked:%d", userID))
return nil
})
}
// Подготовка ответа пользователю
func prepareReply(bot *tgbotapi.BotAPI, userID int64, callback *tgbotapi.CallbackQuery) {
replyingTo[callback.Message.Chat.ID] = userID
msg := tgbotapi.NewMessage(callback.Message.Chat.ID, "Введите сообщение для отправки пользователю.")
bot.Send(msg)
}
// Удаление сообщения у админа
func deleteMessage(bot *tgbotapi.BotAPI, callback *tgbotapi.CallbackQuery) {
del := tgbotapi.NewDeleteMessage(callback.Message.Chat.ID, callback.Message.MessageID)
bot.Send(del)
msg := tgbotapi.NewMessage(callback.Message.Chat.ID, "Сообщение удалено.")
bot.Send(msg)
}
// Логирование сообщений и действий
func logMessage(db *buntdb.DB, userID int64, message string, sender string) {
db.Update(func(tx *buntdb.Tx) error {
key := fmt.Sprintf("%d:%s", time.Now().Unix(), sender)
tx.Set(key, fmt.Sprintf("User: %d, Message: %s", userID, message), nil)
return nil
})
}
// Логирование действий
func logAction(db *buntdb.DB, action string, userID int64) {
db.Update(func(tx *buntdb.Tx) error {
tx.Set(fmt.Sprintf("blocked:%d", userID), "true", nil)
return nil
})
}
// Проверка на блокировку
func isUserBlocked(db *buntdb.DB, userID int64) bool {
blocked := false
db.View(func(tx *buntdb.Tx) error {
_, err := tx.Get(fmt.Sprintf("blocked:%d", userID))
if err == nil {
blocked = true
}
return nil
})
return blocked
}
// Рассылка сообщений всем пользователям
func broadcastMessage(bot *tgbotapi.BotAPI, message string, db *buntdb.DB) {
db.View(func(tx *buntdb.Tx) error {
tx.AscendKeys("user:*", func(key, value string) bool {
userID, _ := strconv.ParseInt(strings.TrimPrefix(key, "user:"), 10, 64)
msg := tgbotapi.NewMessage(userID, message)
bot.Send(msg)
return true
})
return nil
})
}
// Отправка списка заблокированных пользователей
func sendBanList(bot *tgbotapi.BotAPI, chatID int64, db *buntdb.DB) {
var banList []string
db.View(func(tx *buntdb.Tx) error {
tx.AscendKeys("blocked:*", func(key, _ string) bool {
userID := strings.TrimPrefix(key, "blocked:")
banList = append(banList, userID)
return true
})
return nil
})
if len(banList) == 0 {
msg := tgbotapi.NewMessage(chatID, "Нет заблокированных пользователей.")
bot.Send(msg)
} else {
msg := tgbotapi.NewMessage(chatID, "Заблокированные пользователи:\n" + strings.Join(banList, "\n"))
bot.Send(msg)
}
}
// Пересылка сообщения администратору
func forwardMessageToAdmin(bot *tgbotapi.BotAPI, update tgbotapi.Update, adminID int64, userID int64) {
var msg tgbotapi.Chattable
if update.Message.Document != nil {
msg = tgbotapi.NewDocument(adminID, tgbotapi.FileID(update.Message.Document.FileID))
} else if len(update.Message.Photo) > 0 {
msg = tgbotapi.NewPhoto(adminID, tgbotapi.FileID(update.Message.Photo[0].FileID))
} else if update.Message.Video != nil {
msg = tgbotapi.NewVideo(adminID, tgbotapi.FileID(update.Message.Video.FileID))
} else if update.Message.Audio != nil {
msg = tgbotapi.NewAudio(adminID, tgbotapi.FileID(update.Message.Audio.FileID))
} else {
msg = tgbotapi.NewMessage(adminID, update.Message.Text)
}
if msg != nil {
bot.Send(msg)
}
// Добавляем кнопки
buttons := []tgbotapi.InlineKeyboardButton{
tgbotapi.NewInlineKeyboardButtonData("Блокировать", fmt.Sprintf("block:%d", userID)),
tgbotapi.NewInlineKeyboardButtonData("Ответить", fmt.Sprintf("reply:%d", userID)),
tgbotapi.NewInlineKeyboardButtonData("Удалить", fmt.Sprintf("delete:%d", userID)),
}
inlineKeyboard := tgbotapi.NewInlineKeyboardMarkup(buttons)
msgWithButtons := tgbotapi.NewMessage(adminID, fmt.Sprintf("Сообщение от пользователя %d", userID))
msgWithButtons.ReplyMarkup = inlineKeyboard
bot.Send(msgWithButtons)
}
// Отправка сообщения пользователю от администратора
func replyToUser(bot *tgbotapi.BotAPI, userID int64, message string) {
msg := tgbotapi.NewMessage(userID, message)
bot.Send(msg)
}