package main import ( "flag" "fmt" "log" "strings" irc "github.com/fluffle/goirc/client" ) const maxLen = 500 type Notify struct { conn *irc.Conn target string } func NewNotify(conn *irc.Conn, target string) *Notify { return &Notify{conn: conn, target: target} } func limit(n int, s string) string { r := []rune(s) if sz := len(r); sz > n { r = append(r[:n], []rune("...")...) } return string(r) } func (n *Notify) Write(p []byte) (int, error) { s := limit(maxLen, string(p)) log.Println("send", s) n.conn.Notice(n.target, s) return len(p), nil } func privmsg(room string) irc.HandlerFunc { var ( last = make(map[string]string) lastRe = make(map[string]string) ) return func(conn *irc.Conn, line *irc.Line) { defer func() { if r := recover(); r != nil { log.Println("panic", r) } }() t := line.Text() switch { case line.Nick == conn.Me().Nick: // ignore self case isFlood(t): log.Println("flood", line.Nick) conn.Kick(room, line.Nick) case t == last[line.Nick]: log.Println("kick", line.Nick) conn.Kick(room, line.Nick) case t == lastRe[line.Nick]: log.Println("ignore", t) case strings.HasPrefix(t, "s"): global := strings.HasSuffix(t, "g") if tofix, ok := last[line.Nick]; ok { fixed, err := re(tofix, t[1:], global) if err == nil && fixed != tofix { log.Println("regexp", t) fmt.Fprintf(NewNotify(conn, line.Target()), "%v meant to say: %s", line.Nick, fixed) lastRe[line.Nick] = t return } } fallthrough default: for _, v := range getLinks(t) { title, err := getTitle(v) if err != nil { log.Println(v, err) } if title != "" { fmt.Fprintf(NewNotify(conn, line.Target()), "Title: %v", title) } } last[line.Nick] = t } } } func main() { node := flag.String("node", "irc.freenode.org", "IRC Server") ssl := flag.Bool("ssl", false, "Use SSL") room := flag.String("room", "#lor", "IRC Channel") name := flag.String("name", "dim13", "Bots Name") flag.Parse() conf := irc.NewConfig(*name) conf.Server = *node conf.SSL = *ssl conn := irc.Client(conf) done := make(chan struct{}) conn.HandleFunc(irc.DISCONNECTED, func(_ *irc.Conn, _ *irc.Line) { close(done) }) conn.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, _ *irc.Line) { conn.Join(*room) Watch(NewNotify(conn, *room), Feeds) }) conn.HandleFunc(irc.PRIVMSG, privmsg(*room)) conn.HandleFunc(irc.KICK, func(conn *irc.Conn, _ *irc.Line) { conn.Join(*room) }) if err := conn.Connect(); err != nil { log.Fatal(err) } <-done }