This commit is contained in:
taz
2025-08-13 18:40:11 +02:00
7 changed files with 84 additions and 37 deletions
+3
View File
@@ -0,0 +1,3 @@
Dockerfile
docker-compose.yml
.env
+1
View File
@@ -0,0 +1 @@
.env
+20
View File
@@ -0,0 +1,20 @@
# Go Chat Bridge Dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go mod tidy && go build -o chat-bridge .
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/chat-bridge .
# Переменные окружения (можно задать через docker run -e ...)
ENV TELEGRAM_TOKEN=""
ENV DISCORD_TOKEN=""
ENV VK_TOKEN=""
ENV TELEGRAM_CHAT_ID=""
ENV DISCORD_CHANNEL_ID=""
ENV VK_PEER_ID=""
ENV VK_GROUP_ID=""
CMD ["./chat-bridge"]
+10
View File
@@ -1,11 +1,21 @@
package main
import (
"strconv"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/bwmarrin/discordgo"
"github.com/SevereCloud/vksdk/v2/api"
)
// Получить имя пользователя VK по id
func (b *Bridge) GetVKUserName(userID int) (string, error) {
resp, err := b.VK.UsersGet(api.Params{"user_ids": userID})
if err != nil || len(resp) == 0 {
return strconv.Itoa(userID), err
}
return resp[0].FirstName + " " + resp[0].LastName, nil
}
// Структура для хранения клиентов
type Bridge struct {
Telegram *tgbotapi.BotAPI
+14
View File
@@ -0,0 +1,14 @@
version: '3.8'
services:
chat-bridge:
build: .
container_name: chat-bridge
environment:
TELEGRAM_TOKEN: "${TELEGRAM_TOKEN}"
DISCORD_TOKEN: "${DISCORD_TOKEN}"
VK_TOKEN: "${VK_TOKEN}"
TELEGRAM_CHAT_ID: "${TELEGRAM_CHAT_ID}"
DISCORD_CHANNEL_ID: "${DISCORD_CHANNEL_ID}"
VK_PEER_ID: "${VK_PEER_ID}"
VK_GROUP_ID: "${VK_GROUP_ID}"
restart: unless-stopped
+15 -19
View File
@@ -29,49 +29,45 @@ func main() {
discordChannelID := os.Getenv("DISCORD_CHANNEL_ID") // string
vkPeerID := os.Getenv("VK_PEER_ID") // int
forward := func(text string, from string) {
log.Printf("[Bridge] Пересылка сообщения от %s: %s", from, text)
forward := func(text string, from string, sender string) {
log.Printf("[Bridge] Пересылка сообщения от %s (%s): %s", from, sender, text)
// Определяем источник и рассылаем в остальные платформы
switch {
case from == "telegram":
// В Discord и VK
switch from {
case "telegram":
if discordChannelID != "" {
_ = bridge.SendToDiscord(discordChannelID, "[TG] "+from+": "+text)
_ = bridge.SendToDiscord(discordChannelID, "[TG] "+sender+": "+text)
}
if vkPeerID != "" {
if id, err := strconv.Atoi(vkPeerID); err == nil {
_ = bridge.SendToVK(id, "[TG] "+from+": "+text)
_ = bridge.SendToVK(id, "[TG] "+sender+": "+text)
}
}
case from == "discord":
// В Telegram и VK
case "discord":
if telegramChatID != "" {
if id, err := strconv.ParseInt(telegramChatID, 10, 64); err == nil {
_ = bridge.SendToTelegram(id, "[DS] "+from+": "+text)
_ = bridge.SendToTelegram(id, "[DS] "+sender+": "+text)
}
}
if vkPeerID != "" {
if id, err := strconv.Atoi(vkPeerID); err == nil {
_ = bridge.SendToVK(id, "[DS] "+from+": "+text)
_ = bridge.SendToVK(id, "[DS] "+sender+": "+text)
}
}
default:
// Считаем, что from — это VK ID
case "vk":
if telegramChatID != "" {
if id, err := strconv.ParseInt(telegramChatID, 10, 64); err == nil {
_ = bridge.SendToTelegram(id, "[VK] VK ID "+from+": "+text)
_ = bridge.SendToTelegram(id, "[VK] "+sender+": "+text)
}
}
if discordChannelID != "" {
_ = bridge.SendToDiscord(discordChannelID, "[VK] VK ID "+from+": "+text)
_ = bridge.SendToDiscord(discordChannelID, "[VK] "+sender+": "+text)
}
}
}
bridge.StartTelegramListener(func(text, from string) { forward(text, from) })
bridge.StartDiscordListener(func(text, from string) { forward(text, from) })
bridge.StartVKListener(func(text, _ string) { forward(text, "vk") })
bridge.StartTelegramListener(func(text, sender string) { forward(text, "telegram", sender) })
bridge.StartDiscordListener(func(text, sender string) { forward(text, "discord", sender) })
bridge.StartVKListener(func(text, sender string) { forward(text, "vk", sender) })
select {} // Блокируем main, чтобы слушатели работали
}
+5 -2
View File
@@ -29,8 +29,11 @@ func (b *Bridge) StartVKListener(forward func(text string, from string)) {
lp.MessageNew(func(_ context.Context, obj events.MessageNewObject) {
log.Printf("[VK] %d: %s", obj.Message.FromID, obj.Message.Text)
// Передаём текст и имя отправителя (ID)
forward(obj.Message.Text, strconv.Itoa(obj.Message.FromID))
sender := "vk:" + strconv.Itoa(obj.Message.FromID)
if name, err := b.GetVKUserName(obj.Message.FromID); err == nil {
sender = name
}
forward(obj.Message.Text, sender)
})
go lp.Run()
}