feat(irc): view announces per channel (#948)

* feat(irc): add sse to handler

* feat(irc): view and send irc messages per network

* refactor(irc): use id as handlerkey

* refactor(irc): use id as handlerkey

* feat(web): add irc context

* refactor: create sse stream per network channel

* fix(irc): remove non-working wildcard callback handler

* feat: use fork of sse

* chore(deps): update ergo/irc-go to v0.3.0

* fix: clean irc msg before sse publish

* feat: add view channel button

* feat: styling improvements

* feat: show time
This commit is contained in:
ze0s 2023-05-21 15:51:40 +02:00 committed by GitHub
parent bbfcf303ef
commit ccabe96bdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 446 additions and 125 deletions

View file

@ -20,6 +20,7 @@ import (
"github.com/ergochat/irc-go/ircevent"
"github.com/ergochat/irc-go/ircfmt"
"github.com/ergochat/irc-go/ircmsg"
"github.com/r3labs/sse/v2"
"github.com/rs/zerolog"
"github.com/sasha-s/go-deadlock"
)
@ -59,6 +60,7 @@ func (ch *channelHealth) resetMonitoring() {
type Handler struct {
log zerolog.Logger
sse *sse.Server
network *domain.IrcNetwork
releaseSvc release.Service
notificationService notification.Service
@ -83,9 +85,10 @@ type Handler struct {
saslauthed bool
}
func NewHandler(log zerolog.Logger, network domain.IrcNetwork, definitions []*domain.IndexerDefinition, releaseSvc release.Service, notificationSvc notification.Service) *Handler {
func NewHandler(log zerolog.Logger, sse *sse.Server, network domain.IrcNetwork, definitions []*domain.IndexerDefinition, releaseSvc release.Service, notificationSvc notification.Service) *Handler {
h := &Handler{
log: log.With().Str("network", network.Server).Logger(),
sse: sse,
client: nil,
network: &network,
releaseSvc: releaseSvc,
@ -186,6 +189,7 @@ func (h *Handler) Run() error {
h.client.AddConnectCallback(h.onConnect)
h.client.AddDisconnectCallback(h.onDisconnect)
h.client.AddCallback("MODE", h.handleMode)
h.client.AddCallback("INVITE", h.handleInvite)
h.client.AddCallback("366", h.handleJoined)
@ -538,30 +542,41 @@ func (h *Handler) onNick(msg ircmsg.Message) {
}
}
func (h *Handler) publishSSEMsg(msg domain.IrcMessage) {
h.sse.Publish(fmt.Sprintf("%d%s", h.network.ID, strings.TrimPrefix(msg.Channel, "#")), &sse.Event{
Data: msg.Bytes(),
})
}
// onMessage handles PRIVMSG events
func (h *Handler) onMessage(msg ircmsg.Message) {
if len(msg.Params) < 2 {
return
}
// parse announce
announcer := msg.Nick()
nick := msg.Nick()
channel := msg.Params[0]
message := msg.Params[1]
// clean message
cleanedMsg := h.cleanMessage(message)
h.log.Debug().Str("channel", channel).Str("nick", nick).Msg(cleanedMsg)
// publish to SSE stream
h.publishSSEMsg(domain.IrcMessage{Channel: channel, Nick: nick, Message: cleanedMsg, Time: time.Now()})
// check if message is from a valid channel, if not return
if validChannel := h.isValidChannel(channel); !validChannel {
return
}
// check if message is from announce bot, if not return
if validAnnouncer := h.isValidAnnouncer(announcer); !validAnnouncer {
if validAnnouncer := h.isValidAnnouncer(nick); !validAnnouncer {
return
}
// clean message
cleanedMsg := h.cleanMessage(message)
h.log.Debug().Str("channel", channel).Str("user", announcer).Msgf("%v", cleanedMsg)
if err := h.sendToAnnounceProcessor(channel, cleanedMsg); err != nil {
h.log.Error().Stack().Err(err).Msgf("could not queue line: %v", cleanedMsg)
return
@ -819,6 +834,17 @@ func (h *Handler) handleMode(msg ircmsg.Message) {
return
}
func (h *Handler) SendMsg(channel, msg string) error {
h.log.Debug().Msgf("sending msg command: %s", msg)
if err := h.client.Privmsg(channel, msg); err != nil {
h.log.Error().Stack().Err(err).Msgf("error sending msg: %v", msg)
return err
}
return nil
}
// check if announcer is one from the list in the definition
func (h *Handler) isValidAnnouncer(nick string) bool {
h.m.RLock()