first working version
This commit is contained in:
parent
6f20c33c58
commit
850843bac7
72
bot/bot.go
72
bot/bot.go
|
@ -1,6 +1,8 @@
|
||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
"golang.org/x/exp/slog"
|
"golang.org/x/exp/slog"
|
||||||
"maunium.net/go/mautrix"
|
"maunium.net/go/mautrix"
|
||||||
|
@ -27,6 +29,7 @@ type Bot struct {
|
||||||
cryptoHelper *cryptohelper.CryptoHelper
|
cryptoHelper *cryptohelper.CryptoHelper
|
||||||
kagiCient *Kagi
|
kagiCient *Kagi
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
|
messages map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBot(cfg MatrixConfig, kagi *Kagi, logger *slog.Logger) *Bot {
|
func NewBot(cfg MatrixConfig, kagi *Kagi, logger *slog.Logger) *Bot {
|
||||||
|
@ -34,6 +37,7 @@ func NewBot(cfg MatrixConfig, kagi *Kagi, logger *slog.Logger) *Bot {
|
||||||
config: cfg,
|
config: cfg,
|
||||||
kagiCient: kagi,
|
kagiCient: kagi,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
messages: make(map[string]string),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +66,8 @@ func (m *Bot) Init() error {
|
||||||
if m.config.AcceptInvites {
|
if m.config.AcceptInvites {
|
||||||
m.AddEventHandler(m.InviteHandler())
|
m.AddEventHandler(m.InviteHandler())
|
||||||
}
|
}
|
||||||
m.AddEventHandler(m.ResponseHandler())
|
m.AddEventHandler(m.ReactionHandler())
|
||||||
|
m.AddEventHandler(m.MessageHandler())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -105,8 +110,8 @@ func (m *Bot) InviteHandler() (event.Type, mautrix.EventHandler) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Bot) ResponseHandler() (event.Type, mautrix.EventHandler) {
|
func (m *Bot) MessageHandler() (event.Type, mautrix.EventHandler) {
|
||||||
return event.EventReaction, func(source mautrix.EventSource, evt *event.Event) {
|
return event.EventMessage, func(source mautrix.EventSource, evt *event.Event) {
|
||||||
content := evt.Content.AsMessage()
|
content := evt.Content.AsMessage()
|
||||||
eventID := evt.ID
|
eventID := evt.ID
|
||||||
m.logger.Info("received message", slog.String("content", content.Body))
|
m.logger.Info("received message", slog.String("content", content.Body))
|
||||||
|
@ -115,23 +120,53 @@ func (m *Bot) ResponseHandler() (event.Type, mautrix.EventHandler) {
|
||||||
m.logger.Info("message sent by bot itself, ignoring", slog.String("event_id", eventID.String()))
|
m.logger.Info("message sent by bot itself, ignoring", slog.String("event_id", eventID.String()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
url, ok := findFirstURL(content.Body)
|
||||||
|
if !ok {
|
||||||
|
m.logger.Info("message does not contain url, ignoring", slog.String("event_id", eventID.String()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m.messages[eventID.String()] = url
|
||||||
|
m.logger.Info("saved url", slog.String("event_id", eventID.String()), slog.String("url", url))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get reply from GPT
|
func (m *Bot) ReactionHandler() (event.Type, mautrix.EventHandler) {
|
||||||
//reply, err := m.gptClient.Complete(conv)
|
return event.EventReaction, func(source mautrix.EventSource, evt *event.Event) {
|
||||||
//if err != nil {
|
eventID := evt.ID
|
||||||
// m.logger.Error("failed to get reply from openai", slog.String("err", err.Error()), slog.String("bot", m.config.UserDisplayName))
|
// ignore if the message is sent by the bot itself
|
||||||
// return
|
if evt.Sender == id.UserID(m.config.UserID) {
|
||||||
//}
|
m.logger.Info("message sent by bot itself, ignoring", slog.String("event_id", eventID.String()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rel := evt.Content.AsReaction().GetRelatesTo()
|
||||||
|
relID := rel.GetAnnotationID()
|
||||||
|
relKey := rel.GetAnnotationKey()
|
||||||
|
m.logger.Info("received reaction", slog.String("event_id", eventID.String()), slog.String("rel_id", relID.String()), slog.String("rel_key", relKey))
|
||||||
|
if relKey != `🗒️` {
|
||||||
|
m.logger.Info("reaction is not 🗒️, ignoring", slog.String("event_id", eventID.String()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
reply := "the summary"
|
wantedURL, ok := m.messages[relID.String()]
|
||||||
|
if !ok {
|
||||||
|
m.logger.Info("referenced message is not known or does not contain url, ignoring", slog.String("event_id", eventID.String()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
summary, err := m.kagiCient.Summarize(wantedURL)
|
||||||
|
if err != nil {
|
||||||
|
m.logger.Error("failed to summarize", slog.String("err", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reply := summary
|
||||||
formattedReply := format.RenderMarkdown(reply, true, false)
|
formattedReply := format.RenderMarkdown(reply, true, false)
|
||||||
formattedReply.RelatesTo = &event.RelatesTo{
|
formattedReply.RelatesTo = &event.RelatesTo{
|
||||||
InReplyTo: &event.InReplyTo{
|
InReplyTo: &event.InReplyTo{
|
||||||
EventID: eventID,
|
EventID: relID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, err := m.client.SendMessageEvent(evt.RoomID, event.EventMessage, &formattedReply)
|
if _, err := m.client.SendMessageEvent(evt.RoomID, event.EventMessage, &formattedReply); err != nil {
|
||||||
if err != nil {
|
|
||||||
m.logger.Error("failed to send message", slog.String("err", err.Error()))
|
m.logger.Error("failed to send message", slog.String("err", err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -139,6 +174,15 @@ func (m *Bot) ResponseHandler() (event.Type, mautrix.EventHandler) {
|
||||||
if len(reply) > 30 {
|
if len(reply) > 30 {
|
||||||
reply = reply[:30] + "..."
|
reply = reply[:30] + "..."
|
||||||
}
|
}
|
||||||
m.logger.Info("sent reply", slog.String("parent_id", eventID.String()), slog.String("content", reply))
|
m.logger.Info("sent reply", slog.String("parent_id", eventID.String()), slog.String("msg", reply))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findFirstURL(s string) (string, bool) {
|
||||||
|
re := regexp.MustCompile(`https?\:\/\/[^ \)]*`)
|
||||||
|
match := re.FindString(s)
|
||||||
|
if match == "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return match, true
|
||||||
|
}
|
||||||
|
|
16
bot/kagi.go
16
bot/kagi.go
|
@ -1,6 +1,7 @@
|
||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -26,7 +27,6 @@ func NewKagi(baseURL, apiKey string) *Kagi {
|
||||||
|
|
||||||
func (k *Kagi) Summarize(sumURL string) (string, error) {
|
func (k *Kagi) Summarize(sumURL string) (string, error) {
|
||||||
queryURL := fmt.Sprintf("%s/summarize?engine=muriel&url=%s", k.baseURL, url.QueryEscape(sumURL))
|
queryURL := fmt.Sprintf("%s/summarize?engine=muriel&url=%s", k.baseURL, url.QueryEscape(sumURL))
|
||||||
//queryURL = ""
|
|
||||||
req, err := http.NewRequest("GET", queryURL, nil)
|
req, err := http.NewRequest("GET", queryURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -37,7 +37,6 @@ func (k *Kagi) Summarize(sumURL string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
fmt.Println(res.Status)
|
|
||||||
|
|
||||||
resBody, err := io.ReadAll(res.Body)
|
resBody, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -45,7 +44,14 @@ func (k *Kagi) Summarize(sumURL string) (string, error) {
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
fmt.Sprintf("response: %v", string(resBody))
|
resp := struct {
|
||||||
|
Data struct {
|
||||||
return string(resBody), nil
|
Output string
|
||||||
|
}
|
||||||
|
}{}
|
||||||
|
if err := json.Unmarshal(resBody, &resp); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Data.Output, nil
|
||||||
}
|
}
|
||||||
|
|
9
go.mod
9
go.mod
|
@ -2,10 +2,15 @@ module ewintr.nl/matrix-kagisum
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.17
|
||||||
|
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
|
||||||
|
maunium.net/go/mautrix v0.15.3
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
|
||||||
github.com/rs/zerolog v1.29.1 // indirect
|
github.com/rs/zerolog v1.29.1 // indirect
|
||||||
github.com/tidwall/gjson v1.14.4 // indirect
|
github.com/tidwall/gjson v1.14.4 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
@ -13,9 +18,7 @@ require (
|
||||||
github.com/tidwall/sjson v1.2.5 // indirect
|
github.com/tidwall/sjson v1.2.5 // indirect
|
||||||
github.com/yuin/goldmark v1.5.4 // indirect
|
github.com/yuin/goldmark v1.5.4 // indirect
|
||||||
golang.org/x/crypto v0.10.0 // indirect
|
golang.org/x/crypto v0.10.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
|
||||||
golang.org/x/net v0.11.0 // indirect
|
golang.org/x/net v0.11.0 // indirect
|
||||||
golang.org/x/sys v0.9.0 // indirect
|
golang.org/x/sys v0.9.0 // indirect
|
||||||
maunium.net/go/maulogger/v2 v2.4.1 // indirect
|
maunium.net/go/maulogger/v2 v2.4.1 // indirect
|
||||||
maunium.net/go/mautrix v0.15.3 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
5
go.sum
5
go.sum
|
@ -1,6 +1,6 @@
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
@ -10,12 +10,10 @@ github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6
|
||||||
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
|
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
|
||||||
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
|
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
|
||||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
|
@ -38,7 +36,6 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
maunium.net/go/maulogger/v2 v2.4.1 h1:N7zSdd0mZkB2m2JtFUsiGTQQAdP0YeFWT7YMc80yAL8=
|
maunium.net/go/maulogger/v2 v2.4.1 h1:N7zSdd0mZkB2m2JtFUsiGTQQAdP0YeFWT7YMc80yAL8=
|
||||||
maunium.net/go/maulogger/v2 v2.4.1/go.mod h1:omPuYwYBILeVQobz8uO3XC8DIRuEb5rXYlQSuqrbCho=
|
maunium.net/go/maulogger/v2 v2.4.1/go.mod h1:omPuYwYBILeVQobz8uO3XC8DIRuEb5rXYlQSuqrbCho=
|
||||||
maunium.net/go/mautrix v0.15.3 h1:C9BHSUM0gYbuZmAtopuLjIcH5XHLb/ZjTEz7nN+0jN0=
|
maunium.net/go/mautrix v0.15.3 h1:C9BHSUM0gYbuZmAtopuLjIcH5XHLb/ZjTEz7nN+0jN0=
|
||||||
|
|
Loading…
Reference in New Issue