"github.com/bwmarrin/discordgo" "github.com/nicklaw5/helix" TwitchClient *helix.Client guildToChannel map[string]string logger = log.New(os.Stderr, " ", log.Ldate|log.Ltime) flag.StringVar(&DiscordToken, "t", "", "Discord Bot Token") flag.StringVar(&TwitchToken, "tcid", "", "Twitch Client ID ID") func logDebug(v ...interface{}) { logger.SetPrefix("DEBUG ") func logInfo(v ...interface{}) { logger.SetPrefix("INFO ") func logError(v ...interface{}) { logger.SetPrefix("ERROR ") func logPanic(v ...interface{}) { logger.SetPrefix("PANIC ") 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) guildToChannel = make(map[string]string) client, err := helix.NewClient(&helix.Options{ dg, err := discordgo.New("Bot " + strings.TrimSpace(DiscordToken)) fmt.Println("error creating Discord session,", err) dg.AddHandler(presenceUpdate) dg.AddHandler(messageCreate) 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) 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) 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 { 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.Minutes())%60, int(duration.Seconds())%60, startTime.Format(time.Stamp))) if strings.EqualFold(commandItems[0], "!isLive") { if len(commandItems) == 1 { 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) func processPresenceUpdate(s *discordgo.Session, channelid, twitchName string) { resp, err := TwitchClient.GetUsers(&helix.UsersParams{ Logins: []string{twitchName}, 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{ 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, func fileExist(name string) bool { if _, err := os.Stat(name); err != nil {