grim/wasdead

855a25ce5948
LICENSE edited online with Bitbucket
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/bwmarrin/discordgo"
"github.com/nicklaw5/helix"
)
var (
DiscordToken string
TwitchToken string
TwitchClient *helix.Client
logger *log.Logger
startTime time.Time
guildToChannel map[string]string
)
func init() {
logger = log.New(os.Stderr, " ", log.Ldate|log.Ltime)
startTime = time.Now()
flag.StringVar(&DiscordToken, "t", "", "Discord Bot Token")
flag.StringVar(&TwitchToken, "tcid", "", "Twitch Client ID ID")
flag.Parse()
}
func logDebug(v ...interface{}) {
logger.SetPrefix("DEBUG ")
logger.Println(v...)
}
func logInfo(v ...interface{}) {
logger.SetPrefix("INFO ")
logger.Println(v...)
}
func logError(v ...interface{}) {
logger.SetPrefix("ERROR ")
logger.Println(v...)
}
func logPanic(v ...interface{}) {
logger.SetPrefix("PANIC ")
logger.Panicln(v...)
}
func main() {
if len(DiscordToken) <= 0 || len(TwitchToken) <= 0 {
logPanic("Discord Token and Twitch Client ID must be set")
}
logDebug("Discord Token:", DiscordToken)
logDebug("Twitch Token:", TwitchToken)
if fileExist("guilds.json") {
plan, _ := ioutil.ReadFile("guilds.json")
json.Unmarshal(plan, &guildToChannel)
} else {
guildToChannel = make(map[string]string)
}
client, err := helix.NewClient(&helix.Options{
ClientID: TwitchToken,
})
if err != nil {
logPanic(err)
}
TwitchClient = client
dg, err := discordgo.New("Bot " + strings.TrimSpace(DiscordToken))
if err != nil {
fmt.Println("error creating Discord session,", err)
return
}
dg.AddHandler(presenceUpdate)
dg.AddHandler(messageCreate)
err = dg.Open()
if err != nil {
log.Panic(err)
return
}
fmt.Println("Bot is now running. Press CTRL-C to exit.")
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
<-sc
dg.Close()
data, _ := json.Marshal(guildToChannel)
ioutil.WriteFile("guilds.json", data, 0644)
}
func presenceUpdate(sess *discordgo.Session, evt *discordgo.PresenceUpdate) {
logDebug("PRESENSE UPDATE user-ID:", evt.User.ID)
if evt.Game != nil {
logDebug(fmt.Sprintf("PRESENSE UPDATE game: %#v", evt.Game))
if evt.Game.Type == discordgo.GameTypeStreaming {
pURL, _ := url.Parse(evt.Game.URL)
if ch, ok := guildToChannel[evt.GuildID]; ok {
processPresenceUpdate(sess, ch, strings.TrimLeft(pURL.Path, "/"))
}
}
}
}
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.ID == s.State.User.ID {
return
}
commandItems := strings.Split(m.Content, " ")
if strings.EqualFold(commandItems[0], "!uptime") {
duration := time.Now().Sub(startTime)
if ch, ok := guildToChannel[m.GuildID]; ok {
err := sendMessage(s, ch, fmt.Sprintf(
"Uptime is: **%02d:%02d:%02d** (since **%s**)",
int(duration.Hours()),
int(duration.Minutes())%60,
int(duration.Seconds())%60,
startTime.Format(time.Stamp)))
logError(err)
}
}
if strings.EqualFold(commandItems[0], "!isLive") {
if len(commandItems) == 1 {
return
}
if ch, ok := guildToChannel[m.GuildID]; ok {
processPresenceUpdate(s, ch, commandItems[1])
}
}
if strings.EqualFold(commandItems[0], "!init") {
sendMessage(s, m.ChannelID, "All set up to talk in this channel!")
guildToChannel[m.GuildID] = m.ChannelID
}
}
func sendMessage(sess *discordgo.Session, channelid, message string) error {
logInfo("SENDING MESSAGE:", message)
_, err := sess.ChannelMessageSend(channelid, message)
return err
}
func processPresenceUpdate(s *discordgo.Session, channelid, twitchName string) {
resp, err := TwitchClient.GetUsers(&helix.UsersParams{
Logins: []string{twitchName},
})
if err != nil {
logError(err)
return
}
/*
TODO: Use twitch stream info to maybe get that channels info
data, _ := TwitchClient.GetStreamsMetadata(&helix.StreamsMetadataParams {
UserLogins: []string{commandItems[1]}
})
*/
user := resp.Data.Users[0]
f := make([]*discordgo.MessageEmbedField, 0)
f = append(f, &discordgo.MessageEmbedField{
Name: "Description",
Value: user.Description,
})
s.ChannelMessageSendEmbed(channelid, &discordgo.MessageEmbed{
Image: &discordgo.MessageEmbedImage{
URL: user.OfflineImageURL,
},
Author: &discordgo.MessageEmbedAuthor{
URL: "https://twitch.com/" + user.Login,
Name: user.DisplayName + " is now live",
},
Thumbnail: &discordgo.MessageEmbedThumbnail{
URL: user.ProfileImageURL,
},
Fields: f,
})
}
func fileExist(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}