package twitchirc import ( "crypto/tls" "fmt" "time" "git.trj.tw/golang/mtfosbot/model" "gopkg.in/irc.v2" "git.trj.tw/golang/mtfosbot/module/config" ) var client *irc.Client var queue *QueueList var channels []string // InitIRC - func InitIRC() { conf := config.GetConf() tlsConf := &tls.Config{} conn, err := tls.Dial("tcp", conf.Twitch.ChatHost, tlsConf) // conn, err := net.Dial("tcp", conf.Twitch.ChatHost) if err != nil { fmt.Println("create irc connect fail ", err) time.Sleep(time.Second * 3) go InitIRC() return } defer conn.Close() channels = make([]string, 0) queue = NewQueue() runQueue() ReJoin() config := irc.ClientConfig{ Nick: conf.Twitch.BotUser, Pass: conf.Twitch.BotOauth, Handler: irc.HandlerFunc(ircHandle), } client = irc.NewClient(conn, config) err = client.Run() if err != nil { fmt.Println("twitch chat connect fail") // reconnect after 3sec time.Sleep(time.Second * 3) client = nil channels = channels[:0] queue.Clear() go InitIRC() return } } // SendMessage - func SendMessage(ch, msg string) { if len(ch) == 0 { return } if indexOf(channels, ch) == -1 { return } m := &MsgObj{ Command: "PRIVMSG", Params: []string{ fmt.Sprintf("#%s", ch), fmt.Sprintf("%s", msg), }, } queue.Add(m) } // ReJoin - func ReJoin() { ch, err := model.GetAllTwitchChannel() if err != nil { return } LeaveAllChannel() for _, v := range ch { if v.Join { JoinChannel(v.Name) } } } // JoinChannel - func JoinChannel(ch string) { if len(ch) == 0 { return } m := &MsgObj{ Command: "JOIN", Params: []string{ fmt.Sprintf("#%s", ch), }, } queue.Add(m) } // LeaveChannel - func LeaveChannel(ch string) { if len(ch) == 0 { return } if indexOf(channels, ch) == -1 { return } m := &MsgObj{ Command: "PART", Params: []string{ fmt.Sprintf("#%s", ch), }, } queue.Add(m) } // LeaveAllChannel - func LeaveAllChannel() { if len(channels) == 0 { return } for _, v := range channels { m := &MsgObj{ Command: "PART", Params: []string{ fmt.Sprintf("#%s", v), }, } queue.Add(m) } } func runQueue() { go func() { cnt := 0 for { if !queue.IsEmpty() && client != nil { m := queue.Get() msg := &irc.Message{} msg.Command = m.Command msg.Params = m.Params if m.Command == "JOIN" { if indexOf(channels, m.Params[0][1:]) != -1 { continue } channels = append(channels, m.Params[0][1:]) } else if m.Command == "PART" { if indexOf(channels, m.Params[0][1:]) == -1 { continue } idx := indexOf(channels, m.Params[0][1:]) channels = append(channels[:idx], channels[idx+1:]...) } fmt.Println("< ", msg.String()) client.WriteMessage(msg) } cnt++ if cnt > 3600 { // call rejoin ReJoin() cnt = 0 } time.Sleep(time.Second * 1) } }() } func ircHandle(c *irc.Client, m *irc.Message) { fmt.Println("> ", m.String()) if m.Command == "PING" { tmp := &irc.Message{ Command: "PONG", Params: []string{ m.Params[0], }, } fmt.Println("< ", tmp.String()) client.WriteMessage(tmp) } } func indexOf(c []string, data string) int { if len(c) == 0 { return -1 } for k, v := range c { if v == data { return k } } return -1 }