mirror of
https://github.com/42wim/matterbridge.git
synced 2025-02-22 13:19:01 -08:00
Change activity to per-channel
This commit is contained in:
parent
26bda54e16
commit
edbf9c310b
@ -36,9 +36,6 @@ type Bdiscord struct {
|
|||||||
userMemberMap map[string]*discordgo.Member
|
userMemberMap map[string]*discordgo.Member
|
||||||
nickMemberMap map[string]*discordgo.Member
|
nickMemberMap map[string]*discordgo.Member
|
||||||
|
|
||||||
noEmbedPartUrls bool
|
|
||||||
noEmbedUrls bool
|
|
||||||
|
|
||||||
// Webhook specific logic
|
// Webhook specific logic
|
||||||
useAutoWebhooks bool
|
useAutoWebhooks bool
|
||||||
transmitter *transmitter.Transmitter
|
transmitter *transmitter.Transmitter
|
||||||
@ -60,12 +57,6 @@ func New(cfg *bridge.Config) bridge.Bridger {
|
|||||||
b.nickMemberMap = make(map[string]*discordgo.Member)
|
b.nickMemberMap = make(map[string]*discordgo.Member)
|
||||||
b.channelInfoMap = make(map[string]*config.ChannelInfo)
|
b.channelInfoMap = make(map[string]*config.ChannelInfo)
|
||||||
|
|
||||||
b.noEmbedPartUrls = b.GetBool(("NoEmbedPartUrls"))
|
|
||||||
b.noEmbedUrls = b.GetBool(("NoEmbedUrls"))
|
|
||||||
if b.noEmbedPartUrls && b.noEmbedUrls {
|
|
||||||
b.Log.Info("NoEmbedUrls supersedes NoEmbedPartUrls")
|
|
||||||
}
|
|
||||||
|
|
||||||
b.useAutoWebhooks = b.GetBool("AutoWebhooks")
|
b.useAutoWebhooks = b.GetBool("AutoWebhooks")
|
||||||
if b.useAutoWebhooks {
|
if b.useAutoWebhooks {
|
||||||
b.Log.Debug("Using automatic webhooks")
|
b.Log.Debug("Using automatic webhooks")
|
||||||
@ -278,10 +269,6 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
|||||||
msg.Text = "_" + msg.Text + "_"
|
msg.Text = "_" + msg.Text + "_"
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.noEmbedUrls || (msg.Event == config.EventJoinLeave && b.noEmbedPartUrls) {
|
|
||||||
disableEmbedUrls(&msg.Text)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle prefix hint for unthreaded messages.
|
// Handle prefix hint for unthreaded messages.
|
||||||
if msg.ParentNotFound() {
|
if msg.ParentNotFound() {
|
||||||
msg.ParentID = ""
|
msg.ParentID = ""
|
||||||
|
@ -233,11 +233,6 @@ func (b *Bdiscord) splitURL(url string) (string, string, bool) {
|
|||||||
return webhookURLSplit[webhookIdxID], webhookURLSplit[webhookIdxToken], true
|
return webhookURLSplit[webhookIdxID], webhookURLSplit[webhookIdxToken], true
|
||||||
}
|
}
|
||||||
|
|
||||||
func disableEmbedUrls(msg *string) {
|
|
||||||
regex := regexp.MustCompile(`(\w+://\S+)`)
|
|
||||||
*msg = regex.ReplaceAllString(*msg, "<$1>")
|
|
||||||
}
|
|
||||||
|
|
||||||
func enumerateUsernames(s string) []string {
|
func enumerateUsernames(s string) []string {
|
||||||
onlySpace := true
|
onlySpace := true
|
||||||
for _, r := range s {
|
for _, r := range s {
|
||||||
|
@ -114,7 +114,8 @@ func (b *Birc) handleJoinPart(client *girc.Client, event girc.Event) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if event.Source.Name != b.Nick {
|
if event.Source.Name != b.Nick {
|
||||||
if isActive, _ := b.isUserActive(event.Source.Name); !isActive || b.GetBool("nosendjoinpart") {
|
if isActive, _ := b.isUserActive(event.Source.Name, channel); !isActive ||
|
||||||
|
b.GetBool("nosendjoinpart") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
partmsg := ""
|
partmsg := ""
|
||||||
@ -160,11 +161,12 @@ func (b *Birc) handleNick(client *girc.Client, event girc.Event) {
|
|||||||
if b.GetBool("nosendjoinpart") {
|
if b.GetBool("nosendjoinpart") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if isActive, activeTime := b.isUserActive(event.Source.Name); isActive {
|
if activeChannels := b.getActiveChannels(event.Source.Name); len(activeChannels) > 0 {
|
||||||
|
for _, activityInfo := range activeChannels {
|
||||||
msg := config.Message{
|
msg := config.Message{
|
||||||
Username: "system",
|
Username: "system",
|
||||||
Text: event.Source.Name + " changed nick to " + event.Params[0],
|
Text: event.Source.Name + " changed nick to " + event.Params[0],
|
||||||
Channel: b.getPseudoChannel(),
|
Channel: activityInfo.channel,
|
||||||
Account: b.Account,
|
Account: b.Account,
|
||||||
Event: config.EventJoinLeave,
|
Event: config.EventJoinLeave,
|
||||||
}
|
}
|
||||||
@ -172,7 +174,8 @@ func (b *Birc) handleNick(client *girc.Client, event girc.Event) {
|
|||||||
b.Remote <- msg
|
b.Remote <- msg
|
||||||
if b.ActivityTimeout != 0 {
|
if b.ActivityTimeout != 0 {
|
||||||
// This doesn't count as new activity, but it does preserve the value
|
// This doesn't count as new activity, but it does preserve the value
|
||||||
b.markUserActive(event.Params[0], activeTime)
|
b.markUserActive(event.Params[0], activityInfo.channel, activityInfo.activeTime)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,9 +232,10 @@ func (b *Birc) handlePrivMsg(client *girc.Client, event girc.Event) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channel := strings.ToLower(event.Params[0])
|
||||||
rmsg := config.Message{
|
rmsg := config.Message{
|
||||||
Username: event.Source.Name,
|
Username: event.Source.Name,
|
||||||
Channel: strings.ToLower(event.Params[0]),
|
Channel: channel,
|
||||||
Account: b.Account,
|
Account: b.Account,
|
||||||
UserID: event.Source.Ident + "@" + event.Source.Host,
|
UserID: event.Source.Ident + "@" + event.Source.Host,
|
||||||
}
|
}
|
||||||
@ -284,7 +288,7 @@ func (b *Birc) handlePrivMsg(client *girc.Client, event girc.Event) {
|
|||||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", event.Params[0], b.Account)
|
b.Log.Debugf("<= Sending message from %s on %s to gateway", event.Params[0], b.Account)
|
||||||
if b.ActivityTimeout > 0 {
|
if b.ActivityTimeout > 0 {
|
||||||
b.Log.Debugf("<= Updating last-active time for user %s", event.Source.Name)
|
b.Log.Debugf("<= Updating last-active time for user %s", event.Source.Name)
|
||||||
b.markUserActive(event.Source.Name, time.Now().Unix())
|
b.markUserActive(event.Source.Name, channel, time.Now().Unix())
|
||||||
}
|
}
|
||||||
b.Remote <- rmsg
|
b.Remote <- rmsg
|
||||||
b.cleanActiveMap()
|
b.cleanActiveMap()
|
||||||
@ -293,23 +297,30 @@ func (b *Birc) handlePrivMsg(client *girc.Client, event girc.Event) {
|
|||||||
func (b *Birc) handleQuit(client *girc.Client, event girc.Event) {
|
func (b *Birc) handleQuit(client *girc.Client, event girc.Event) {
|
||||||
if event.Source.Name == b.Nick && strings.Contains(event.Last(), "Ping timeout") {
|
if event.Source.Name == b.Nick && strings.Contains(event.Last(), "Ping timeout") {
|
||||||
b.Log.Infof("%s reconnecting ..", b.Account)
|
b.Log.Infof("%s reconnecting ..", b.Account)
|
||||||
b.Remote <- config.Message{Username: "system", Text: "reconnect", Channel: b.getPseudoChannel(), Account: b.Account, Event: config.EventFailure}
|
for mychan := range b.channels {
|
||||||
|
b.Remote <- config.Message{Username: "system", Text: "reconnect", Channel: mychan, Account: b.Account, Event: config.EventFailure}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
} else if b.GetBool("nosendjoinpart") {
|
} else if b.GetBool("nosendjoinpart") {
|
||||||
return
|
return
|
||||||
} else if isActive, _ := b.isUserActive(event.Source.Name); isActive || isKill(event.Last()) {
|
} else if activeChannels, found := b.activeUsers[event.Source.Name]; found {
|
||||||
|
userWasKilled := isKill(event.Last())
|
||||||
verbosequit := ""
|
verbosequit := ""
|
||||||
quitmsg := ""
|
quitmsg := ""
|
||||||
|
nowTime := time.Now().Unix()
|
||||||
if len(event.Params) >= 1 {
|
if len(event.Params) >= 1 {
|
||||||
quitmsg = " with message: " + event.Last()
|
quitmsg = " with message: " + event.Last()
|
||||||
}
|
}
|
||||||
if b.GetBool("verbosejoinpart") {
|
if b.GetBool("verbosejoinpart") {
|
||||||
verbosequit = " (" + event.Source.Ident + "@" + event.Source.Host + ")"
|
verbosequit = " (" + event.Source.Ident + "@" + event.Source.Host + ")"
|
||||||
}
|
}
|
||||||
msg := config.Message{Username: "system", Text: event.Source.Name + verbosequit + " quit" + quitmsg, Channel: b.getPseudoChannel(), Account: b.Account, Event: config.EventJoinLeave}
|
for channel, activeTime := range activeChannels {
|
||||||
|
if userWasKilled || b.isActive(activeTime, nowTime) {
|
||||||
|
msg := config.Message{Username: "system", Text: event.Source.Name + verbosequit + " quit" + quitmsg, Channel: channel, Account: b.Account, Event: config.EventJoinLeave}
|
||||||
b.Log.Debugf("<= Message is %#v", msg)
|
b.Log.Debugf("<= Message is %#v", msg)
|
||||||
b.Remote <- msg
|
b.Remote <- msg
|
||||||
return
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ type Birc struct {
|
|||||||
i *girc.Client
|
i *girc.Client
|
||||||
Nick string
|
Nick string
|
||||||
names map[string][]string
|
names map[string][]string
|
||||||
activeUsers map[string]int64
|
activeUsers map[string]map[string]int64
|
||||||
activeUsersLastCleaned int64
|
activeUsersLastCleaned int64
|
||||||
activeUsersMutex sync.RWMutex
|
activeUsersMutex sync.RWMutex
|
||||||
connected chan error
|
connected chan error
|
||||||
@ -41,12 +41,17 @@ type Birc struct {
|
|||||||
*bridge.Config
|
*bridge.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ActivityInfo struct {
|
||||||
|
channel string
|
||||||
|
activeTime int64
|
||||||
|
}
|
||||||
|
|
||||||
func New(cfg *bridge.Config) bridge.Bridger {
|
func New(cfg *bridge.Config) bridge.Bridger {
|
||||||
b := &Birc{}
|
b := &Birc{}
|
||||||
b.Config = cfg
|
b.Config = cfg
|
||||||
b.Nick = b.GetString("Nick")
|
b.Nick = b.GetString("Nick")
|
||||||
b.names = make(map[string][]string)
|
b.names = make(map[string][]string)
|
||||||
b.activeUsers = make(map[string]int64)
|
b.activeUsers = make(map[string]map[string]int64)
|
||||||
b.connected = make(chan error)
|
b.connected = make(chan error)
|
||||||
b.channels = make(map[string]bool)
|
b.channels = make(map[string]bool)
|
||||||
|
|
||||||
@ -434,33 +439,45 @@ func (b *Birc) getTLSConfig() (*tls.Config, error) {
|
|||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Birc) isUserActive(nick string) (bool, int64) {
|
func (b *Birc) isActive(activityTime int64, nowTime int64) bool {
|
||||||
|
return (nowTime - activityTime) < b.ActivityTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Birc) isUserActive(nick string, channel string) (bool, int64) {
|
||||||
b.Log.Debugf("checking activity for %s", nick)
|
b.Log.Debugf("checking activity for %s", nick)
|
||||||
if b.ActivityTimeout == 0 {
|
if b.ActivityTimeout == 0 {
|
||||||
return true, 0
|
return true, 0
|
||||||
}
|
}
|
||||||
b.activeUsersMutex.RLock()
|
b.activeUsersMutex.RLock()
|
||||||
defer b.activeUsersMutex.RUnlock()
|
defer b.activeUsersMutex.RUnlock()
|
||||||
if activeTime, ok := b.activeUsers[nick]; ok {
|
if activeTime, ok := b.activeUsers[nick][channel]; ok {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
b.Log.Debugf("last activity for %s was %d, currently %d", nick, activeTime, now)
|
b.Log.Debugf("last activity for %s was %d, currently %d", nick, activeTime, now)
|
||||||
if now < activeTime {
|
if now < activeTime {
|
||||||
b.Log.Errorf("User %s has active time in the future: %d", nick, activeTime)
|
b.Log.Errorf("User %s has active time in the future: %d", nick, activeTime)
|
||||||
return true, now // err on the side of caution
|
return true, now // err on the side of caution
|
||||||
}
|
}
|
||||||
return (now - activeTime) < b.ActivityTimeout, activeTime
|
return b.isActive(now, activeTime), activeTime
|
||||||
}
|
}
|
||||||
return false, 0
|
return false, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Birc) getPseudoChannel() string {
|
func (b *Birc) getActiveChannels(nick string) []ActivityInfo {
|
||||||
for channelname, active := range b.channels {
|
retval := make([]ActivityInfo, 0)
|
||||||
if active {
|
if channels, found := b.activeUsers[nick]; found {
|
||||||
return channelname
|
now := time.Now().Unix()
|
||||||
|
for channel, activeTime := range channels {
|
||||||
|
if now < activeTime {
|
||||||
|
b.Log.Errorf("User %s has active time for channel %s in the future: %d",
|
||||||
|
nick,
|
||||||
|
channel,
|
||||||
|
activeTime)
|
||||||
|
} else if (now - activeTime) < b.ActivityTimeout {
|
||||||
|
retval = append(retval, ActivityInfo{channel, activeTime})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.Log.Warningf("Bot not active in any channels!")
|
}
|
||||||
return ""
|
return retval
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Birc) cleanActiveMap() {
|
func (b *Birc) cleanActiveMap() {
|
||||||
@ -470,16 +487,26 @@ func (b *Birc) cleanActiveMap() {
|
|||||||
}
|
}
|
||||||
b.activeUsersMutex.Lock()
|
b.activeUsersMutex.Lock()
|
||||||
defer b.activeUsersMutex.Unlock()
|
defer b.activeUsersMutex.Unlock()
|
||||||
for nick, activeTime := range b.activeUsers {
|
for nick, activeChannels := range b.activeUsers {
|
||||||
|
for channel, activeTime := range activeChannels {
|
||||||
if now-activeTime > b.ActivityTimeout {
|
if now-activeTime > b.ActivityTimeout {
|
||||||
b.Log.Debugf("last activity for %s was %d, currently %d. Deleting.", nick, activeTime, now)
|
b.Log.Debugf("last activity for %s was %d, currently %d. Deleting.", nick, activeTime, now)
|
||||||
|
delete(activeChannels, channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if 0 == len(activeChannels) {
|
||||||
delete(b.activeUsers, nick)
|
delete(b.activeUsers, nick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Birc) markUserActive(nick string, activeTime int64) {
|
func (b *Birc) markUserActive(nick string, channel string, activeTime int64) {
|
||||||
b.activeUsersMutex.Lock()
|
b.activeUsersMutex.Lock()
|
||||||
defer b.activeUsersMutex.Unlock()
|
defer b.activeUsersMutex.Unlock()
|
||||||
b.activeUsers[nick] = activeTime
|
nickActivity, found := b.activeUsers[nick]
|
||||||
|
if !found {
|
||||||
|
b.activeUsers[nick] = make(map[string]int64)
|
||||||
|
nickActivity = b.activeUsers[nick]
|
||||||
|
}
|
||||||
|
nickActivity[channel] = activeTime
|
||||||
}
|
}
|
||||||
|
@ -947,15 +947,6 @@ IgnoreNicks=""
|
|||||||
# IgnoreMessages="^~~ badword"
|
# IgnoreMessages="^~~ badword"
|
||||||
IgnoreMessages=""
|
IgnoreMessages=""
|
||||||
|
|
||||||
# Prevent URL embeds by encasing URLs in <> angle brackets.
|
|
||||||
# Useful if trolls are a problem on the other end of your bridge.
|
|
||||||
NoEmbedUrls=false
|
|
||||||
|
|
||||||
# Prevent URL embeds in part/quit messages by encasing URLs in <> angle brackets.
|
|
||||||
# Useful if trolls spam in their quit messages or you're tired of seeing embeds for
|
|
||||||
# IRC client homepages.
|
|
||||||
NoEmbedPartUrls=false
|
|
||||||
|
|
||||||
# ReplaceMessages replaces substrings of messages in outgoing messages.
|
# ReplaceMessages replaces substrings of messages in outgoing messages.
|
||||||
# Regular expressions are supported.
|
# Regular expressions are supported.
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user