// handleMessage gets messages received on the IRC network and parses them to recognize commands. func (a *Amigo) handleMessage(msg *irc.Message) { // Handle panics defer func() { if r := recover(); r != nil { log.Println("!!! I'm panicking !!! ", r) } }() // Log message log.Println(msg.String()) // Handle PING if msg.Command == "PING" { a.Send("PONG :" + msg.Trailing) } // Handle message if msg.Command == "PRIVMSG" { // Are you talking to me? if strings.HasPrefix(msg.Trailing, a.Nick) { a.handleCommand(msg) } else { // Free talk ('say when', 'cmd when') a.handleConversation(msg) } } }
// Write handles sending messages, it reconnects if there are problems // can be called concurrently func (c *IConn) Write(m *irc.Message) { if t := c.rateLimit(m.Len()); t != 0 { <-time.After(t) } c.w <- m }
func (server *Server) NewMessage(msg *irc.Message, serverAddr string) (string, error) { message := &Message{ Message: msg.String(), Server: serverAddr, } serialized, err := json.Marshal(message) return string(serialized), err }
func (net *netImpl) privmsg(evt *msg.Message) { if evt.Params[0][0] == '@' { evt.Params[0] = evt.Params[0][1:] } if evt.IsServer() { if evt.Params[0][0] != '#' { return } evt.Name = fmt.Sprintf("SERVER [%s]", evt.Name) } net.ReceiveMessage(evt.Params[0], evt.Name, "privmsg", evt.Trailing) }
func MsgHandler(s ircx.Sender, m *irc.Message) { message := strings.Split(m.String(), " ") user := strings.Split(message[0], "!")[0][1:] err := db.Update(func(tx *bolt.Tx) error { words := make(map[string]uint64) message[3] = message[3][1:] for _, element := range message[3:] { words[element]++ } b := tx.Bucket([]byte(*channel)) bu := b.Bucket([]byte(users)) bm := b.Bucket([]byte(messages)) v := bu.Get([]byte(user)) var count uint64 = 0 if v != nil { count = ByteToUint64(v) } count = count + uint64(len(message[3:])) err := bu.Put([]byte(user), Uint64ToByte(count)) if err != nil { return err } for word, count := range words { v := bm.Get([]byte(word)) var sum uint64 = 0 if v != nil { sum = ByteToUint64(v) } sum = sum + count err := bm.Put([]byte(word), Uint64ToByte(sum)) if err != nil { return err } } return nil }) if err != nil { log.Fatal(err) } else { log.Println(user + " said " + strings.Join(message[3:], " ")) } }
func PrivacyFilterIrcmsg(message *irc.Message) *irc.Message { if message == nil { return nil } if message.Command == irc.PRIVMSG || message.Command == irc.NOTICE { message.Trailing = "<privacy filtered>" } if message.Command == irc.PASS { message.Params = []string{"<privacy filtered>"} message.Trailing = "" } return message }
func (logger *Logger) logRaw(msg *irc.Message, server string) { timestamp := time.Now().Format(time.RFC3339) entry := &rawLog{ Server: server, TimeStamp: timestamp, Message: msg.String(), } _, err := rdb.DB("bot").Table("raw_logs").Insert(entry).RunWrite(logger.DbSession) if err != nil { fmt.Println(err) return } }
// CmdPing is a handler for the /PING command. func CmdPing(s Server, u *User, msg *irc.Message) error { if len(msg.Params) > 0 { msg.Trailing = msg.Params[0] } s.EncodeMessage(u, irc.PONG, []string{s.Name()}, msg.Trailing) return nil }
// send converts |msg| into a RobustMessage and appends it to |reply|. func (i *IRCServer) send(reply *Replyctx, msg *irc.Message) *types.RobustMessage { if reply.lastmsg == msg { return reply.Messages[len(reply.Messages)-1] } reply.replyid++ robustmsg := &types.RobustMessage{ // The IDs must be the same across servers. Id: types.RobustId{ Id: reply.msgid, Reply: reply.replyid, }, Data: string(msg.Bytes()), InterestingFor: make(map[int64]bool), } reply.Messages = append(reply.Messages, robustmsg) reply.lastmsg = msg return robustmsg }
func MessageHandler(s ircx.Sender, m *irc.Message) { msg := m.Trailing var command string if m.Params[0] == name { m.Params = []string{m.Name} } if strings.HasPrefix(strings.ToLower(msg), strings.ToLower(name)) { pieces := strings.Split(msg, " ") if len(pieces) >= 2 { command = pieces[1] runCommand(command, pieces, msg, s, m) return } } else if strings.HasPrefix(msg, prefix) { pieces := strings.Split(msg, " ") if len(pieces) >= 1 { command = pieces[0][1:] runCommand(command, pieces, msg, s, m) return } } else if strings.HasPrefix(msg, "\x01VERSION") { log.Println(ctcp.VersionReply()) s.Send(&irc.Message{ Command: irc.PRIVMSG, Params: m.Params, Trailing: ctcp.VersionReply(), }) return } else { for k := range replies { if ok := k.FindAllString(msg, 1); ok != nil { s.Send(&irc.Message{ Command: irc.PRIVMSG, Params: m.Params, Trailing: replies[k], }) return } } } }
// CmdPrivMsg is a handler for the /PRIVMSG command. func CmdPrivMsg(s Server, u *User, msg *irc.Message) error { var err error if len(msg.Params) > 1 { tr := strings.Join(msg.Params[1:], " ") msg.Trailing = msg.Trailing + tr } // empty message if msg.Trailing == "" { return nil } query := msg.Params[0] if ch, exists := s.HasChannel(query); exists { //p := strings.Replace(query, "#", "", -1) msg.Trailing = strings.Replace(msg.Trailing, "\r", "", -1) // fix non-rfc clients if !strings.HasPrefix(msg.Trailing, ":") { if len(msg.Params) == 2 { msg.Trailing = msg.Params[1] } } // CTCP ACTION (/me) if strings.HasPrefix(msg.Trailing, "\x01ACTION ") { msg.Trailing = strings.Replace(msg.Trailing, "\x01ACTION ", "", -1) msg.Trailing = "*" + msg.Trailing + "*" } msg.Trailing += " " post := &model.Post{ChannelId: ch.ID(), Message: msg.Trailing} _, err := u.mc.Client.CreatePost(post) if err != nil { u.MsgSpoofUser("mattermost", "msg: "+msg.Trailing+" could not be send: "+err.Error()) } } else if toUser, exists := s.HasUser(query); exists { if query == "mattermost" { go u.handleMMServiceBot(toUser, msg.Trailing) return nil } if toUser.MmGhostUser { u.mc.SendDirectMessage(toUser.User, msg.Trailing) return nil } err = s.EncodeMessage(u, irc.PRIVMSG, []string{toUser.Nick}, msg.Trailing) } else { err = s.EncodeMessage(u, irc.ERR_NOSUCHNICK, msg.Params, "No such nick/channel") } return err }
func (h *HandlerFuncs) HandlePirvMsg(m *irc.Message) (err error) { // Print Private messagess log.Printf("%s: %s %s %s\n", h.Name, m.Command, m.Prefix.Name, m.Trailing) // Check for portal reference if val, ok := responses.Portal[m.Trailing]; ok { err = h.ClientConn.PrivMsg(m.Params[0], val) if err != nil { log.Printf("ircutil.PrivMsg(): %s\n", err) return } return } // Check for DDG query if strings.HasPrefix(m.Trailing, "!ddg") { m.Trailing = strings.TrimPrefix(m.Trailing, "!ddg") if m.Trailing == "" { err = h.ClientConn.PrivMsg(m.Params[0], fmt.Sprintf("%s: %s", m.Prefix.Name, "No Query Specified")) if err != nil { log.Printf("ircutil.PrivMsg(): %s\n", err) return err } return } q := &ddg.Client{ Dial: h.Dial, NoHTML: true, } _, text, err := q.FeelingLucky(m.Trailing) if err != nil { log.Printf("ddg.FeelingLucky(): %s\n", err) } if len(text) < 1 { text = "No Results" } err = h.ClientConn.PrivMsg(m.Params[0], fmt.Sprintf("%s: %s", m.Prefix.Name, text)) if err != nil { log.Printf("ircutil.PrivMsg(): %s\n", err) return err } } // Check if message contains URL if crawler.IsURL(m.Trailing) { if strings.HasPrefix(m.Trailing, "dontcrawl") { return } c := &crawler.Client{ Dial: h.Dial, } r, err := c.Crawl(crawler.ExtractUrl(m.Trailing)) if err != nil { log.Printf("crawler.GetTitle(): %s\n", err) return nil } if len(r.Title) > 1 { err = h.ClientConn.PrivMsg(m.Params[0], fmt.Sprintf("^ %s", r.Title)) if err != nil { log.Printf("ircutil.PrivMsg(): %s\n", err) return err } } } return }
func (net *netImpl) rawHandler(evt *msg.Message) { // libmauirc adds the trailing text as a param, remove it. evt.Params = evt.Params[:len(evt.Params)-1] net.Owner.SendMessage(messages.Container{Type: messages.MsgRaw, Object: messages.RawMessage{Network: net.GetName(), Message: evt.String()}}) }
func (server *Server) sendMessage(msg *irc.Message) error { if msg.Command != irc.PRIVMSG { fmt.Printf(">> %s\n", msg.String()) } return server.Writer.Encode(msg) }
func (channel *IrcChannel) handlePrivMsg(msg *irc.Message) { //fmt.Println(msg) fmt_msg := new(TwitchChat) fmt_msg.raw = msg.String() // Parse the tags out of the PRIVMSG for use in the front end // Parse usertype reUserType, err := regexp.Compile(`user-type\=(.*?)(\;|\s)`) if err != nil { log.Print("Could not parse UserType\n") } fmt_msg.usertype = reUserType.FindStringSubmatch(fmt_msg.raw) // Parse subscriber reSub, err := regexp.Compile(`subscriber\=(.*?)(\;|\s)`) if err != nil { log.Print("Could not parse Subscriber\n") } fmt_msg.sub = reSub.FindStringSubmatch(fmt_msg.raw) // Parse turbo reTurbo, err := regexp.Compile(`turbo\=(.*?)(\;|\s)`) if err != nil { log.Print("Could not parse Turbo\n") } fmt_msg.turbo = reTurbo.FindStringSubmatch(fmt_msg.raw) // Parse display name reDisp, err := regexp.Compile(`display-name\=(.*?)(\;|\s)`) if err != nil { log.Print("Could not parse DisplayName\n") } fmt_msg.disp_name = reDisp.FindStringSubmatch(fmt_msg.raw) // Parse color tag reColor, err := regexp.Compile(`#[[:xdigit:]]{6}`) if err != nil { log.Print("Could not parse Color\n") } fmt_msg.color = reColor.FindStringSubmatch(fmt_msg.raw) if len(fmt_msg.color) == 1 && len(fmt_msg.disp_name) >= 1 && len(fmt_msg.sub) >= 1 && len(fmt_msg.turbo) >= 1 && len(fmt_msg.usertype) >= 1 { // User has all fields (mod or staff) // <a href='https://www.twitch.tv/" + msg.Prefix.Name + "/profile' target='_blank'><strong>" + fmt_msg.disp_name[1] + "</strong></a> channel.ReadFromChannel <- []byte("<span data-usertype='" + fmt_msg.usertype[1] + "' data-sub='" + fmt_msg.sub[1] + "' data-turbo='" + fmt_msg.turbo[1] + "' style='color:" + fmt_msg.color[0] + "' id='username'><strong>" + fmt_msg.disp_name[1] + "</strong></span><span id='text'>: " + html.EscapeString(msg.Trailing) + " </span>") } else if len(fmt_msg.color) == 1 && len(fmt_msg.disp_name) >= 1 && len(fmt_msg.sub) >= 1 && len(fmt_msg.turbo) >= 1 { // User is missing user-type tag (non-mod) channel.ReadFromChannel <- []byte("<span data-sub='" + fmt_msg.sub[1] + "' data-turbo='" + fmt_msg.turbo[1] + "' style='color:" + fmt_msg.color[0] + "' id='username'><strong>" + fmt_msg.disp_name[1] + "</strong></span><span id='text'>: " + html.EscapeString(msg.Trailing) + " </span>") } else if len(fmt_msg.color) == 1 && len(fmt_msg.disp_name) >= 1 { // User is missing user-type, subscriber, and turbo tags (rare) channel.ReadFromChannel <- []byte("<span data-sub='0' data-turbo='0' style='color:" + fmt_msg.color[0] + "' id='username'><strong>" + fmt_msg.disp_name[1] + "</strong></span><span id='text'>: " + html.EscapeString(msg.Trailing) + " </span>") } else if len(fmt_msg.color) == 1 { // User is bot (or not authenticated) channel.ReadFromChannel <- []byte("<span style='color:" + fmt_msg.color[0] + "' id='username'><strong>" + msg.Prefix.Name + "</strong></span><span id='text'>: " + html.EscapeString(msg.Trailing) + " </span>") } else { // Randomize colors if the user has never set them before rand.Seed(time.Now().UTC().UnixNano()) colors := []string{ "#FF0000", "#0000FF", "#008000", "#B22222", "#FF7F50", "#9ACD32", "#FF4500", "#2E8B57", "#DAA520", "#D2691E", "#5F9EA0", "#1E90FF", "#FF69B4", "#8A2BE2", "#00FF7F", } /* Map colors to the name, broken for some reason color, ok := fmt_msg.colorMap[msg.Prefix.Name] if !ok { color = colors[rand.Intn(len(colors))] fmt_msg.colorMap[msg.Prefix.Name] = color }*/ color := colors[rand.Intn(len(colors))] if len(fmt_msg.disp_name) >= 1 && len(fmt_msg.sub) >= 1 && len(fmt_msg.turbo) >= 1 && len(fmt_msg.usertype) >= 1 { // User has all fields (mod or staff) channel.ReadFromChannel <- []byte("<span data-usertype='" + fmt_msg.usertype[1] + "' data-sub='" + fmt_msg.sub[1] + "' data-turbo='" + fmt_msg.turbo[1] + "' style='color:" + color + "' id='username'><strong>" + fmt_msg.disp_name[1] + "</strong></span><span id='text'>: " + html.EscapeString(msg.Trailing) + " </span>") } else if len(fmt_msg.disp_name) >= 1 && len(fmt_msg.sub) >= 1 && len(fmt_msg.turbo) >= 1 { // User is missing user-type tag (non-mod) channel.ReadFromChannel <- []byte("<span data-sub='" + fmt_msg.sub[1] + "' data-turbo='" + fmt_msg.turbo[1] + "' style='color:" + color + "' id='username'><strong>" + fmt_msg.disp_name[1] + "</strong></span><span id='text'>: " + html.EscapeString(msg.Trailing) + " </span>") } else if len(fmt_msg.disp_name) >= 1 { // User is missing user-type, subscriber, and turbo tags (rare) channel.ReadFromChannel <- []byte("<span data-sub='0' data-turbo='0' style='color:" + color + "' id='username'><strong>" + fmt_msg.disp_name[1] + "</strong></span><span id='text'>: " + html.EscapeString(msg.Trailing) + " </span>") } } }
func (sender ServerSender) Send(msg *irc.Message, server string) { fmt.Printf(">> %s\n", msg.String()) sender.r.Publish(server, msg.String()) }
func (sender ServerSender) Send(msg *irc.Message) error { fmt.Printf(">> %s\n", msg.String()) return sender.writer.Encode(msg) }
// SendStruct sends a message. func (b *Bot) SendStruct(msg *irc.Message) { b.SendString(msg.String()) }