|
| 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