Skip to content

Instantly share code, notes, and snippets.

@omaraboumrad
Created January 2, 2016 08:16
Show Gist options
  • Save omaraboumrad/98d17f61625711a23e9b to your computer and use it in GitHub Desktop.
Save omaraboumrad/98d17f61625711a23e9b to your computer and use it in GitHub Desktop.
irc bot in golang
package main
import (
"bufio"
"fmt"
"gopkg.in/ini.v1"
"net"
"os"
"regexp"
"strings"
"sync"
)
type Bot struct {
nickname string
realname string
hostname string
servername string
username string
server string
channels []string
incoming chan string
outgoing chan string
group *sync.WaitGroup
reader *bufio.Reader
writer *bufio.Writer
}
func (bot Bot) Initiate() {
var wg sync.WaitGroup
bot.group = &wg
wg.Add(1)
bot.incoming = make(chan string)
bot.outgoing = make(chan string)
if conn, err := net.Dial("tcp", bot.server); err != nil {
fmt.Println(err)
os.Exit(1)
} else {
bot.reader = bufio.NewReader(conn)
bot.writer = bufio.NewWriter(conn)
go bot.ReadFromNetwork()
go bot.HandleIncomingMessages()
go bot.HandleOutgoingMessages()
wg.Wait()
}
}
func (bot Bot) ReadFromNetwork() {
defer bot.group.Done()
for {
if line, err := bot.reader.ReadString('\n'); err != nil {
fmt.Println(err)
break
} else {
bot.incoming <- line
}
}
}
func (bot Bot) HandleIncomingMessages() {
message := <-bot.incoming
bot.HandleUser()
bot.HandleAutoJoin()
for {
fmt.Printf("<-- %s", message)
bot.HandlePing(message)
message = <-bot.incoming
}
}
func (bot Bot) HandleOutgoingMessages() {
for {
message := <-bot.outgoing
bot.writer.WriteString(message + "\n")
bot.writer.Flush()
fmt.Printf("--> %s\n", message)
}
}
/* Protocol functions here. Pull out to separate file later */
func (bot Bot) HandleUser() {
bot.outgoing <- fmt.Sprintf("USER %s %s %s %s",
bot.username,
bot.hostname,
bot.servername,
bot.realname)
bot.outgoing <- fmt.Sprintf("NICK %s", bot.nickname)
}
func (bot Bot) HandleAutoJoin() {
for _, channel := range bot.channels {
bot.outgoing <- fmt.Sprintf("JOIN #%s", channel)
}
}
func (bot Bot) HandlePing(msg string) {
exp := regexp.MustCompile(`^PING :(.*)`)
if matches := exp.FindStringSubmatch(msg); len(matches) > 0 {
bot.outgoing <- fmt.Sprintf("PONG :%s", matches[1])
}
}
func MakeBotFromConfig(cfg *ini.File) Bot {
/* Config Example
nickname = godukes
username = godukes
hostname = godukes
servername = godukes
realname = godukes
server = irc.freenode.net:6667
channels = gogobotbot godukes
*/
return Bot{
nickname: cfg.Section("").Key("nickname").Value(),
username: cfg.Section("").Key("username").Value(),
hostname: cfg.Section("").Key("hostname").Value(),
servername: cfg.Section("").Key("servername").Value(),
realname: cfg.Section("").Key("realname").Value(),
server: cfg.Section("").Key("server").Value(),
channels: strings.Fields(cfg.Section("").Key("channels").Value()),
}
}
func main() {
if cfg, err := ini.Load("bot.ini"); err != nil {
fmt.Println(err)
} else {
bot := MakeBotFromConfig(cfg)
bot.Initiate()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment