From 0ab510adefddd5f3a1b87d7319921573b49ca565 Mon Sep 17 00:00:00 2001
From: Von Random <von@mechanus.net>
Date: Sun, 9 Feb 2025 14:29:04 +0200
Subject: [PATCH] initial prototype, only responds with tokens

---
 go.mod                 |  7 +++++
 go.sum                 |  4 +++
 main.go                | 31 +++++++++++++++++++
 matcher/matcher.go     | 70 ++++++++++++++++++++++++++++++++++++++++++
 responder/responder.go | 16 ++++++++++
 5 files changed, 128 insertions(+)
 create mode 100644 go.mod
 create mode 100644 go.sum
 create mode 100644 main.go
 create mode 100644 matcher/matcher.go
 create mode 100644 responder/responder.go

diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..b558da1
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,7 @@
+module mechanus.net/pgbot
+
+go 1.23.3
+
+require gopkg.in/telebot.v4 v4.0.0-beta.4
+
+require gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..f90eb04
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,4 @@
+gopkg.in/telebot.v4 v4.0.0-beta.4 h1:9O3elrJ1GYJhNBpi7WDlBOaM/KQPvr5xpFPUEbA+dpk=
+gopkg.in/telebot.v4 v4.0.0-beta.4/go.mod h1:jhcQjM/176jZm/s9Up/MzV5VFGPjyI8oiJhWvCMxayI=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..21a4270
--- /dev/null
+++ b/main.go
@@ -0,0 +1,31 @@
+package main
+
+import (
+	"log"
+	"os"
+	"time"
+
+	"mechanus.net/pgobot/matcher"
+	"mechanus.net/pgobot/responder"
+
+	"gopkg.in/telebot.v4"
+)
+
+func main() {
+	pref := telebot.Settings{
+		Token:  os.Getenv("TOKEN"),
+		Poller: &telebot.LongPoller{Timeout: 10 * time.Second},
+	}
+
+	tokenMatcher := matcher.InitMatcher("tokens.yml")
+
+	bot, err := telebot.NewBot(pref)
+	if err != nil {
+		log.Fatal(err)
+		return
+	}
+
+	responder.InitResponder(bot, tokenMatcher)
+
+	bot.Start()
+}
diff --git a/matcher/matcher.go b/matcher/matcher.go
new file mode 100644
index 0000000..f022393
--- /dev/null
+++ b/matcher/matcher.go
@@ -0,0 +1,70 @@
+package matcher
+
+import (
+	"os"
+	"regexp"
+
+	"gopkg.in/yaml.v3"
+)
+
+type Matcher struct {
+	tokens []TokenCompiled
+}
+
+type TokenCompiled struct {
+	token string
+	regex []*regexp.Regexp
+}
+
+func createToken(token string, regexList []string) TokenCompiled {
+	result := new(TokenCompiled)
+	result.token = token
+	result.regex = make([]*regexp.Regexp, len(regexList))
+	for i, regex := range regexList {
+		result.regex[i] = regexp.MustCompile(regex)
+	}
+	return *result
+}
+
+func (t TokenCompiled) match(input string) (bool, string) {
+	for _, regex := range t.regex {
+		if regex.MatchString(input) {
+			return true, t.token
+		}
+	}
+	return false, ""
+}
+
+func (m *Matcher) Tokenize(input string) []string {
+	result := make([]string, 0, 10)
+	for _, token := range m.tokens {
+		ok, matchedToken := token.match(input)
+		if ok {
+			result = append(result, matchedToken)
+		}
+	}
+	return result
+}
+
+func InitMatcher(config string) *Matcher {
+	configData, err := os.ReadFile(config)
+	if err != nil {
+		panic(err)
+	}
+	var configMap map[string][]string
+
+	err = yaml.Unmarshal(configData, &configMap)
+	if err != nil {
+		panic(err)
+	}
+
+	tokens := make([]TokenCompiled, 0, len(configMap))
+
+	for k, v := range configMap {
+		tokensCompiled := createToken(k, v)
+		tokens = append(tokens, tokensCompiled)
+	}
+	result := new(Matcher)
+	result.tokens = tokens
+	return result
+}
diff --git a/responder/responder.go b/responder/responder.go
new file mode 100644
index 0000000..d3f0376
--- /dev/null
+++ b/responder/responder.go
@@ -0,0 +1,16 @@
+package responder
+
+import (
+	"strings"
+
+	"mechanus.net/pgobot/matcher"
+
+	"gopkg.in/telebot.v4"
+)
+
+func InitResponder(bot *telebot.Bot, tokenMatcher *matcher.Matcher) {
+	bot.Handle(telebot.OnText, func(c telebot.Context) error {
+		tokens := tokenMatcher.Tokenize(c.Message().Text)
+		return c.Send(strings.Join(tokens, ","))
+	})
+}