Campaigns
This Document will explain the flow every campaign goes trough until it appears as a message in your discord server
Sending a Campaign
The first step is that the user fills out the google form and sends it. The campaign will be converted from a google form to a json object which looks like this:
{
"campaign_name": "Test Campaign",
"dm_name": "Hans",
"language": "English",
"description": "This is the description",
"difficulty":"Medium",
"players_max": 5,
"location": "Some location",
"time": "Every day, all day long",
"notes": "here come the optional notes",
"icon": "Shield",
"username": "Hans#0002"
}
Important to note is, that difficulty can be either "Beginner/Easy", "Medium" or "Expert/Difficult" and icon can be "Dice", "Swords" or "Shield" as seen in the interface for the google forms data:
export interface GoogleFormsData {
"campaign_name": string,
"dm_name": string,
"language": string,
"description": string,
"difficulty": "Beginner/Easy" | "Medium" | "Expert/Difficult",
"players_max": number,
"location": string,
"time": string,
"notes": string | null,
"icon": "Dice" | "Swords" | "Shield",
"username": string
}
If the express server now receives the google forms data it calls the generateCampaign() function in the next step.
Generating the Campaign
Generating channels and buttons and registering user
Before anything else the bot generates the correct channels and registers the buttons for the campaign. After that it adds the user which it gets via the username (=Discord tag).
//fetch user by username and get the id
const user = await getMemberFromUsername(data.username, process.env.GUILD_ID!);
//generates and gets corresponding channels
const campaignChannels: CampaignChannels = await generateCampaignChannels(
data.campaign_name,
user?.id ?? "",
);
//add DM to User Database
const userData = await userToUserDataObject(user as GuildMember, { isDM: true, isInCampaign: true });
await addUserDataDBEntry(userData).then(async () => {
await addCampaignToUser(user!, campaignId);
});
//generates and registers the "apply for campaign" Button
const btnRow = new MessageActionRow().addComponents(
new MessageButton()
.setCustomId("beitreten")
.setLabel("Apply for Campaign ")
.setStyle("PRIMARY")
.setEmoji("📝"),
);
registerCampaignEmbedButton(
btnRow.components[0] as MessageButton,
campaignId,
);
Campaign Channels are made up of a text channel, a voice channel and a category as a parent. The the Category is named the same as the name of the campaign and the voice and text channels are called "Campaign Voice" and "Campaign Text" respectively.
In addition to the channels the bot creates also roles in the same step. These roles have the permission to see and access the aforementioned channels and are names "[campaign name] -- Roll". Also mods and admins have access to the channels.
Afterwards it generates the embed for the campaign by calling formsDataToCampEmbed() and passing the campaign data and the campaign id.
Generating the Embed
The Embed is a big Javascript Object which looks like this:
{
color: Number.parseInt(campData.color.replace("#", "0x")),
title: `__${campData.title}__`,
description: campData.description,
fields: [
{ name: "**🏠 Where**", value: campData.location, inline: false },
{ name: "**🕣 When**", value: campData.time, inline: false },
{
name: "**📝 Notes**",
value: campData.notes ?? "",
inline: false,
},
{ name: "\u200B", value: centerText(" Additional Info ", 30, "━"), inline: false },
{
name: "\u200B",
value: `⚔️ ${campData.currentPlayers}/${campData.maxPlayers} Players\n 📖 DM Name: ${campData.dmName}`,
inline: true,
},
{
name: "\u200B",
value: `🧮 Difficulty: ${campData.difficulty} \n 🌍 Language: ${campData.language}`,
inline: true,
},
],
image: {
url: "https://i.imgur.com/Tz2QZ5O.png",
},
thumbnail: {
url: url,
},
timestamp: campData.timestamp?.getDate() ?? new Date().getTime(),
footer: {
text: campData.footerText + `\nCampaign-ID: ${campData.campId}`,
icon_url: "https://i.imgur.com/mMW6WlB.png",
}
};
Where campData is the google forms data object except the icon which is passed separately and associated to a url with this code snippet
let url = "";
switch (icon) {
case "Dice":
url = "https://i.imgur.com/snWt2hZ.png";
break;
case "Swords":
url = "https://i.imgur.com/GJaCzBE.png";
break;
case "Shield":
url = "https://i.imgur.com/GFAHDGo.png";
break;
default:
url = "https://i.imgur.com/snWt2hZ.png";
break;
}
```
### Finishing up
This embed is then sent with
```typescript
await campaignOverviewChannel
.send({ content: "\u200B", embeds: [campaignEmbed], components: [btnRow] })
.then((message) => {
msgId = message.id;
});
and the Campaign is added to the database with
Also the metrics for pm2 are updated.