Merge branch 'release/1.0'
This commit is contained in:
commit
fbadd19a79
|
@ -15,4 +15,9 @@
|
|||
.glide/
|
||||
|
||||
# Golang project vendor packages which should be ignored
|
||||
vendor/
|
||||
vendor/
|
||||
|
||||
# Production files must not be in public repository
|
||||
config.yaml
|
||||
cert.key
|
||||
cert.pem
|
|
@ -0,0 +1,8 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.9
|
||||
- tip
|
||||
|
||||
install:
|
||||
- go get
|
|
@ -0,0 +1,26 @@
|
|||
# Build package by default with all general tools and things
|
||||
all:
|
||||
make localization
|
||||
make build
|
||||
|
||||
# Build minimal package only
|
||||
build:
|
||||
go build
|
||||
|
||||
# Build debug version with more logs
|
||||
debug:
|
||||
go build -tags=debug
|
||||
|
||||
# Format the source code
|
||||
fmt:
|
||||
go fmt
|
||||
|
||||
# Build localization files with separated untranslated strings
|
||||
translation:
|
||||
goi18n merge -format yaml -sourceLanguage en-us -outdir ./i18n/ ./i18n/*
|
||||
|
||||
# Build localization files and merge untranslated strings
|
||||
localization:
|
||||
make translation
|
||||
goi18n -format yaml -sourceLanguage en-us -outdir ./i18n/ ./i18n/*.all.yaml \
|
||||
./i18n/*.untranslated.yaml
|
|
@ -0,0 +1,7 @@
|
|||
# [Patrons!](https://www.patreon.com/bePatron?c=243288)
|
||||
**These people have sponsored the current version of the project:**
|
||||
- **Ivan Kolesnikov**
|
||||
- Daniil Tlenov
|
||||
- Aurielb
|
||||
- Yami Odymel
|
||||
- MoD21k
|
|
@ -0,0 +1,107 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
)
|
||||
|
||||
func commandAdd(msg *telegram.Message, pack bool) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(msg.Chat.ID, T("reply_add_sticker"))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
err = dbChangeUserState(msg.From.ID, stateAddSticker)
|
||||
errCheck(err)
|
||||
|
||||
if pack {
|
||||
reply.Text = T("reply_add_pack")
|
||||
|
||||
err = dbChangeUserState(msg.From.ID, stateAddPack)
|
||||
errCheck(err)
|
||||
}
|
||||
|
||||
log.Ln("Sending add reply...")
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
||||
|
||||
func actionAdd(msg *telegram.Message, pack bool) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(msg.Chat.ID, T("success_add_sticker"))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
switch {
|
||||
case pack && msg.Sticker.SetName == "":
|
||||
reply.Text = T("error_empty_add_pack", map[string]interface{}{
|
||||
"AddStickerCommand": cmdAddSticker,
|
||||
})
|
||||
case pack && msg.Sticker.SetName != "":
|
||||
set, err := bot.GetStickerSet(msg.Sticker.SetName)
|
||||
errCheck(err)
|
||||
|
||||
log.Ln("SetTitle:", set.Title)
|
||||
reply.Text = T("success_add_pack", map[string]interface{}{
|
||||
"SetTitle": set.Title,
|
||||
})
|
||||
|
||||
allExists := true
|
||||
for _, sticker := range set.Stickers {
|
||||
exists, err := dbAddSticker(msg.From.ID, sticker.FileID, sticker.Emoji)
|
||||
errCheck(err)
|
||||
|
||||
if !exists {
|
||||
allExists = false
|
||||
}
|
||||
}
|
||||
|
||||
log.Ln("All exists?", allExists)
|
||||
|
||||
if allExists {
|
||||
reply.Text = T("error_already_add_pack", map[string]interface{}{
|
||||
"SetTitle": set.Title,
|
||||
})
|
||||
} else {
|
||||
markup := telegram.NewInlineKeyboardMarkup(
|
||||
telegram.NewInlineKeyboardRow(
|
||||
telegram.NewInlineKeyboardButtonSwitch(
|
||||
T("button_share"),
|
||||
" ",
|
||||
),
|
||||
),
|
||||
)
|
||||
reply.ReplyMarkup = &markup
|
||||
}
|
||||
default:
|
||||
exists, err := dbAddSticker(msg.From.ID, msg.Sticker.FileID, msg.Sticker.Emoji)
|
||||
errCheck(err)
|
||||
|
||||
if exists {
|
||||
reply.Text = T("error_already_add_sticker")
|
||||
}
|
||||
|
||||
if msg.Sticker.Emoji == "" {
|
||||
msg.Sticker.Emoji = " "
|
||||
}
|
||||
|
||||
markup := telegram.NewInlineKeyboardMarkup(
|
||||
telegram.NewInlineKeyboardRow(
|
||||
telegram.NewInlineKeyboardButtonSwitch(
|
||||
T("button_share"),
|
||||
msg.Sticker.Emoji,
|
||||
),
|
||||
),
|
||||
)
|
||||
reply.ReplyMarkup = &markup
|
||||
}
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package main
|
||||
|
||||
import "github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
|
||||
func commandCancel(msg *telegram.Message) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
state, err := dbGetUserState(msg.From.ID)
|
||||
errCheck(err)
|
||||
|
||||
var text string
|
||||
switch state {
|
||||
case stateAddSticker:
|
||||
text = T("cancel_add_sticker")
|
||||
case stateAddPack:
|
||||
text = T("cancel_add_pack")
|
||||
case stateDelete:
|
||||
text = T("cancel_del")
|
||||
case stateReset:
|
||||
text = T("cancel_reset")
|
||||
default:
|
||||
text = T("cancel_error")
|
||||
}
|
||||
|
||||
err = dbChangeUserState(msg.From.ID, stateNone)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(msg.Chat.ID, text)
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/toby3d/botan"
|
||||
"github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
)
|
||||
|
||||
const (
|
||||
cmdAddPack = "addPack"
|
||||
cmdAddSticker = "addSticker"
|
||||
cmdCancel = "cancel"
|
||||
cmdHelp = "help"
|
||||
cmdDelete = "del"
|
||||
cmdReset = "reset"
|
||||
cmdStart = "start"
|
||||
)
|
||||
|
||||
func commands(msg *telegram.Message) {
|
||||
log.Ln("Received a", msg.Command(), "command")
|
||||
switch strings.ToLower(msg.Command()) {
|
||||
case strings.ToLower(cmdStart):
|
||||
appMetrika.TrackAsync(
|
||||
"Start", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
commandStart(msg)
|
||||
|
||||
<-metrika
|
||||
case strings.ToLower(cmdHelp):
|
||||
appMetrika.TrackAsync(
|
||||
"Help", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
commandHelp(msg)
|
||||
|
||||
<-metrika
|
||||
case strings.ToLower(cmdAddSticker):
|
||||
appMetrika.TrackAsync(
|
||||
"Add single sticker", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
commandAdd(msg, false)
|
||||
|
||||
<-metrika
|
||||
case strings.ToLower(cmdAddPack):
|
||||
appMetrika.TrackAsync(
|
||||
"Add pack", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
commandAdd(msg, true)
|
||||
|
||||
<-metrika
|
||||
case strings.ToLower(cmdDelete):
|
||||
appMetrika.TrackAsync(
|
||||
"Delete single sticker", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
commandDelete(msg)
|
||||
|
||||
<-metrika
|
||||
case strings.ToLower(cmdReset):
|
||||
appMetrika.TrackAsync(
|
||||
"Reset", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
commandReset(msg)
|
||||
|
||||
<-metrika
|
||||
case strings.ToLower(cmdCancel):
|
||||
appMetrika.TrackAsync(
|
||||
"Cancel", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
commandCancel(msg)
|
||||
|
||||
<-metrika
|
||||
default:
|
||||
appMetrika.Track("Command", msg.From.ID, *msg)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
telegram:
|
||||
token: 123456789:ABCd1efGhjKLM23O4pqR5stuvwx678yz90
|
||||
webhook:
|
||||
set: https://www.google.com
|
||||
listen: /bot
|
||||
serve: 0.0.0.0:2368
|
||||
|
||||
botan: 12345a67-8b9c-01d2-e345-67fg8901hj23
|
|
@ -0,0 +1,167 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/tidwall/buntdb" // Redis-like database
|
||||
)
|
||||
|
||||
const (
|
||||
stateNone = "none"
|
||||
stateAddSticker = "addSticker"
|
||||
stateAddPack = "addPack"
|
||||
stateDelete = "del"
|
||||
stateReset = "reset"
|
||||
)
|
||||
|
||||
var db *buntdb.DB
|
||||
|
||||
func dbInit() {
|
||||
log.Ln("Open database file...")
|
||||
var err error
|
||||
db, err = buntdb.Open("stickers.db")
|
||||
errCheck(err)
|
||||
|
||||
log.Ln("Creating user_stickers index...")
|
||||
err = db.CreateIndex(
|
||||
"user_stickers", // name
|
||||
"user:*:sticker:*", // pattern
|
||||
buntdb.IndexString, // options
|
||||
)
|
||||
errCheck(err)
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
func dbChangeUserState(userID int, state string) error {
|
||||
log.Ln("Trying to change", userID, "state to", state)
|
||||
return db.Update(func(tx *buntdb.Tx) error {
|
||||
_, _, err := tx.Set(
|
||||
fmt.Sprint("user:", userID, ":state"), // key
|
||||
state, // val
|
||||
nil, // options
|
||||
)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func dbGetUserState(userID int) (string, error) {
|
||||
log.Ln("Trying to get", userID, "state")
|
||||
var state string
|
||||
err := db.View(func(tx *buntdb.Tx) error {
|
||||
var err error
|
||||
state, err = tx.Get(fmt.Sprint("user:", userID, ":state"))
|
||||
return err
|
||||
})
|
||||
|
||||
switch err {
|
||||
case buntdb.ErrNotFound:
|
||||
log.Ln(userID, "not found, create new one")
|
||||
if err := dbChangeUserState(userID, stateNone); err != nil {
|
||||
return state, err
|
||||
}
|
||||
}
|
||||
|
||||
return state, err
|
||||
}
|
||||
|
||||
func dbAddSticker(userID int, fileID, emoji string) (bool, error) {
|
||||
log.Ln("Trying to add", fileID, "sticker from", userID, "user")
|
||||
var exists bool
|
||||
err := db.Update(func(tx *buntdb.Tx) error {
|
||||
var err error
|
||||
_, exists, err = tx.Set(
|
||||
fmt.Sprint("user:", userID, ":sticker:", fileID), // key
|
||||
emoji, // value
|
||||
nil, // options
|
||||
)
|
||||
|
||||
if err == buntdb.ErrIndexExists {
|
||||
exists = true
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
return exists, err
|
||||
}
|
||||
|
||||
func dbDeleteSticker(userID int, fileID string) (bool, error) {
|
||||
log.Ln("Trying to remove", fileID, "sticker from", userID, "user")
|
||||
err := db.Update(func(tx *buntdb.Tx) error {
|
||||
_, err := tx.Delete(fmt.Sprint("user:", userID, ":sticker:", fileID))
|
||||
return err
|
||||
})
|
||||
|
||||
switch err {
|
||||
case buntdb.ErrNotFound:
|
||||
log.Ln(userID, "not found, create new one")
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
func dbResetUserStickers(userID int) error {
|
||||
log.Ln("Trying reset all stickers of", userID, "user")
|
||||
return db.Update(func(tx *buntdb.Tx) error {
|
||||
var keys []string
|
||||
|
||||
err := tx.Ascend(
|
||||
"user_stickers", // index
|
||||
func(key, val string) bool { // iterator
|
||||
subKeys := strings.Split(key, ":")
|
||||
if subKeys[1] == strconv.Itoa(userID) {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
return true
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range keys {
|
||||
_, err = tx.Delete(keys[i])
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func dbGetUserStickers(userID int) ([]string, []string, error) {
|
||||
log.Ln("Trying to get", userID, "stickers")
|
||||
var stickers, emojis []string
|
||||
err := db.View(func(tx *buntdb.Tx) error {
|
||||
return tx.Ascend(
|
||||
"user_stickers", // index
|
||||
func(key, val string) bool { // iterator
|
||||
subKeys := strings.Split(key, ":")
|
||||
if subKeys[1] != strconv.Itoa(userID) {
|
||||
return true
|
||||
}
|
||||
|
||||
stickers = append(stickers, subKeys[3])
|
||||
emojis = append(emojis, val)
|
||||
return true
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
switch {
|
||||
case err == buntdb.ErrNotFound:
|
||||
log.Ln("Not found stickers")
|
||||
return nil, nil, nil
|
||||
case err != nil:
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return stickers, emojis, nil
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import "github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
|
||||
func commandDelete(msg *telegram.Message) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
stickers, _, err := dbGetUserStickers(msg.From.ID)
|
||||
errCheck(err)
|
||||
|
||||
if len(stickers) <= 0 {
|
||||
err = dbChangeUserState(msg.From.ID, stateNone)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(msg.Chat.ID, T("error_empty_remove"))
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = dbChangeUserState(msg.From.ID, stateDelete)
|
||||
errCheck(err)
|
||||
|
||||
markup := telegram.NewInlineKeyboardMarkup(
|
||||
telegram.NewInlineKeyboardRow(
|
||||
telegram.NewInlineKeyboardButtonSwitchSelf(
|
||||
T("button_remove"),
|
||||
" ",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
reply := telegram.NewMessage(msg.Chat.ID, T("reply_remove"))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
reply.ReplyMarkup = &markup
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
||||
|
||||
func actionDelete(msg *telegram.Message) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
notExist, err := dbDeleteSticker(msg.From.ID, msg.Sticker.FileID)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(msg.Chat.ID, T("success_remove"))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
if notExist {
|
||||
reply.Text = T("error_already_remove")
|
||||
}
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
version: "3"
|
||||
services:
|
||||
bot:
|
||||
container_name: mypackbot
|
||||
image: golang:latest
|
||||
expose:
|
||||
- 2368
|
||||
volumes:
|
||||
- ./MyPackBot:/go/MyPackBot
|
||||
- ./i18n/:/go/i18n/
|
||||
- ./config.yaml:/go/config.yaml
|
||||
- ./stickers.db:/go/stickers.db
|
||||
entrypoint: ["/go/MyPackBot", "-webhook"]
|
|
@ -0,0 +1,8 @@
|
|||
package main
|
||||
|
||||
// errCheck helps debug critical errors without warnings from 'gocyclo' linter
|
||||
func errCheck(err error) {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
)
|
||||
|
||||
// allowedUpdates is a value for parameter of updates configuration
|
||||
var allowedUpdates = []string{
|
||||
telegram.UpdateChosenInlineResult, // For collecting statistics
|
||||
telegram.UpdateInlineQuery, // For searching and sending stickers
|
||||
telegram.UpdateMessage, // For get commands and messages
|
||||
}
|
||||
|
||||
// getUpdatesChannel return webhook or long polling channel with bot updates
|
||||
func getUpdatesChannel() telegram.UpdatesChannel {
|
||||
log.Ln("Preparing channel for updates...")
|
||||
if !*flagWebhook {
|
||||
log.Ln("Use LongPolling updates")
|
||||
|
||||
log.Ln("Deleting webhook if exists")
|
||||
_, err := bot.DeleteWebhook()
|
||||
errCheck(err)
|
||||
|
||||
return bot.NewLongPollingChannel(&telegram.GetUpdatesParameters{
|
||||
Offset: 0,
|
||||
Limit: 100,
|
||||
Timeout: 60,
|
||||
AllowedUpdates: allowedUpdates,
|
||||
})
|
||||
}
|
||||
|
||||
set := cfg.UString("telegram.webhook.set")
|
||||
listen := cfg.UString("telegram.webhook.listen")
|
||||
serve := cfg.UString("telegram.webhook.serve")
|
||||
|
||||
log.Ln(
|
||||
"Trying set webhook on address:",
|
||||
fmt.Sprint(set, listen, bot.AccessToken),
|
||||
)
|
||||
|
||||
log.Ln("Creating new webhook...")
|
||||
webhook := telegram.NewWebhook(
|
||||
fmt.Sprint(set, listen, bot.AccessToken), nil,
|
||||
)
|
||||
webhook.MaxConnections = 100
|
||||
webhook.AllowedUpdates = allowedUpdates
|
||||
|
||||
return bot.NewWebhookChannel(
|
||||
webhook, // params
|
||||
"", // certFile
|
||||
"", // keyFile
|
||||
set, // set
|
||||
fmt.Sprint(listen, bot.AccessToken), // listen
|
||||
serve, // serve
|
||||
)
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package main
|
||||
|
||||
import "github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
|
||||
func commandHelp(msg *telegram.Message) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
err := dbChangeUserState(msg.From.ID, stateNone)
|
||||
errCheck(err)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
markup := telegram.NewInlineKeyboardMarkup(
|
||||
telegram.NewInlineKeyboardRow(
|
||||
telegram.NewInlineKeyboardButtonSwitch(
|
||||
T("button_share"),
|
||||
" ",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
reply := telegram.NewMessage(
|
||||
msg.Chat.ID, T("reply_help", map[string]interface{}{
|
||||
"AddStickerCommand": cmdAddSticker,
|
||||
"AddPackCommand": cmdAddPack,
|
||||
"DeleteCommand": cmdDelete,
|
||||
"ResetCommand": cmdReset,
|
||||
"CancelCommand": cmdCancel,
|
||||
"Username": bot.Self.Username,
|
||||
}),
|
||||
)
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
reply.ReplyMarkup = &markup
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
button_inline_add:
|
||||
one: You have {{.Count}} sticker. Add one more?
|
||||
other: You have {{.Count}} stickers. Add one more?
|
||||
button_inline_empty:
|
||||
other: Your pack is empty
|
||||
button_inline_nothing:
|
||||
other: Not found stickers for {{.Query}}, add one?
|
||||
button_remove:
|
||||
other: Select sticker for remove
|
||||
button_share:
|
||||
other: Use your stickers pack!
|
||||
cancel_add:
|
||||
other: You cancelled the process of adding a new sticker to your pack.
|
||||
cancel_add_pack:
|
||||
other: You cancelled the process of adding a new pack to yours.
|
||||
cancel_add_sticker:
|
||||
other: You cancelled the process of adding a new sticker to your pack.
|
||||
cancel_del:
|
||||
other: You cancelled the process of removing a sticker from your pack.
|
||||
cancel_error:
|
||||
other: Nothing to cancel.
|
||||
cancel_remove:
|
||||
other: You cancelled the process of removing a sticker from your pack.
|
||||
cancel_reset:
|
||||
other: You cancelled the process of reseting your stickers pack.
|
||||
error_already_add:
|
||||
other: This sticker is already in your pack.
|
||||
error_already_add_pack:
|
||||
other: All stickers from *{{.SetTitle}}* pack is already in yours.
|
||||
error_already_add_sticker:
|
||||
other: This sticker is already in your pack.
|
||||
error_already_del:
|
||||
other: Maybe this sticker is already removed from your pack.
|
||||
error_already_remove:
|
||||
other: Maybe this sticker is already removed from your pack.
|
||||
error_already_reset:
|
||||
other: There is nothing to reset, pack is already empty.
|
||||
error_empty_add_pack:
|
||||
other: You try to add a sticker that exists outside the packs. Use /{{.AddStickerCommand}}
|
||||
instead.
|
||||
error_empty_del:
|
||||
other: There is nothing to remove, pack is empty.
|
||||
error_empty_remove:
|
||||
other: There is nothing to remove, pack is empty.
|
||||
error_reset_phrase:
|
||||
other: Invalid phrase of resetting. This action has been canceled.
|
||||
error_unknown:
|
||||
other: |-
|
||||
I do not know what to do with this sticker.
|
||||
Please run /{{.AddStickerCommand}}, /{{.AddPackCommand}} or /{{.DeleteCommand}} command first.
|
||||
meta_reset_1:
|
||||
other: Wait. Who are you?
|
||||
meta_reset_2:
|
||||
other: What are you doing here?
|
||||
meta_reset_3:
|
||||
other: What am I doing here?
|
||||
reply_add:
|
||||
other: Send an existing sticker from any other pack to add it to yourself.
|
||||
reply_add_pack:
|
||||
other: Send an existing stickers from any other packs to add the entire packs to
|
||||
yourself.
|
||||
reply_add_sticker:
|
||||
other: Send an existing stickers from any other packs to add it to yourself.
|
||||
reply_del:
|
||||
other: Send an existing stickers from your pack for removing it.
|
||||
reply_help:
|
||||
other: |-
|
||||
/{{.AddStickerCommand}} - add a single sticker to your pack
|
||||
/{{.AddPackCommand}} - add a full other pack to your pack
|
||||
/{{.DeleteCommand}} - remove a single sticker from your pack
|
||||
/{{.ResetCommand}} - remove all stickers from your pack
|
||||
/{{.CancelCommand}} - cancel the current operation
|
||||
|
||||
To view and send stickers from your pack, just type `@{{.Username}}` (and space) in any chat.
|
||||
reply_remove:
|
||||
other: Send an existing sticker from your pack for removing it.
|
||||
reply_reset:
|
||||
other: |
|
||||
This operation will remove *all* stickers from your pack and *this can't be undone*.
|
||||
|
||||
Send `{{.KeyPhrase}}` to confirm what you really want to reset my brain (oh god why).
|
||||
Or use /{{.CancelCommand}} for abort current operation.
|
||||
reply_start:
|
||||
other: |
|
||||
Hello, I'm the [@{{.Username}}](tg://user?id={{.ID}})!
|
||||
I can create your personal pack with stickers from others packs.
|
||||
Without limits and installing. In any chat. For free.
|
||||
success_add:
|
||||
other: The sticker was successfully added to your pack!
|
||||
success_add_pack:
|
||||
other: The sticker pack *{{.SetTitle}}* was successfully added to yours!
|
||||
success_add_sticker:
|
||||
other: The sticker was successfully added to your pack!
|
||||
success_del:
|
||||
other: The sticker was successfully removed from your pack!
|
||||
success_remove:
|
||||
other: The sticker was successfully removed from your pack!
|
||||
success_reset:
|
||||
other: The contents of your pack are completely reset!..
|
|
@ -0,0 +1,11 @@
|
|||
button_inline_empty:
|
||||
other: Your pack is empty
|
||||
button_inline_nothing:
|
||||
other: Not found stickers for {{.Query}}, add one?
|
||||
button_inline_add:
|
||||
one: You have {{.Count}} sticker. Add one more?
|
||||
other: You have {{.Count}} stickers. Add one more?
|
||||
button_remove:
|
||||
other: Select sticker for remove
|
||||
button_share:
|
||||
other: Use your stickers pack!
|
|
@ -0,0 +1,10 @@
|
|||
cancel_add_sticker:
|
||||
other: You cancelled the process of adding a new sticker to your pack.
|
||||
cancel_add_pack:
|
||||
other: You cancelled the process of adding a new pack to yours.
|
||||
cancel_del:
|
||||
other: You cancelled the process of removing a sticker from your pack.
|
||||
cancel_reset:
|
||||
other: You cancelled the process of reseting your stickers pack.
|
||||
cancel_error:
|
||||
other: Nothing to cancel.
|
|
@ -0,0 +1,18 @@
|
|||
error_already_add_sticker:
|
||||
other: This sticker is already in your pack.
|
||||
error_already_add_pack:
|
||||
other: All stickers from *{{.SetTitle}}* pack is already in yours.
|
||||
error_already_del:
|
||||
other: Maybe this sticker is already removed from your pack.
|
||||
error_already_reset:
|
||||
other: There is nothing to reset, pack is already empty.
|
||||
error_reset_phrase:
|
||||
other: Invalid phrase of resetting. This action has been canceled.
|
||||
error_empty_del:
|
||||
other: There is nothing to remove, pack is empty.
|
||||
error_empty_add_pack:
|
||||
other: You try to add a sticker that exists outside the packs. Use /{{.AddStickerCommand}} instead.
|
||||
error_unknown:
|
||||
other: |
|
||||
I do not know what to do with this sticker.
|
||||
Please run /{{.AddStickerCommand}}, /{{.AddPackCommand}} or /{{.DeleteCommand}} command first.
|
|
@ -0,0 +1,6 @@
|
|||
meta_reset_1:
|
||||
other: Wait. Who are you?
|
||||
meta_reset_2:
|
||||
other: What are you doing here?
|
||||
meta_reset_3:
|
||||
other: What am I doing here?
|
|
@ -0,0 +1,26 @@
|
|||
reply_start:
|
||||
other: |
|
||||
Hello, I'm the [@{{.Username}}](tg://user?id={{.ID}})!
|
||||
I can create your personal pack with stickers from others packs.
|
||||
Without limits and installing. In any chat. For free.
|
||||
reply_add_sticker:
|
||||
other: Send an existing stickers from any other packs to add it to yourself.
|
||||
reply_add_pack:
|
||||
other: Send an existing stickers from any other packs to add the entire packs to yourself.
|
||||
reply_del:
|
||||
other: Send an existing stickers from your pack for removing it.
|
||||
reply_reset:
|
||||
other: |
|
||||
This operation will remove *all* stickers from your pack and *this can't be undone*.
|
||||
|
||||
Send `{{.KeyPhrase}}` to confirm what you really want to reset my brain (oh god why).
|
||||
Or use /{{.CancelCommand}} for abort current operation.
|
||||
reply_help:
|
||||
other: |
|
||||
/{{.AddStickerCommand}} - add a single sticker to your pack
|
||||
/{{.AddPackCommand}} - add a full other pack to your pack
|
||||
/{{.DeleteCommand}} - remove a single sticker from your pack
|
||||
/{{.ResetCommand}} - remove all stickers from your pack
|
||||
/{{.CancelCommand}} - cancel the current operation
|
||||
|
||||
To view and send stickers from your pack, just type `@{{.Username}}` (and space) in any chat.
|
|
@ -0,0 +1,8 @@
|
|||
success_add_sticker:
|
||||
other: The sticker was successfully added to your pack!
|
||||
success_add_pack:
|
||||
other: The sticker pack *{{.SetTitle}}* was successfully added to yours!
|
||||
success_del:
|
||||
other: The sticker was successfully removed from your pack!
|
||||
success_reset:
|
||||
other: The contents of your pack are completely reset!..
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -0,0 +1,68 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/nicksnyder/go-i18n/i18n" // Internationalization and localization
|
||||
"github.com/olebedev/config" // Easy configuration file parsing
|
||||
"github.com/toby3d/botan"
|
||||
)
|
||||
|
||||
var (
|
||||
// Variables with types from imports
|
||||
cfg *config.Config
|
||||
appMetrika *botan.Botan
|
||||
|
||||
// Setted variables
|
||||
metrika = make(chan bool)
|
||||
flagWebhook = flag.Bool(
|
||||
"webhook",
|
||||
false,
|
||||
"enable work via webhooks (required valid certificates)",
|
||||
)
|
||||
)
|
||||
|
||||
// init prepare configuration and other things for successful start of main
|
||||
// function.
|
||||
func init() {
|
||||
log.Ln("Initializing...")
|
||||
log.Ln("Parse flags...")
|
||||
flag.Parse()
|
||||
|
||||
err := filepath.Walk("./i18n/", func(path string, info os.FileInfo, err error) error {
|
||||
if strings.HasSuffix(path, ".all.yaml") {
|
||||
i18n.MustLoadTranslationFile(path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
errCheck(err)
|
||||
|
||||
log.Ln("Loading configuration file...")
|
||||
cfg, err = config.ParseYamlFile("config.yaml")
|
||||
errCheck(err)
|
||||
|
||||
appMetrika = botan.New(cfg.UString("botan"))
|
||||
|
||||
log.Ln("Checking bot access token in configuration file...")
|
||||
_, err = cfg.String("telegram.token")
|
||||
errCheck(err)
|
||||
|
||||
if *flagWebhook {
|
||||
log.Ln("Enabled webhook mode, check configuration strings...")
|
||||
log.Ln("Checking webhook set string...")
|
||||
_, err = cfg.String("telegram.webhook.set")
|
||||
errCheck(err)
|
||||
|
||||
log.Ln("Checking webhook listen string...")
|
||||
_, err = cfg.String("telegram.webhook.listen")
|
||||
errCheck(err)
|
||||
|
||||
log.Ln("Checking webhook listen string...")
|
||||
_, err = cfg.String("telegram.webhook.serve")
|
||||
errCheck(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
)
|
||||
|
||||
const perPage = 50
|
||||
|
||||
var r = strings.NewReplacer(
|
||||
"🏻", "",
|
||||
"🏼", "",
|
||||
"🏽", "",
|
||||
"🏾", "",
|
||||
"🏿", "",
|
||||
)
|
||||
|
||||
func inlineQuery(inline *telegram.InlineQuery) {
|
||||
inline.Query = r.Replace(inline.Query)
|
||||
|
||||
log.Ln("Let's preparing answer...")
|
||||
T, err := switchLocale(inline.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
log.Ln("INLINE OFFSET:", inline.Offset)
|
||||
if inline.Offset == "" {
|
||||
inline.Offset = "-1"
|
||||
}
|
||||
offset, err := strconv.Atoi(inline.Offset)
|
||||
errCheck(err)
|
||||
if offset == -1 {
|
||||
offset++
|
||||
}
|
||||
|
||||
answer := &telegram.AnswerInlineQueryParameters{
|
||||
InlineQueryID: inline.ID,
|
||||
CacheTime: 1,
|
||||
IsPersonal: true,
|
||||
}
|
||||
|
||||
stickers, emojis, err := dbGetUserStickers(inline.From.ID)
|
||||
errCheck(err)
|
||||
|
||||
packSize := len(stickers)
|
||||
|
||||
if inline.Query != "" {
|
||||
var buffer []string
|
||||
for i := range stickers {
|
||||
if emojis[i] != inline.Query {
|
||||
continue
|
||||
}
|
||||
|
||||
buffer = append(buffer, stickers[i])
|
||||
}
|
||||
stickers = buffer
|
||||
}
|
||||
|
||||
totalStickers := len(stickers)
|
||||
totalPages := totalStickers / perPage
|
||||
if totalStickers == 0 {
|
||||
if inline.Query != "" {
|
||||
// If search stickers by emoji return 0 results
|
||||
answer.SwitchPrivateMessageText = T(
|
||||
"button_inline_nothing",
|
||||
map[string]interface{}{"Query": inline.Query},
|
||||
)
|
||||
answer.SwitchPrivateMessageParameter = cmdAddSticker
|
||||
} else {
|
||||
// If query is empty and get 0 stickers
|
||||
answer.SwitchPrivateMessageText = T("button_inline_empty")
|
||||
answer.SwitchPrivateMessageParameter = cmdAddSticker
|
||||
}
|
||||
} else {
|
||||
log.Ln("LESS THAN:", offset < totalPages)
|
||||
if offset < totalPages {
|
||||
from := offset * perPage
|
||||
if offset > 0 {
|
||||
from--
|
||||
}
|
||||
to := from + perPage
|
||||
|
||||
log.Ln("from:", from)
|
||||
log.Ln("to:", to)
|
||||
|
||||
stickers = stickers[from:to]
|
||||
|
||||
offset++
|
||||
answer.NextOffset = strconv.Itoa(offset)
|
||||
} else {
|
||||
from := offset * perPage
|
||||
if offset > 0 {
|
||||
from--
|
||||
}
|
||||
to := from
|
||||
log.Ln("MINUS:", totalStickers%perPage)
|
||||
if totalStickers%perPage != 0 {
|
||||
log.Ln("FUCK")
|
||||
to += totalStickers % perPage
|
||||
} else {
|
||||
to += perPage
|
||||
}
|
||||
|
||||
log.Ln("from:", from)
|
||||
log.Ln("to:", to)
|
||||
stickers = stickers[from:to]
|
||||
}
|
||||
|
||||
log.Ln("Stickers after checks:", len(stickers))
|
||||
|
||||
var results = make([]interface{}, len(stickers))
|
||||
for i, sticker := range stickers {
|
||||
results[i] = telegram.NewInlineQueryResultCachedSticker(
|
||||
sticker, sticker,
|
||||
)
|
||||
}
|
||||
|
||||
answer.SwitchPrivateMessageText = T(
|
||||
"button_inline_add",
|
||||
packSize,
|
||||
map[string]interface{}{
|
||||
"Count": packSize,
|
||||
})
|
||||
answer.SwitchPrivateMessageParameter = cmdAddSticker
|
||||
answer.Results = results
|
||||
}
|
||||
|
||||
_, err = bot.AnswerInlineQuery(answer)
|
||||
errCheck(err)
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/toby3d/botan"
|
||||
"github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
)
|
||||
|
||||
// bot is general structure of the bot
|
||||
var bot *telegram.Bot
|
||||
|
||||
// main function is a general function for work of this bot
|
||||
func main() {
|
||||
log.Ln("Let'g Get It Started...")
|
||||
var err error
|
||||
|
||||
go dbInit()
|
||||
|
||||
log.Ln("Initializing new bot via checking access_token...")
|
||||
bot, err = telegram.NewBot(cfg.UString("telegram.token"))
|
||||
errCheck(err)
|
||||
|
||||
log.Ln("Let's check updates channel!")
|
||||
for update := range getUpdatesChannel() {
|
||||
switch {
|
||||
case update.ChosenInlineResult != nil:
|
||||
log.Ln("Get ChosenInlineResult update")
|
||||
appMetrika.Track(
|
||||
"Chosen inline result",
|
||||
update.ChosenInlineResult.From.ID,
|
||||
*update.ChosenInlineResult,
|
||||
)
|
||||
case update.InlineQuery != nil:
|
||||
// Just don't check same updates
|
||||
log.D(update.InlineQuery.Query)
|
||||
if len(update.InlineQuery.Query) > 25 {
|
||||
continue
|
||||
}
|
||||
|
||||
appMetrika.TrackAsync(
|
||||
"Inline query", update.InlineQuery.From.ID, *update.InlineQuery,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
inlineQuery(update.InlineQuery)
|
||||
|
||||
<-metrika
|
||||
case update.Message != nil:
|
||||
if update.Message.From.ID == bot.Self.ID {
|
||||
log.Ln("Received a message from myself, ignore this update")
|
||||
return
|
||||
}
|
||||
|
||||
if update.Message.ForwardFrom != nil {
|
||||
if update.Message.ForwardFrom.ID == bot.Self.ID {
|
||||
log.Ln("Received a forward from myself, ignore this update")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
messages(update.Message)
|
||||
default:
|
||||
log.Ln("Get unsupported update")
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err = db.Close()
|
||||
errCheck(err)
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/toby3d/botan"
|
||||
"github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
)
|
||||
|
||||
// message function check Message update on commands, sended stickers or other
|
||||
// user stuff
|
||||
func messages(msg *telegram.Message) {
|
||||
if msg.IsCommand() {
|
||||
commands(msg)
|
||||
return
|
||||
}
|
||||
|
||||
state, err := dbGetUserState(msg.From.ID)
|
||||
errCheck(err)
|
||||
|
||||
switch state {
|
||||
case stateNone:
|
||||
appMetrika.TrackAsync(
|
||||
"Nothing", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(
|
||||
msg.Chat.ID,
|
||||
T("error_unknown", map[string]interface{}{
|
||||
"AddStickerCommand": cmdAddSticker,
|
||||
"AddPackCommand": cmdAddPack,
|
||||
"DeleteCommand": cmdDelete,
|
||||
}))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
|
||||
<-metrika
|
||||
case stateAddSticker:
|
||||
if msg.Sticker == nil {
|
||||
appMetrika.Track("Message", msg.From.ID, *msg)
|
||||
return
|
||||
}
|
||||
|
||||
log.D(msg.Sticker)
|
||||
log.D(msg.Sticker.Emoji)
|
||||
|
||||
appMetrika.TrackAsync(
|
||||
"Add single sticker", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
actionAdd(msg, false)
|
||||
|
||||
<-metrika
|
||||
case stateAddPack:
|
||||
if msg.Sticker == nil {
|
||||
appMetrika.Track("Message", msg.From.ID, *msg)
|
||||
return
|
||||
}
|
||||
|
||||
appMetrika.TrackAsync(
|
||||
"Add pack", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
log.D(msg.Sticker)
|
||||
log.D(msg.Sticker.Emoji)
|
||||
|
||||
actionAdd(msg, true)
|
||||
|
||||
<-metrika
|
||||
case stateDelete:
|
||||
if msg.Sticker == nil {
|
||||
appMetrika.Track("Message", msg.From.ID, *msg)
|
||||
return
|
||||
}
|
||||
|
||||
appMetrika.TrackAsync(
|
||||
"Delete sticker", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
log.D(msg.Sticker)
|
||||
log.D(msg.Sticker.Emoji)
|
||||
|
||||
actionDelete(msg)
|
||||
|
||||
<-metrika
|
||||
case stateReset:
|
||||
appMetrika.TrackAsync(
|
||||
"Reset pack", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
actionReset(msg)
|
||||
|
||||
<-metrika
|
||||
default:
|
||||
appMetrika.TrackAsync(
|
||||
"Message", msg.From.ID, *msg,
|
||||
func(answer *botan.Answer, err error) {
|
||||
log.Ln("Asynchonous:", answer.Status)
|
||||
metrika <- true
|
||||
},
|
||||
)
|
||||
|
||||
err = dbChangeUserState(msg.From.ID, stateNone)
|
||||
errCheck(err)
|
||||
|
||||
messages(msg)
|
||||
|
||||
<-metrika
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
)
|
||||
|
||||
const keyPhrase = "Yes, I am totally sure."
|
||||
|
||||
func commandReset(msg *telegram.Message) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
stickers, _, err := dbGetUserStickers(msg.From.ID)
|
||||
errCheck(err)
|
||||
|
||||
if len(stickers) <= 0 {
|
||||
err = dbChangeUserState(msg.From.ID, stateNone)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(msg.Chat.ID, T("error_already_reset"))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = dbChangeUserState(msg.From.ID, stateReset)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(
|
||||
msg.Chat.ID,
|
||||
T("reply_reset", map[string]interface{}{
|
||||
"KeyPhrase": keyPhrase,
|
||||
"CancelCommand": cmdCancel,
|
||||
}))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
||||
|
||||
func actionReset(msg *telegram.Message) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
err := dbChangeUserState(msg.From.ID, stateNone)
|
||||
errCheck(err)
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
if msg.Text != keyPhrase {
|
||||
reply := telegram.NewMessage(msg.Chat.ID, T("error_reset_phrase"))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = dbResetUserStickers(msg.From.ID)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(msg.Chat.ID, T("success_reset"))
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
|
||||
for i := 1; i <= 3; i++ {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
text := T(fmt.Sprint("meta_reset_", i))
|
||||
|
||||
time.Sleep(time.Minute * time.Duration(len(text)) / 1000)
|
||||
|
||||
reply = telegram.NewMessage(msg.Chat.ID, text)
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/toby3d/go-telegram" // My Telegram bindings
|
||||
)
|
||||
|
||||
func commandStart(msg *telegram.Message) {
|
||||
bot.SendChatAction(msg.Chat.ID, telegram.ActionTyping)
|
||||
|
||||
err := dbChangeUserState(msg.From.ID, stateNone)
|
||||
errCheck(err)
|
||||
|
||||
if msg.HasArgument() {
|
||||
log.Ln("Received a", msg.Command(), "command with", msg.CommandArgument(), "argument")
|
||||
if strings.ToLower(msg.CommandArgument()) == strings.ToLower(cmdAddSticker) {
|
||||
commandAdd(msg, false)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
T, err := switchLocale(msg.From.LanguageCode)
|
||||
errCheck(err)
|
||||
|
||||
reply := telegram.NewMessage(
|
||||
msg.Chat.ID, T("reply_start", map[string]interface{}{
|
||||
"Username": bot.Self.Username,
|
||||
"ID": bot.Self.ID,
|
||||
}),
|
||||
)
|
||||
reply.ParseMode = telegram.ModeMarkdown
|
||||
|
||||
_, err = bot.SendMessage(reply)
|
||||
errCheck(err)
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
log "github.com/kirillDanshin/dlog" // Insert logs only in debug builds
|
||||
"github.com/nicksnyder/go-i18n/i18n" // Internationalization and localization
|
||||
)
|
||||
|
||||
const langDefault = "en-us"
|
||||
|
||||
func switchLocale(langCode string) (T i18n.TranslateFunc, err error) {
|
||||
log.Ln("Check", langCode, "localization")
|
||||
T, err = i18n.Tfunc(langCode)
|
||||
if err != nil {
|
||||
log.Ln("Unsupported language, change to 'en-us' by default")
|
||||
T, err = i18n.Tfunc(langDefault)
|
||||
}
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue