Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.0.2: LatestRelease <- Development #2

Merged
merged 7 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.idea
credentials.json
credentials.json
go.sum
invite-roles.json
44 changes: 43 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,43 @@
# discord-autorole
# discord-autorole

## What is discord-autorole go bot?
This discord bot can automatically assign a role to a new user based on invitation link value.
It is made with Go and can be used for your own discord bot. You can freely take it and modify it to your needs.
Since the API token is your own, this script should work if you add a credentials.json and invite-roles.json.

## How to use
Download the files from this repository (and then maybe make your own or keep it local, you decide).
Then set up Go (if you dont know Go, follow some youtube tutorial you will get started within 1 hour i am sure)
After you have installed Go, you can get started with the domain:

You can follow the example jsons. First make a discord application (bot), then find token and put it into credentials.json.
Then find out what permissions you need, then decide how you want the authentication to work,
here you can get a link based on permissions and assign the bot to a server directly.
Then you add in the roleID's and invitation links (only the value of the link, so everything after discord.com etc...).
And lastly after you added the roleID's and invitation links, you test it. (first test it in a separated room, just in case).
Now you have a working bot, you can use on your server, that automatically assigns roles for your new users, customers, friends or whatever.

I use it for my own discord server

This bot has 3 parts:
1) Connect-test
* Connects to discord and disconnect right after
2) onready-give-role
* Is a hardcoded script that connects to discord and gives a certain user a certain role, then it runs until being interrupted by user.
3) autorole-onjoin
* Connects to discord and makes a list of users in the server/guild (only works with 1 server/guild so far), then it use that list of users as data
* Adds an event-listener for OnEvent -> CreateMessage as this was the only way i could register the new user. It uses the data from the OnReady event with all the users, then it sees the difference between the users. It does this to find the invite link, as the invite link should be the difference between before and now (by checking every member). This operation is custom made and heavy, but it was necessary because i could not get invite link otherwise.
* Then after it got the invite link for the new user, it checks what invite link was used and assign the role id to the user. This only works when joining the first time or not being member of server/guild on startup of script, it will work again after restarting script.

## Please Note
invite-roles.json: links.value is the value from the discord link that is shared with no expire date. It needs to be manually added in just like role name and role id

## Author
Lars M Bek (Main author) - June 2023

ChatGPT (junior-developer) - June 2023

## Further Development
* Adding functionality like:
* New room for certain type of role, where only that person and the server owner is assigned
* Added to certain room based on invite link (so we dont have to assign role manually like everything else in this bot)
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,17 @@ import (
)

type Data struct {
Token string `json:"token"`
InviteRole map[string]string `json:"inviteRole"` // Map to store invite links and their corresponding roles
Token string `json:"token"`
}

type InviteLink struct {
Name string `json:"name"`
Value string `json:"value"`
RoleID string `json:"roleID"`
}

type InviteRoleMap struct {
Links []InviteLink `json:"links"`
}

type MemberList struct {
Expand All @@ -21,6 +30,8 @@ type MemberList struct {
InviteRole map[string]string
}

var inviteRoleMap InviteRoleMap

func getTokenFromCredentials(filePath string) (string, error) {
data, err := os.ReadFile(filePath)
if err != nil {
Expand All @@ -36,11 +47,28 @@ func getTokenFromCredentials(filePath string) (string, error) {
return jsonData.Token, nil
}

func getInviteRole(inviteLink string, inviteRoleMap map[string]string) string {
if role, ok := inviteRoleMap[inviteLink]; ok {
return role
func getInviteRoleMapFromJSON(filePath string) (InviteRoleMap, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return InviteRoleMap{}, err
}

var inviteRoleMap InviteRoleMap
err = json.Unmarshal(data, &inviteRoleMap)
if err != nil {
return InviteRoleMap{}, err
}
return "" // Replace with the default role ID or name

return inviteRoleMap, nil
}

func getInviteRole(inviteRoleMap InviteRoleMap, value string) string {
for _, link := range inviteRoleMap.Links {
if link.Value == value {
return link.RoleID
}
}
return ""
}

func onReady(session *discordgo.Session, event *discordgo.Ready, memberList *MemberList) {
Expand All @@ -61,7 +89,7 @@ func onReady(session *discordgo.Session, event *discordgo.Ready, memberList *Mem
}

for _, member := range members {
memberList.Members[member.User.Username] = true
memberList.Members[member.User.ID] = true
}

invites, err := session.GuildInvites(guildID)
Expand All @@ -71,8 +99,9 @@ func onReady(session *discordgo.Session, event *discordgo.Ready, memberList *Mem
}

for _, invite := range invites {
//fmt.Printf("Invite code: %v \n", invite.Code)
memberList.InviteCounters[invite.Code] = invite.Uses
memberList.InviteRole[invite.Code] = "1108944121630044172" // Replace "roleID" with the corresponding role ID or name
memberList.InviteRole[invite.Code] = "" // Replace "roleID" with the corresponding role ID or name
}

fmt.Println("Existing members:")
Expand All @@ -88,7 +117,7 @@ func onEvent(session *discordgo.Session, event interface{}, memberList *MemberLi
return
}

fmt.Println("new message...")
//fmt.Println("new message...")
authorID := ev.Author.ID

if memberList.Members[authorID] {
Expand All @@ -113,37 +142,38 @@ func onEvent(session *discordgo.Session, event interface{}, memberList *MemberLi
}

if usedInvite == nil {
fmt.Println("No invite found for the user:", ev.Author.Username)
fmt.Println("No invite found for the user:", ev.Author.ID)
return
}

inviteCode := usedInvite.Code
fmt.Print("invite code:")
fmt.Print("invite code: ")
fmt.Println(inviteCode)
role := getInviteRole(inviteCode, memberList.InviteRole)
if role == "" {
roleID := getInviteRole(inviteRoleMap, inviteCode)
if roleID == "" {
fmt.Println("No role assigned for invite code:", inviteCode)
return
}

if roleID == "" {
fmt.Println("No role assigned for invite link:", inviteCode)
return
}
guilds := session.State.Guilds
if len(guilds) > 0 {
guildID := guilds[0].ID
assignRoleToUser(session, guildID, ev.Author.Username, "Customer")
assignRoleToUser(session, guildID, ev.Author.ID, roleID)
} else {
fmt.Println("Error: No guilds available")
}

//fmt.Println(guildID)
//fmt.Println(ev.Author.Username)
//fmt.Println(role)
/*
err = session.GuildMemberRoleAdd(guildID, ev.Author.ID, "1108944121630044172")
if err != nil {
fmt.Println("Error assigning role to user:", err)
return
}
*/
fmt.Printf("Assigned role '%s' to user %s\n", role, ev.Author.Username)
err = session.GuildMemberRoleAdd(guildID, ev.Author.ID, roleID)
if err != nil {
fmt.Println("Error assigning role to user:", err)
return
}

fmt.Printf("Assigned role '%s' to user %s\n", roleID, ev.Author.ID)
}
}

Expand All @@ -158,6 +188,11 @@ func main() {
log.Fatal("Error creating Discord session:", err)
}

inviteRoleMap, err = getInviteRoleMapFromJSON("invite-roles.json")
if err != nil {
log.Fatal("Error reading invited-roles.json:", err)
}

memberList := &MemberList{
Members: make(map[string]bool),
InviteCounters: make(map[string]int),
Expand Down Expand Up @@ -186,8 +221,8 @@ func main() {
session.Close()
}

func assignRoleToUser(session *discordgo.Session, guildID, username, roleName string) {
// Find the member by username
func assignRoleToUser(session *discordgo.Session, guildID string, userID string, roleID string) {
// Find the member by ID
members, err := session.GuildMembers(guildID, "", 1000)
if err != nil {
fmt.Println("Error retrieving guild members:", err)
Expand All @@ -196,7 +231,7 @@ func assignRoleToUser(session *discordgo.Session, guildID, username, roleName st

var member *discordgo.Member
for _, m := range members {
if m.User.Username == username {
if m.User.ID == userID {
member = m
break
}
Expand All @@ -209,9 +244,8 @@ func assignRoleToUser(session *discordgo.Session, guildID, username, roleName st
return
}

var roleID string
for _, role := range roles {
if role.Name == roleName {
if role.ID == roleID {
roleID = role.ID
break
}
Expand All @@ -225,7 +259,7 @@ func assignRoleToUser(session *discordgo.Session, guildID, username, roleName st
fmt.Println("Error assigning role to user:", err)
return
}
fmt.Println("Assigned role", roleName, "to user", username)
fmt.Println("Assigned role", roleID, "to user", userID)
} else {
fmt.Println("Error: Member or role not found")
}
Expand Down
File renamed without changes.
19 changes: 19 additions & 0 deletions invite-roles-example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"links": [
{
"name": "Customer",
"value": "1HJk5bsnY8",
"roleID": "12345"
},
{
"name": "Partner",
"value": "2HJk5bsnY8",
"roleID": "12345"
},
{
"name": "Guest",
"value": "3HJk5bsnY8",
"roleID": "12345"
}
]
}
File renamed without changes.
122 changes: 0 additions & 122 deletions prev-try (old-dont-use)/main.go

This file was deleted.