Change-Id: If519e789a91fbf427373daa383c6ae00ba5e0b6c Reviewed-on: https://cl.tvl.fyi/c/depot/+/2007 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in>
		
			
				
	
	
		
			170 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"crypto/tls"
 | |
| 	"encoding/json"
 | |
| 	"flag"
 | |
| 	"fmt"
 | |
| 	"log"
 | |
| 	"net"
 | |
| 	"sync"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/go-redis/redis"
 | |
| 	"gopkg.in/irc.v3"
 | |
| )
 | |
| 
 | |
| var messageBeat chan bool
 | |
| var firstMessage chan bool
 | |
| var client *irc.Client
 | |
| var safeLock sync.Mutex
 | |
| 
 | |
| func main() {
 | |
| 	nick := flag.String("nick", "NONE", "the ircnick you want")
 | |
| 	from := flag.String("ip", "[::1]", "src address")
 | |
| 	flag.Parse()
 | |
| 
 | |
| 	localAddrDialier := &net.Dialer{
 | |
| 		LocalAddr: &net.TCPAddr{
 | |
| 			IP:   net.ParseIP(*from),
 | |
| 			Port: 0,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	conn, err := tls.DialWithDialer(localAddrDialier, "tcp", "chat.freenode.net:6697", &tls.Config{})
 | |
| 	if err != nil {
 | |
| 		log.Fatalln(err)
 | |
| 	}
 | |
| 
 | |
| 	messageBeat = make(chan bool)
 | |
| 	firstMessage = make(chan bool, 10)
 | |
| 	go ircKeepalive()
 | |
| 
 | |
| 	redisc := redis.NewClient(&redis.Options{
 | |
| 		Addr:     fmt.Sprintf("127.0.0.1:%d", 6379),
 | |
| 		Password: "", // no password set
 | |
| 		DB:       0,  // use default DB
 | |
| 	})
 | |
| 
 | |
| 	go func() {
 | |
| 		for {
 | |
| 			time.Sleep(time.Second)
 | |
| 			r := redisc.Ping()
 | |
| 			if r.Err() != nil {
 | |
| 				redisc = redis.NewClient(&redis.Options{
 | |
| 					Addr:     fmt.Sprintf("127.0.0.1:%d", 6379),
 | |
| 					Password: "", // no password set
 | |
| 					DB:       0,  // use default DB
 | |
| 				})
 | |
| 			}
 | |
| 			redisc.Set(fmt.Sprintf("alive-%s", *nick), "yes", time.Second*5)
 | |
| 		}
 | |
| 	}()
 | |
| 
 | |
| 	if *nick == "NONE" {
 | |
| 		log.Fatalf("You must set a nick")
 | |
| 	}
 | |
| 
 | |
| 	go func() {
 | |
| 		<-firstMessage
 | |
| 		for {
 | |
| 			psub := redisc.Subscribe(fmt.Sprintf("irc-%s", *nick))
 | |
| 
 | |
| 			for {
 | |
| 				msg, err := psub.ReceiveMessage()
 | |
| 				if err != nil {
 | |
| 					break
 | |
| 				}
 | |
| 				client.WriteMessage(&irc.Message{
 | |
| 					Command: "PRIVMSG",
 | |
| 					Params: []string{
 | |
| 						"##tvl-ebooks",
 | |
| 						msg.Payload,
 | |
| 					},
 | |
| 				})
 | |
| 			}
 | |
| 			time.Sleep(time.Second * 10)
 | |
| 		}
 | |
| 
 | |
| 	}()
 | |
| 
 | |
| 	go func() {
 | |
| 		<-firstMessage
 | |
| 		for {
 | |
| 			psub := redisc.Subscribe(fmt.Sprintf("raw-irc-%s", *nick))
 | |
| 
 | |
| 			for {
 | |
| 				msg, err := psub.ReceiveMessage()
 | |
| 				if err != nil {
 | |
| 					break
 | |
| 				}
 | |
| 				im := irc.Message{}
 | |
| 				err = json.Unmarshal([]byte(msg.Payload), &im)
 | |
| 				if err == nil {
 | |
| 					client.WriteMessage(&im)
 | |
| 				}
 | |
| 			}
 | |
| 			time.Sleep(time.Second * 10)
 | |
| 		}
 | |
| 
 | |
| 	}()
 | |
| 
 | |
| 	seenMsgBefore := false
 | |
| 	config := irc.ClientConfig{
 | |
| 		Nick: *nick,
 | |
| 		User: *nick,
 | |
| 		Name: fmt.Sprintf("%s Ebooks", *nick),
 | |
| 		Handler: irc.HandlerFunc(func(c *irc.Client, m *irc.Message) {
 | |
| 			b, _ := json.Marshal(m)
 | |
| 			log.Printf("%#v", string(b))
 | |
| 
 | |
| 			messageBeat <- true
 | |
| 
 | |
| 			if !seenMsgBefore {
 | |
| 				firstMessage <- true
 | |
| 				seenMsgBefore = true
 | |
| 			}
 | |
| 			res := redisc.Publish("ebook", string(b))
 | |
| 			if res.Err() != nil {
 | |
| 				log.Printf("Publish error! %#v", err)
 | |
| 			}
 | |
| 			if m.Command == "001" {
 | |
| 				// 001 is a welcome event, so we join channels there
 | |
| 				c.Write("JOIN ##tvl-ebooks")
 | |
| 			}
 | |
| 			// else if m.Command == "PRIVMSG" && c.FromChannel(m) {
 | |
| 			// 	// // Create a handler on all messages.
 | |
| 			// 	// c.WriteMessage(&irc.Message{
 | |
| 			// 	// 	Command: "PRIVMSG",
 | |
| 			// 	// 	Params: []string{
 | |
| 			// 	// 		m.Params[0],
 | |
| 			// 	// 		m.Trailing(),
 | |
| 			// 	// 	},
 | |
| 			// 	// })
 | |
| 			// }
 | |
| 		}),
 | |
| 	}
 | |
| 
 | |
| 	// Create the client
 | |
| 	client = irc.NewClient(conn, config)
 | |
| 	err = client.Run()
 | |
| 	if err != nil {
 | |
| 		log.Fatalln(err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func ircKeepalive() {
 | |
| 	tt := time.NewTimer(time.Second)
 | |
| 	lastPing := time.Now()
 | |
| 	for {
 | |
| 		select {
 | |
| 		case <-tt.C:
 | |
| 			if time.Since(lastPing) > time.Minute*5 {
 | |
| 				log.Fatalf("It's been too long since the last IRC message, blowing up")
 | |
| 			}
 | |
| 			break
 | |
| 		case <-messageBeat:
 | |
| 			lastPing = time.Now()
 | |
| 		}
 | |
| 	}
 | |
| }
 |