irc_bot/main.go

154 lines
4.2 KiB
Go

package main
import (
"fmt"
"log"
"net"
"strings"
"crypto/tls"
"github.com/oschwald/geoip2-golang"
"github.com/thoj/go-ircevent"
)
func main() {
config, err := LoadConfig("config.json")
if err != nil {
log.Fatalf("Error loading config: %v", err)
}
irccon := irc.IRC(config.Nickname, config.Nickname)
irccon.VerboseCallbackHandler = true
irccon.Debug = true
irccon.UseTLS = config.SSL
irccon.TLSConfig = &tls.Config{InsecureSkipVerify: true}
err = irccon.Connect(fmt.Sprintf("%s:%d", config.IRCServer, config.IRCPort))
if err != nil {
log.Fatalf("Failed to connect to IRC server: %v", err)
}
irccon.AddCallback("001", func(e *irc.Event) {
for _, channel := range config.Channels {
irccon.Join(channel)
}
})
irccon.AddCallback("PRIVMSG", func(e *irc.Event) {
if len(e.Arguments) < 2 {
return
}
message := e.Arguments[1]
parts := strings.Fields(message)
if len(parts) == 0 {
return
}
cmd := strings.TrimPrefix(parts[0], "!")
if commandFunc, ok := commands[cmd]; ok {
commandFunc(irccon, e, parts)
}
})
irccon.Loop()
}
type CommandFunc func(irccon *irc.Connection, e *irc.Event, args []string)
var commands = map[string]CommandFunc{
"geoip": handleGeoIPCommand,
// add more commands here
}
func handleGeoIPCommand(irccon *irc.Connection, e *irc.Event, args []string) {
if len(args) < 2 {
irccon.Privmsg(e.Arguments[0], "Usage: !geoip <IP or domain>")
return
}
ipOrDomain := args[1]
config, err := LoadConfig("config.json")
if err != nil {
log.Fatalf("Error loading config: %v", err)
}
cityDbPath := config.GeoIPDatabase // Update with actual path
asnDbPath := config.GeoIPASN // Update with actual path
ip := net.ParseIP(ipOrDomain)
if ip == nil {
resolvedIP, err := net.LookupIP(ipOrDomain)
if err != nil || len(resolvedIP) == 0 {
irccon.Privmsg(e.Arguments[0], fmt.Sprintf("Invalid IP address or domain: %s", ipOrDomain))
return
}
ip = resolvedIP[0]
}
var (
city = "N/A"
subdivision = "N/A"
country = "N/A"
latitude = "N/A"
longitude = "N/A"
asn = "N/A"
isp = "N/A"
)
// Lookup City Information
if cityDb, err := geoip2.Open(cityDbPath); err == nil {
defer cityDb.Close()
if cityRecord, err := cityDb.City(ip); err == nil {
if name := cityRecord.City.Names["en"]; name != "" {
city = name
}
if len(cityRecord.Subdivisions) > 0 {
if name := cityRecord.Subdivisions[0].Names["en"]; name != "" {
subdivision = name
}
}
if name := cityRecord.Country.Names["en"]; name != "" {
country = name
}
if lat := cityRecord.Location.Latitude; lat != 0 {
latitude = fmt.Sprintf("%.6f", lat)
}
if lon := cityRecord.Location.Longitude; lon != 0 {
longitude = fmt.Sprintf("%.6f", lon)
}
} else {
log.Printf("City lookup error: %v", err)
}
} else {
log.Printf("Error opening City database: %v", err)
}
// Lookup ASN Information
if asnDb, err := geoip2.Open(asnDbPath); err == nil {
defer asnDb.Close()
if asnRecord, err := asnDb.ASN(ip); err == nil {
if asnNum := asnRecord.AutonomousSystemNumber; asnNum != 0 {
asn = fmt.Sprintf("%d", asnNum)
}
if org := asnRecord.AutonomousSystemOrganization; org != "" {
isp = org
}
} else {
log.Printf("ASN lookup error: %v", err)
}
} else {
log.Printf("Error opening ASN database: %v", err)
}
response := fmt.Sprintf(
"IP: %s | Location: %s, %s, %s | Coordinates: %s, %s | ASN: %s | ISP: %s",
ip.String(), city, subdivision, country, latitude, longitude, asn, isp,
)
irccon.Privmsg(e.Arguments[0], response)
}