func (a *adapter) startIRCConnection() { if a.nick == "" { a.nick = a.user } conn := irc.IRC(a.nick, a.user) if a.useTLS { conn.UseTLS = true conn.TLSConfig = &tls.Config{ServerName: a.server} } conn.Password = a.password conn.Debug = (hal.Logger.Level() == 10) err := conn.Connect(a.connectionString()) if err != nil { panic("failed to connect to" + err.Error()) } conn.AddCallback("001", func(e *irc.Event) { for _, channel := range a.channels { conn.Join(channel) hal.Logger.Debug("irc - joined " + channel) } }) conn.AddCallback("PRIVMSG", func(e *irc.Event) { message := a.newMessage(e) a.Receive(message) }) a.conn = conn hal.Logger.Debug("irc - waiting for server acknowledgement") conn.Loop() }
// New creates a new irc connection func New(nick, user, server, serverPass string, useTLS bool, output io.Writer) (*IRC, error) { con := ircevent.IRC(nick, user) con.Log = log.New(ioutil.Discard, "", log.LstdFlags) con.UseTLS = useTLS con.Password = serverPass if err := con.Connect(server); err != nil { return nil, err } ircc := IRC{ Nick: nick, User: user, UseTLS: useTLS, Server: server, ServerPass: serverPass, Output: output, Connection: con, Connected: false, } con.AddCallback("001", ircc.OnConnect) con.AddCallback("JOIN", ircc.OnJoin) con.AddCallback("PART", ircc.OnPart) con.AddCallback("PRIVMSG", ircc.OnMsg) con.AddCallback("NOTICE", ircc.OnMsg) con.AddCallback("QUIT", ircc.OnQuit) go con.Loop() return &ircc, nil }
func Receive( server string, port int, nick string, channels []string, ch chan<- string, ) { conn := irc.IRC(nick, "aun") hostAndPort := fmt.Sprintf("%s:%d", server, port) conn.VerboseCallbackHandler = true conn.Connect(hostAndPort) conn.AddCallback("PRIVMSG", func(event *irc.Event) { m := IrcMessage{ From: event.Nick, To: event.Arguments[0], Text: event.Message(), } buf, err := json.Marshal(m) if err != nil { log.Fatal(err) } ch <- string(buf) }) for _, channel := range channels { conn.Join(channel) } }
func connect() error { connection := irclib.IRC(config.BotNick, config.BotUser) err := connection.Connect(config.Server) if err != nil { logger.GenericLogger(fmt.Sprintf("%s/ana-irc.log", config.LogDir), fmt.Sprintf("%v\n", err)) return err } return nil }
// ConnectIRC is used to connect to IRC func ConnectIRC() *irc.Connection { con := irc.IRC(config.IRCNick, config.IRCUsername) if config.IRCPass != "" { con.Password = config.IRCPass } err := con.Connect(config.IRCHostname) if err != nil { log.Fatalf("Problem connecting to irc: %s", err) } return con }
//Starts the irc client func ircConnStart(c *ircConfig) { ircCfg = c ircConn = ircevent.IRC(c.Nickname, c.Nickname) ircConn.Debug = c.Debug ircConn.VerboseCallbackHandler = c.Verbose ircConn.AddCallback("PRIVMSG", ircMsgHandler) ircConn.AddCallback("001", ircWelcomeHandler) err := ircConn.Connect(c.Server) if err != nil { log.Fatal("ircConnStart() => Connect() error:\t", err) } ircConn.Loop() }
func connect(mgr *IrcConnectionManager, conf *config.Configuration, l *log.Logger) { if mgr.conn == nil { mgr.conn = ircevent.IRC(conf.Nick, conf.Username) mgr.conn.Log = l mgr.injector.Map(mgr.conn) mgr.injector.Invoke(bindEvents) } if conf.TLS { mgr.conn.UseTLS = true mgr.conn.TLSConfig = &tls.Config{InsecureSkipVerify: true} } mgr.status = Connecting mgr.injector.Invoke(triggerConnecting) mgr.conn.Connect(conf.Network) }
// Run reads the Config, connect to the specified IRC server and starts the bot. // The bot will automatically join all the channels specified in the configuration func Run(c *Config) { config = c ircConn = ircevent.IRC(c.User, c.Nick) ircConn.Password = c.Password ircConn.UseTLS = c.UseTLS ircConn.TLSConfig = &tls.Config{ ServerName: getServerName(c.Server), } ircConn.VerboseCallbackHandler = c.Debug b = bot.New(&bot.Handlers{ Response: responseHandler, }) ircConn.AddCallback("001", onWelcome) ircConn.AddCallback("PRIVMSG", onPRIVMSG) err := ircConn.Connect(c.Server) if err != nil { log.Fatal(err) } ircConn.Loop() }
func worker(number int, quit <-chan bool) { name := fmt.Sprintf(nickpattern, number) irc := ircevent.IRC(name, name) irc.Connect(server) irc.AddCallback("001", func(event *ircevent.Event) { for { var buffer bytes.Buffer buffer.WriteString("MONITOR + ") for i := 0; i < (maxlen / nicklen); i++ { buffer.WriteString(makeNick(nicklen)) buffer.WriteString(",") } irc.SendRaw(buffer.String()) time.Sleep(delay) irc.SendRaw("MONITOR C") time.Sleep(delay) } }) <-quit irc.Quit() }
func main() { // get config confPath := fmt.Sprintf("%s/.config/irkbot/irkbot.ini", os.Getenv("HOME")) cfg := lib.Config{} err := gcfg.ReadFileInto(&cfg, confPath) if err != nil { fmt.Fprintln(os.Stderr, err) return } conn := goirc.IRC(cfg.User.Nick, cfg.User.User) err = conn.Connect(fmt.Sprintf( "%s:%s", cfg.Server.Host, cfg.Server.Port)) if err != nil { fmt.Fprintln(os.Stderr, err) return } conn.VerboseCallbackHandler = cfg.Connection.Verbose_callback_handler conn.Debug = cfg.Connection.Debug conn.AddCallback("001", func(e *goirc.Event) { conn.Join(cfg.Channel.Channelname) }) conn.AddCallback("366", func(e *goirc.Event) { if len(cfg.Channel.Greeting) != 0 { conn.Privmsg(e.Arguments[1], cfg.Channel.Greeting) } }) // register modules var pmMods []*lib.Module modpm.RegisterMods(func(m *lib.Module) { pmMods = append(pmMods, m) if m.Configure != nil { m.Configure(&cfg) } }) // TODO: start multiple sayLoops, one per conn // TODO: pass conn to sayLoop instead of privmsg callbacks? sayChan := make(chan lib.SayMsg) go lib.SayLoop(sayChan) conn.AddCallback("PRIVMSG", func(e *goirc.Event) { p := lib.Privmsg{} p.Msg = e.Message() p.MsgArgs = strings.Split(p.Msg, " ") p.Dest = e.Arguments[0] if !strings.HasPrefix(p.Dest, "#") { p.Dest = e.Nick } p.Event = e p.Conn = conn p.SayChan = sayChan for _, mod := range pmMods { if mod.Run(&p) { break } } }) // TODO: add time-based modules conn.Loop() }
// IRC returns the IRC message provider func IRC(user, nick, server, channels, password, useTLS string) *providerIRC { pi := &providerIRC{ channels: strings.Split(channels, ","), in: make(chan messages.Message), out: make(chan messages.Message), } ircConn := ircevent.IRC(user, nick) ircConn.Password = password ircConn.UseTLS = false if useTLS != "" { log.Println("irc: activating TLS") serverName, _, err := net.SplitHostPort(server) if err != nil { pi.err = fmt.Errorf("error spliting host port: %v", err) return pi } useTLSBool, err := strconv.ParseBool(useTLS) if err != nil { pi.err = fmt.Errorf("error parsing bool (useTLS): %v", err) return pi } ircConn.UseTLS = useTLSBool if useTLSBool { ircConn.TLSConfig = &tls.Config{ ServerName: serverName, } } } ircConn.AddCallback( "001", func(e *ircevent.Event) { for _, channel := range pi.channels { ircConn.Join(channel) } }, ) ircConn.AddCallback("PRIVMSG", func(e *ircevent.Event) { msg := messages.Message{ Room: e.Arguments[0], FromUserName: e.Nick, Message: e.Message(), // Direct: strings.HasPrefix(data.Channel, "D"), } pi.in <- msg }) if err := ircConn.Connect(server); err != nil { pi.err = fmt.Errorf("error connecting to server (%s): %v", server, err) return pi } pi.ircConn = ircConn log.Println("irc: starting message loops") go pi.ircConn.Loop() go pi.dispatchLoop() return pi }
func main() { if len(os.Args) != 4 { fmt.Fprintf(os.Stderr, "Usage: %s server:port channel bot-username", os.Args[0]) os.Exit(1) } ready := make(chan bool, 1) ready <- true // http client client := &http.Client{} // setup IRC icon := irc.IRC(os.Args[3], "hahawtflol") err := icon.Connect(os.Args[1]) geddit.CheckError(err) icon.AddCallback("001", func(e *irc.Event) { icon.Join("#" + os.Args[2]) }) //icon.AddCallback("JOIN", func(e *irc.IRCEvent) { //icon.SendRaw("PRIVMSG #" + os.Args[2] + " :SCV ready s(^_^)-b") //}) icon.AddCallback("PRIVMSG", func(e *irc.Event) { if strings.HasPrefix(e.Message, "@reddit") { // check for message longer than '@reddit sub' if len(e.Message) < 8 { return } req, err := http.NewRequest("GET", "http://reddit.com/r/"+e.Message[8:]+".json", nil) req.Header.Set("User-Agent", "wtf_is_up ~ playing with Go-lang") // make request resp, err := client.Do(req) geddit.CheckError(err) if resp.StatusCode != http.StatusOK { log.Println("bad HTTP response: " + resp.Status) return } // read response defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) geddit.CheckError(err) // hackish way of dealing with XML returned from reddit redirect caused // by subreddit not existing if strings.HasPrefix(string(body), "<") { log.Println("returned xml; bad") icon.SendRaw("PRIVMSG " + e.Arguments[0] + " :\x031,4q-(v_v)z \x034,1 bad subreddit") return } // parse JSON var jRep geddit.Top err = json.Unmarshal(body, &jRep) geddit.CheckError(err) select { case <-ready: go sendIRC(jRep.ToIRCStrings(), icon, e, ready) default: icon.SendRaw("PRIVMSG " + e.Arguments[0] + " :\x031,4q-(v_v)z \x034,1 wait ur turn (flood control, l0l) ") } } if strings.Contains(e.Message, "ur mom") { time.Sleep(time.Second * 2) icon.SendRaw("PRIVMSG " + e.Arguments[0] + " :\x031,4http://en.wikipedia.org/wiki/List_of_burn_centers_in_the_United_States") } }) icon.Loop() }
func main() { var ( irc *goirc.Connection err error ) var configFile = flag.String("c", "r2d2.cfg", "Load configuration from file") flag.Parse() _, err = os.Stat(*configFile) if err != nil { log.Fatal("%v", err) os.Exit(1) } err = gcfg.ReadFileInto(&cfg, *configFile) if err != nil { log.Fatal("Error in configuration file: %v", err) os.Exit(1) } irc = goirc.IRC(cfg.Irc.Nick, cfg.Irc.Nick) irc.UseTLS = cfg.Irc.TLS irc.VerboseCallbackHandler = cfg.Irc.Debug irc.Debug = cfg.Irc.Debug err = irc.Connect(cfg.Irc.Server) if err != nil { log.Fatal("Connection to IRC server failed: %v", err) os.Exit(1) } // block while performing authentication handleAuth(irc) // we are identified, let's continue if cfg.Irc.ChannelPass != "" { // if a channel pass is used, craft a join command // of the form "&<channel>; <key>" irc.Join(cfg.Irc.Channel + " " + cfg.Irc.ChannelPass) } else { irc.Join(cfg.Irc.Channel) } if cfg.Irc.Debug { irc.Privmsg(cfg.Irc.Channel, "beep beedibeep dibeep") } go watchGithub(irc) go watchUntappd(irc) go fetchPageTitles(irc) initMaxmind() // add callback that captures messages sent to bot terminate := make(chan bool) irc.AddCallback("PRIVMSG", func(e *goirc.Event) { re := regexp.MustCompile("^" + cfg.Irc.Nick + ":(.+)$") if re.MatchString(e.Message()) { parsed := re.FindStringSubmatch(e.Message()) if len(parsed) != 2 { return } req := strings.Trim(parsed[1], " ") resp := handleRequest(e.Nick, req, irc) if resp != "" { irc.Privmsgf(cfg.Irc.Channel, "%s: %s", e.Nick, resp) } } }) <-terminate irc.Loop() irc.Disconnect() }
func main() { if err := parseConfig(); err != nil { log.Fatal(err) } notificationTemplates, err := loadNotificationTemplates() if err != nil { log.Fatal(err) } var logSink io.Writer if config.LonelyCat.LogFile != "" { logFile, err := os.OpenFile(config.LonelyCat.LogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660) if err != nil { log.Fatal(err) } defer logFile.Close() logSink = io.MultiWriter(os.Stdout, logFile) } else { logSink = os.Stdout } s := &lonelycat.NetMsgListener{} go s.Listen(config.LonelyCat.Addr) // Where to write msg replies replyChan := make(chan lonelycat.MessageOut) lc := lonelycat.NewLonelyCat() tc := lonelycat.NewTrelloClient() tc.ApiKey = config.Trello.ApiKey tc.Token = config.Trello.Token tc.BaseURL = "https://api.trello.com" lc.Trello = tc lc.L = log.New(logSink, "lonelycat: ", log.LstdFlags) log.SetOutput(logSink) RegisterHandlers(lc) var quitCounter int // Listen for messages coming from msg server msgChan := make(chan lonelycat.MessageIn) s.SubscribeWith(msgChan) go func() { log.Println("Listening for local messages...") for { select { case msg := <-msgChan: lc.L.Printf("Local msg: %s\n", msg) err := lc.ProcessMessage(msg, replyChan) switch { case err == lonelycat.ErrMsgNoSuitableHandler: lc.L.Println(err) case err != nil: lc.L.Println(err) replyChan <- lonelycat.MessageOut{ Msg: "An error occurred.", Dest: msg.Source, } } case v := <-lc.QuitChan: quitCounter-- lc.QuitChan <- v return } } }() quitCounter++ // Start trello notifications fetcher delay := time.Duration(int64(time.Second) * int64(config.LonelyCat.NotificationsFetchDelay)) go func() { log.Println("Started notifications poller...") var m sync.Mutex for { select { case <-time.After(delay): m.Lock() go func() { defer func() { m.Unlock() log.Println("Fetch done") }() log.Println("Starting fetch") relayChan := make(chan lonelycat.Notification) go func() { err := FetchAndRelayNewNotifications(lc, relayChan) if err != nil { lc.L.Println(err) return } }() for n := range relayChan { s, err := FormatNotification(notificationTemplates, n) if err == ErrNoTemplate { continue } if err != nil { lc.L.Println(err) continue } ch, ok := config.LonelyCat.BoardIrcChanMap[n.Data.Board.Name] if !ok { lc.L.Printf("No irc chan for board \"%s\"\n", n.Data.Board.Name) continue } msg := lonelycat.MessageOut{ Msg: s, Dest: ch, } replyChan <- msg } }() case v := <-lc.QuitChan: quitCounter-- lc.QuitChan <- v return } } }() quitCounter++ irccon := irc.IRC(config.Irc.Nick, config.Irc.User) err = irccon.Connect(config.Irc.Addr) if err != nil { log.Fatal(err) } irccon.AddCallback("001", func(e *irc.Event) { for _, ch := range config.LonelyCat.BoardIrcChanMap { irccon.Join(ch) } }) irccon.AddCallback("PRIVMSG", func(e *irc.Event) { isAuthorizedNick := false for _, u := range config.Irc.AuthorizedNicks { if u == e.Nick { isAuthorizedNick = true break } } if !isAuthorizedNick { return } msgChan <- lonelycat.MessageIn{Msg: e.Message, Source: e.Nick} }) go irccon.Loop() sigCh := make(chan os.Signal) signal.Notify(sigCh, os.Interrupt) log.Println("Listening for reply messages...") for { select { case <-sigCh: lc.Quit() case v := <-lc.QuitChan: if quitCounter > 0 { lc.QuitChan <- v } else { irccon.Quit() return } case msg := <-replyChan: cleanMsg := strings.Replace(msg.Msg, "\n", " ", -1) if len(cleanMsg) == 0 || msg.Dest == "" { break } log.Printf("[OUT] ->%s: %s\n", msg.Dest, cleanMsg) switch msg.Dest { case lonelycat.NetMsgName: case "": default: irccon.Privmsg(msg.Dest, cleanMsg) time.Sleep(time.Millisecond * 100) } } } }
func main() { var ( iconMapFilename string ) flag.StringVar(&WebhookURL, "webhook-url", "", "Slack Incomming Webhook URL") flag.StringVar(&WebhookToken, "webhook-token", "", "Slack Outgoing Webhook token") flag.StringVar(&ListenAddr, "listen", ":7777", "HTTP listen address (for accept Outgoing Webhook)") flag.StringVar(&IRCNick, "nick", "sirbot", "IRC nick") flag.StringVar(&IRCHost, "irc-host", "localhost", "IRC server host") flag.IntVar(&IRCPort, "irc-port", 6666, "IRC server port") flag.StringVar(&IRCPassword, "irc-password", "", "IRC server password") flag.BoolVar(&IRCSecure, "irc-secure", false, "IRC use SSL") flag.StringVar(&IRCChannel, "irc-channel", "", "IRC channel to join") flag.StringVar(&SlackChannel, "slack-channel", "", "Slack channel to join") flag.StringVar(&iconMapFilename, "icon-map", "", "icon map file(yaml)") flag.Parse() if iconMapFilename != "" { var err error IconMap, err = LoadIconMap(iconMapFilename) if err != nil { log.Println(err) } } ch := make(chan Message, 10) go startHttpServer(ch) slack := &SlackAgent{ WebhookURL: WebhookURL, client: &http.Client{}, } agent := irc.IRC(IRCNick, IRCNick) agent.UseTLS = IRCSecure agent.Password = IRCPassword err := agent.Connect(fmt.Sprintf("%s:%d", IRCHost, IRCPort)) if err != nil { log.Println(err) return } agent.AddCallback("001", func(e *irc.Event) { agent.Join(IRCChannel) log.Println("Joined", IRCChannel) }) agent.AddCallback("PRIVMSG", func(e *irc.Event) { nick := strings.ToLower(e.Nick) msg := Message{ Channel: SlackChannel, Text: e.Message(), UserName: fmt.Sprintf( "%s[%s]", e.Nick, e.Arguments[0], // channel ), LinkNames: 1, } if u := IconMap.Icons[nick]; u != "" { msg.IconURL = u } err := slack.Post(msg) if err != nil { log.Println("[error]", err) } }) go func() { for { msg := <-ch agent.Privmsg(IRCChannel, msg.Text) time.Sleep(1 * time.Second) } }() agent.Loop() }