Skip to content

Instantly share code, notes, and snippets.

@scooper4711
Created November 28, 2025 04:35
Show Gist options
  • Select an option

  • Save scooper4711/dbd6099cc4e06e841195857c02c8cbc8 to your computer and use it in GitHub Desktop.

Select an option

Save scooper4711/dbd6099cc4e06e841195857c02c8cbc8 to your computer and use it in GitHub Desktop.
Associate discord usernames with FoundryVTT users. This is needed for the exportSceneToSage.js gist
// FoundryVTT Macro: Set Discord Usernames for Users
// This macro allows the GM to map Foundry usernames to Discord usernames
(async () => {
// Check if user is GM
if (!game.user.isGM) {
ui.notifications.warn("Only the GM can set Discord usernames");
return;
}
// Get all users
const users = game.users.contents;
// Build form content with current mappings
let formContent = `
<form>
<p style="margin-bottom: 15px;">Map Foundry usernames to Discord usernames (without @ symbol):</p>
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr style="border-bottom: 2px solid #999;">
<th style="text-align: left; padding: 8px;">Foundry User</th>
<th style="text-align: left; padding: 8px;">Discord Username</th>
</tr>
</thead>
<tbody>
`;
for (const user of users) {
const currentDiscord = user.getFlag("world", "discordUsername") || "";
const userColor = user.color || "#FFFFFF";
formContent += `
<tr style="border-bottom: 1px solid #555;">
<td style="padding: 8px;">
<span style="color: ${userColor}; font-weight: bold;">●</span>
${user.name}
${user.isGM ? '<em>(GM)</em>' : ''}
</td>
<td style="padding: 8px;">
<input
type="text"
name="discord_${user.id}"
value="${currentDiscord}"
placeholder="username"
style="width: 100%; padding: 4px; box-sizing: border-box;"
/>
</td>
</tr>
`;
}
formContent += `
</tbody>
</table>
<p style="margin-top: 15px; font-size: 0.9em; color: #aaa;">
<strong>Note:</strong> Enter Discord usernames without the @ symbol (e.g., "coop4711" not "@coop4711")
</p>
</form>
`;
// Create dialog
new Dialog({
title: "Set Discord Usernames",
content: formContent,
buttons: {
save: {
icon: '<i class="fas fa-save"></i>',
label: "Save Mappings",
callback: async (html) => {
let saveCount = 0;
for (const user of users) {
const input = html.find(`input[name="discord_${user.id}"]`);
const discordUsername = input.val().trim();
if (discordUsername) {
await user.setFlag("world", "discordUsername", discordUsername);
saveCount++;
} else {
// Clear flag if empty
await user.unsetFlag("world", "discordUsername");
}
}
ui.notifications.info(`Discord usernames saved for ${saveCount} user(s)`);
}
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: "Cancel"
}
},
default: "save",
render: (html) => {
// Focus first input
html.find("input").first().focus();
}
}, {
width: 500,
height: "auto"
}).render(true);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment