Skip to content

Instantly share code, notes, and snippets.

@aamiaa
Last active July 4, 2026 18:49
Show Gist options
  • Select an option

  • Save aamiaa/7cdd590e3949cd654758bc90bcb4710b to your computer and use it in GitHub Desktop.

Select an option

Save aamiaa/7cdd590e3949cd654758bc90bcb4710b to your computer and use it in GitHub Desktop.

Widget Creator Script

This script does most of the widget creating work for you if you've found the manual tutorials too hard to follow.

How to use:

  1. Navigate to the Discord Developer Portal
  2. Press Ctrl+Shift+I to open DevTools
  3. Go to the Console tab
  4. Paste the following code and hit enter:
Click to expand
let wpRequire = webpackChunkdiscord_developers.push([[Symbol()], {}, r => r]);
webpackChunkdiscord_developers.pop();

let ApexStore = Object.values(wpRequire.c).find(x => x?.exports?.A?.createOverride).exports.A;
let UserStore = Object.values(wpRequire.c).find(x => x?.exports?.A?.__proto__?.getCurrentUser).exports.A;
let FluxDispatcher = Object.values(wpRequire.c).find(x => x?.exports?.A?.__proto__?.flushWaitQueue).exports.A;
let api = Object.values(wpRequire.c).find(x => x?.exports?.Bo?.get).exports.Bo;
let globalCopy = navigator.userAgent.includes("Firefox") ? navigator.clipboard.writeText.bind(navigator.clipboard) : copy
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const userId = UserStore.getCurrentUser().id
console.log("[Widget Creator] Creating a new app... Please solve the captcha if prompted")
const appRes = await api.post({url: "/applications", body: {name: "My New Widget", team_id: null}})
FluxDispatcher.dispatch({type: "APPLICATION_CREATE_SUCCESS", application: appRes.body})
const appId = appRes.body.id

console.log("[Widget Creator] Enabling social sdk...")
await api.post({url: `/applications/${appId}/social-sdk/enable`, body: {"name":"a","business_email":"foo@bar.com","game_or_studio_name":"a","game_or_studio_url":"","email_updates_consent":false,"country_or_region":"United States","title_role":"Founder","target_platforms":[],"form_type":"Dev Solutions","sfdc_leadsource":"Dev Portal","utm_campaign":"SDK Enable Form"}})

console.log("[Widget Creator] Creating a new widget...")
const configRes = await api.post({url: `/applications/${appId}/widget-configs`, body: {display_name: "My Widget"}})
const configId = configRes.body.config_id
await api.patch({url: `/applications/${appId}/widget-configs/${configId}`, body: {"surfaces":{"widget_top":{"layout":"widget_top_hero","components":{"hero_image":{"fields":{"image":{"presentation_type":"image","value_type":"data","value":"change this to an image"}}},"title":{"fields":{"text":{"presentation_type":"text","value_type":"custom_string","value":"some title here"}}}}},"widget_bottom":{"layout":"widget_bottom_stats","components":{"stat_1":{"fields":{"value":{"presentation_type":"text","value_type":"custom_string","value":"text 1 here"},"label":{"presentation_type":"text","value_type":"custom_string","value":"label 1 here"}}},"stat_2":{"fields":{"value":{"presentation_type":"text","value_type":"custom_string","value":"text 2 here"},"label":{"presentation_type":"text","value_type":"custom_string","value":"label 2 here"}}},"stat_3":{"fields":{"value":{"presentation_type":"text","value_type":"custom_string","value":"text 3 here"},"label":{"presentation_type":"text","value_type":"custom_string","value":"label 3 here"}}},"stat_4":{"fields":{"value":{"presentation_type":"text","value_type":"custom_string","value":"text 4 here"},"label":{"presentation_type":"text","value_type":"custom_string","value":"label 4 here"}}},"stat_5":{"fields":{"value":{"presentation_type":"text","value_type":"custom_string","value":"text 5 here"},"label":{"presentation_type":"text","value_type":"custom_string","value":"label 5 here"}}},"stat_6":{"fields":{"value":{"presentation_type":"text","value_type":"custom_string","value":"text 6 here"},"label":{"presentation_type":"text","value_type":"custom_string","value":"label 6 here"}}}}},"add_widget_preview":{"layout":"add_widget_preview_hero","components":{"hero_image":{"fields":{"image":{"presentation_type":"image","value_type":"data","value":"change this to an image"}}}}}}}})
await api.post({url: `/applications/${appId}/widget-configs/${configId}/publish`})

console.log("[Widget Creator] Adding the widget to profile...")
await api.patch({url: `/applications/${appId}`, body: {redirect_uris: ["https://discord.com"]}})
await api.post({url: `/oauth2/authorize?client_id=${appId}&response_type=token&scope=sdk.social_layer_presence`, body: {authorize: true}})
const profileRes = await api.get({url: `/users/${userId}/profile`})
const existingWidgets = profileRes.body.widgets
existingWidgets.unshift({"data":{"type":"application","application_id":appId}})
await api.put({url: `/users/@me/widgets`, body: {"widgets": existingWidgets}})

console.log("[Widget Creator] Getting the bot's token... Please enter your 2FA if prompted")
const botTokenRes = await api.post({url: `/applications/${appId}/bot/reset`})
const botToken = botTokenRes.body.token

