Ejemplo n.º 1
0
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()
}
Ejemplo n.º 2
0
// 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
}
Ejemplo n.º 3
0
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)
	}
}
Ejemplo n.º 4
0
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
}
Ejemplo n.º 5
0
// 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
}
Ejemplo n.º 6
0
//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()
}
Ejemplo n.º 7
0
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)
}
Ejemplo n.º 8
0
// 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()
}
Ejemplo n.º 9
0
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()

}
Ejemplo n.º 10
0
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()
}
Ejemplo n.º 11
0
// 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
}
Ejemplo n.º 12
0
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()
}
Ejemplo n.º 13
0
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()
}
Ejemplo n.º 14
0
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)
			}
		}
	}
}
Ejemplo n.º 15
0
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()
}