Update bot logic, Dockerfile and docker-compose.yml
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# Build stage
|
||||
FROM golang:1.21-alpine AS builder
|
||||
FROM golang:1.25-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
COPY go.mod go.sum ./
|
||||
@@ -15,6 +15,7 @@ ENV TZ=Asia/Shanghai
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/go-helper .
|
||||
COPY image.png .
|
||||
COPY .env.example .env
|
||||
|
||||
ENTRYPOINT ["./go-helper"]
|
||||
|
||||
36
docker-compose.yml
Normal file
36
docker-compose.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
# PostgreSQL 数据库
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
container_name: gpt-team-db
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: teamhelper
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# Go Helper Bot
|
||||
bot:
|
||||
build: .
|
||||
container_name: gpt-team-bot
|
||||
restart: always
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
# 覆盖 .env 中的数据库连接串,指向 docker 内部的 db 服务
|
||||
DATABASE_URL: postgres://postgres:postgres@db:5432/teamhelper?sslmode=disable
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
@@ -1,4 +1,4 @@
|
||||
package bot
|
||||
package bot
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -589,17 +589,13 @@ func (b *Bot) callbackActionPick(chatID int64, msgID int, action string, userID
|
||||
}
|
||||
|
||||
backCallback = "cmd:list_accounts"
|
||||
prefix := "📧"
|
||||
|
||||
if action == "del" {
|
||||
label = "🗑️ 选择要删除的账号"
|
||||
prefix = "🗑"
|
||||
} else if action == "ref" {
|
||||
label = "🔄 选择要刷新的账号"
|
||||
prefix = "🔄"
|
||||
} else if action == "pending_invite" {
|
||||
label = "📩 选择管理账户"
|
||||
prefix = "📧"
|
||||
backCallback = "cmd:back"
|
||||
}
|
||||
|
||||
@@ -622,17 +618,29 @@ func (b *Bot) callbackActionPick(chatID int64, msgID int, action string, userID
|
||||
shown := accounts[start:end]
|
||||
|
||||
var rows [][]tgbotapi.InlineKeyboardButton
|
||||
var lns []string
|
||||
var rBtns []tgbotapi.InlineKeyboardButton
|
||||
|
||||
// Create a button map
|
||||
for _, a := range shown {
|
||||
for i, a := range shown {
|
||||
btnAction := fmt.Sprintf("%s:%d", action, a.ID)
|
||||
idx := start + i + 1
|
||||
|
||||
lns = append(lns, fmt.Sprintf("*%d.* ID: `%d` (%s)", idx, a.ID, a.Email))
|
||||
|
||||
rows = append(rows, tgbotapi.NewInlineKeyboardRow(
|
||||
tgbotapi.NewInlineKeyboardButtonData(
|
||||
fmt.Sprintf("%s %s", prefix, a.Email),
|
||||
btnAction,
|
||||
),
|
||||
rBtns = append(rBtns, tgbotapi.NewInlineKeyboardButtonData(
|
||||
fmt.Sprintf("%d", idx),
|
||||
btnAction,
|
||||
))
|
||||
|
||||
// Row break every 5 items
|
||||
if len(rBtns) == 5 {
|
||||
rows = append(rows, tgbotapi.NewInlineKeyboardRow(rBtns...))
|
||||
rBtns = nil
|
||||
}
|
||||
}
|
||||
// Append remaining buttons
|
||||
if len(rBtns) > 0 {
|
||||
rows = append(rows, tgbotapi.NewInlineKeyboardRow(rBtns...))
|
||||
}
|
||||
|
||||
// Pagination buttons
|
||||
@@ -647,9 +655,16 @@ func (b *Bot) callbackActionPick(chatID int64, msgID int, action string, userID
|
||||
rows = append(rows, tgbotapi.NewInlineKeyboardRow(navRow...))
|
||||
}
|
||||
|
||||
rows = append(rows, tgbotapi.NewInlineKeyboardRow(
|
||||
tgbotapi.NewInlineKeyboardButtonData("⬅️ 返回", backCallback),
|
||||
))
|
||||
if action == "ref" {
|
||||
rows = append(rows, tgbotapi.NewInlineKeyboardRow(
|
||||
tgbotapi.NewInlineKeyboardButtonData("🔄 刷新全部", "cmd:refresh_all"),
|
||||
tgbotapi.NewInlineKeyboardButtonData("⬅️ 返回", backCallback),
|
||||
))
|
||||
} else {
|
||||
rows = append(rows, tgbotapi.NewInlineKeyboardRow(
|
||||
tgbotapi.NewInlineKeyboardButtonData("⬅️ 返回", backCallback),
|
||||
))
|
||||
}
|
||||
|
||||
kb := tgbotapi.InlineKeyboardMarkup{InlineKeyboard: rows}
|
||||
|
||||
@@ -658,7 +673,7 @@ func (b *Bot) callbackActionPick(chatID int64, msgID int, action string, userID
|
||||
pageInfo = fmt.Sprintf("\n(第 %d/%d 页)", page+1, totalPages)
|
||||
}
|
||||
|
||||
b.editMsgWithKeyboard(chatID, msgID, fmt.Sprintf("%s%s:", label, pageInfo), &kb)
|
||||
b.editMsgWithKeyboard(chatID, msgID, fmt.Sprintf("%s%s:\n\n%s", label, pageInfo, strings.Join(lns, "\n")), &kb)
|
||||
}
|
||||
|
||||
func (b *Bot) callbackDelAccount(chatID int64, msgID int, idStr string) {
|
||||
@@ -722,6 +737,16 @@ func (b *Bot) callbackRefAccount(chatID int64, msgID int, idStr string) {
|
||||
|
||||
_ = b.db.UpdateAccountTokens(id, result.AccessToken, result.RefreshToken)
|
||||
|
||||
// Sync member counts after token refresh.
|
||||
acc.Token = result.AccessToken
|
||||
if userTotal, _, err2 := b.client.GetUsers(acc); err2 == nil {
|
||||
invTotal := acc.InviteCount
|
||||
if inv, _, err3 := b.client.GetInvites(acc); err3 == nil {
|
||||
invTotal = inv
|
||||
}
|
||||
_ = b.db.UpdateAccountCounts(id, userTotal, invTotal)
|
||||
}
|
||||
|
||||
kb := tgbotapi.NewInlineKeyboardMarkup(
|
||||
tgbotapi.NewInlineKeyboardRow(
|
||||
tgbotapi.NewInlineKeyboardButtonData("⬅️ 返回列表", "cmd:list_accounts"),
|
||||
@@ -1014,8 +1039,10 @@ func (b *Bot) handleMessage(msg *tgbotapi.Message) {
|
||||
if hasSess && !strings.HasPrefix(text, "/") {
|
||||
switch sess.flowType {
|
||||
case "redeem_code":
|
||||
b.deleteMsg(chatID, msg.MessageID)
|
||||
b.handleRedeemCode(chatID, text)
|
||||
case "redeem":
|
||||
b.deleteMsg(chatID, msg.MessageID)
|
||||
b.handleRedeemEmail(chatID, sess, text)
|
||||
case "login":
|
||||
b.handleLoginCallback(chatID, msg.MessageID, text)
|
||||
@@ -1030,7 +1057,7 @@ func (b *Bot) handleMessage(msg *tgbotapi.Message) {
|
||||
if email == "" {
|
||||
return
|
||||
}
|
||||
accounts, err := b.db.GetOpenAccounts(b.cfg.TeamCapacity)
|
||||
accounts, err := b.db.GetOpenAccounts(b.cfg.TeamCapacity - 1)
|
||||
if err != nil || len(accounts) == 0 {
|
||||
kb := tgbotapi.NewInlineKeyboardMarkup(
|
||||
tgbotapi.NewInlineKeyboardRow(
|
||||
@@ -1230,7 +1257,7 @@ func (b *Bot) handleRedeemEmail(chatID int64, sess *chatSession, email string) {
|
||||
if panelMsgID != 0 {
|
||||
b.editMsgWithKeyboard(chatID, panelMsgID, "⏳ 正在处理兑换,请稍候...", nil)
|
||||
|
||||
result, err := redeem.Redeem(b.db, b.client, sess.code, email, b.cfg.TeamCapacity)
|
||||
result, err := redeem.Redeem(b.db, b.client, sess.code, email, b.cfg.TeamCapacity-1)
|
||||
if err != nil {
|
||||
b.editMsgWithKeyboard(chatID, panelMsgID, fmt.Sprintf("❌ 兑换失败: %s", err.Error()), &backKb)
|
||||
return
|
||||
@@ -1239,7 +1266,7 @@ func (b *Bot) handleRedeemEmail(chatID int64, sess *chatSession, email string) {
|
||||
} else {
|
||||
msgID := b.sendAndGetID(chatID, "⏳ 正在处理兑换,请稍候...")
|
||||
|
||||
result, err := redeem.Redeem(b.db, b.client, sess.code, email, b.cfg.TeamCapacity)
|
||||
result, err := redeem.Redeem(b.db, b.client, sess.code, email, b.cfg.TeamCapacity-1)
|
||||
if err != nil {
|
||||
b.editMsg(chatID, msgID, fmt.Sprintf("❌ 兑换失败: %s", err.Error()))
|
||||
return
|
||||
@@ -1337,9 +1364,9 @@ func (b *Bot) handleAddAccount(chatID int64, panelMsgID int, args string) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Generate codes based on remaining capacity: 6 - (current user count + pending invites).
|
||||
// Generate codes based on remaining capacity: (b.cfg.TeamCapacity - 1) - (current user count + pending invites).
|
||||
newAcct, _ := b.db.GetAccountByID(id)
|
||||
codeCount := 6
|
||||
codeCount := b.cfg.TeamCapacity
|
||||
if newAcct != nil {
|
||||
var userTotal, inviteTotal int
|
||||
if ut, _, err2 := b.client.GetUsers(newAcct); err2 == nil {
|
||||
@@ -1348,7 +1375,7 @@ func (b *Bot) handleAddAccount(chatID int64, panelMsgID int, args string) {
|
||||
if it, _, err3 := b.client.GetInvites(newAcct); err3 == nil {
|
||||
inviteTotal = it
|
||||
}
|
||||
codeCount = 6 - (userTotal + inviteTotal)
|
||||
codeCount = b.cfg.TeamCapacity - (userTotal + inviteTotal)
|
||||
_ = b.db.UpdateAccountCounts(id, userTotal, inviteTotal)
|
||||
}
|
||||
if codeCount < 0 {
|
||||
@@ -1549,7 +1576,7 @@ func (b *Bot) handleGenCodes(chatID int64, panelMsgID int, args string) {
|
||||
email := eligible[i].Email
|
||||
existing, _ := b.db.CountAvailableCodesByAccount(email)
|
||||
|
||||
maxCodes := b.cfg.TeamCapacity - eligible[i].UserCount - eligible[i].InviteCount
|
||||
maxCodes := (b.cfg.TeamCapacity - 1) - eligible[i].UserCount - eligible[i].InviteCount
|
||||
if maxCodes < 0 {
|
||||
maxCodes = 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user