Back to APIs list

Discord API examples & templates

Use these vals as a playground to view and fork Discord API examples and templates on Val Town. Run any example below or find templates that can be used as a pre-built solution.
1
2
3
4
import { discordSendDM } from "https://esm.town/v/vtdocs/discordSendDM";
const result = await discordSendDM(Deno.env.get("discordBot"), "420257368417239041", "Hello!");
console.log(result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { fetch } from "https://esm.town/v/std/fetch";
export const registerDiscordSlashCommandWithOptions = (appID: string, botToken: string, command: {
name: string;
description: string;
options?: {
name: string;
description: string;
type: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
required?: boolean;
choices?: {
name: string;
value: string;
}[];
}[];
defaultPermission?: boolean;
}) => {
const base = new URL("https://discord.com/api/v10/");
const commandsUrl = new URL(`applications/${appID}/commands`, base);
return fetch(commandsUrl.toString(), {
headers: {
Authorization: `Bot ${botToken}`,
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify({
type: 1,
...command,
}),
});
};

Forward Render Error Emails to Val Town's Engineering Discord Channel

shapes at 24-02-08 12.23.08.png

Render sends emails when deploys fail but I want those notifications to come in our team Discord channel, and tag our team. Render doesn't have webhooks for this, so I set up a Gmail filter and forward to this email handler val, which in turn forwards the content to our engineering Discord channel.

1
2
3
4
5
6
7
8
9
10
11
12
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
export default async function(email: Email) {
console.log(JSON.stringify(email));
if (email.from !== "Jason Lengstorf <jason@learnwithjason.dev>") return "Unauthorized";
discordWebhook({
url: Deno.env.get("showbotDiscord"),
content: `<@354095834432012300> LWJ Email: ${email.subject}`,
});
}
Runs every 1 min
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { blob } from "https://esm.town/v/std/blob?v=12";
import { discordGetMembers } from "https://esm.town/v/vtdocs/discordGetMembers?v=6";
import { discordSendDM } from "https://esm.town/v/vtdocs/discordSendDM?v=6";
// Welcome new members to the Val Town Discord
// Make your own welcome bot: https://docs.val.town/create-a-discord-welcome-bot
export const discordWelcomeBotCron = async () => {
let discordWelcomeBotStartedAt = await blob.getJSON("discordWelcomeBotStartedAt");
let discordWelcomedMembers = await blob.getJSON("discordWelcomedMembers");
let discordDMs = await blob.getJSON("discordDMs");
// Only target new users going forwards from bot creation
if (discordWelcomeBotStartedAt === undefined) {
discordWelcomeBotStartedAt = Date.now();
}
// Don't message a user more than once
if (discordWelcomedMembers === undefined) {
discordWelcomedMembers = [];
}
// Store channels we've sent a DM to
// in case we want to forward replies to the bot
if (discordDMs === undefined) {
discordDMs = [];
}
const members = await discordGetMembers(
Deno.env.get("discordBot"),
Deno.env.get("discordServerId"),
);
await Promise.all(members.map(async (member) => {
const existingMember = (new Date(member.joined_at)).getTime()
< discordWelcomeBotStartedAt;
const alreadyWelcomed = discordWelcomedMembers.includes(
member.user.id,
);
if (existingMember || alreadyWelcomed) {
return;
}
const DMid = await discordSendDM(
Deno.env.get("discordBot"),
member.user.id,
`👋 Welcome to Val Town's Discord! Everyone is excited to meet you!
Feel free to post anything Val Town related in <#1020432421243592717>
Bugs in <#1063180396931592192>
DM <@420257368417239041> for anything private
The Val Town Team and community are very friendly,
but I am an antisocial bot that doesn't answer messages.
View my source code: https://www.val.town/v/stevekrouse.discordWelcomeBotCron
`,
);
// Store that we have messaged this user
discordWelcomedMembers.push(member.user.id);
if (DMid !== undefined)
discordDMs.push(DMid);
}));
await Promise.all([
blob.setJSON(
"discordWelcomeBotStartedAt",
discordWelcomeBotStartedAt,
),
blob.setJSON("discordDMs", discordDMs),
blob.setJSON(
"discordWelcomedMembers",
discordWelcomedMembers,
),
]);
};
1
2
// set at Thu May 02 2024 17:56:39 GMT+0000 (Coordinated Universal Time)
export let discordWelcomedMembers = ["810866199536861224","399192125000122410","208758630642614272","168114361586548739","693604532877525033","1037134219085885480","836849743677751306","928433034716385301","865264239413690378","530789581390479390","2649095
1
2
// set at Thu May 02 2024 17:56:39 GMT+0000 (Coordinated Universal Time)
export let discordWelcomeBotStartedAt = 1687289563521;

Twitter 𝕏 keyword Alerts

Custom notifications for when you, your company, or anything you care about is mentioned on Twitter.

1. Authentication

You'll need a Twitter Bearer Token. Follow these instructions to get one.

Unfortunately it costs $100 / month to have a Basic Twitter Developer account. If you subscribe to Val Town Pro, I can let you "borrow" my token. Just comment on this val and I'll hook you up.

2. Query

Change the query variable for what you want to get notified for.

You can use Twitter's search operators to customize your query, for some collection of keywords, filtering out others, and much more!

3. Notification

Below I'm sending these mentions to a private channel in our company Discord, but you can customize that to whatever you want, @std/email, Slack, Telegram, whatever.

Runs every 1 hrs
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import { twitterSearch } from "https://esm.town/v/stevekrouse/twitterSearch";
const query = "\"val.town\" OR \"val town\" -_ValTown_";
export async function twitterAlert({ lastRunAt }: Interval) {
const results = await twitterSearch({
query,
start_time: lastRunAt,
bearerToken: Deno.env.get("twitter"),
});
if (!results.length) return;
// format results
let content = results
.map(({ author_name, author_username, text, id }) => `https://fxtwitter.com/${author_username}/status/${id}`)
.join("\n");
// notify
await discordWebhook({
url: Deno.env.get("mentionsDiscord"),
content,
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
const pingDiscord = async (url: string, username: string, content: string): Promise<Response> =>
await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: username,
content: content,
}),
});
export default pingDiscord;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { discordFetch } from "https://esm.town/v/vtdocs/discordFetch?v=10";
const recipientId = "420257368417239041";
const content = "Hello from valtown!";
const botToken = Deno.env.get("discordBot");
const DM = await discordFetch(
botToken,
"/users/@me/channels",
"POST",
JSON.stringify({
recipient_id: recipientId,
}),
);
console.log(DM);
// Then, we send a message via the DM
const result = await discordFetch(
botToken,
`/channels/${DM.id}/messages`,
"POST",
JSON.stringify({
content,
}),
);
console.log(result);

Water Plant Reminder Discord Bot

Every Monday at 9am EDT send a message to our team's Discord channel to remind us to water our plant.

Screenshot 2024-04-17 at 11.53.31.png

Runs every 14 days
Fork
1
2
3
4
5
6
7
8
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
export default async function() {
discordWebhook({
url: Deno.env.get("engDiscord"), // TODO replace this with the #office channel
content: `<@&1081224342110736394> Water the plant!! 🌴`,
});
}

Daily Standup Bot

Every weekday at 9am EDT send a message to our team's #engineering Discord channel to start a thread to remind us to do our standup.

Screenshot 2024-03-14 at 09.27.26.png

Slack version: @mikker/dailySlackRoundup

1
2
3
4
5
6
7
8
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
export default async function() {
discordWebhook({
url: Deno.env.get("engDiscord"),
content: `<@&1081224342110736394> Daily updates thread ${new Date().toLocaleDateString()} 🚨`,
});
}
1
2
3
4
5
6
7
export default async function handler(req: Request) {
if (req.method !== 'POST') {
return new Response('Method not allowed', { status: 405 });
}
console.log(await req.json());
return Response.json({ ok: true });
}

Twitter 𝕏 keyword Alerts

Custom notifications for when you, your company, or anything you care about is mentioned on Twitter.

1. Authentication

You'll need a Twitter Bearer Token. Follow these instructions to get one.

Unfortunately it costs $100 / month to have a Basic Twitter Developer account. If you subscribe to Val Town Pro, I can let you "borrow" my token. Just comment on this val and I'll hook you up.

2. Query

Change the query variable for what you want to get notified for.

You can use Twitter's search operators to customize your query, for some collection of keywords, filtering out others, and much more!

3. Notification

Below I'm sending these mentions to a private channel in our company Discord, but you can customize that to whatever you want, @std/email, Slack, Telegram, whatever.

Runs every 1 hrs
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import { twitterSearch } from "https://esm.town/v/stevekrouse/twitterSearch";
const query = "\"val.town\" OR \"val town\" -_ValTown_";
export async function twitterAlert({ lastRunAt }: Interval) {
const results = await twitterSearch({
query,
start_time: lastRunAt,
bearerToken: Deno.env.get("twitter"),
});
if (!results.length) return;
// format results
let content = results
.map(({ author_name, author_username, text, id }) => `https://fxtwitter.com/${author_username}/status/${id}`)
.join("\n");
// notify
await discordWebhook({
url: Deno.env.get("mentionsDiscord"),
content,
});
}

Daily Standup Bot

Every weekday at 9am EDT send a message to our team's #engineering Discord channel to start a thread to remind us to do our standup.

Screenshot 2024-03-14 at 09.27.26.png

Slack version: @mikker/dailySlackRoundup

1
2
3
4
5
6
7
8
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
export default async function() {
discordWebhook({
url: Deno.env.get("engDiscord"),
content: `<@&1081224342110736394> Daily updates thread ${new Date().toLocaleDateString()} 🚨`,
});
}
1
2
3
4
5
6
7
8
import { discordWebhook } from "https://esm.town/v/stevekrouse/discordWebhook";
import process from "node:process";
export const discordWebhookEx = discordWebhook({
url:
"https://discord.com/api/webhooks/1220801040870281357/1aA_0F-CcEY64yQsvVxOx0mP8E_XbdduAxlqFtiix5H72p9g0WxIGkFoDGNlyr7Q-LaH",
content: "Hi from val town!",
});