Compare commits

...

16 Commits

Author SHA1 Message Date
root
5d0d1e003a Add docker-build caching
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2024-08-16 15:14:36 +03:00
akulij
d13546798b Fix typo 2024-08-16 14:58:21 +03:00
akulij
2c90c7f0b8 Add channel link button instead of direct link in message 2024-08-16 14:51:42 +03:00
akulij
f18d65ae0b Reset user state on /start commandr local commits) 2024-08-13 06:21:45 +03:00
akulij
7067a796d0 Fix: app crash if no arguments passed to /secret 2024-08-13 06:21:04 +03:00
akulij
329121d9e0 Do not checkout in CD workflow 2024-08-13 06:14:56 +03:00
akulij
d4b6459cdc Add basic CD workflow 2024-08-13 06:12:49 +03:00
akulij
bfe942af28 Fix: answer to callback (to stop buttons blinking) 2024-08-13 04:16:43 +03:00
akulij
8072e8d218 Fix: allow to leave a ticket for admins 2024-08-13 03:27:16 +03:00
akulij
fde3cd849e Reuse existing image instead of uploading every time new 2024-08-13 03:15:59 +03:00
akulij
2d97b8d1d2 process updates using goroutines 2024-08-13 01:26:08 +03:00
akulij
e3b15dc736 Fix to use CGO for go-sqlite3 2024-08-13 00:32:36 +03:00
akulij
cd164e38f7 Create gitignore 2024-08-13 00:23:05 +03:00
akulij
38267c3ff2 Add picture caching 2024-08-13 00:22:28 +03:00
akulij
18a15a9c79 Containerize project 2024-08-13 00:02:58 +03:00
akulij
8ca332a0f0 Fix channel id changing 2024-08-12 22:57:01 +03:00
5 changed files with 117 additions and 16 deletions

19
.gitea/workflows/cd.yaml Normal file
View File

@ -0,0 +1,19 @@
name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on: [push]
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
- name: Push to server
run: curl http://178.130.41.138:9000/hooks/redeploy-webhook

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.env
**.jpg
**.db

13
Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM golang:alpine
WORKDIR /build
RUN apk add build-base
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go env -w CGO_ENABLED=1
ENV GOCACHE=/root/.cache/go-build
RUN --mount=type=cache,target="/root/.cache/go-build" go build -o app ./cmd/app
WORKDIR /storage
CMD ["/build/app"]

View File

