Fixes and refactor
This commit is contained in:
		
							
								
								
									
										39
									
								
								commands.go
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								commands.go
									
									
									
									
									
								
							@ -1,47 +1,14 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	neco "git.nefrace.ru/nefrace/nechotron"
 | 
						neco "git.nefrace.ru/nefrace/nechotron"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var commandMe = neco.NewCommand("me", "Пишу ваш текст о вас в третьем лице", false)
 | 
					var commandMe = neco.NewCommand("me", "Пишу ваш текст о вас в третьем лице", false)
 | 
				
			||||||
 | 
					 | 
				
			||||||
func handleMe(u *neco.Update) error {
 | 
					 | 
				
			||||||
	u.DeleteMessage()
 | 
					 | 
				
			||||||
	param := commandMe.Param(u.Text())
 | 
					 | 
				
			||||||
	_, err := u.AnswerMarkdown(fmt.Sprintf("_*%s* %s_", neco.EscapeMd2(u.From().FirstName), neco.EscapeMd2(param)))
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var commandHelp = neco.NewCommand("help", "Показываю данный текст", false)
 | 
					var commandHelp = neco.NewCommand("help", "Показываю данный текст", false)
 | 
				
			||||||
 | 
					 | 
				
			||||||
var helpText = `
 | 
					 | 
				
			||||||
Вот мои команды:
 | 
					 | 
				
			||||||
%s
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Время сборки бота: %s`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func handleHelp(u *neco.Update) error {
 | 
					 | 
				
			||||||
	commands := neco.MakeCommandList("`%s` \\- _%s_\n", commandHelp, commandMe)
 | 
					 | 
				
			||||||
	_, err := u.AnswerMarkdown(fmt.Sprintf(helpText, commands, BuildTime))
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var commandSay = neco.NewCommand("say", "Пишу ваш текст от своего имени.", true)
 | 
					var commandSay = neco.NewCommand("say", "Пишу ваш текст от своего имени.", true)
 | 
				
			||||||
 | 
					 | 
				
			||||||
func handleSay(u *neco.Update) error {
 | 
					 | 
				
			||||||
	u.DeleteMessage()
 | 
					 | 
				
			||||||
	param := commandSay.Param(u.Text())
 | 
					 | 
				
			||||||
	_, err := u.AnswerMarkdown(fmt.Sprintf("*_%s_*", neco.EscapeMd2(param)))
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var commandWarn = neco.NewCommand("warn", "Делаю предупреждение пользователю", true)
 | 
					var commandWarn = neco.NewCommand("warn", "Делаю предупреждение пользователю", true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func handleWarn(u *neco.Update) error {
 | 
					var defaultCommands = []*neco.Command{commandHelp, commandMe}
 | 
				
			||||||
	param := commandWarn.Param(u.Text())
 | 
					var adminCommands = []*neco.Command{commandSay, commandWarn}
 | 
				
			||||||
	_, err := u.AnswerMarkdown(fmt.Sprintf("*_%s_*", neco.EscapeMd2(param)))
 | 
					var allCommands = append(defaultCommands, adminCommands...)
 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								filters.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								filters.go
									
									
									
									
									
								
							@ -44,3 +44,13 @@ func docRequest(u *neco.Update) bool {
 | 
				
			|||||||
	u.Ctx = context.WithValue(u.Ctx, neco.FilteredValue("docTopic"), result["topic"])
 | 
						u.Ctx = context.WithValue(u.Ctx, neco.FilteredValue("docTopic"), result["topic"])
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func isFile(u *neco.Update) bool {
 | 
				
			||||||
 | 
						if u.Message == nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if u.Message.Document == nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										105
									
								
								handle-docs.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								handle-docs.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.nefrace.ru/nefrace/nechotron"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var docApiURL = "https://docs.godotengine.org/_/api/v2/search/?q=%s&project=godot&version=%s&language=en"
 | 
				
			||||||
 | 
					var docURL = "https://docs.godotengine.org/ru/stable/search.html?q=%s"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DocResponse struct {
 | 
				
			||||||
 | 
						Count    uint        `json:"count"`
 | 
				
			||||||
 | 
						Next     string      `json:"next"`
 | 
				
			||||||
 | 
						Previous string      `json:"previous"`
 | 
				
			||||||
 | 
						Results  []DocResult `json:"results"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DocResult struct {
 | 
				
			||||||
 | 
						Title      string        `json:"title"`
 | 
				
			||||||
 | 
						Domain     string        `json:"domain"`
 | 
				
			||||||
 | 
						Path       string        `json:"path"`
 | 
				
			||||||
 | 
						Highlights DocHighlights `json:"highlights"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DocHighlights struct {
 | 
				
			||||||
 | 
						Title []string `json:"title"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getDocs(topic string, version string) (string, error) {
 | 
				
			||||||
 | 
						topic_escaped := nechotron.EscapeMd2(topic)
 | 
				
			||||||
 | 
						not_found := fmt.Sprintf("Извините, по запросу *%s* ничего не найдено.", topic_escaped)
 | 
				
			||||||
 | 
						req, err := url.ParseRequestURI(fmt.Sprintf(docApiURL, url.QueryEscape(topic), version))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return not_found, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result, err := http.Get(req.String())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return not_found, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer result.Body.Close()
 | 
				
			||||||
 | 
						var response DocResponse
 | 
				
			||||||
 | 
						err = json.NewDecoder(result.Body).Decode(&response)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return not_found, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						textResults := ""
 | 
				
			||||||
 | 
						for i, r := range response.Results {
 | 
				
			||||||
 | 
							if i > 9 {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							text := nechotron.EscapeMd2(r.Title)
 | 
				
			||||||
 | 
							link, _ := url.JoinPath(r.Domain, r.Path)
 | 
				
			||||||
 | 
							textResults += fmt.Sprintf("%d\\. [%s](%s)\n", i+1, text, link)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						text := fmt.Sprintf("Вот что я нашла по запросу *%s* \\(для версии `%s`\\): \n\n%s", topic_escaped, version, textResults)
 | 
				
			||||||
 | 
						return text, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleDocRequest(u *nechotron.Update) error {
 | 
				
			||||||
 | 
						topic := u.Ctx.Value(nechotron.FilteredValue("docTopic")).(string)
 | 
				
			||||||
 | 
						kb := nechotron.NewInlineKeyboard().
 | 
				
			||||||
 | 
							Row(
 | 
				
			||||||
 | 
								nechotron.InButtonCallback("Дай для 3.5", fmt.Sprintf("docs3:%s", topic)),
 | 
				
			||||||
 | 
								nechotron.InButtonCallback("А на русском можно?", "rudocs")).
 | 
				
			||||||
 | 
							Row(nechotron.InButtonURL("Поищу сам", fmt.Sprintf(docURL, url.QueryEscape(topic)))).
 | 
				
			||||||
 | 
							Row(nechotron.InButtonCallback("Спасибо, не надо", "delete"))
 | 
				
			||||||
 | 
						opts := nechotron.NewOptions().
 | 
				
			||||||
 | 
							MarkdownV2().
 | 
				
			||||||
 | 
							ReplyTo(u.MessageID()).
 | 
				
			||||||
 | 
							ReplyMarkup(kb.Markup()).
 | 
				
			||||||
 | 
							MessageOptions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						text, docerr := getDocs(topic, "latest")
 | 
				
			||||||
 | 
						if docerr != nil {
 | 
				
			||||||
 | 
							log.Println("Can't get docs: ", docerr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err := u.AnswerText(text, opts)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleDocRequest3(u *nechotron.Update) error {
 | 
				
			||||||
 | 
						topic := strings.TrimPrefix(u.Callback(), "docs3:")
 | 
				
			||||||
 | 
						kb := nechotron.NewInlineKeyboard().
 | 
				
			||||||
 | 
							Row(
 | 
				
			||||||
 | 
								nechotron.InButtonCallback("А на русском можно?", "rudocs")).
 | 
				
			||||||
 | 
							Row(nechotron.InButtonURL("Поищу сам", fmt.Sprintf(docURL, url.QueryEscape(topic)))).
 | 
				
			||||||
 | 
							Row(nechotron.InButtonCallback("Спасибо, не надо", "delete"))
 | 
				
			||||||
 | 
						opts := nechotron.NewOptions().
 | 
				
			||||||
 | 
							MarkdownV2().
 | 
				
			||||||
 | 
							ReplyMarkup(kb.Markup()).
 | 
				
			||||||
 | 
							MessageTextOptions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						text, docerr := getDocs(topic, "3.5")
 | 
				
			||||||
 | 
						if docerr != nil {
 | 
				
			||||||
 | 
							log.Println("Can't get docs: ", docerr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err := u.EditText(text, opts)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										89
									
								
								handle-karma.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								handle-karma.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.nefrace.ru/nefrace/nechotron"
 | 
				
			||||||
 | 
						"git.nefrace.ru/nefrace/tongo"
 | 
				
			||||||
 | 
						"github.com/NicoNex/echotron/v3"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Returns slices of good and bad triggers
 | 
				
			||||||
 | 
					func GetTriggers() map[string]int {
 | 
				
			||||||
 | 
						return map[string]int{
 | 
				
			||||||
 | 
							"+": 1,
 | 
				
			||||||
 | 
							"-": -1,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleKarma(u *nechotron.Update) error {
 | 
				
			||||||
 | 
						from, _ := u.Ctx.Value("userfrom").(*User)
 | 
				
			||||||
 | 
						to, _ := u.Ctx.Value("userto").(*User)
 | 
				
			||||||
 | 
						mentionFrom := nechotron.UserMention(u.Message.From)
 | 
				
			||||||
 | 
						mentionTo := nechotron.UserMention(u.Message.ReplyToMessage.From)
 | 
				
			||||||
 | 
						if from.ID == to.ID {
 | 
				
			||||||
 | 
							res, err := u.AnswerMarkdown(
 | 
				
			||||||
 | 
								fmt.Sprintf("Лайкать себя \\- плохая затея, *%s*", mentionFrom))
 | 
				
			||||||
 | 
							go func() {
 | 
				
			||||||
 | 
								time.Sleep(10 * time.Second)
 | 
				
			||||||
 | 
								u.Bot.DeleteMessage(u.ChatID(), res.Result.ID)
 | 
				
			||||||
 | 
							}()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						value := u.Ctx.Value(nechotron.FilteredValue("karmaValue")).(int)
 | 
				
			||||||
 | 
						// trigger := u.Ctx.Value(nechotron.FilteredValue("karmaTrigger")).(string)
 | 
				
			||||||
 | 
						store := tongo.NewStore[KarmaShot](db)
 | 
				
			||||||
 | 
						fromKarma, _ := store.Count(u.Ctx, tongo.E("to", from.ID))
 | 
				
			||||||
 | 
						totalFromKarma := from.KarmaOffset + fromKarma
 | 
				
			||||||
 | 
						if totalFromKarma < 0 {
 | 
				
			||||||
 | 
							res, err := u.AnswerText(
 | 
				
			||||||
 | 
								fmt.Sprintf("У тебя слишком маленькая карма *\\(%d\\), чтобы менять её другим\\.", totalFromKarma),
 | 
				
			||||||
 | 
								&echotron.MessageOptions{ParseMode: echotron.MarkdownV2, ReplyToMessageID: u.MessageID()})
 | 
				
			||||||
 | 
							go waitAndDelete(u, u.ChatID(), res.Result.ID)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						timeThreshold := time.Now().Add(1 * -time.Minute)
 | 
				
			||||||
 | 
						recentShots, err := store.Count(
 | 
				
			||||||
 | 
							u.Ctx,
 | 
				
			||||||
 | 
							tongo.E("from", from.ID),
 | 
				
			||||||
 | 
							tongo.E("to", to.ID),
 | 
				
			||||||
 | 
							tongo.E("when", tongo.D(tongo.E("$gte", timeThreshold))))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if recentShots > 0 {
 | 
				
			||||||
 | 
							// u.DeleteMessage()
 | 
				
			||||||
 | 
							res, err := u.AnswerMarkdown(
 | 
				
			||||||
 | 
								fmt.Sprintf("*%s*, ты только недавно менял карму *%s*\\. Подожди минуту\\.", mentionFrom, mentionTo))
 | 
				
			||||||
 | 
							go waitAndDelete(u, u.ChatID(), res.Result.ID)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if to.ID == u.Bot.Me.ID {
 | 
				
			||||||
 | 
							if value > 0 {
 | 
				
			||||||
 | 
								u.AnswerMarkdown("*_Ой, это мне?_*")
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								res, err := u.AnswerMarkdown("*_Кажется, вы ошиблись адресатом :/_*")
 | 
				
			||||||
 | 
								go waitAndDelete(u, u.ChatID(), res.Result.ID)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						newShot := KarmaShot{
 | 
				
			||||||
 | 
							Item:        tongo.NewID(),
 | 
				
			||||||
 | 
							From:        from.ID,
 | 
				
			||||||
 | 
							To:          to.ID,
 | 
				
			||||||
 | 
							MessageText: nechotron.GetText(u.Message.ReplyToMessage),
 | 
				
			||||||
 | 
							When:        time.Now(),
 | 
				
			||||||
 | 
							Count:       value,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						store.InsertOne(u.Ctx, &newShot)
 | 
				
			||||||
 | 
						newKarma, _ := store.Count(u.Ctx, tongo.E("to", to.ID))
 | 
				
			||||||
 | 
						totalToKarma := to.KarmaOffset + newKarma
 | 
				
			||||||
 | 
						changeText := "повысил"
 | 
				
			||||||
 | 
						if value < 0 {
 | 
				
			||||||
 | 
							changeText = "понизил"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = u.AnswerMarkdown(
 | 
				
			||||||
 | 
							fmt.Sprintf("*%s \\(%d\\)* только что %s карму *%s \\(%d\\)*", mentionFrom, totalFromKarma, changeText, mentionTo, totalToKarma))
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										181
									
								
								handlers.go
									
									
									
									
									
								
							
							
						
						
									
										181
									
								
								handlers.go
									
									
									
									
									
								
							@ -1,181 +1,37 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"math/rand"
 | 
						"math/rand"
 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.nefrace.ru/nefrace/nechotron"
 | 
						"git.nefrace.ru/nefrace/nechotron"
 | 
				
			||||||
	"git.nefrace.ru/nefrace/tongo"
 | 
						"git.nefrace.ru/nefrace/tongo"
 | 
				
			||||||
	"github.com/NicoNex/echotron/v3"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var docApiURL = "https://docs.godotengine.org/_/api/v2/search/?q=%s&project=godot&version=%s&language=en"
 | 
					// Docs
 | 
				
			||||||
var docURL = "https://docs.godotengine.org/ru/stable/search.html?q=%s"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type DocResponse struct {
 | 
					func handleMe(u *nechotron.Update, text string) error {
 | 
				
			||||||
	Count    uint        `json:"count"`
 | 
						u.DeleteMessage()
 | 
				
			||||||
	Next     string      `json:"next"`
 | 
						_, err := u.AnswerMarkdown(fmt.Sprintf("_*%s* %s_", nechotron.EscapeMd2(u.From().FirstName), nechotron.EscapeMd2(text)))
 | 
				
			||||||
	Previous string      `json:"previous"`
 | 
					 | 
				
			||||||
	Results  []DocResult `json:"results"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type DocResult struct {
 | 
					 | 
				
			||||||
	Title      string        `json:"title"`
 | 
					 | 
				
			||||||
	Domain     string        `json:"domain"`
 | 
					 | 
				
			||||||
	Path       string        `json:"path"`
 | 
					 | 
				
			||||||
	Highlights DocHighlights `json:"highlights"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type DocHighlights struct {
 | 
					 | 
				
			||||||
	Title []string `json:"title"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getDocs(topic string, version string) (string, error) {
 | 
					 | 
				
			||||||
	topic_escaped := nechotron.EscapeMd2(topic)
 | 
					 | 
				
			||||||
	not_found := fmt.Sprintf("Извините, по запросу *%s* ничего не найдено.", topic_escaped)
 | 
					 | 
				
			||||||
	req, err := url.ParseRequestURI(fmt.Sprintf(docApiURL, url.QueryEscape(topic), version))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return not_found, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	result, err := http.Get(req.String())
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return not_found, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer result.Body.Close()
 | 
					 | 
				
			||||||
	var response DocResponse
 | 
					 | 
				
			||||||
	err = json.NewDecoder(result.Body).Decode(&response)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return not_found, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	textResults := ""
 | 
					 | 
				
			||||||
	for i, r := range response.Results {
 | 
					 | 
				
			||||||
		if i > 9 {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		text := nechotron.EscapeMd2(r.Title)
 | 
					 | 
				
			||||||
		link, _ := url.JoinPath(r.Domain, r.Path)
 | 
					 | 
				
			||||||
		textResults += fmt.Sprintf("%d\\. [%s](%s)\n", i+1, text, link)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	text := fmt.Sprintf("Вот что я нашла по запросу *%s* \\(для версии `%s`\\): \n\n%s", topic_escaped, version, textResults)
 | 
					 | 
				
			||||||
	return text, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func handleDocRequest(u *nechotron.Update) error {
 | 
					 | 
				
			||||||
	topic := u.Ctx.Value(nechotron.FilteredValue("docTopic")).(string)
 | 
					 | 
				
			||||||
	kb := nechotron.NewInlineKeyboard().
 | 
					 | 
				
			||||||
		Row(
 | 
					 | 
				
			||||||
			nechotron.InButtonCallback("Дай для 3.5", fmt.Sprintf("docs3:%s", topic)),
 | 
					 | 
				
			||||||
			nechotron.InButtonCallback("А на русском можно?", "rudocs")).
 | 
					 | 
				
			||||||
		Row(nechotron.InButtonURL("Поищу сам", fmt.Sprintf(docURL, url.QueryEscape(topic)))).
 | 
					 | 
				
			||||||
		Row(nechotron.InButtonCallback("Спасибо, не надо", "delete"))
 | 
					 | 
				
			||||||
	opts := nechotron.NewOptions().
 | 
					 | 
				
			||||||
		MarkdownV2().
 | 
					 | 
				
			||||||
		ReplyTo(u.MessageID()).
 | 
					 | 
				
			||||||
		ReplyMarkup(kb.Markup()).
 | 
					 | 
				
			||||||
		MessageOptions()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	text, docerr := getDocs(topic, "latest")
 | 
					 | 
				
			||||||
	if docerr != nil {
 | 
					 | 
				
			||||||
		log.Println("Can't get docs: ", docerr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_, err := u.AnswerText(text, opts)
 | 
					 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func handleDocRequest3(u *nechotron.Update) error {
 | 
					var helpText = `
 | 
				
			||||||
	topic := strings.TrimPrefix(u.Callback(), "docs3:")
 | 
					Вот мои команды:
 | 
				
			||||||
	kb := nechotron.NewInlineKeyboard().
 | 
					%s
 | 
				
			||||||
		Row(
 | 
					 | 
				
			||||||
			nechotron.InButtonCallback("А на русском можно?", "rudocs")).
 | 
					 | 
				
			||||||
		Row(nechotron.InButtonURL("Поищу сам", fmt.Sprintf(docURL, url.QueryEscape(topic)))).
 | 
					 | 
				
			||||||
		Row(nechotron.InButtonCallback("Спасибо, не надо", "delete"))
 | 
					 | 
				
			||||||
	opts := nechotron.NewOptions().
 | 
					 | 
				
			||||||
		MarkdownV2().
 | 
					 | 
				
			||||||
		ReplyMarkup(kb.Markup()).
 | 
					 | 
				
			||||||
		MessageTextOptions()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	text, docerr := getDocs(topic, "3.5")
 | 
					Время сборки бота: %s`
 | 
				
			||||||
	if docerr != nil {
 | 
					
 | 
				
			||||||
		log.Println("Can't get docs: ", docerr)
 | 
					func handleHelp(u *nechotron.Update, text string) error {
 | 
				
			||||||
	}
 | 
						commands := nechotron.MakeCommandList("`%s` \\- _%s_\n", commandHelp, commandMe)
 | 
				
			||||||
	_, err := u.EditText(text, opts)
 | 
						_, err := u.AnswerMarkdown(fmt.Sprintf(helpText, commands, BuildTime))
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func handleKarma(u *nechotron.Update) error {
 | 
					func handleSay(u *nechotron.Update, text string) error {
 | 
				
			||||||
	from, _ := u.Ctx.Value("userfrom").(*User)
 | 
						u.DeleteMessage()
 | 
				
			||||||
	to, _ := u.Ctx.Value("userto").(*User)
 | 
						_, err := u.AnswerMarkdown(fmt.Sprintf("*_%s_*", nechotron.EscapeMd2(text)))
 | 
				
			||||||
	mentionFrom := nechotron.UserMention(u.Message.From)
 | 
					 | 
				
			||||||
	mentionTo := nechotron.UserMention(u.Message.ReplyToMessage.From)
 | 
					 | 
				
			||||||
	if from.ID == to.ID {
 | 
					 | 
				
			||||||
		res, err := u.AnswerMarkdown(
 | 
					 | 
				
			||||||
			fmt.Sprintf("Лайкать себя \\- плохая затея, *%s*", mentionFrom))
 | 
					 | 
				
			||||||
		go func() {
 | 
					 | 
				
			||||||
			time.Sleep(10 * time.Second)
 | 
					 | 
				
			||||||
			u.Bot.DeleteMessage(u.ChatID(), res.Result.ID)
 | 
					 | 
				
			||||||
		}()
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	value := u.Ctx.Value(nechotron.FilteredValue("karmaValue")).(int)
 | 
					 | 
				
			||||||
	// trigger := u.Ctx.Value(nechotron.FilteredValue("karmaTrigger")).(string)
 | 
					 | 
				
			||||||
	store := tongo.NewStore[KarmaShot](db)
 | 
					 | 
				
			||||||
	fromKarma, _ := store.Count(u.Ctx, tongo.E("to", from.ID))
 | 
					 | 
				
			||||||
	totalFromKarma := from.KarmaOffset + fromKarma
 | 
					 | 
				
			||||||
	if totalFromKarma < 0 {
 | 
					 | 
				
			||||||
		res, err := u.AnswerText(
 | 
					 | 
				
			||||||
			fmt.Sprintf("У тебя слишком маленькая карма *\\(%d\\), чтобы менять её другим\\.", totalFromKarma),
 | 
					 | 
				
			||||||
			&echotron.MessageOptions{ParseMode: echotron.MarkdownV2, ReplyToMessageID: u.MessageID()})
 | 
					 | 
				
			||||||
		go waitAndDelete(u, u.ChatID(), res.Result.ID)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	timeThreshold := time.Now().Add(1 * -time.Minute)
 | 
					 | 
				
			||||||
	recentShots, err := store.Count(
 | 
					 | 
				
			||||||
		u.Ctx,
 | 
					 | 
				
			||||||
		tongo.E("from", from.ID),
 | 
					 | 
				
			||||||
		tongo.E("to", to.ID),
 | 
					 | 
				
			||||||
		tongo.E("when", tongo.D(tongo.E("$gte", timeThreshold))))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if recentShots > 0 {
 | 
					 | 
				
			||||||
		// u.DeleteMessage()
 | 
					 | 
				
			||||||
		res, err := u.AnswerMarkdown(
 | 
					 | 
				
			||||||
			fmt.Sprintf("*%s*, ты только недавно менял карму *%s*\\. Подожди минуту\\.", mentionFrom, mentionTo))
 | 
					 | 
				
			||||||
		go waitAndDelete(u, u.ChatID(), res.Result.ID)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if to.ID == u.Bot.Me.ID {
 | 
					 | 
				
			||||||
		if value > 0 {
 | 
					 | 
				
			||||||
			u.AnswerMarkdown("*_Ой, это мне?_*")
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			res, err := u.AnswerMarkdown("*_Кажется, вы ошиблись адресатом :/_*")
 | 
					 | 
				
			||||||
			go waitAndDelete(u, u.ChatID(), res.Result.ID)
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	newShot := KarmaShot{
 | 
					 | 
				
			||||||
		Item:        tongo.NewID(),
 | 
					 | 
				
			||||||
		From:        from.ID,
 | 
					 | 
				
			||||||
		To:          to.ID,
 | 
					 | 
				
			||||||
		MessageText: nechotron.GetText(u.Message.ReplyToMessage),
 | 
					 | 
				
			||||||
		When:        time.Now(),
 | 
					 | 
				
			||||||
		Count:       value,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	store.InsertOne(u.Ctx, &newShot)
 | 
					 | 
				
			||||||
	newKarma, _ := store.Count(u.Ctx, tongo.E("to", to.ID))
 | 
					 | 
				
			||||||
	totalToKarma := to.KarmaOffset + newKarma
 | 
					 | 
				
			||||||
	changeText := "повысил"
 | 
					 | 
				
			||||||
	if value < 0 {
 | 
					 | 
				
			||||||
		changeText = "понизил"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_, err = u.AnswerMarkdown(
 | 
					 | 
				
			||||||
		fmt.Sprintf("*%s \\(%d\\)* только что %s карму *%s \\(%d\\)*", mentionFrom, totalFromKarma, changeText, mentionTo, totalToKarma))
 | 
					 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -207,3 +63,10 @@ func handleDeleteCallback(u *nechotron.Update) error {
 | 
				
			|||||||
	u.DeleteMessage()
 | 
						u.DeleteMessage()
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleUsersImport(u *nechotron.Update) error {
 | 
				
			||||||
 | 
						f, _ := u.Bot.GetFile(u.Message.Document.FileID)
 | 
				
			||||||
 | 
						file, _ := u.Bot.DownloadFile(f.Result.FilePath)
 | 
				
			||||||
 | 
						log.Println(string(file))
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								karma.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								karma.go
									
									
									
									
									
								
							@ -1,9 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Returns slices of good and bad triggers
 | 
					 | 
				
			||||||
func GetTriggers() map[string]int {
 | 
					 | 
				
			||||||
	return map[string]int{
 | 
					 | 
				
			||||||
		"+": 1,
 | 
					 | 
				
			||||||
		"-": -1,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										3
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								main.go
									
									
									
									
									
								
							@ -32,9 +32,6 @@ func main() {
 | 
				
			|||||||
		Use(ErrorLogger).
 | 
							Use(ErrorLogger).
 | 
				
			||||||
		Use(ExecTimeLogger)
 | 
							Use(ExecTimeLogger)
 | 
				
			||||||
	api := echotron.NewAPI(token)
 | 
						api := echotron.NewAPI(token)
 | 
				
			||||||
	defaultCommands := []*nechotron.Command{commandHelp, commandMe}
 | 
					 | 
				
			||||||
	adminCommands := []*nechotron.Command{commandSay, commandWarn}
 | 
					 | 
				
			||||||
	allCommands := append(defaultCommands, adminCommands...)
 | 
					 | 
				
			||||||
	nechotron.SetMyCommands(api, "", echotron.BotCommandScope{Type: echotron.Any}, defaultCommands...)
 | 
						nechotron.SetMyCommands(api, "", echotron.BotCommandScope{Type: echotron.Any}, defaultCommands...)
 | 
				
			||||||
	nechotron.SetMyCommands(api, "", echotron.BotCommandScope{Type: echotron.BCSTAllChatAdministrators}, allCommands...)
 | 
						nechotron.SetMyCommands(api, "", echotron.BotCommandScope{Type: echotron.BCSTAllChatAdministrators}, allCommands...)
 | 
				
			||||||
	log.Fatal(neco.DispatchPoll())
 | 
						log.Fatal(neco.DispatchPoll())
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										15
									
								
								states.go
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								states.go
									
									
									
									
									
								
							@ -6,22 +6,29 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var MainState = neco.State{
 | 
					var MainState = neco.State{
 | 
				
			||||||
	Fn: func(u *neco.Update) error {
 | 
						Fn: func(u *neco.Update) error {
 | 
				
			||||||
		adminOnly := neco.NewDispatcher().
 | 
							adminDispatcher := neco.NewDispatcher().
 | 
				
			||||||
			HandleCallback(neco.CallbackExact("delete"), handleDeleteCallback).
 | 
								HandleCallback(neco.CallbackExact("delete"), handleDeleteCallback).
 | 
				
			||||||
			HandleCommand(commandSay, handleSay)
 | 
								HandleCommand(commandSay, handleSay).
 | 
				
			||||||
 | 
								HandleFilter(isFile, handleUsersImport)
 | 
				
			||||||
 | 
							adminOnly := neco.NewDispatcher().
 | 
				
			||||||
 | 
								HandleFilter(neco.IsUserAdmin, adminDispatcher.Run)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		mainCommands := neco.NewDispatcher().
 | 
							mainCommands := neco.NewDispatcher().
 | 
				
			||||||
			HandleCommand(commandMe, handleMe).
 | 
								HandleCommand(commandMe, handleMe).
 | 
				
			||||||
			HandleCommand(commandHelp, handleHelp)
 | 
								HandleCommand(commandHelp, handleHelp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		replyDispatcher := neco.NewDispatcher().
 | 
							replyDispatcher := neco.NewDispatcher().
 | 
				
			||||||
			HandleCommand(commandWarn, handleWarn).
 | 
					 | 
				
			||||||
			HandleFilter(karmaTriggers, handleKarma)
 | 
								HandleFilter(karmaTriggers, handleKarma)
 | 
				
			||||||
		replies := neco.NewDispatcher().
 | 
							replies := neco.NewDispatcher().
 | 
				
			||||||
			HandleFilter(neco.IsReply, replyDispatcher.Run)
 | 
								HandleFilter(neco.IsReply, replyDispatcher.Run)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		docs := neco.NewDispatcher().
 | 
							docs := neco.NewDispatcher().
 | 
				
			||||||
			HandleFilter(docRequest, handleDocRequest).
 | 
								HandleFilter(docRequest, handleDocRequest).
 | 
				
			||||||
			HandleCallback(neco.CallbackPrefix("docs3"), handleDocRequest3)
 | 
								HandleCallback(neco.CallbackPrefix("docs3"), handleDocRequest3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		triggers := neco.NewDispatcher().
 | 
							triggers := neco.NewDispatcher().
 | 
				
			||||||
			HandleFilter(offtopTrigger, handleOfftop)
 | 
								HandleFilter(offtopTrigger, handleOfftop)
 | 
				
			||||||
		return neco.ChainRun(u, mainCommands, replies, docs, adminOnly, triggers)
 | 
					
 | 
				
			||||||
 | 
							return neco.RunEach(u, mainCommands, replies, docs, adminOnly, triggers)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user