Passed
Push — master ( ff1349...f1973d )
by Viktor
01:40
created

main.registerCommands   A

Complexity

Conditions 1

Size

Total Lines 17
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nop 0
dl 0
loc 17
rs 9.55
c 0
b 0
f 0
1
package main
2
3
import (
4
	"bytes"
5
	"fmt"
6
	"github.com/DiscordBotList/dblgo"
7
	"net/http"
8
	"os"
9
	"os/signal"
10
	"strings"
11
	"syscall"
12
	"time"
13
14
	"gopkg.in/robfig/cron.v2"
15
16
	"github.com/FlameInTheDark/dtbot/bot"
17
	"github.com/FlameInTheDark/dtbot/cmd"
18
	"github.com/bwmarrin/discordgo"
19
)
20
21
var (
22
	conf *bot.Config
23
	// CmdHandler bot command handler
24
	CmdHandler *bot.CommandHandler
25
	// Sessions bot session manager
26
	Sessions        *bot.SessionManager
27
	botId           string
0 ignored issues
show
introduced by
var botId should be botID
Loading history...
28
	youtube         *bot.Youtube
29
	botMsg          *bot.BotMessages
30
	dataType        *bot.DataType
31
	dbWorker        *bot.DBWorker
32
	guilds          bot.GuildsMap
33
	botCron         *cron.Cron
34
	messagesCounter int
35
)
36
37
func main() {
38
	botCron = cron.New()
39
	conf = bot.LoadConfig()
40
	CmdHandler = bot.NewCommandHandler()
41
	registerCommands()
42
	Sessions = bot.NewSessionManager()
43
	youtube = &bot.Youtube{Conf: conf}
44
	botMsg = bot.NewMessagesMap()
45
	dataType = bot.NewDataType()
46
	discord, err := discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
47
	if err != nil {
48
		fmt.Println("Create session error, ", err)
49
		return
50
	}
51
	usr, err := discord.User("@me")
52
	if err != nil {
53
		fmt.Println("Error obtaining account details,", err)
54
		return
55
	}
56
	botId = usr.ID
57
	discord.AddHandler(commandHandler)
58
	discord.AddHandler(func(discord *discordgo.Session, ready *discordgo.Ready) {
59
		_ = discord.UpdateStatus(0, conf.General.Game)
60
		guilds := discord.State.Guilds
61
		fmt.Println("Ready with", len(guilds), "guilds.")
62
	})
63
64
	err = discord.Open()
65
	if err != nil {
66
		fmt.Printf("Connection open error: %v", err)
67
		return
68
	}
69
	defer discord.Close()
70
	fmt.Println("Bot is now running.")
71
72
	sc := make(chan os.Signal, 1)
73
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
74
	dbWorker = bot.NewDBSession(conf.General.DatabaseName)
75
	guilds = dbWorker.InitGuilds(discord, conf)
76
	botCron.Start()
77
	go MetricsSender(discord)
78
	defer botCron.Stop()
79
	defer dbWorker.DBSession.Close()
80
	<-sc
81
}
82
83
// Handle discord messages
84
func commandHandler(discord *discordgo.Session, message *discordgo.MessageCreate) {
85
	messagesCounter++
86
	user := message.Author
87
	if user.ID == botId || user.Bot {
88
		return
89
	}
90
	args := strings.Split(message.Content, " ")
91
	name := strings.ToLower(args[0])
92
	command, found := CmdHandler.Get(name)
93
	if !found {
94
		return
95
	}
96
97
	var permission = true
98
	var msg string
99
	// Checking permissions
100
	perm, err := discord.State.UserChannelPermissions(botId, message.ChannelID)
101
	if err != nil {
102
		msg = fmt.Sprintf("Error whilst getting bot permissions %v\n", err)
103
		permission = false
104
	} else {
105
		if perm&discordgo.PermissionSendMessages != discordgo.PermissionSendMessages ||
106
			perm&discordgo.PermissionAttachFiles != discordgo.PermissionAttachFiles {
107
			msg = "Permissions denied"
108
			permission = false
109
		}
110
	}
111
112
	channel, err := discord.State.Channel(message.ChannelID)
113
	if err != nil {
114
		fmt.Println("Error getting channel,", err)
115
		return
116
	}
117
	guild, err := discord.State.Guild(channel.GuildID)
118
	if err != nil {
119
		fmt.Println("Error getting guild,", err)
120
		return
121
	}
122
123
	if permission {
124
		ctx := bot.NewContext(
125
			botId,
126
			discord,
127
			guild,
128
			channel,
129
			user,
130
			message,
131
			conf,
132
			CmdHandler,
133
			Sessions,
134
			youtube,
135
			botMsg,
136
			dataType,
137
			dbWorker,
138
			guilds,
139
			botCron)
140
		ctx.Args = args[1:]
141
		c := *command
142
		c(*ctx)
143
	} else {
144
		dbWorker.Log("Message", guild.ID, msg)
145
		query := []byte(fmt.Sprintf("logs,server=%v module=\"%v\"", guild.ID, "message"))
146
		addr := fmt.Sprintf("%v/write?db=%v", conf.Metrics.Address, conf.Metrics.Database)
147
		r := bytes.NewReader(query)
148
		_, _ = http.Post(addr, "", r)
149
	}
150
}
151
152
// Adds bot commands
153
func registerCommands() {
154
	CmdHandler.Register("!r", cmd.PlayerCommand)
155
	CmdHandler.Register("!w", cmd.WeatherCommand)
156
	CmdHandler.Register("!t", cmd.TranslateCommand)
157
	CmdHandler.Register("!n", cmd.NewsCommand)
158
	CmdHandler.Register("!c", cmd.CurrencyCommand)
159
	CmdHandler.Register("!y", cmd.YoutubeCommand)
160
	CmdHandler.Register("!v", cmd.VoiceCommand)
161
	CmdHandler.Register("!b", cmd.BotCommand)
162
	CmdHandler.Register("!play", cmd.YoutubeShortCommand)
163
	CmdHandler.Register("!d", cmd.DebugCommand)
164
	CmdHandler.Register("!p", cmd.PollCommand)
165
	CmdHandler.Register("!m", cmd.YandexmapCommand)
166
	CmdHandler.Register("!dice", cmd.DiceCommand)
167
	CmdHandler.Register("!help", cmd.HelpCommand)
168
	CmdHandler.Register("!cron", cmd.CronCommand)
169
	CmdHandler.Register("!geoip", cmd.GeoIPCommand)
170
}
171
172
// MetricsSender sends metrics to InfluxDB
173
func MetricsSender(d *discordgo.Session) {
174
	for {
175
		usersCount := 0
176
		for _,g := range d.State.Guilds {
177
			usersCount += len(g.Members)
178
		}
179
180
		// Metrics counters
181
		queryCounters := []byte(fmt.Sprintf("counters guilds=%v,messages=%v,users=%v", len(d.State.Guilds), messagesCounter, usersCount))
182
		addrCounters := fmt.Sprintf("%v/write?db=%v&u=%v&p=%v",
183
			conf.Metrics.Address, conf.Metrics.Database, conf.Metrics.User, conf.Metrics.Password)
184
		rCounters := bytes.NewReader(queryCounters)
185
		_, _ = http.Post(addrCounters, "", rCounters)
186
187
		// Bot lists
188
		if conf.DBL.Token != "" {
189
			s := dblgo.NewDBL(conf.DBL.Token, d.State.User.ID)
190
			_ = s.PostStats(len(d.State.Guilds))
191
		}
192
		messagesCounter = 0
193
		time.Sleep(time.Minute)
194
	}
195
}