Skip to content

Commit 7ce92b0

Browse files
authored
v0.0.3: LatestRelease <- Development (#3)
2 parents 8340c4a + 1b22635 commit 7ce92b0

File tree

5 files changed

+542
-3
lines changed

5 files changed

+542
-3
lines changed

autorole-new-room-onjoin/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
autorole-bot

autorole-new-room-onjoin/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
This one is used for Beksoft discord server
2+
It tracks who is already member of the discord group
3+
When a new member is added, depending on the invite link, they are assigned a role.
4+
They are also assigned into a new room called "Welcome! Tell us about you"
5+
6+
This project will be crosscompiled from windows using:
7+
set GOOS=linux
8+
set GOARCH=amd64
9+
go build -o autorole-bot
10+
11+
These settings (GOOS and GOARCH) will only be temporary
12+
13+
Then the autorole-bot linux executable is sent to a linux server, that should run it 24/7
14+
I have put it on my LMBEK server (for test purposes so far - 05-07-2023)
15+
16+
The credentials.json and invite-roles.json is also sent to the linux server, they should sit in the same folder as the executable

autorole-new-room-onjoin/main.go

Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/bwmarrin/discordgo"
7+
"log"
8+
"os"
9+
"os/signal"
10+
"syscall"
11+
)
12+
13+
type Data struct {
14+
Token string `json:"token"`
15+
}
16+
17+
type InviteLink struct {
18+
Name string `json:"name"`
19+
Value string `json:"value"`
20+
RoleID string `json:"roleID"`
21+
}
22+
23+
type InviteRoleMap struct {
24+
Links []InviteLink `json:"links"`
25+
}
26+
27+
type MemberList struct {
28+
Members map[string]bool
29+
InviteCounters map[string]int
30+
InviteRole map[string]string
31+
}
32+
33+
var inviteRoleMap InviteRoleMap
34+
35+
var guildID = "774195371903025168" // Set your server id here
36+
37+
func main() {
38+
//token, err := getTokenFromCredentials("./credentials.json") // test server
39+
token, err := getTokenFromCredentials("/var/www/discord-autorole-bot/credentials.json") // production
40+
if err != nil {
41+
log.Fatal("Error retrieving bot token:", err)
42+
}
43+
44+
session, err := discordgo.New("Bot " + token)
45+
if err != nil {
46+
log.Fatal("Error creating Discord session:", err)
47+
}
48+
49+
// (Only 1 "hardcoded" server id is supported for now) Please note this will only work for one server, the script needs to be improved and extended upon to add more guilds
50+
//inviteRoleMap, err = getInviteRoleMapFromJSON("./invite-roles.json") // test server
51+
inviteRoleMap, err = getInviteRoleMapFromJSON("/var/www/discord-autorole-bot/invite-roles.json") //production
52+
if err != nil {
53+
log.Fatal("Error reading invited-roles.json:", err)
54+
}
55+
56+
// (Only 1 "hardcoded" server id is supported for now) Please note this will only work for one server, the script needs to be improved and extended upon to add more guilds
57+
memberList := &MemberList{
58+
Members: make(map[string]bool),
59+
InviteCounters: make(map[string]int),
60+
InviteRole: make(map[string]string),
61+
}
62+
63+
session.AddHandler(func(s *discordgo.Session, event *discordgo.Ready) {
64+
for _, guild := range event.Guilds {
65+
// ensure it only runs on the selected "hardcoded" server ID
66+
if guild.ID == guildID {
67+
onReady(s, event, memberList)
68+
}
69+
}
70+
})
71+
72+
session.AddHandler(func(s *discordgo.Session, event *discordgo.MessageCreate) {
73+
// ensure it only runs on the selected "hardcoded" server ID
74+
if event.GuildID == guildID {
75+
onEvent(s, event, memberList)
76+
}
77+
})
78+
79+
err = session.Open()
80+
if err != nil {
81+
log.Fatal("Error opening connection:", err)
82+
}
83+
84+
fmt.Println("Bot is now running. Press CTRL-C to exit.")
85+
86+
sc := make(chan os.Signal, 1)
87+
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
88+
<-sc
89+
90+
session.Close()
91+
}
92+
93+
func getTokenFromCredentials(filePath string) (string, error) {
94+
data, err := os.ReadFile(filePath)
95+
if err != nil {
96+
return "", err
97+
}
98+
99+
var jsonData Data
100+
err = json.Unmarshal(data, &jsonData)
101+
if err != nil {
102+
return "", err
103+
}
104+
105+
return jsonData.Token, nil
106+
}
107+
108+
func getInviteRoleMapFromJSON(filePath string) (InviteRoleMap, error) {
109+
data, err := os.ReadFile(filePath)
110+
if err != nil {
111+
return InviteRoleMap{}, err
112+
}
113+
114+
var inviteRoleMap InviteRoleMap
115+
err = json.Unmarshal(data, &inviteRoleMap)
116+
if err != nil {
117+
return InviteRoleMap{}, err
118+
}
119+
120+
return inviteRoleMap, nil
121+
}
122+
123+
func getInviteRole(inviteRoleMap InviteRoleMap, value string) string {
124+
for _, link := range inviteRoleMap.Links {
125+
if link.Value == value {
126+
return link.RoleID
127+
}
128+
}
129+
return ""
130+
}
131+
132+
func onReady(session *discordgo.Session, event *discordgo.Ready, memberList *MemberList) {
133+
fmt.Println("Bot is ready!")
134+
135+
guilds := session.State.Guilds
136+
if len(guilds) == 0 {
137+
fmt.Println("No guilds found")
138+
return
139+
}
140+
141+
guildID := guilds[0].ID
142+
143+
members, err := session.GuildMembers(guildID, "", 1000)
144+
if err != nil {
145+
fmt.Println("Error fetching guild members:", err)
146+
return
147+
}
148+
149+
for _, member := range members {
150+
memberList.Members[member.User.ID] = true
151+
}
152+
153+
invites, err := session.GuildInvites(guildID)
154+
if err != nil {
155+
fmt.Println("Error fetching guild invites:", err)
156+
return
157+
}
158+
159+
for _, invite := range invites {
160+
//fmt.Printf("Invite code: %v \n", invite.Code)
161+
memberList.InviteCounters[invite.Code] = invite.Uses
162+
memberList.InviteRole[invite.Code] = "" // Replace "roleID" with the corresponding role ID or name
163+
}
164+
165+
fmt.Println("Existing members:")
166+
fmt.Println("----------------------")
167+
for member := range memberList.Members {
168+
fmt.Println(member)
169+
}
170+
fmt.Println("All member id's listed")
171+
fmt.Println("----------------------")
172+
}
173+
174+
func onEvent(session *discordgo.Session, event interface{}, memberList *MemberList) {
175+
switch ev := event.(type) {
176+
case *discordgo.MessageCreate:
177+
if ev.Author.Bot {
178+
return
179+
}
180+
181+
//fmt.Println("new message...")
182+
authorID := ev.Author.ID
183+
184+
if memberList.Members[authorID] {
185+
return
186+
}
187+
188+
memberList.Members[authorID] = true
189+
190+
eventGuildID := ev.GuildID
191+
invites, err := session.GuildInvites(eventGuildID)
192+
if err != nil {
193+
fmt.Println("Error fetching guild invites:", err)
194+
return
195+
}
196+
197+
var usedInvite *discordgo.Invite
198+
for _, invite := range invites {
199+
if invite.Uses > memberList.InviteCounters[invite.Code] {
200+
usedInvite = invite
201+
break
202+
}
203+
}
204+
205+
if usedInvite == nil {
206+
fmt.Println("No invite found for the user:", ev.Author.ID)
207+
return
208+
}
209+
210+
fmt.Println("New Member:")
211+
inviteCode := usedInvite.Code
212+
fmt.Print("invite code: ")
213+
fmt.Println(inviteCode)
214+
roleID := getInviteRole(inviteRoleMap, inviteCode)
215+
if roleID == "" {
216+
fmt.Println("No role assigned for invite code:", inviteCode)
217+
return
218+
}
219+
220+
if roleID == "" {
221+
fmt.Println("No role assigned for invite link:", inviteCode)
222+
return
223+
}
224+
225+
assignRoleToUser(session, eventGuildID, ev.Author.ID, roleID)
226+
227+
err = session.GuildMemberRoleAdd(eventGuildID, ev.Author.ID, roleID)
228+
if err != nil {
229+
fmt.Println("Error assigning role to user:", err)
230+
return
231+
}
232+
233+
fmt.Printf("Assigned role '%s' to user %s\n", roleID, ev.Author.ID)
234+
235+
createPrivateWelcomeRoom(session, eventGuildID, ev.Author.ID) // Call the function here
236+
237+
}
238+
}
239+
240+
func assignRoleToUser(session *discordgo.Session, guildID string, userID string, roleID string) {
241+
// Find the member by ID
242+
members, err := session.GuildMembers(guildID, "", 1000)
243+
if err != nil {
244+
fmt.Println("Error retrieving guild members:", err)
245+
return
246+
}
247+
248+
var member *discordgo.Member
249+
for _, m := range members {
250+
if m.User.ID == userID {
251+
member = m
252+
break
253+
}
254+
}
255+
256+
// Find the role by name
257+
roles, err := session.GuildRoles(guildID)
258+
if err != nil {
259+
fmt.Println("Error retrieving guild roles:", err)
260+
return
261+
}
262+
263+
for _, role := range roles {
264+
if role.ID == roleID {
265+
roleID = role.ID
266+
break
267+
}
268+
}
269+
270+
// If the member and role are found, assign the role to the member
271+
if member != nil && roleID != "" {
272+
err = session.GuildMemberRoleAdd(guildID, member.User.ID, roleID)
273+
274+
if err != nil {
275+
fmt.Println("Error assigning role to user:", err)
276+
return
277+
}
278+
fmt.Println("Assigned role", roleID, "to user", userID)
279+
} else {
280+
fmt.Println("Error: Member or role not found")
281+
}
282+
}
283+
284+
func createPrivateWelcomeRoom(session *discordgo.Session, guildID string, memberID string) {
285+
// Create the category for the group
286+
category, err := session.GuildChannelCreateComplex(guildID, discordgo.GuildChannelCreateData{
287+
Name: "Welcome! Tell us about you",
288+
Type: discordgo.ChannelTypeGuildCategory,
289+
Position: 1,
290+
})
291+
if err != nil {
292+
fmt.Println("Error creating category:", err)
293+
return
294+
}
295+
296+
// Create the chat room under the category
297+
chatRoom, err := session.GuildChannelCreateComplex(guildID, discordgo.GuildChannelCreateData{
298+
Name: "Chat with Beksoft ApS",
299+
Type: discordgo.ChannelTypeGuildText,
300+
ParentID: category.ID,
301+
PermissionOverwrites: []*discordgo.PermissionOverwrite{
302+
{
303+
ID: guildID,
304+
Type: discordgo.PermissionOverwriteTypeRole,
305+
Deny: discordgo.PermissionViewChannel,
306+
},
307+
{
308+
ID: memberID,
309+
Type: discordgo.PermissionOverwriteTypeMember,
310+
Allow: discordgo.PermissionViewChannel,
311+
},
312+
{
313+
ID: session.State.User.ID, // Add the bot's user ID here
314+
Type: discordgo.PermissionOverwriteTypeMember,
315+
Allow: discordgo.PermissionViewChannel,
316+
},
317+
},
318+
})
319+
if err != nil {
320+
fmt.Println("Error creating chat room:", err)
321+
return
322+
}
323+
324+
// Send the welcome message
325+
welcomeMessage := "Welcome, let us know more about you! / Velkommen, lad os lære hinanden at kende"
326+
_, err = session.ChannelMessageSend(chatRoom.ID, welcomeMessage)
327+
if err != nil {
328+
fmt.Println("Error sending welcome message:", err)
329+
}
330+
331+
// Send the welcome message
332+
welcomeMessage2 := "We answer as soon as possible / Vi svarer hurtigst muligt"
333+
_, err = session.ChannelMessageSend(chatRoom.ID, welcomeMessage2)
334+
if err != nil {
335+
fmt.Println("Error sending welcome message:", err)
336+
}
337+
338+
// Create the voice room under the category
339+
//voiceRoom, err := session.GuildChannelCreateComplex(guildID, discordgo.GuildChannelCreateData{
340+
// Name: "voice",
341+
// Type: discordgo.ChannelTypeGuildVoice,
342+
// ParentID: category.ID,
343+
// PermissionOverwrites: []*discordgo.PermissionOverwrite{
344+
// {
345+
// ID: guildID,
346+
// Type: discordgo.PermissionOverwriteTypeRole,
347+
// Deny: discordgo.PermissionViewChannel,
348+
// },
349+
// {
350+
// ID: memberID,
351+
// Type: discordgo.PermissionOverwriteTypeMember,
352+
// Allow: discordgo.PermissionViewChannel,
353+
// },
354+
// },
355+
//})
356+
//if err != nil {
357+
// fmt.Println("Error creating voice room:", err)
358+
// return
359+
//}
360+
361+
fmt.Println("Welcome group created successfully!")
362+
fmt.Printf("Category: %s\n", category.Name)
363+
fmt.Printf("Chat Room: %s\n", chatRoom.Name)
364+
//fmt.Printf("Voice Room: %s\n", voiceRoom.Name)
365+
fmt.Println("----------------------")
366+
}

0 commit comments

Comments
 (0)