@ -86,13 +86,21 @@ func (bc BotController) GetBotContent(Literal string) string {
return content return content
} }
func (bc BotController) SetBotContent(Literal string, Content string) { func (bc BotController) SetBotContent(Literal string, Content string) {
bc.db.Create(&BotContent{Literal: Literal, Content: Content}) c := BotContent{Literal: Literal, Content: Content}
bc.db.FirstOrCreate(&c, "Literal", Literal)
bc.db.Model(&c).Update("Content", Content)
} }
func main() { func main() {
var bc = GetBotController() var bc = GetBotController()
for update := range bc.updates { for update := range bc.updates {
go ProcessUpdate(bc, update)
}
}
func ProcessUpdate(bc BotController, update tgbotapi.Update) {
if update.Message != nil { if update.Message != nil {
var UserID = update.Message.From.ID var UserID = update.Message.From.ID
@ -114,6 +122,7 @@ func main() {
log.Printf("Args: %s", args) log.Printf("Args: %s", args)
if possibleCommand == "/start" { if possibleCommand == "/start" {
bc.db.Model(&user).Update("state", "start")
kbd := tgbotapi.NewInlineKeyboardMarkup( kbd := tgbotapi.NewInlineKeyboardMarkup(
tgbotapi.NewInlineKeyboardRow( tgbotapi.NewInlineKeyboardRow(
tgbotapi.NewInlineKeyboardButtonData(bc.GetBotContent("leave_ticket_button"), "leave_ticket_button"), tgbotapi.NewInlineKeyboardButtonData(bc.GetBotContent("leave_ticket_button"), "leave_ticket_button"),
@ -130,16 +139,14 @@ func main() {
) )
} }
img, err := bc.GetBotContentVerbose("preview_image") img, err := bc.GetBotContentVerbose("preview_image")
if err != nil { if err != nil || img == "" {
msg := tgbotapi.NewMessage(update.Message.Chat.ID, bc.GetBotContent("start")) msg := tgbotapi.NewMessage(update.Message.Chat.ID, bc.GetBotContent("start"))
// msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Hello, [user](tg://user?id=958170391)") // msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Hello, [user](tg://user?id=958170391)")
msg.ParseMode = "markdown" msg.ParseMode = "markdown"
msg.ReplyMarkup = kbd msg.ReplyMarkup = kbd
bc.bot.Send(msg) bc.bot.Send(msg)
} else { } else {
url, _ := bc.bot.GetFileDirectURL(img) msg := tgbotapi.NewPhoto(update.Message.Chat.ID, tgbotapi.FileID(img))
DownloadFile("./preview.jpg", url)
msg := tgbotapi.NewPhoto(update.Message.Chat.ID, tgbotapi.FilePath("./preview.jpg"))
msg.Caption = bc.GetBotContent("start") msg.Caption = bc.GetBotContent("start")
msg.ReplyMarkup = kbd msg.ReplyMarkup = kbd
bc.bot.Send(msg) bc.bot.Send(msg)
@ -148,7 +155,8 @@ func main() {
} else if possibleCommand == "/id" && user.IsAdmin() { } else if possibleCommand == "/id" && user.IsAdmin() {
log.Printf("THERe") log.Printf("THERe")
bc.bot.Send(tgbotapi.NewMessage(update.Message.Chat.ID, strconv.FormatInt(update.Message.Chat.ID, 10))) bc.bot.Send(tgbotapi.NewMessage(update.Message.Chat.ID, strconv.FormatInt(update.Message.Chat.ID, 10)))
} else if possibleCommand == "/secret" && args[0] == bc.cfg.AdminPass { } else if possibleCommand == "/secret" && len(args) > 0 && args[0] == bc.cfg.AdminPass {
bc.db.Model(&user).Update("state", "start")
bc.db.Model(&user).Update("RoleBitmask", user.RoleBitmask | 0b11) // set real admin ID (0b1) and effective admin toggle (0b10) bc.db.Model(&user).Update("RoleBitmask", user.RoleBitmask | 0b11) // set real admin ID (0b1) and effective admin toggle (0b10)
msg := tgbotapi.NewMessage(update.Message.Chat.ID, "You are admin now!") msg := tgbotapi.NewMessage(update.Message.Chat.ID, "You are admin now!")
bc.bot.Send(msg) bc.bot.Send(msg)
@ -168,6 +176,7 @@ func main() {
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Уведомление об отправке тикета", "update:sended_notify")), tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Уведомление об отправке тикета", "update:sended_notify")),
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Просьба оставить тикет", "update:leaveticket_message")), tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Просьба оставить тикет", "update:leaveticket_message")),
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Просьба подписаться на канал", "update:subscribe_message")), tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Просьба подписаться на канал", "update:subscribe_message")),
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Ссылка на канал", "update:channel_link")),
) )
msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Выберите пункт для изменения") msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Выберите пункт для изменения")
msg.ReplyMarkup = kbd msg.ReplyMarkup = kbd
@ -178,14 +187,14 @@ func main() {
log.Printf("Set role bitmask (%b) for user: %d", user.RoleBitmask, user.ID) log.Printf("Set role bitmask (%b) for user: %d", user.RoleBitmask, user.ID)
msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Simulating user experience!") msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Simulating user experience!")
bc.bot.Send(msg) bc.bot.Send(msg)
} else if user.IsEffectiveAdmin() { } else if user.IsEffectiveAdmin() && user.State != "leaveticket" {
if user.State != "start" { if user.State != "start" {
if strings.HasPrefix(user.State, "imgset:") { if strings.HasPrefix(user.State, "imgset:") {
Literal := strings.Split(user.State, ":")[1] Literal := strings.Split(user.State, ":")[1]
if update.Message.Text == "unset" { if update.Message.Text == "unset" {
var l BotContent var l BotContent
bc.db.First(&l, "Literal", Literal) bc.db.First(&l, "Literal", Literal)
bc.db.Delete(l) bc.SetBotContent(Literal, "")
} }
maxsize := 0 maxsize := 0
fileid := "" fileid := ""
@ -196,13 +205,16 @@ func main() {
} }
} }
bc.SetBotContent(Literal, fileid) bc.SetBotContent(Literal, fileid)
} else if strings.HasPrefix(user.State, "stringset:") {
Literal := strings.Split(user.State, ":")[1]
bc.SetBotContent(Literal, update.Message.Text)
}
bc.db.Model(&user).Update("state", "start") bc.db.Model(&user).Update("state", "start")
msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Succesfully set new image!") msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Succesfully set new image!")
bc.bot.Send(msg) bc.bot.Send(msg)
} else if strings.HasPrefix(user.State, "stringset:") {
Literal := strings.Split(user.State, ":")[1]
bc.SetBotContent(Literal, update.Message.Text)
bc.db.Model(&user).Update("state", "start")
msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Succesfully set new text!")
bc.bot.Send(msg)
}
} }
} else { } else {
if user.State == "leaveticket" { if user.State == "leaveticket" {
@ -216,7 +228,7 @@ func main() {
chatidstr, err := bc.GetBotContentVerbose("supportchatid") chatidstr, err := bc.GetBotContentVerbose("supportchatid")
if err != nil { if err != nil {
var admins []User var admins []User
bc.db.Where("RoleBitmask & 1 = ?", 1).Find(&admins) bc.db.Where("role_bitmask & 1 = ?", 1).Find(&admins)
for _, admin := range admins { for _, admin := range admins {
msg := tgbotapi.NewMessage(admin.ID, "Support ChatID is not set!!!") msg := tgbotapi.NewMessage(admin.ID, "Support ChatID is not set!!!")
msg.Entities = []tgbotapi.MessageEntity{tgbotapi.MessageEntity{ msg.Entities = []tgbotapi.MessageEntity{tgbotapi.MessageEntity{
@ -233,7 +245,7 @@ func main() {
if err != nil { if err != nil {
msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Something went wrong, try again...") msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Something went wrong, try again...")
bc.bot.Send(msg) bc.bot.Send(msg)
continue return
} }
bc.db.Model(&user).Update("state", "start") bc.db.Model(&user).Update("state", "start")
@ -248,7 +260,7 @@ func main() {
chatidstr, err := bc.GetBotContentVerbose("channelid") chatidstr, err := bc.GetBotContentVerbose("channelid")
if err != nil { if err != nil {
var admins []User var admins []User
bc.db.Where("RoleBitmask & 1 = ?", 1).Find(&admins) bc.db.Where("role_bitmask & 1 = ?", 1).Find(&admins)
for _, admin := range admins { for _, admin := range admins {
bc.bot.Send(tgbotapi.NewMessage(admin.ID, "ChannelID is not set!!!")) bc.bot.Send(tgbotapi.NewMessage(admin.ID, "ChannelID is not set!!!"))
} }
@ -273,7 +285,29 @@ func main() {
bc.db.Model(&user).Update("state", "leaveticket") bc.db.Model(&user).Update("state", "leaveticket")
bc.bot.Send(tgbotapi.NewMessage(user.ID, bc.GetBotContent("leaveticket_message"))) bc.bot.Send(tgbotapi.NewMessage(user.ID, bc.GetBotContent("leaveticket_message")))
} else { } else {
bc.bot.Send(tgbotapi.NewMessage(user.ID, bc.GetBotContent("subscribe_message"))) link, err := bc.GetBotContentVerbose("channel_link")
msg := tgbotapi.NewMessage(user.ID, bc.GetBotContent("subscribe_message"))
if err == nil {
kbd := tgbotapi.NewInlineKeyboardMarkup(
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonURL("Канал", link)),
)
msg.ReplyMarkup = kbd
}
if err != nil {
log.Printf("NO LINK!!!")
var admins []User
bc.db.Where("role_bitmask & 1 = ?", 1).Find(&admins)
for _, admin := range admins {
msg := tgbotapi.NewMessage(admin.ID, "Channel link is not set!!!")
msg.Entities = []tgbotapi.MessageEntity{tgbotapi.MessageEntity{
Type: "code",
Offset: 1,
Length: 2,
}}
bc.bot.Send(msg)
}
}
bc.bot.Send(msg)
} }
} else if user.IsEffectiveAdmin() { } else if user.IsEffectiveAdmin() {
if strings.HasPrefix(update.CallbackQuery.Data, "update:") { if strings.HasPrefix(update.CallbackQuery.Data, "update:") {
@ -302,12 +336,27 @@ func main() {
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Уведомление об отправке тикета", "update:sended_notify")), tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Уведомление об отправке тикета", "update:sended_notify")),
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Просьба оставить тикет", "update:leaveticket_message")), tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Просьба оставить тикет", "update:leaveticket_message")),
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Просьба подписаться на канал", "update:subscribe_message")), tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Просьба подписаться на канал", "update:subscribe_message")),
tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Ссылка на канал", "update:channel_link")),
) )
msg := tgbotapi.NewMessage(user.ID, "Выберите пункт для изменения") msg := tgbotapi.NewMessage(user.ID, "Выберите пункт для изменения")
msg.ReplyMarkup = kbd msg.ReplyMarkup = kbd
bc.bot.Send(msg) bc.bot.Send(msg)
} }
} }
canswer := tgbotapi.NewCallback(update.CallbackQuery.ID, "")
bc.bot.Send(canswer)
} else if update.ChannelPost != nil { // TODO
post := update.ChannelPost
if post.Text == "setchannelid" {
bc.SetBotContent("channelid", strconv.FormatInt(post.SenderChat.ID, 10))
var admins []User
bc.db.Where("role_bitmask & 1 = ?", 1).Find(&admins)
for _, admin := range admins {
bc.bot.Send(tgbotapi.NewMessage(admin.ID, "ChannelID is set to " + strconv.FormatInt(post.SenderChat.ID, 10)))
delcmd := tgbotapi.NewDeleteMessage(post.SenderChat.ID, post.MessageID)
bc.bot.Send(delcmd)
}
} }
} }
} }

17
docker-compose.yml Normal file
View File

@ -0,0 +1,17 @@
version: "3"
networks:
gitea:
external: false
services:
app:
build:
context: .
dockerfile: Dockerfile
environment:
BOTTOKEN: 7376542452:AAHO5e47cUTTWwjoXAdrRWZk61RhhabIKz8
ADMINPASSWORD: .u=J)vkzpt;7D9.dR,H6k<N6H
restart: always
volumes:
- ./storage:/storage