grim/wasdead

Parents e180369f51a1
Children f6f8ebbbc668
Still a lot of work to actually do under the hood to make this fully ready for prototype use, but it's getting there!
  • +132 -20
    main.go
  • --- a/main.go Tue Mar 19 21:40:24 2019 -0700
    +++ b/main.go Wed Mar 20 11:35:26 2019 -0700
    @@ -1,9 +1,12 @@
    package main
    import (
    + "encoding/json"
    "flag"
    "fmt"
    + "io/ioutil"
    "log"
    + "net/url"
    "os"
    "os/signal"
    "strings"
    @@ -11,19 +14,26 @@
    "time"
    "github.com/bwmarrin/discordgo"
    + "github.com/nicklaw5/helix"
    )
    var (
    - Token string
    - logger *log.Logger
    - startTime time.Time
    + 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(&Token, "t", "", "Bot Token")
    + flag.StringVar(&DiscordToken, "t", "", "Discord Bot Token")
    + flag.StringVar(&TwitchToken, "tcid", "", "Twitch Client ID ID")
    +
    flag.Parse()
    }
    @@ -42,16 +52,41 @@
    logger.Println(v...)
    }
    +func logPanic(v ...interface{}) {
    + logger.SetPrefix("PANIC ")
    + logger.Panicln(v...)
    +}
    +
    func main() {
    - logDebug("Bot Token:", Token)
    + 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)
    - dg, err := discordgo.New("Bot " + strings.TrimSpace(Token))
    + 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(newPresenceEvent)
    + dg.AddHandler(presenceUpdate)
    dg.AddHandler(messageCreate)
    err = dg.Open()
    @@ -66,34 +101,62 @@
    <-sc
    dg.Close()
    +
    + data, _ := json.Marshal(guildToChannel)
    + ioutil.WriteFile("guilds.json", data, 0644)
    }
    -func newPresenceEvent(sess *discordgo.Session, evt *discordgo.PresenceUpdate) {
    - logDebug("PRESENSE UPDATE fired for user-ID:", evt.User.ID)
    - logDebug(fmt.Sprintf("PRESENSE UPDATE data: %#v", evt))
    +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) {
    - logDebug("Message: ", m.Content)
    -
    if m.Author.ID == s.State.User.ID {
    return
    }
    - if strings.EqualFold(m.Content, "!uptime") {
    + commandItems := strings.Split(m.Content, " ")
    +
    + if strings.EqualFold(commandItems[0], "!uptime") {
    duration := time.Now().Sub(startTime)
    - err := sendMessage(s, m.ChannelID, fmt.Sprintf(
    - "Uptime is: **%02d:%02d:%02d** (since **%s**)",
    - int(duration.Hours()),
    - int(duration.Minutes())%60,
    - int(duration.Seconds())%60,
    - startTime.Format(time.Stamp)))
    + 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)
    + }
    + }
    - 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
    }
    }
    @@ -102,3 +165,52 @@
    _, 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
    +}