mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-21 18:22:00 -08:00
3fcce2d8a0
Don't add more columns to the IRC nicks table than the total number of nicks in the IRC channel.
231 lines
5.9 KiB
Go
231 lines
5.9 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"flag"
|
|
"github.com/42wim/matterbridge/matterhook"
|
|
"github.com/peterhellberg/giphy"
|
|
"github.com/thoj/go-ircevent"
|
|
"log"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Bridge struct {
|
|
i *irc.Connection
|
|
m *matterhook.Client
|
|
cmap map[string]string
|
|
*Config
|
|
}
|
|
|
|
func NewBridge(name string, config *Config) *Bridge {
|
|
b := &Bridge{}
|
|
b.Config = config
|
|
b.cmap = make(map[string]string)
|
|
if len(b.Config.Token) > 0 {
|
|
for _, val := range b.Config.Token {
|
|
b.cmap[val.IRCChannel] = val.MMChannel
|
|
}
|
|
}
|
|
b.m = matterhook.New(b.Config.Mattermost.URL,
|
|
matterhook.Config{Port: b.Config.Mattermost.Port, Token: b.Config.Mattermost.Token,
|
|
InsecureSkipVerify: b.Config.Mattermost.SkipTLSVerify,
|
|
BindAddress: b.Config.Mattermost.BindAddress})
|
|
b.i = b.createIRC(name)
|
|
go b.handleMatter()
|
|
return b
|
|
}
|
|
|
|
func (b *Bridge) createIRC(name string) *irc.Connection {
|
|
i := irc.IRC(b.Config.IRC.Nick, b.Config.IRC.Nick)
|
|
i.UseTLS = b.Config.IRC.UseTLS
|
|
i.TLSConfig = &tls.Config{InsecureSkipVerify: b.Config.IRC.SkipTLSVerify}
|
|
if b.Config.IRC.Password != "" {
|
|
i.Password = b.Config.IRC.Password
|
|
}
|
|
i.Connect(b.Config.IRC.Server + ":" + strconv.Itoa(b.Config.IRC.Port))
|
|
time.Sleep(time.Second)
|
|
log.Println("Joining", b.Config.IRC.Channel, "as", b.Config.IRC.Nick)
|
|
i.Join(b.Config.IRC.Channel)
|
|
for _, val := range b.Config.Token {
|
|
log.Println("Joining", val.IRCChannel, "as", b.Config.IRC.Nick)
|
|
i.Join(val.IRCChannel)
|
|
}
|
|
i.AddCallback("PRIVMSG", b.handlePrivMsg)
|
|
i.AddCallback("CTCP_ACTION", b.handlePrivMsg)
|
|
if b.Config.Mattermost.ShowJoinPart {
|
|
i.AddCallback("JOIN", b.handleJoinPart)
|
|
i.AddCallback("PART", b.handleJoinPart)
|
|
}
|
|
i.AddCallback("*", b.handleOther)
|
|
return i
|
|
}
|
|
|
|
func (b *Bridge) handlePrivMsg(event *irc.Event) {
|
|
msg := ""
|
|
if event.Code == "CTCP_ACTION" {
|
|
msg = event.Nick + " "
|
|
}
|
|
msg += event.Message()
|
|
b.Send("irc-"+event.Nick, msg, b.getMMChannel(event.Arguments[0]))
|
|
}
|
|
|
|
func (b *Bridge) handleJoinPart(event *irc.Event) {
|
|
b.Send(b.Config.IRC.Nick, "irc-"+event.Nick+" "+strings.ToLower(event.Code)+"s "+event.Message(), b.getMMChannel(event.Arguments[0]))
|
|
//b.SendType(b.Config.IRC.Nick, "irc-"+event.Nick+" "+strings.ToLower(event.Code)+"s "+event.Message(), b.getMMChannel(event.Arguments[0]), "join_leave")
|
|
}
|
|
|
|
func tableformatter (nicks_s string, nicksPerRow int) string {
|
|
nicks := strings.Split(nicks_s, " ")
|
|
result := "|IRC users"
|
|
if nicksPerRow < 1 {
|
|
nicksPerRow = 4
|
|
}
|
|
for i := 0; i < 2; i++ {
|
|
for j := 1; j <= nicksPerRow && j <= len(nicks); j++ {
|
|
if i == 0 {
|
|
result += "|"
|
|
} else {
|
|
result += ":-|"
|
|
}
|
|
}
|
|
result += "\r\n|"
|
|
}
|
|
result += nicks[0] + "|"
|
|
for i := 1; i < len(nicks); i++ {
|
|
if i % nicksPerRow == 0 {
|
|
result += "\r\n|" + nicks[i] + "|"
|
|
} else {
|
|
result += nicks[i] + "|"
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func plainformatter (nicks string, nicksPerRow int) string {
|
|
return nicks + " currently on IRC"
|
|
}
|
|
|
|
func (b *Bridge) formatnicks (nicks string) string {
|
|
switch (b.Config.Mattermost.NickFormatter) {
|
|
case "table":
|
|
return tableformatter(nicks, b.Config.Mattermost.NicksPerRow)
|
|
default:
|
|
return plainformatter(nicks, b.Config.Mattermost.NicksPerRow)
|
|
}
|
|
}
|
|
|
|
func (b *Bridge) handleOther(event *irc.Event) {
|
|
switch event.Code {
|
|
case "353":
|
|
log.Println("handleOther", b.getMMChannel(event.Arguments[0]))
|
|
b.Send(b.Config.IRC.Nick, b.formatnicks(event.Message()), b.getMMChannel(event.Arguments[0]))
|
|
default:
|
|
log.Printf("got unknown event: %+v\n", event);
|
|
}
|
|
}
|
|
|
|
func (b *Bridge) Send(nick string, message string, channel string) error {
|
|
return b.SendType(nick, message, channel, "")
|
|
}
|
|
|
|
func IsMarkup(message string) bool {
|
|
switch (message[0]) {
|
|
case '|': fallthrough
|
|
case '#': fallthrough
|
|
case '_': fallthrough
|
|
case '*': fallthrough
|
|
case '~': fallthrough
|
|
case '-': fallthrough
|
|
case ':': fallthrough
|
|
case '>': fallthrough
|
|
case '=': return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (b *Bridge) SendType(nick string, message string, channel string, mtype string) error {
|
|
matterMessage := matterhook.OMessage{IconURL: b.Config.Mattermost.IconURL}
|
|
matterMessage.Channel = channel
|
|
matterMessage.UserName = nick
|
|
matterMessage.Type = mtype
|
|
if b.Config.Mattermost.PrefixMessagesWithNick {
|
|
if IsMarkup(message) {
|
|
matterMessage.Text = nick + ":\n\n" + message
|
|
} else {
|
|
matterMessage.Text = nick + ": " + message
|
|
}
|
|
} else {
|
|
matterMessage.Text = message
|
|
}
|
|
err := b.m.Send(matterMessage)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b *Bridge) handleMatter() {
|
|
var username string
|
|
for {
|
|
message := b.m.Receive()
|
|
username = message.UserName + ": "
|
|
if b.Config.IRC.UseSlackCircumfix {
|
|
username = "<" + message.UserName + "> "
|
|
}
|
|
cmd := strings.Fields(message.Text)[0]
|
|
switch cmd {
|
|
case "!users":
|
|
log.Println("received !users from", message.UserName)
|
|
b.i.SendRaw("NAMES " + b.getIRCChannel(message.Token))
|
|
return
|
|
case "!gif":
|
|
message.Text = b.giphyRandom(strings.Fields(strings.Replace(message.Text, "!gif ", "", 1)))
|
|
b.Send(b.Config.IRC.Nick, message.Text, b.getIRCChannel(message.Token))
|
|
return
|
|
}
|
|
texts := strings.Split(message.Text, "\n")
|
|
for _, text := range texts {
|
|
b.i.Privmsg(b.getIRCChannel(message.Token), username+text)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (b *Bridge) giphyRandom(query []string) string {
|
|
g := giphy.DefaultClient
|
|
if b.Config.General.GiphyAPIKey != "" {
|
|
g.APIKey = b.Config.General.GiphyAPIKey
|
|
}
|
|
res, err := g.Random(query)
|
|
if err != nil {
|
|
return "error"
|
|
}
|
|
return res.Data.FixedHeightDownsampledURL
|
|
}
|
|
|
|
func (b *Bridge) getMMChannel(ircChannel string) string {
|
|
mmchannel, ok := b.cmap[ircChannel]
|
|
if !ok {
|
|
mmchannel = b.Config.Mattermost.Channel
|
|
}
|
|
return mmchannel
|
|
}
|
|
|
|
func (b *Bridge) getIRCChannel(token string) string {
|
|
ircchannel := b.Config.IRC.Channel
|
|
_, ok := b.Config.Token[token]
|
|
if ok {
|
|
ircchannel = b.Config.Token[token].IRCChannel
|
|
}
|
|
return ircchannel
|
|
}
|
|
|
|
func main() {
|
|
flagConfig := flag.String("conf", "matterbridge.conf", "config file")
|
|
flag.Parse()
|
|
NewBridge("matterbot", NewConfig(*flagConfig))
|
|
select {}
|
|
}
|