if(navigator.userAgentData?.platform === "Windows" || navigator.userAgent.includes("Windows")) {
	globalCopy(`Invoke-RestMethod -Method PATCH -Headers @{"Content-Type"="application/json"; "Authorization"="Bot ${botToken}";"User-Agent"="DiscordBot (https://github.com/discord/discord-api-docs, 1.0.0)"} -Uri https://discord.com/api/v9/applications/${appId}/users/${userId}/identities/0/profile -Body '${JSON.stringify({data: {dynamic: []}})}'`)
} else {
	globalCopy(`curl -X PATCH "https://discord.com/api/v9/applications/${appId}/users/${userId}/identities/0/profile" -H "Content-Type: application/json" -H "Authorization: Bot ${botToken}" -H "User-Agent: DiscordBot (https://github.com/discord/discord-api-docs, 1.0.0)" -d '${JSON.stringify({data: {dynamic: []}})}'`)
}
console.log("[Widget Creator] A command has been copied to your clipboard. Paste it in your pc's terminal and hit enter.")

ApexStore.createOverride("2026-03-widget-config-editor", 1)
document.querySelector(`a[href="/developers/applications/${appId}"]`).click()
while(!document.querySelector(`a[href="/developers/applications/${appId}/widget"]`)) {
    await sleep(100)
}
document.querySelector(`a[href="/developers/applications/${appId}/widget"]`).click()
console.log("[Widget Creator] Afterwards, you can edit your widget on this page!")
  1. If prompted, complete the captcha and enter your 2FA
  2. Once it's finished, it will copy a PowerShell command to your clipboard
  3. Launch a PowerShell terminal by right clicking the Windows button in bottom left and clicking on "PowerShell" or "Terminal"
image
  1. Right click in the terminal to paste the copied command
  2. Hit Enter to run it
  3. Close the terminal
  4. Go back to the browser tab to edit your widget

The script automatically adds the new widget to your discord profile.

FAQ

Q: I closed my browser tab. How do I get back to the widget editing screen?

A: Run this script in the console:

Click to expand
let wpRequire = webpackChunkdiscord_developers.push([[Symbol()], {}, r => r]);
webpackChunkdiscord_developers.pop();

let ApexStore = Object.values(wpRequire.c).find(x => x?.exports?.A?.createOverride).exports.A;
ApexStore.createOverride("2026-03-widget-config-editor", 1)

then navigate to your app, and go to Games -> Widget

image



Q: How do I add images to the widget?

A: Make sure Value Type is set to Application Asset, then use this button to upload and select an image:

image
@MiguVT

MiguVT commented Jun 28, 2026

Copy link
Copy Markdown

It will be good to say that the command also works on Linux if curl is installed

@aamiaa

aamiaa commented Jun 28, 2026

Copy link
Copy Markdown
Author

I just changed the command to use Invoke-RestMethod instead of curl for more windows compatibility so that's no longer the case, but I trust that linux users are advanced enough to know how to adjust it for their system.

@amolinarius

Copy link
Copy Markdown

Can't the script use api.patch or Javascript's fetch directly instead of telling you to copy a command into the terminal so that it works on every OS?

@aamiaa

aamiaa commented Jun 29, 2026

Copy link
Copy Markdown
Author

No because discord's api blocks bot token requests that come from a browser useragent, and you can't change the useragent without extensions.

@peanutbuttery2763

Copy link
Copy Markdown

yo guys what if i already HAVE an existing bot
do i just go kill myself or

@DarthGigi

Copy link
Copy Markdown

Why not use curl for linux/macos users?

@amolinarius

Copy link
Copy Markdown

According to Amia:

I just changed the command to use Invoke-RestMethod instead of curl for more windows compatibility so that's no longer the case, but I trust that linux users are advanced enough to know how to adjust it for their system.

However I think it would still be good to add OS detection based on navigator.userAgent or navigator.userAgentData on Chromium.
For example:

if (navigator.userAgentData?.platform == "Windows" /* Chromium */ || navigator.userAgent.includes("Windows") /* Firefox/Gecko */)
    globalCopy(`Invoke-RestMethod -Method PATCH -Headers @{"Content-Type"="application/json"; "Authorization"="Bot ${botToken}";"User-Agent"="DiscordBot (https://github.com/discord/discord-api-docs, 1.0.0)"} -Uri https://discord.com/api/v9/applications/${appId}/users/${userId}/identities/0/profile -Body '{"data": {"dynamic": []}}'`);
else
    globalCopy(`curl https://discord.com/api/v9/applications/${appId}/users/${userId}/identities/0/profile -X PATCH -A "DiscordBot (https://github.com/discord/discord-api-docs, 1.0.0)" -H "Content-Type: application/json" -H "Authorization: Bot ${botToken}" --data '{"data": {"dynamic": []}}'`);

PS: Unrelated but @DarthGigi, as a fellow SkyCrypt user, thanks ❤️

@DarthGigi

Copy link
Copy Markdown

I agree that the simple useragent check should be added.

@amolinarius Thank you btw, appreciate it 🫶🏼

@aamiaa

aamiaa commented Jun 30, 2026

Copy link
Copy Markdown
Author

Okay I added the OS check

@Kanamiz

Kanamiz commented Jul 3, 2026

Copy link
Copy Markdown

@aamiaa
image
what i can do here

@aamiaa

aamiaa commented Jul 3, 2026

Copy link
Copy Markdown
Author

You deleted an app whose widget you've previously added to your profile. Run this to wipe your profile board:

let wp = (window.webpackChunkdiscord_app ?? window.webpackChunkdiscord_developers)
let wpRequire = wp.push([[Symbol()], {}, r => r]);
wp.pop();
let api = Object.values(wpRequire.c).find(x => x?.exports?.Bo?.get).exports.Bo;
api.put({url: `/users/@me/widgets`, body: {widgets: []}})

@Kanamiz

Kanamiz commented Jul 3, 2026

Copy link
Copy Markdown

@aamiaa tysmm

@KloBraticc

Copy link
Copy Markdown

yall are the best

@Oskar-pinara

Copy link
Copy Markdown

thnx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment