Passed
Push — master ( 2236ae...943c76 )
by Viktor
01:29
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
	"net/url"
9
	"os"
10
	"os/signal"
11
	"strconv"
12
	"strings"
13
	"syscall"
14
	"time"
15
16
	"gopkg.in/robfig/cron.v2"
17
18
	"github.com/FlameInTheDark/dtbot/bot"
19
	"github.com/FlameInTheDark/dtbot/cmd"
20
	"github.com/bwmarrin/discordgo"
21
)
22
23
var (
24
	conf *bot.Config
25
	// CmdHandler bot command handler
26
	CmdHandler *bot.CommandHandler
27
	// Sessions bot session manager
28
	Sessions        *bot.SessionManager
29
	botId           string
0 ignored issues
show
introduced by
var botId should be botID
Loading history...
30
	youtube         *bot.Youtube
31
	botMsg          *bot.BotMessages
32
	dataType        *bot.DataType
33
	dbWorker        *bot.DBWorker
34
	guilds          bot.GuildsMap
35
	botCron         *cron.Cron
36
	messagesCounter int
37
)
38
39
func main() {
40
	botCron = cron.New()
41
	conf = bot.LoadConfig()
42
	CmdHandler = bot.NewCommandHandler()
43
	registerCommands()
44
	Sessions = bot.NewSessionManager()
45
	youtube = &bot.Youtube{Conf: conf}
46
	botMsg = bot.NewMessagesMap()
47
	dataType = bot.NewDataType()
48
	discord, err := discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
49
	if err != nil {
50
		fmt.Println("Create session error, ", err)
51
		return
52
	}
53
	usr, err := discord.User("@me")
54
	if err != nil {
55
		fmt.Println("Error obtaining account details,", err)
56
		return
57
	}
58
	botId = usr.ID
59
	discord.AddHandler(commandHandler)
60
	discord.AddHandler(func(discord *discordgo.Session, ready *discordgo.Ready) {
61
		_ = discord.UpdateStatus(0, conf.General.Game)
62
		guilds := discord.State.Guilds
63
		fmt.Println("Ready with", len(guilds), "guilds.")
64
	})
65
66
	err = discord.Open()
67
	if err != nil {
68
		fmt.Printf("Connection open error: %v", err)
69
		return
70
	}
71
	defer discord.Close()
72
	fmt.Println("Bot is now running.")
73
74
	sc := make(chan os.Signal, 1)
75
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
76
	dbWorker = bot.NewDBSession(conf.General.DatabaseName)
77
	guilds = dbWorker.InitGuilds(discord, conf)
78
	botCron.Start()
79
	go MetricsSender(discord)
80
	defer botCron.Stop()
81
	defer dbWorker.DBSession.Close()
82
	<-sc
83
}
84
85
// Handle discord messages
86
func commandHandler(discord *discordgo.Session, message *discordgo.MessageCreate) {
87
	messagesCounter++
88
	user := message.Author
89
	if user.ID == botId || user.Bot {
90
		return
91
	}
92
	args := strings.Split(message.Content, " ")
93
	name := strings.ToLower(args[0])
94
	command, found := CmdHandler.Get(name)
95
	if !found {
96
		return
97
	}
98
99
	var permission = true
100
	var msg string
101
	// Checking permissions
102
	perm, err := discord.State.UserChannelPermissions(botId, message.ChannelID)
103
	if err != nil {
104
		msg = fmt.Sprintf("Error whilst getting bot permissions %v\n", err)
105
		permission = false
106
	} else {
107
		if perm&discordgo.PermissionSendMessages != discordgo.PermissionSendMessages ||
108
			perm&discordgo.PermissionAttachFiles != discordgo.PermissionAttachFiles {
109
			msg = "Permissions denied"
110
			permission = false
111
		}
112
	}
113
114
	channel, err := discord.State.Channel(message.ChannelID)
115
	if err != nil {
116
		fmt.Println("Error getting channel,", err)
117
		return
118
	}
119
	guild, err := discord.State.Guild(channel.GuildID)
120
	if err != nil {
121
		fmt.Println("Error getting guild,", err)
122
		return
123
	}
124
125
	if permission {
126
		ctx := bot.NewContext(
127
			botId,
128
			discord,
129
			guild,
130
			channel,
131
			user,
132
			message,
133
			conf,
134
			CmdHandler,
135
			Sessions,
136
			youtube,
137
			botMsg,
138
			dataType,
139
			dbWorker,
140
			guilds,
141
			botCron)
142
		ctx.Args = args[1:]
143
		c := *command
144
		c(*ctx)
145
	} else {
146
		dbWorker.Log("Message", guild.ID, msg)
147
		query := []byte(fmt.Sprintf("logs,server=%v module=\"%v\"", guild.ID, "message"))
148
		addr := fmt.Sprintf("%v/write?db=%v", conf.Metrics.Address, conf.Metrics.Database)
149
		r := bytes.NewReader(query)
150
		_, _ = http.Post(addr, "", r)
151
	}
152
}
153
154
// Adds bot commands
155
func registerCommands() {
156
	CmdHandler.Register("!r", cmd.PlayerCommand)
157
	CmdHandler.Register("!w", cmd.WeatherCommand)
158
	CmdHandler.Register("!t", cmd.TranslateCommand)
159
	CmdHandler.Register("!n", cmd.NewsCommand)
160
	CmdHandler.Register("!c", cmd.CurrencyCommand)
161
	CmdHandler.Register("!y", cmd.YoutubeCommand)
162
	CmdHandler.Register("!v", cmd.VoiceCommand)
163
	CmdHandler.Register("!b", cmd.BotCommand)
164
	CmdHandler.Register("!play", cmd.YoutubeShortCommand)
165
	CmdHandler.Register("!d", cmd.DebugCommand)
166
	CmdHandler.Register("!p", cmd.PollCommand)
167
	CmdHandler.Register("!m", cmd.YandexmapCommand)
168
	CmdHandler.Register("!dice", cmd.DiceCommand)
169
	CmdHandler.Register("!help", cmd.HelpCommand)
170
	CmdHandler.Register("!cron", cmd.CronCommand)
171
	CmdHandler.Register("!geoip", cmd.GeoIPCommand)
172
}
173
174
// MetricsSender sends metrics to InfluxDB
175
func MetricsSender(d *discordgo.Session) {
176
	for {
177
		usersCount := 0
178
		for _,g := range d.State.Guilds {
179
			usersCount += len(g.Members)
180
		}
181
182
		// Metrics
183
		queryMsg := []byte(fmt.Sprintf("messages count=%v", messagesCounter))
184
		addrMsg := fmt.Sprintf("%v/write?db=%v&u=%v&p=%v",
185
			conf.Metrics.Address, conf.Metrics.Database, conf.Metrics.User, conf.Metrics.Password)
186
		rMsg := bytes.NewReader(queryMsg)
187
		_, _ = http.Post(addrMsg, "", rMsg)
188
189
		queryGuilds := []byte(fmt.Sprintf("guilds count=%v", len(d.State.Guilds)))
190
		addrGuilds := fmt.Sprintf("%v/write?db=%v&u=%v&p=%v",
191
			conf.Metrics.Address, conf.Metrics.Database, conf.Metrics.User, conf.Metrics.Password)
192
		rGuilds := bytes.NewReader(queryGuilds)
193
		_, _ = http.Post(addrGuilds, "", rGuilds)
194
195
		queryCounters := []byte(fmt.Sprintf("counters guilds=%v,messages=%v,users=%v", len(d.State.Guilds), messagesCounter, usersCount))
196
		addrCounters := fmt.Sprintf("%v/write?db=%v&u=%v&p=%v",
197
			conf.Metrics.Address, conf.Metrics.Database, conf.Metrics.User, conf.Metrics.Password)
198
		rCounters := bytes.NewReader(queryCounters)
199
		_, _ = http.Post(addrCounters, "", rCounters)
200
201
		// Bot lists
202
		if conf.DBL.Token != "" {
203
			s := dblgo.NewDBL(conf.DBL.Token, d.State.User.ID)
204
			_ = s.PostStats(len(d.State.Guilds))
205
		}
206
		if conf.DBL.TokenDBL != "" {
207
			users := 0
208
			for _, g := range d.State.Guilds {
209
				users += len(g.Members)
210
			}
211
			data := url.Values{}
212
			data.Set("shard_id", "0")
213
			data.Set("guilds", strconv.Itoa(len(d.State.Guilds)))
214
			fmt.Println("Guilds: ", strconv.Itoa(len(d.State.Guilds)))
215
			data.Set("users", strconv.Itoa(users))
216
			fmt.Println("Users: ",strconv.Itoa(users))
217
			data.Set("voice_connections", strconv.Itoa(Sessions.Count()))
218
			fmt.Println("Voice connections: ", strconv.Itoa(Sessions.Count()))
219
			client := &http.Client{}
220
			fmt.Println(data.Encode())
221
			req, err := http.NewRequest("POST", fmt.Sprintf("https://discordbotlist.com/api/bots/%v/stats",conf.DBL.DBLID), bytes.NewBuffer([]byte(data.Encode())))
222
			if err != nil {
223
				fmt.Println(err.Error())
224
			} else {
225
				req.Header.Add("Authorization", fmt.Sprintf("Bot %v", conf.DBL.TokenDBL))
226
			}
227
			defer req.Body.Close()
228
			res, _ := client.Do(req)
229
			fmt.Println(res.Status)
230
		}
231
		messagesCounter = 0
232
		time.Sleep(time.Minute)
233
	}
234
}