<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Anisile | 生活、分享]]></title><description><![CDATA[如果這裡充滿雜草，請記得幫我除一除。]]></description><link>https://blog.anisile.cc/</link><image><url>https://blog.anisile.cc/favicon.png</url><title>Anisile | 生活、分享</title><link>https://blog.anisile.cc/</link></image><generator>Ghost 5.62</generator><lastBuildDate>Sun, 28 Dec 2025 23:17:08 GMT</lastBuildDate><atom:link href="https://blog.anisile.cc/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[從零開始的Discord機器人(6) - 其他功能]]></title><description><![CDATA[本篇會介紹如何使用Modals、Context Menus與Embed，為本系列作一個收尾。]]></description><link>https://blog.anisile.cc/discord-bot-6/</link><guid isPermaLink="false">650aefb3869f86000163d7d3</guid><category><![CDATA[Discord.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[從零開始的Discord機器人]]></category><dc:creator><![CDATA[Anisile]]></dc:creator><pubDate>Wed, 20 Sep 2023 17:48:44 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x2003;&#x2003;&#x5728;&#x4E0A;&#x4E00;&#x7BC7;&#x4E2D;&#xFF0C;&#x4ECB;&#x7D39;&#x4E86;Components&#x7684;&#x4F5C;&#x7528;&#x8207;&#x4F7F;&#x7528;&#x65B9;&#x6CD5;&#x3002;&#x63A5;&#x4E0B;&#x4F86;&#xFF0C;&#x6211;&#x6C7A;&#x5B9A;&#x5C07;&#x5269;&#x4E0B;&#x7684;Modal&#xFF08;&#x8868;&#x55AE;&#xFF09;&#x3001;Context Menus&#xFF08;&#x53F3;&#x9375;&#x9078;&#x55AE;&#xFF09;&#x8207;Embed&#xFF08;&#x5D4C;&#x5165;&#x5F0F;&#x8A0A;&#x606F;&#xFF09;&#x5728;&#x672C;&#x7BC7;&#x4E00;&#x6B21;&#x4ECB;&#x7D39;&#x5B8C;&#xFF0C;&#x9019;&#x500B;&#x5F9E;&#x96F6;&#x958B;&#x59CB;&#x7684;Discord&#x6A5F;&#x5668;&#x4EBA;&#x7CFB;&#x5217;&#x5C31;&#x7B97;&#x544A;&#x4E00;&#x500B;&#x6BB5;&#x843D;&#x4E86;&#x3002;</p>
<p>&#x2003;&#x2003;&#x7531;&#x65BC;&#x8981;&#x64F4;&#x5145;Modal&#x8207;Context Menus&#x7684;&#x529F;&#x80FD;&#x5176;&#x5BE6;&#x548C;&#x4E0A;&#x4E00;&#x7BC7;Components&#x7684;&#x601D;&#x8DEF;&#x57FA;&#x672C;&#x4E0A;&#x662F;&#x4E00;&#x81F4;&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x9019;&#x908A;&#x5C31;&#x4E0D;&#x518D;&#x91CD;&#x8907;&#x4ECB;&#x7D39;&#x4E00;&#x904D;&#x5982;&#x4F55;&#x63A5;&#x6536;&#x4E8B;&#x4EF6;&#x7684;&#x90E8;&#x5206;&#xFF0C;&#x53EA;&#x5C08;&#x6CE8;&#x65BC;&#x5EFA;&#x7ACB;&#x9019;&#x4E9B;&#x7269;&#x4EF6;&#x3002;&#x5982;&#x679C;&#x60F3;&#x77E5;&#x9053;&#x5982;&#x4F55;&#x64F4;&#x5145;&#xFF0C;&#x53EF;&#x4EE5;&#x8FD4;&#x56DE;&#x4E0A;&#x4E00;&#x7BC7;&#x8DDF;&#x8457;&#x505A;&#x3002;</p>
<h1 id="1-modal">1. Modal</h1>
<p>&#x2003;&#x2003;&#x7B2C;&#x4E00;&#x500B;&#x8981;&#x4ECB;&#x7D39;&#x7684;&#x662F;Modal&#xFF08;&#x8868;&#x55AE;&#xFF09;&#x3002;Modal&#x548C;Component&#x4E0D;&#x540C;&#xFF0C;&#x5B83;&#x5011;&#x4E26;&#x4E0D;&#x9700;&#x8981;&#x4F9D;&#x9644;&#x65BC;&#x56DE;&#x61C9;&#x4E2D;&#xFF0C;&#x800C;&#x662F;&#x4F7F;&#x7528;<code>interaction.showModal ()</code>&#x4F86;&#x986F;&#x793A;&#x5EFA;&#x7ACB;&#x597D;&#x7684;&#x8868;&#x55AE;&#x3002;</p>
<p>&#x2003;&#x2003;&#x6B63;&#x5982;&#x4E0A;&#x4E00;&#x7BC7;&#x6240;&#x8AAA;&#xFF0C;Discord.js&#x70BA;&#x5EFA;&#x7ACB;&#x9019;&#x4E9B;&#x7269;&#x4EF6;&#x63D0;&#x4F9B;&#x4E86;&#x65B9;&#x4FBF;&#x7684;Builder&#xFF0C;&#x56E0;&#x6B64;&#x6211;&#x5011;&#x4E5F;&#x6709;<code>ModalBuilder ()</code>&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x3002;&#x4EE5;&#x4E0B;&#x662F;&#x4E00;&#x500B;Modal&#x7684;&#x7BC4;&#x4F8B;&#xFF1A;</p>
<pre><code class="language-javascript">const modal = new ModalBuilder()
    .setCustomId(&apos;myModal&apos;)
    .setTitle(&apos;My Modal&apos;);
</code></pre>
<p>&#x2003;&#x2003;&#x5982;&#x6B64;&#x4E00;&#x4F86;&#x5C31;&#x80FD;&#x5EFA;&#x7ACB;&#x4E00;&#x500B;Modal&#xFF0C;&#x4E26;&#x5E6B;&#x5B83;&#x8A2D;&#x5B9A;&#x4E00;&#x500B;CustomId&#x8207;Title&#x4E86;&#x3002;</p>
<p>&#x2003;&#x2003;&#x4F46;&#x76EE;&#x524D;&#x9019;&#x500B;Modal&#x88E1;&#x9762;&#x9084;&#x6C92;&#x6709;&#x6B04;&#x4F4D;&#xFF0C;&#x8981;&#x5E6B;Modal&#x52A0;&#x5165;&#x6B04;&#x4F4D;&#x5176;&#x5BE6;&#x548C;&#x4E0A;&#x4E00;&#x7BC7;&#x9001;&#x51FA;Components&#x662F;&#x4E00;&#x6A21;&#x4E00;&#x6A23;&#x7684;&#x3002;&#x6211;&#x5011;&#x9700;&#x8981;&#x4F7F;&#x7528;<code>TextInputBuilder ()</code>&#x5EFA;&#x7ACB;&#x4E00;&#x500B;&#x6587;&#x5B57;&#x8F38;&#x5165;&#x7684;&#x6B04;&#x4F4D;&#xFF0C;&#x4E26;&#x4E00;&#x6A23;&#x88DD;&#x9032;Action Row&#x5167;&#xFF0C;&#x6700;&#x5F8C;&#x518D;&#x4F7F;&#x7528;<code>addComponents ()</code>&#x52A0;&#x9032;&#x53BB;&#x5373;&#x53EF;&#x3002;</p>
<p>&#x2003;&#x2003;&#x9700;&#x8981;&#x6CE8;&#x610F;&#x7684;&#x662F;&#xFF0C;&#x4E00;&#x500B;Modal&#x88E1;&#x6700;&#x591A;&#x53EF;&#x4EE5;&#x653E;&#x5165;5&#x500B;Action Rows&#xFF0C;&#x6BCF;&#x500B;Action Row&#x90FD;&#x53EA;&#x80FD;&#x653E;&#x5165;&#x4E00;&#x500B;Text Input&#xFF0C;&#x4E26;&#x4E14;&#x76EE;&#x524D;&#x7121;&#x6CD5;&#x653E;&#x5165;Buttons&#x8207;Select Menus&#x3002;&#x4EE5;&#x4E0B;&#x662F;&#x52A0;&#x5165;Text Inputs&#x4E26;&#x585E;&#x5165;Modal&#x5167;&#x7684;&#x7BC4;&#x4F8B;&#xFF1A;</p>
<pre><code class="language-javascript">const favoriteColorInput = new TextInputBuilder ()
    .setCustomId (&apos;favoriteColorInput&apos;)
    .setLabel (&quot;What&apos;s your favorite color?&quot;)
    .setStyle (TextInputStyle.Short);

const hobbiesInput = new TextInputBuilder ()
    .setCustomId (&apos;hobbiesInput&apos;)
    .setLabel (&quot;What&apos;s some of your favorite hobbies?&quot;)
    .setStyle (TextInputStyle.Paragraph);

const firstActionRow = new ActionRowBuilder ()
    .addComponents (favoriteColorInput);
const secondActionRow = new ActionRowBuilder ()
    .addComponents (hobbiesInput);
    
modal.addComponents (firstActionRow, secondActionRow);
</code></pre>
<p>&#x2003;&#x2003;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>setStyle ()</code>&#x8A2D;&#x5B9A;Text Input&#x7684;&#x985E;&#x578B;&#xFF0C;<code>TextInputStyle.Short</code>&#x70BA;&#x55AE;&#x884C;&#x6B04;&#x4F4D;&#xFF0C;&#x800C;<code>TextInputStyle.Paragraph</code>&#x70BA;&#x591A;&#x884C;&#x6B04;&#x4F4D;&#x3002;&#x5982;&#x679C;&#x5E0C;&#x671B;&#x6B04;&#x4F4D;&#x70BA;&#x5FC5;&#x586B;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>setRequired ()</code>&#x5C07;&#x5176;&#x8A2D;&#x70BA;&#x5FC5;&#x586B;&#x3002;</p>
<p>&#x2003;&#x2003;&#x6700;&#x5F8C;&#xFF0C;&#x7576;Modal&#x9001;&#x51FA;&#x4E4B;&#x5F8C;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>interaction.isModalSubmit ()</code>&#x78BA;&#x8A8D;&#x63A5;&#x6536;&#x5230;&#x7684;interaction&#x662F;&#x5426;&#x70BA;&#x8868;&#x55AE;&#x9001;&#x51FA;&#xFF0C;&#x4E26;&#x4F7F;&#x7528;CustomId&#x4F5C;&#x70BA;&#x5224;&#x65B7;&#x3002;</p>
<h1 id="2-context-menus">2. Context Menus</h1>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#x8981;&#x4ECB;&#x7D39;&#x7684;&#x662F;Context Menus&#xFF08;&#x53F3;&#x9375;&#x9078;&#x55AE;&#xFF09;&#x3002;&#x53F3;&#x9375;&#x9078;&#x55AE;&#x61C9;&#x8A72;&#x662F;&#x5168;&#x90E8;&#x88E1;&#x9762;&#x6700;&#x55AE;&#x7D14;&#x7684;&#x7684;&#x529F;&#x80FD;&#x4E86;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x70BA;&#x9078;&#x9805;&#x8A2D;&#x5B9A;&#x4E00;&#x500B;&#x540D;&#x7A31;&#x8207;&#x985E;&#x578B;&#x5373;&#x53EF;&#x3002;&#x4EE5;&#x4E0B;&#x662F;&#x4E00;&#x500B;<code>ContextMenuCommandBuilder ()</code>&#x7684;&#x7BC4;&#x4F8B;&#xFF1A;</p>
<pre><code class="language-javascript">const data = new ContextMenuCommandBuilder ()
    .setName (&apos;User Information&apos;)
    .setType (ApplicationCommandType.User);
</code></pre>
<p>&#x2003;&#x2003;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>setType ()</code>&#x8A2D;&#x5B9A;&#x9019;&#x500B;&#x53F3;&#x9375;&#x9078;&#x55AE;&#x8981;&#x986F;&#x793A;&#x5728;&#x4F55;&#x8655;&#xFF0C;<code>ApplicationCommandType.User</code>&#x70BA;&#x5C0D;&#x6210;&#x54E1;&#x53F3;&#x9375;&#x6642;&#x986F;&#x793A;&#xFF0C;&#x800C;<code>ApplicationCommandType.Message</code>&#x70BA;&#x5C0D;&#x8A0A;&#x606F;&#x53F3;&#x9375;&#x6642;&#x986F;&#x793A;&#x3002;</p>
<p>&#x2003;&#x2003;&#x6700;&#x5F8C;&#xFF0C;&#x7576;&#x4F7F;&#x7528;&#x53F3;&#x9375;&#x9078;&#x55AE;&#x4E4B;&#x5F8C;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>interaction.isContextMenuCommand ()</code>&#x78BA;&#x8A8D;&#x63A5;&#x6536;&#x5230;&#x53F3;&#x9375;&#x9078;&#x55AE;&#xFF0C;&#x6216;&#x8005;&#x60F3;&#x8981;&#x6BD4;&#x8F03;&#x7D30;&#x4E00;&#x9EDE;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>isMessageContextMenuCommand()</code>&#x548C;<code>isUserContextMenuCommand()</code>&#x5224;&#x65B7;&#x662F;&#x5C0D;&#x6210;&#x54E1;&#x53F3;&#x9375;&#x6216;&#x662F;&#x5C0D;&#x8A0A;&#x606F;&#x53F3;&#x9375;&#x3002;</p>
<p>&#x2003;&#x2003;&#x4F60;&#x53EF;&#x4EE5;&#x6CE8;&#x610F;&#x5230;&#x53EA;&#x6709;&#x53F3;&#x9375;&#x9078;&#x55AE;&#x6C92;&#x6709;&#x4F7F;&#x7528;&#x5230;CustomId&#xFF0C;&#x53D6;&#x800C;&#x4EE3;&#x4E4B;&#x7684;&#x662F;&#x4F7F;&#x7528;<code>interaction.targetUser</code>&#x8207;<code>interaction.targetMember</code>&#x53D6;&#x5F97;&#x76EE;&#x6A19;&#x6210;&#x54E1;&#xFF0C;&#x4EE5;&#x53CA;&#x4F7F;&#x7528;<code>interaction.targetMessage</code>&#x53D6;&#x5F97;&#x76EE;&#x6A19;&#x8A0A;&#x606F;&#x3002;</p>
<h1 id="3-embed">3. Embed</h1>
<p>&#x2003;&#x2003;&#x6700;&#x5F8C;&#x4E00;&#x500B;&#x8981;&#x4ECB;&#x7D39;&#x7684;&#x662F;Embed&#xFF08;&#x5D4C;&#x5165;&#x5F0F;&#x8A0A;&#x606F;&#xFF09;&#x3002;Embed&#x662F;&#x4E00;&#x7A2E;&#x53EF;&#x4EE5;&#x900F;&#x904E;&#x81EA;&#x8A02;&#x6392;&#x7248;&#x3001;&#x986F;&#x793A;&#x5716;&#x7247;&#x3001;&#x52A0;&#x4E0A;&#x8D85;&#x9023;&#x7D50;&#x7B49;&#x4E00;&#x7CFB;&#x5217;&#x529F;&#x80FD;&#xFF0C;&#x65B9;&#x4FBF;&#x6211;&#x5011;&#x7F8E;&#x5316;&#x4E26;&#x6E05;&#x695A;&#x5C55;&#x793A;&#x8CC7;&#x8A0A;&#x7684;&#x7279;&#x6B8A;&#x6392;&#x7248;&#x3002;</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.anisile.cc/content/images/2023/09/image-1.png" class="kg-image" alt loading="lazy" width="619" height="615" srcset="https://blog.anisile.cc/content/images/size/w600/2023/09/image-1.png 600w, https://blog.anisile.cc/content/images/2023/09/image-1.png 619w"><figcaption>Embed&#x53EF;&#x4EE5;&#x8B93;&#x4F60;&#x66F4;&#x597D;&#x7684;&#x5C55;&#x793A;&#x8CC7;&#x8A0A;</figcaption></figure><!--kg-card-begin: markdown--><p>&#x2003;&#x2003;&#x4EE5;&#x4E0A;&#x9762;&#x7684;Embed&#x70BA;&#x7BC4;&#x4F8B;&#xFF0C;&#x4E0B;&#x9762;&#x5C31;&#x76F4;&#x63A5;&#x5C55;&#x793A;&#x7A0B;&#x5F0F;&#x78BC;&#xFF0C;&#x4E26;&#x4E00;&#x4E00;&#x89E3;&#x91CB;&#x6BCF;&#x500B;function&#x5C0D;&#x61C9;&#x7684;&#x4F4D;&#x7F6E;&#xFF1A;</p>
<pre><code class="language-javascript">const exampleEmbed = new EmbedBuilder()
    .setColor(0x0099FF)
    .setTitle(&apos;Some title&apos;)
    .setURL(&apos;https://discord.js.org/&apos;)
    .setAuthor({ name: &apos;Some name&apos;, iconURL: &apos;https://i.imgur.com/AfFp7pu.png&apos;, url: &apos;https://discord.js.org&apos; })
    .setDescription(&apos;Some description here&apos;)
    .setThumbnail(&apos;https://i.imgur.com/AfFp7pu.png&apos;)
    .addFields(
        { name: &apos;Regular field title&apos;, value: &apos;Some value here&apos; },
        { name: &apos;\u200B&apos;, value: &apos;\u200B&apos; },
        { name: &apos;Inline field title&apos;, value: &apos;Some value here&apos;, inline: true },
        { name: &apos;Inline field title&apos;, value: &apos;Some value here&apos;, inline: true },
    )
    .addFields({ name: &apos;Inline field title&apos;, value: &apos;Some value here&apos;, inline: true })
    .setImage(&apos;https://i.imgur.com/AfFp7pu.png&apos;)
    .setTimestamp()
    .setFooter({ text: &apos;Some footer text here&apos;, iconURL: &apos;https://i.imgur.com/AfFp7pu.png&apos; });
</code></pre>
<ul>
<li><code>setColor ()</code>&#xFF1A;&#x986F;&#x793A;&#x65BC;Embed&#x5DE6;&#x5074;&#x908A;&#x7DE3;&#x7684;&#x984F;&#x8272;&#x3002;</li>
<li><code>setTitle ()</code>&#xFF1A;Embed&#x7684;&#x6A19;&#x984C;&#x3002;</li>
<li><code>setURL ()</code>&#xFF1A;&#x9EDE;&#x64CA;&#x6A19;&#x984C;&#x6642;&#x6703;&#x5C0E;&#x5411;&#x7684;&#x7DB2;&#x5740;&#x3002;</li>
<li><code>setAuthor ()</code>&#xFF1A;Embed&#x986F;&#x793A;&#x7684;&#x4F5C;&#x8005;&#xFF0C;&#x53EF;&#x4EE5;&#x8A2D;&#x5B9A;&#x540D;&#x7A31;&#x3001;icon&#xFF0C;&#x4E5F;&#x80FD;&#x8A2D;&#x5B9A;&#x9EDE;&#x64CA;&#x4F5C;&#x8005;&#x6642;&#x5C0E;&#x5411;&#x7684;&#x7DB2;&#x5740;&#x3002;</li>
<li><code>setDescription ()</code>&#xFF1A;&#x986F;&#x793A;&#x95DC;&#x65BC;Embed&#x7684;&#x63CF;&#x8FF0;&#x3002;</li>
<li><code>setThumbnail ()</code>&#xFF1A;Embed&#x7684;&#x7E2E;&#x7565;&#x5716;&#xFF0C;&#x6703;&#x5728;&#x53F3;&#x4E0A;&#x89D2;&#x986F;&#x793A;&#x3002;</li>
<li><code>addFields ()</code>&#xFF1A;&#x9700;&#x8981;&#x65B0;&#x589E;&#x6B04;&#x4F4D;&#x6642;&#x4F7F;&#x7528;&#xFF0C;&#x6BCF;&#x4E00;&#x500B;&#x6B04;&#x4F4D;&#x90FD;&#x5FC5;&#x9808;&#x5305;&#x542B;name&#x3001;value&#x9019;&#x5169;&#x500B;&#x503C;&#xFF0C;&#x5982;&#x679C;&#x60F3;&#x8981;&#x8B93;&#x4E00;&#x4E9B;&#x6B04;&#x4F4D;&#x4E26;&#x6392;&#x5728;&#x540C;&#x4E00;&#x884C;&#xFF0C;&#x53EF;&#x4EE5;&#x52A0;&#x4E0A;inline&#x9019;&#x500B;&#x503C;&#x3002;&#x4F60;&#x53EF;&#x80FD;&#x6709;&#x6CE8;&#x610F;&#x5230;&#x5176;&#x4E2D;&#x4E00;&#x500B;name&#x8207;value&#x70BA;<code>\u200b</code>&#x7684;&#x6B04;&#x4F4D;&#xFF0C;<code>\u200b</code>&#x662F;&#x4E00;&#x7A2E;&#x7279;&#x6B8A;&#x5B57;&#x5143;&#xFF0C;&#x610F;&#x601D;&#x662F;&#x5BEC;&#x5EA6;&#x70BA;0&#x7684;&#x7A7A;&#x683C;&#xFF0C;&#x53EF;&#x4EE5;&#x7528;&#x4F86;&#x4F5C;&#x70BA;&#x5EFA;&#x7ACB;&#x7A7A;&#x683C;&#x6B04;&#x4F4D;&#x4F7F;&#x7528;&#x3002;</li>
<li><code>setImage ()</code>&#xFF1A;Embed&#x5305;&#x542B;&#x7684;&#x5716;&#x7247;&#x3002;</li>
<li><code>setTimestamp ()</code>&#xFF1A;&#x986F;&#x793A;&#x5EFA;&#x7ACB;Embed&#x7684;&#x6642;&#x9593;&#x3002;</li>
<li><code>setFooter ()</code>&#xFF1A;&#x986F;&#x793A;Embed&#x7684;Footer&#x3002;</li>
</ul>
<p>&#x2003;&#x2003;&#x5BE6;&#x969B;&#x4E0A;&#x4F7F;&#x7528;Embed&#x6642;&#xFF0C;&#x4F60;&#x4E0D;&#x9700;&#x8981;&#x50CF;&#x4E0A;&#x9762;&#x90A3;&#x6A23;&#x8A2D;&#x5B9A;&#x6240;&#x6709;&#x7684;&#x90E8;&#x5206;&#xFF0C;&#x53EF;&#x4EE5;&#x6839;&#x64DA;&#x81EA;&#x5DF1;&#x7684;&#x9700;&#x8981;&#x589E;&#x6E1B;&#x8A2D;&#x5B9A;&#x5373;&#x53EF;&#x3002;&#x7531;&#x65BC;Discord API&#x7684;&#x9650;&#x5236;&#xFF0C;Embed&#x7684;&#x5404;&#x500B;&#x6B04;&#x4F4D;&#x90FD;&#x6709;&#x4E0D;&#x540C;&#x7684;&#x5B57;&#x6578;&#x9650;&#x5236;&#xFF0C;&#x800C;&#x81EA;&#x8A02;&#x7684;&#x6B04;&#x4F4D;&#x4E5F;&#x6709;&#x6578;&#x91CF;&#x9650;&#x5236;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;<a href="https://discord.com/developers/docs/resources/channel?ref=blog.anisile.cc#embed-object-embed-limits">&#x770B;&#x9019;&#x88E1;</a>&#x5F97;&#x5230;&#x66F4;&#x8A73;&#x76E1;&#x7684;&#x9650;&#x5236;&#x3002;&#x5B8C;&#x6210;&#x5EFA;&#x7ACB;Embed&#x4E4B;&#x5F8C;&#xFF0C;&#x9001;&#x51FA;Embed&#x7684;&#x65B9;&#x5F0F;&#x4E5F;&#x548C;&#x9001;&#x51FA;Component&#x4E00;&#x6A23;&#xFF0C;&#x6211;&#x5011;&#x53EA;&#x9700;&#x8981;&#x9019;&#x9EBC;&#x505A;&#xFF1A;</p>
<pre><code class="language-javascript">interaction.reply({
    embeds: [embed],
})
</code></pre>
<p>&#x2003;&#x2003;&#x5982;&#x6B64;&#x4E00;&#x4F86;&#xFF0C;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x56DE;&#x61C9;&#x5E95;&#x4E0B;&#x5C31;&#x6703;&#x986F;&#x793A;Embed&#x56C9;&#xFF01;</p>
<h1 id="4-%E7%B5%90%E8%AA%9E">4. &#x7D50;&#x8A9E;</h1>
<p>&#x2003;&#x2003;&#x5230;&#x9019;&#x88E1;&#xFF0C;&#x5F9E;&#x96F6;&#x958B;&#x59CB;&#x7684;Discord&#x6A5F;&#x5668;&#x4EBA;&#x7CFB;&#x5217;&#x5C31;&#x544A;&#x4E00;&#x500B;&#x6BB5;&#x843D;&#x4E86;&#x3002;&#x4E0D;&#x904E;&#xFF0C;&#x9019;&#x88E1;&#x6240;&#x4ECB;&#x7D39;&#x7684;&#x5167;&#x5BB9;&#x9084;&#x9060;&#x9060;&#x4E0D;&#x662F;Discord.js&#x7684;&#x5168;&#x90E8;&#x3002;&#x60F3;&#x8981;&#x77E5;&#x9053;Discord.js&#x9084;&#x6709;&#x4EC0;&#x9EBC;&#x529F;&#x80FD;&#xFF0C;&#x6216;&#x662F;&#x5728;&#x88FD;&#x4F5C;&#x6A5F;&#x5668;&#x4EBA;&#x6642;&#x6709;&#x9047;&#x5230;&#x56F0;&#x96E3;&#xFF0C;&#x90FD;&#x53EF;&#x4EE5;&#x95B1;&#x8B80;<a href="https://old.discordjs.dev/?ref=blog.anisile.cc#/docs/discord.js/14.13.0/general/welcome">&#x5B98;&#x65B9;&#x6587;&#x4EF6;</a>&#xFF0C;&#x6211;&#x76F8;&#x4FE1;&#x90FD;&#x80FD;&#x627E;&#x5230;&#x4F60;&#x9700;&#x8981;&#x7684;&#x8CC7;&#x8A0A;&#x7684;&#x3002;</p>
<p>&#x2003;&#x2003;&#x5982;&#x679C;&#x4F60;&#x662F;&#x5F9E;&#x7B2C;&#x4E00;&#x7BC7;&#x4E00;&#x8DEF;&#x770B;&#x5230;&#x6700;&#x5F8C;&#x4E00;&#x7BC7;&#xFF0C;&#x5728;&#x9019;&#x88E1;&#x8AAA;&#x4E00;&#x8072;&#x8B1D;&#x8B1D;&#x4F60;&#xFF01;&#xFF08;&#x7576;&#x7136;&#x5C31;&#x7B97;&#x4E0D;&#x662F;&#x6211;&#x4E5F;&#x5F88;&#x611F;&#x8B1D;&#x4F60;&#xFF09;&#x9019;&#x662F;&#x6211;&#x7B2C;&#x4E00;&#x6B21;&#x5BEB;&#x9019;&#x7A2E;&#x7CFB;&#x5217;&#x6587;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x9047;&#x5230;&#x554F;&#x984C;&#x6216;&#x60F3;&#x8981;&#x63D0;&#x4F9B;&#x5EFA;&#x8B70;&#xFF0C;&#x90FD;&#x6B61;&#x8FCE;&#x806F;&#x7E6B;&#x6211;&#xFF0C;&#x8B1D;&#x8B1D;&#x3002;</p>
<p>&#x2003;&#x2003;&#x611F;&#x8B1D;&#x4F60;&#x770B;&#x5230;&#x9019;&#x908A;&#xFF0C;&#x6211;&#x5011;&#x4E0B;&#x500B;&#x7CFB;&#x5217;&#x898B;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[從零開始的Discord機器人(5) - 增加互動]]></title><description><![CDATA[本篇會介紹如何使用Components，並實際建立Button與Select Menu這兩種Components。]]></description><link>https://blog.anisile.cc/discord-bot-5/</link><guid isPermaLink="false">650519b7869f86000163d4d4</guid><category><![CDATA[Discord.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[從零開始的Discord機器人]]></category><dc:creator><![CDATA[Anisile]]></dc:creator><pubDate>Tue, 19 Sep 2023 17:12:17 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x2003;&#x2003;&#x5230;&#x4E0A;&#x4E00;&#x7BC7;&#x70BA;&#x6B62;&#xFF0C;&#x6211;&#x5011;&#x5DF2;&#x7D93;&#x5F04;&#x597D;&#x4E86;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x67B6;&#x69CB;&#x3002;&#x6240;&#x4EE5;&#x9019;&#x6B21;&#x7684;&#x4E3B;&#x984C;&#x4E0D;&#x662F;&#x95DC;&#x65BC;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x672C;&#x9AD4;&#xFF0C;&#x800C;&#x662F;&#x8457;&#x91CD;&#x65BC;&#x53EF;&#x4EE5;&#x8B93;&#x4F7F;&#x7528;&#x8005;&#x4E92;&#x52D5;&#x7684;&#x529F;&#x80FD;&#x3002;</p>
<p>&#x2003;&#x2003;&#x672C;&#x7BC7;&#x5C07;&#x6703;&#x4ECB;&#x7D39;Button&#x3001;Select Menu&#x9019;&#x5169;&#x7A2E;Component&#x3001;&#x5982;&#x4F55;&#x4F7F;&#x7528;Action Row&#x5C07;Component&#x52A0;&#x5165;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x56DE;&#x61C9;&#x4E2D;&#xFF0C;&#x4E26;&#x4E14;&#x5728;&#x4F7F;&#x7528;&#x8005;&#x4E92;&#x52D5;&#x6642;&#x6A5F;&#x5668;&#x4EBA;&#x80FD;&#x5920;&#x63A5;&#x6536;&#x4E26;&#x56DE;&#x61C9;&#x3002;</p>
<h1 id="1-%E5%9C%A8%E9%80%99%E4%B9%8B%E5%89%8D%EF%BC%8C%E4%BB%80%E9%BA%BC%E6%98%AFcomponent%EF%BC%9F">1. &#x5728;&#x9019;&#x4E4B;&#x524D;&#xFF0C;&#x4EC0;&#x9EBC;&#x662F;Component&#xFF1F;</h1>
<p>&#x2003;&#x2003;<code>MessageComponent</code>&#xFF0C;&#x6216;&#x7C21;&#x7A31;&#x70BA;<code>Component</code>&#xFF0C;&#x662F;&#x4E00;&#x7CFB;&#x5217;&#x53EF;&#x4EE5;&#x5728;&#x6A5F;&#x5668;&#x4EBA;&#x50B3;&#x9001;&#x7684;&#x8A0A;&#x606F;&#x4E2D;&#x52A0;&#x5165;&#x7684;&#x53EF;&#x4E92;&#x52D5;&#x7269;&#x4EF6;&#xFF0C;&#x4F8B;&#x5982;&#x5728;&#x8A0A;&#x606F;&#x4E0B;&#x65B9;&#x986F;&#x793A;&#x53EF;&#x4EE5;&#x6309;&#x7684;&#x6309;&#x9215;&#xFF0C;&#x6216;&#x662F;&#x53EF;&#x4EE5;&#x9078;&#x64C7;&#x7684;&#x9078;&#x55AE;&#xFF0C;&#x751A;&#x81F3;&#x662F;&#x8868;&#x55AE;&#x7684;&#x8F38;&#x5165;&#x6846;&#xFF08;&#x9019;&#x90E8;&#x5206;&#x6703;&#x5728;&#x4EE5;&#x5F8C;&#x7684;&#x7AE0;&#x7BC0;&#x63D0;&#x5230;&#xFF09;&#x3002;</p>
<p>&#x2003;&#x2003;&#x5728;&#x4F7F;&#x7528;&#x6309;&#x9215;&#x3001;&#x9078;&#x55AE;&#x7B49;Components&#x6642;&#xFF0C;&#x6703;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x5230;&#x4E00;&#x7A2E;&#x7279;&#x5225;&#x7684;Component&#xFF1A;<code>Action Row</code>&#x3002;&#x6240;&#x6709;&#x5176;&#x4ED6;&#x7684;Components&#x90FD;&#x9700;&#x8981;&#x88AB;&#x88DD;&#x9032;<code>Action Row</code>&#x9019;&#x7A2E;&#x4F5C;&#x70BA;&#x5BB9;&#x5668;&#x7684;Component&#x5167;&#xFF0C;&#x6700;&#x5F8C;&#x5C07;&#x5B83;&#x5011;&#x585E;&#x9032;&#x8A0A;&#x606F;&#x7684;components&#x5167;&#x9001;&#x51FA;&#x3002;&#x9019;&#x90E8;&#x5206;&#x6703;&#x5728;&#x5F8C;&#x9762;&#x63D0;&#x5230;&#x3002;</p>
<h1 id="2-button">2. Button</h1>
<p>&#x2003;&#x2003;&#x5C31;&#x50CF;<code>SlashCommandBuilder ()</code>&#x4E00;&#x6A23;&#xFF0C;Discord.js&#x70BA;&#x5EFA;&#x7ACB;Components&#x63D0;&#x4F9B;&#x4E86;&#x5404;&#x81EA;&#x7684;Builder&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x3002;&#x8981;&#x5EFA;&#x7ACB;&#x4E00;&#x500B;Button&#xFF0C;&#x7576;&#x7136;&#x5C31;&#x6709;<code>ButtonBuilder ()</code>&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x56C9;&#x3002;&#x4EE5;&#x4E0B;&#x662F;&#x4E00;&#x500B;<code>ButtonBuilder ()</code>&#x7684;&#x7BC4;&#x4F8B;&#xFF1A;</p>
<pre><code class="language-javascript">const button = new ButtonBuilder()
    .setCustomId(&apos;submit&apos;)
    .setLabel(&apos;Click&apos;)
    .setStyle(ButtonStyle.Primary);
</code></pre>
<p>&#x2003;&#x2003;&#x6BCF;&#x4E00;&#x500B;Component&#x90FD;&#x9700;&#x8981;&#x4E00;&#x500B;CustomId&#xFF0C;&#x7576;&#x8207;Component&#x4E92;&#x52D5;&#x89F8;&#x767C;InteractionCreate&#x4E8B;&#x4EF6;&#x6642;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;CustomId&#x4F5C;&#x70BA;&#x5224;&#x65B7;&#x3002;&#x6B64;&#x5916;&#xFF0C;&#x53EF;&#x4EE5;&#x70BA;Button&#x8A2D;&#x5B9A;&#x4E94;&#x7A2E;&#x6A23;&#x5F0F;&#xFF0C;&#x5206;&#x5225;&#x662F;&#xFF1A;</p>
<ul>
<li>Primary&#xFF1A;&#x6700;&#x5E38;&#x898B;&#x7684;&#x85CD;&#x8272;&#x6309;&#x9215;&#x3002;</li>
<li>Secondary&#xFF1A;&#x7070;&#x8272;&#x6309;&#x9215;&#x3002;</li>
<li>Success&#xFF1A;&#x7DA0;&#x8272;&#x6309;&#x9215;&#x3002;</li>
<li>Danger&#xFF1A;&#x7D05;&#x8272;&#x6309;&#x9215;&#x3002;</li>
<li>Link&#xFF1A;&#x4E00;&#x6A23;&#x662F;&#x7070;&#x8272;&#x6309;&#x9215;&#xFF0C;&#x4E0D;&#x904E;Link&#x7684;&#x7528;&#x6CD5;&#x8F03;&#x70BA;&#x7279;&#x6B8A;&#x3002;</li>
</ul>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.anisile.cc/content/images/2023/09/image.png" class="kg-image" alt loading="lazy" width="529" height="108"><figcaption>Button&#x7684;&#x6A23;&#x5F0F;&#x6709;&#x5206;&#x6210;&#x4E94;&#x7A2E;&#x3002;</figcaption></figure><!--kg-card-begin: markdown--><p>&#x2003;&#x2003;Link&#x9867;&#x540D;&#x601D;&#x7FA9;&#x662F;&#x4F5C;&#x70BA;&#x8D85;&#x9023;&#x7D50;&#x4F7F;&#x7528;&#xFF0C;&#x7576;&#x4F7F;&#x7528;Link&#x6642;&#xFF0C;&#x6703;&#x9700;&#x8981;&#x52A0;&#x4E0A;&#x4E00;&#x500B;url&#xFF0C;&#x4E26;&#x4E14;&#x4E0D;&#x80FD;&#x64C1;&#x6709;CustomId&#xFF0C;&#x56E0;&#x70BA;&#x9EDE;&#x64CA;Link&#x7684;&#x6309;&#x9215;&#x4E0D;&#x6703;&#x89F8;&#x767C;InteractionCreate&#x7684;&#x4E8B;&#x4EF6;&#x3002;&#x4EE5;&#x4E0B;&#x662F;Link&#x6309;&#x9215;&#x7684;&#x7BC4;&#x4F8B;&#xFF1A;</p>
<pre><code class="language-javascript">const button = new ButtonBuilder()
    .setLabel(&apos;discord.js docs&apos;)
    .setURL(&apos;https://discord.js.org&apos;)
    .setStyle(ButtonStyle.Link);
</code></pre>
<h1 id="3-select-menu">3. Select Menu</h1>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#x8981;&#x4ECB;&#x7D39;&#x7684;&#x662F;Select Menu&#xFF0C;&#x5C31;&#x50CF;Button&#x4E00;&#x6A23;&#xFF0C;Select Menu&#x4E5F;&#x6709;&#x985E;&#x4F3C;&#x7684;<code>SelectMenuBuilder ()</code>&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x3002;&#x4EE5;&#x4E0B;&#x662F;&#x4E00;&#x500B;Select Menu&#x7684;&#x7BC4;&#x4F8B;&#xFF0C;&#x6211;&#x5011;&#x4EE5;&#x7BC4;&#x4F8B;&#x4F86;&#x89E3;&#x91CB;&#x7528;&#x6CD5;&#xFF1A;</p>
<pre><code class="language-javascript">const select = new StringSelectMenuBuilder()
    .setCustomId(&apos;starter&apos;)
    .setPlaceholder(&apos;Make a selection!&apos;)
    .addOptions(
        new StringSelectMenuOptionBuilder()
            .setLabel(&apos;Bulbasaur&apos;)
            .setDescription(&apos;The dual-type Grass/Poison Seed Pok&#xE9;mon.&apos;)
            .setValue(&apos;bulbasaur&apos;),
        new StringSelectMenuOptionBuilder()
            .setLabel(&apos;Charmander&apos;)
            .setDescription(&apos;The Fire-type Lizard Pok&#xE9;mon.&apos;)
            .setValue(&apos;charmander&apos;),
        new StringSelectMenuOptionBuilder()
            .setLabel(&apos;Squirtle&apos;)
            .setDescription(&apos;The Water-type Tiny Turtle Pok&#xE9;mon.&apos;)
            .setValue(&apos;squirtle&apos;),
);
</code></pre>
<p>&#x2003;&#x2003;&#x9019;&#x662F;&#x4E00;&#x500B;<code>StringSelectMenuBuilder ()</code>&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x6BCF;&#x4E00;&#x500B;&#x9078;&#x9805;&#x90FD;&#x662F;&#x4E00;&#x500B;&#x55AE;&#x7D14;&#x7684;&#x5B57;&#x4E32;&#x3002;&#x548C;Button&#x4EE5;&#x53CA;&#x5176;&#x4ED6;Component&#x4E00;&#x6A23;&#xFF0C;&#x6211;&#x5011;&#x9700;&#x8981;&#x70BA;Select Menu&#x8A2D;&#x5B9A;&#x4E00;&#x500B;CustomId&#xFF0C;&#x4E26;&#x4E14;&#x6211;&#x5011;&#x9084;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>setPlaceholder ()</code>&#x4F86;&#x8A2D;&#x5B9A;&#x4F7F;&#x7528;&#x8005;&#x672A;&#x9078;&#x64C7;&#x9078;&#x9805;&#x6642;&#x986F;&#x793A;&#x7684;&#x6587;&#x5B57;&#x3002;</p>
<p>&#x2003;&#x2003;&#x65E2;&#x7136;&#x662F;Select Menu&#xFF0C;&#x6700;&#x91CD;&#x8981;&#x7684;&#x7576;&#x7136;&#x662F;&#x9078;&#x9805;&#xFF0C;&#x5728;&#x9019;&#x88E1;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>addOptions ()</code>&#x4F86;&#x5C07;&#x9078;&#x9805;&#x52A0;&#x9032;&#x4F86;&#xFF0C;&#x800C;Discord.js&#x4E5F;&#x6709;&#x63D0;&#x4F9B;<code>StringSelectMenuOptionBuilder ()</code>&#x65B9;&#x4FBF;&#x6211;&#x5011;&#x5EFA;&#x7ACB;&#x9078;&#x9805;&#x3002;</p>
<p>&#x2003;&#x2003;&#x5728;&#x6BCF;&#x500B;&#x9078;&#x9805;&#x4E2D;&#xFF0C;&#x90FD;&#x5FC5;&#x9808;&#x8981;&#x7528;<code>setLabel ()</code>&#x8A2D;&#x5B9A;&#x9078;&#x9805;&#x986F;&#x793A;&#x7684;&#x6587;&#x5B57;&#xFF1B;&#x540C;&#x6642;&#x4E5F;&#x5FC5;&#x9808;&#x8981;&#x7528;<code>setValue ()</code>&#x5E6B;&#x9078;&#x9805;&#x8A2D;&#x5B9A;&#x4E00;&#x500B;&#x503C;&#xFF0C;&#x9019;&#x6A23;&#x6A5F;&#x5668;&#x4EBA;&#x624D;&#x80FD;&#x6839;&#x64DA;&#x503C;&#x505A;&#x51FA;&#x76F8;&#x61C9;&#x7684;&#x52D5;&#x4F5C;&#x3002;&#x6700;&#x5F8C;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>setDefault ()</code>&#x5C07;&#x9078;&#x9805;&#x8A2D;&#x70BA;&#x9810;&#x8A2D;&#x9078;&#x9805;&#x3002;</p>
<p>&#x2003;&#x2003;&#x9664;&#x4E86;&#x53EF;&#x81EA;&#x8A02;&#x9078;&#x9805;&#x7684;<code>StringSelectMenuBuilder ()</code>&#x4E4B;&#x5916;&#xFF0C;&#x9084;&#x6709;&#x4EE5;&#x4E0B;&#x5E7E;&#x7A2E;Select Menus&#xFF1A;</p>
<ul>
<li>UserSelectMenuBuilder&#xFF1A;&#x9078;&#x64C7;&#x4F7F;&#x7528;&#x8005;</li>
<li>RoleSelectMenuBuilder&#xFF1A;&#x9078;&#x64C7;&#x8EAB;&#x5206;&#x7D44;</li>
<li>MentionableSelectMenuBuilder&#xFF1A;&#x9078;&#x64C7;&#x4F7F;&#x7528;&#x8005;&#x6216;&#x8EAB;&#x5206;&#x7D44;</li>
<li>ChannelSelectMenuBuilder&#xFF1A;&#x9078;&#x64C7;&#x983B;&#x9053;</li>
</ul>
<p>&#x2003;&#x2003;&#x9019;&#x5E7E;&#x7A2E;Select Menus&#x7531;&#x65BC;&#x4E0D;&#x9700;&#x8981;&#x81EA;&#x5DF1;&#x8A2D;&#x5B9A;&#x9078;&#x9805;&#xFF0C;&#x6240;&#x4EE5;&#x5C11;&#x4E86;<code>addOptions ()</code>&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x3002;&#x53E6;&#x5916;&#xFF0C;<code>ChannelSelectMenuBuilder ()</code>&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>setChannelTypes ()</code>&#x81EA;&#x8A02;&#x60F3;&#x8981;&#x986F;&#x793A;&#x5728;&#x9078;&#x9805;&#x7684;&#x983B;&#x9053;&#x985E;&#x578B;&#x3002;&#x60F3;&#x4E86;&#x89E3;&#x66F4;&#x591A;&#x95DC;&#x65BC;ChannelType&#x7684;&#x985E;&#x578B;&#x53EF;&#x4EE5;<a href="https://discord-api-types.dev/api/discord-api-types-v10/enum/ChannelType?ref=blog.anisile.cc">&#x9EDE;&#x64CA;&#x9019;&#x88E1;</a>&#x3002;</p>
<h1 id="4-%E5%A6%82%E4%BD%95%E9%80%81%E5%87%BAcomponent">4. &#x5982;&#x4F55;&#x9001;&#x51FA;Component</h1>
<p>&#x2003;&#x2003;&#x6211;&#x5011;&#x5DF2;&#x7D93;&#x9806;&#x5229;&#x5EFA;&#x7ACB;Components&#x4E86;&#xFF0C;&#x4F46;&#x9084;&#x53EA;&#x5DEE;&#x4E00;&#x6B65;&#x5C31;&#x80FD;&#x9001;&#x51FA;&#x9019;&#x4E9B;Components&#x3002;&#x524D;&#x9762;&#x6709;&#x63D0;&#x5230;&#xFF0C;&#x6240;&#x6709;&#x5176;&#x4ED6;&#x7684;Components&#x90FD;&#x9700;&#x8981;&#x88AB;&#x88DD;&#x9032;<code>Action Row</code>&#x9019;&#x7A2E;&#x4F5C;&#x70BA;&#x5BB9;&#x5668;&#x7684;Component&#x5167;&#xFF0C;&#x6700;&#x5F8C;&#x5C07;&#x5B83;&#x5011;&#x585E;&#x9032;&#x8A0A;&#x606F;&#x7684;components&#x5167;&#x9001;&#x51FA;&#x3002;&#x6240;&#x4EE5;&#x9996;&#x5148;&#x8981;&#x65B0;&#x589E;&#x4E00;&#x500B;Action Row&#xFF0C;&#x65E2;&#x7136;Action Row&#x4E5F;&#x662F;&#x4E00;&#x7A2E;Component&#xFF0C;&#x5F88;&#x7406;&#x6240;&#x7576;&#x7136;&#x7684;&#x4E5F;&#x6709;&#x5C0D;&#x61C9;&#x7684;<code>ActionRowBuilder ()</code>&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#xFF1A;</p>
<pre><code class="language-javascript">const row = new ActionRowBuilder ()
    .addComponents (button);
</code></pre>
<p>&#x2003;&#x2003;&#x9019;&#x61C9;&#x8A72;&#x662F;&#x5168;&#x90E8;&#x88E1;&#x9762;&#x6700;&#x7C21;&#x55AE;&#x7684;Component&#x4E86;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x5EFA;&#x7ACB;&#x65B0;&#x7684;Action Row&#x4E26;&#x4F7F;&#x7528;<code>addComponents ()</code>&#x5C07;&#x5176;&#x4ED6;Components&#x52A0;&#x9032;&#x4F86;&#x5C31;&#x884C;&#x3002;&#x503C;&#x5F97;&#x6CE8;&#x610F;&#x7684;&#x662F;&#xFF0C;&#x4E00;&#x500B;Action Row&#x5167;&#x53EF;&#x4EE5;&#x653E;&#x5165;&#x591A;&#x500B;Buttons&#xFF0C;&#x4F46;&#x53EA;&#x80FD;&#x653E;&#x5165;&#x4E00;&#x500B;Select Menu&#xFF0C;&#x4E26;&#x4E14;&#x7576;&#x653E;&#x5165;Select Menu&#x4E4B;&#x5F8C;&#x5C31;&#x4E0D;&#x80FD;&#x518D;&#x653E;&#x5165;Button&#x4E86;&#x3002;</p>
<p>&#x2003;&#x2003;&#x800C;&#x6700;&#x5F8C;&#x8981;&#x5C07;Action Row&#x52A0;&#x9032;&#x56DE;&#x61C9;&#x4E5F;&#x5F88;&#x7C21;&#x55AE;&#xFF0C;&#x6211;&#x5011;&#x53EA;&#x9700;&#x8981;&#x9019;&#x9EBC;&#x505A;&#xFF1A;</p>
<pre><code class="language-javascript">interaction.reply({
    content: &quot;&#x4F60;&#x60F3;&#x8981;&#x6A5F;&#x5668;&#x4EBA;&#x56DE;&#x61C9;&#x7684;&#x5167;&#x5BB9;&quot;,
    components: [row],
})
</code></pre>
<p>&#x2003;&#x2003;&#x8ACB;&#x6CE8;&#x610F;<code>components</code>&#x653E;&#x7684;&#x662F;&#x4E00;&#x500B;array&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x8AAA;&#x53EF;&#x4EE5;&#x653E;&#x5165;&#x591A;&#x500B;Action Rows&#xFF0C;&#x7576;&#x6A5F;&#x5668;&#x4EBA;&#x9001;&#x51FA;&#x56DE;&#x61C9;&#x6642;&#x5C31;&#x6703;&#x5F97;&#x5230;&#x591A;&#x884C;&#x7684;Components&#x4E86;&#x3002;</p>
<h1 id="5-%E6%8E%A5%E6%94%B6%E4%BA%92%E5%8B%95%E4%B8%A6%E5%9B%9E%E6%87%89">5. &#x63A5;&#x6536;&#x4E92;&#x52D5;&#x4E26;&#x56DE;&#x61C9;</h1>
<p>&#x2003;&#x2003;&#x5230;&#x76EE;&#x524D;&#x70BA;&#x6B62;&#xFF0C;&#x6211;&#x5011;&#x5DF2;&#x7D93;&#x9806;&#x5229;&#x9001;&#x51FA;Component&#x4E86;&#xFF0C;&#x63A5;&#x4E0B;&#x4F86;&#x5C31;&#x8981;&#x63A5;&#x6536;&#x9019;&#x4E9B;Component&#x7684;&#x89F8;&#x767C;&#x4E8B;&#x4EF6;&#x4E86;&#x3002;&#x9996;&#x5148;&#x8B93;&#x6211;&#x5011;&#x56DE;&#x9867;&#x4E00;&#x4E0B;interactionCreate.js&#xFF1A;</p>
<pre><code class="language-javascript">module.exports = {
    name: &apos;interactionCreate&apos;,
    async execute (interaction) {
        let reaction;
        if (interaction.isChatInputCommand()) {
            reaction = interaction.client.commands.get(interaction.commandName);
        }

        try {
            if (interaction.replied) return
            reaction.execute(interaction);
        }
        catch (error) {
            console.error(error);
        }
    }
}
</code></pre>
<p>&#x2003;&#x2003;&#x5728;&#x9019;&#x88E1;&#xFF0C;&#x6211;&#x5011;&#x6839;&#x64DA;&#x63A5;&#x6536;&#x5230;&#x7684;interaction&#x985E;&#x578B;&#xFF0C;&#x5982;&#x679C;&#x6536;&#x5230;&#x7684;&#x662F;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x5F9E;<code>client.commands</code>&#x5167;&#x627E;&#x5230;&#x6307;&#x4EE4;&#x4E26;&#x57F7;&#x884C;&#x76F8;&#x61C9;&#x7684;&#x52D5;&#x4F5C;&#x3002;&#x800C;Component&#x5176;&#x5BE6;&#x8DDF;&#x6307;&#x4EE4;&#x7684;&#x908F;&#x8F2F;&#x5DEE;&#x4E0D;&#x591A;&#xFF0C;&#x540C;&#x6A23;&#x662F;&#x78BA;&#x8A8D;&#x985E;&#x578B;&#xFF0C;&#x627E;&#x5230;&#x5C0D;&#x61C9;&#x7684;&#x6A94;&#x6848;&#xFF0C;&#x4E26;&#x57F7;&#x884C;&#x76F8;&#x61C9;&#x7684;&#x52D5;&#x4F5C;&#x3002;&#x9996;&#x5148;&#xFF0C;&#x6211;&#x5011;&#x5148;&#x5C07;&#x78BA;&#x8A8D;&#x985E;&#x578B;&#x88DC;&#x4E0A;&#x53BB;&#xFF1A;</p>
<pre><code class="language-javascript">module.exports = {
    name: &apos;interactionCreate&apos;,
    async execute (interaction) {
        let reaction;
        if (interaction.isChatInputCommand()) {
            reaction = interaction.client.commands.get(interaction.commandName);
        }
// ---------------START---------------
        else if (interaction.isButton()) {
            reaction = interaction.client.buttons.get(interaction.customId);
        }
        else if (interaction.isStringSelectMenu()) {
            reaction = interaction.client.selectMenus.get(interaction.customId);
        }
// ----------------END----------------
        try {
            if (interaction.replied) return
            reaction.execute(interaction);
        }
        catch (error) {
            console.error(error);
        }
    }
}
</code></pre>
<p>&#x2003;&#x2003;&#x8DDF;&#x6307;&#x4EE4;&#x4E0D;&#x540C;&#x7684;&#x662F;&#xFF0C;&#x6307;&#x4EE4;&#x662F;&#x5F9E;<code>interaction.commandName</code>&#x53D6;&#x5F97;&#x540D;&#x7A31;&#xFF0C;&#x800C;Component&#x662F;&#x5F9E;<code>interaction.customId</code>&#x53D6;&#x5F97;&#xFF0C;&#x9019;&#x548C;&#x6211;&#x5011;&#x524D;&#x9762;&#x6240;&#x505A;&#x7684;&#x8A2D;&#x5B9A;&#x662F;&#x4E00;&#x81F4;&#x7684;&#x3002;</p>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#xFF0C;&#x6307;&#x4EE4;&#x7684;&#x90E8;&#x5206;&#x662F;&#x5F9E;<code>client.commands</code>&#x5167;&#x53D6;&#x5F97;&#x7684;&#xFF0C;&#x9084;&#x8A18;&#x5F97;&#x6211;&#x5011;&#x524D;&#x9762;&#x6709;&#x9019;&#x500B;&#x6771;&#x897F;&#x55CE;&#xFF1A;</p>
<pre><code class="language-javascript">client.commands = getCommands (&apos;./commands&apos;);
</code></pre>
<p>&#x2003;&#x2003;&#x6211;&#x5011;&#x5728;&#x9019;&#x88E1;&#x53EF;&#x4EE5;&#x7A0D;&#x5FAE;&#x6539;&#x5BEB;&#x4E00;&#x4E0B;<code>getCommands ()</code>&#xFF0C;&#x5BEB;&#x6210;&#x4E00;&#x500B;&#x529F;&#x80FD;&#x5DEE;&#x4E0D;&#x591A;&#x7684;<code>getComponents ()</code>&#x4F86;&#x5E6B;&#x6211;&#x5011;&#x53D6;&#x5F97;&#x9700;&#x8981;&#x7684;&#x6A94;&#x6848;&#xFF08;&#x7576;&#x7136;&#x4F60;&#x4E5F;&#x53EF;&#x4EE5;&#x7528;&#x81EA;&#x5DF1;&#x7684;&#x65B9;&#x6CD5;&#x53D6;&#x5F97;&#xFF0C;&#x9019;&#x88E1;&#x70BA;&#x53C3;&#x8003;&#xFF09;&#xFF1A;</p>
<pre><code class="language-javascript">function getComponents (dir) {
    let components = new Collection();
    const componentFiles = getFiles(dir);

    for (const componentFile of componentFiles) {
        const component = require(&quot;.&quot; + componentFile);
        components.set(component.name, component);
    }
    return components;
}
</code></pre>
<p>&#x2003;&#x2003;&#x6709;&#x4E86;<code>getComponents ()</code>&#x4E4B;&#x5F8C;&#xFF0C;&#x6211;&#x5011;&#x5C31;&#x80FD;&#x6839;&#x64DA;&#x81EA;&#x5DF1;&#x7684;&#x9700;&#x8981;&#x64F4;&#x5145;&#x985E;&#x4F3C;&#x7684;Collection&#xFF0C;&#x4E26;&#x5EFA;&#x7ACB;&#x5B58;&#x653E;&#x9019;&#x4E9B;&#x6A94;&#x6848;&#x7684;&#x8CC7;&#x6599;&#x593E;&#xFF1A;</p>
<pre><code class="language-javascript">client.buttons = getComponents (&apos;./buttons&apos;);
client.selectMenus = getComponents (&apos;./selectMenus&apos;);
</code></pre>
<p>&#x2003;&#x2003;&#x6700;&#x5F8C;&#xFF0C;&#x53EA;&#x8981;&#x65B0;&#x589E;&#x6BCF;&#x500B;Component&#x5C0D;&#x61C9;&#x7684;&#x6A94;&#x6848;&#x5373;&#x53EF;&#x3002;&#x683C;&#x5F0F;&#x8207;&#x65B0;&#x589E;&#x6307;&#x4EE4;&#x975E;&#x5E38;&#x985E;&#x4F3C;&#xFF0C;&#x53EA;&#x4E0D;&#x904E;&#x6211;&#x5011;&#x53EA;&#x9700;&#x8981;<code>execute ()</code>&#x7684;&#x90E8;&#x5206;&#x5C31;&#x597D;&#x3002;&#x6211;&#x5011;&#x4EE5;&#x4E0A;&#x9762;&#x7684;Button&#x70BA;&#x7BC4;&#x4F8B;&#xFF1A;</p>
<pre><code class="language-javascript">module.exports = {
    name: &quot;submit&quot;,
    async execute (interaction) {
        // &#x5728;&#x9019;&#x88E1;&#x5BE6;&#x4F5C;&#x4F60;&#x60F3;&#x8981;&#x6A5F;&#x5668;&#x4EBA;&#x505A;&#x7684;&#x4E8B;&#x60C5;
    }
}
</code></pre>
<h1 id="6-%E6%8E%A5%E4%B8%8B%E4%BE%86%E8%A6%81%E5%81%9A%E7%9A%84%E4%BA%8B%E6%83%85">6. &#x63A5;&#x4E0B;&#x4F86;&#x8981;&#x505A;&#x7684;&#x4E8B;&#x60C5;</h1>
<p>&#x2003;&#x2003;&#x5230;&#x76EE;&#x524D;&#x70BA;&#x6B62;&#xFF0C;&#x6211;&#x5011;&#x4ECB;&#x7D39;&#x4E86;Components&#x4E26;&#x5BE6;&#x969B;&#x5EFA;&#x7ACB;&#x4E86;&#x6309;&#x9215;&#x8207;&#x4E0B;&#x62C9;&#x5F0F;&#x9078;&#x55AE;&#xFF0C;&#x4E4B;&#x5F8C;&#x6211;&#x5011;&#x53EF;&#x80FD;&#x6703;&#x628A;&#x8868;&#x55AE;&#xFF08;Modal&#xFF09;&#x7684;&#x90E8;&#x5206;&#x88DC;&#x5B8C;&#xFF0C;&#x6216;&#x662F;&#x4ECB;&#x7D39;Embeds&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x6CD5;&#xFF08;&#x5427;&#xFF09;&#x3002;</p>
<p>&#x2003;&#x2003;&#x611F;&#x8B1D;&#x4F60;&#x770B;&#x5230;&#x9019;&#x908A;&#xFF0C;&#x6211;&#x5011;&#x4E0B;&#x6B21;&#x898B;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[從零開始的Discord機器人(4) - 改善事件架構]]></title><description><![CDATA[本篇會將改善目前Discord機器人的事件架構，使其更易於擴充與維護。]]></description><link>https://blog.anisile.cc/discord-bot-4/</link><guid isPermaLink="false">6503f696869f86000163d3b0</guid><category><![CDATA[Discord.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[從零開始的Discord機器人]]></category><dc:creator><![CDATA[Anisile]]></dc:creator><pubDate>Fri, 15 Sep 2023 18:51:05 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x2003;&#x2003;&#x5728;&#x4E0A;&#x4E00;&#x7BC7;&#x4E2D;&#xFF0C;&#x6211;&#x5011;&#x6539;&#x5584;&#x4E86;&#x95DC;&#x65BC;&#x6307;&#x4EE4;&#x90E8;&#x5206;&#x7684;&#x67B6;&#x69CB;&#x3002;&#x800C;&#x9019;&#x6B21;&#x6211;&#x5011;&#x8981;&#x63A5;&#x8457;&#x6539;&#x5584;&#x76E3;&#x807D;&#x4E8B;&#x4EF6;&#x7684;&#x5BEB;&#x6CD5;&#xFF0C;&#x8B93;&#x6A5F;&#x5668;&#x4EBA;&#x66F4;&#x5BB9;&#x6613;&#x7DAD;&#x8B77;&#x8207;&#x64F4;&#x5145;&#x3002;</p>
<h1 id="1-%E4%B8%80%E6%A8%A3%E5%BE%9E%E4%BA%8B%E4%BB%B6%E6%9C%AC%E9%AB%94%E9%96%8B%E5%A7%8B">1. &#x4E00;&#x6A23;&#x5F9E;&#x4E8B;&#x4EF6;&#x672C;&#x9AD4;&#x958B;&#x59CB;</h1>
<p>&#x2003;&#x2003;&#x9996;&#x5148;&#xFF0C;&#x6211;&#x5011;&#x4E00;&#x6A23;&#x8981;&#x5148;&#x4F86;&#x8655;&#x7406;&#x4E8B;&#x4EF6;&#x672C;&#x9AD4;&#x7684;&#x90E8;&#x5206;&#x3002;</p>
<p>&#x2003;&#x2003;&#x8DDF;&#x4E0A;&#x4E00;&#x7BC7;&#x4E00;&#x6A23;&#xFF0C;&#x5230;&#x76EE;&#x524D;&#x70BA;&#x6B62;&#x6211;&#x5011;&#x7684;&#x76E3;&#x807D;&#x4E8B;&#x4EF6;&#x4E5F;&#x5168;&#x90FD;&#x5BEB;&#x5728;index.js&#x88E1;&#x3002;&#x6240;&#x4EE5;&#x63A5;&#x4E0B;&#x4F86;&#x6211;&#x5011;&#x8981;&#x505A;&#x7684;&#x4E8B;&#x60C5;&#x662F;&#x628A;&#x4E8B;&#x4EF6;&#x90FD;&#x62C6;&#x5206;&#x6210;&#x5404;&#x81EA;&#x7684;&#x6A94;&#x6848;&#x3002;</p>
<p>&#x2003;&#x2003;&#x65B0;&#x589E;&#x4E00;&#x500B;events&#x8CC7;&#x6599;&#x593E;&#xFF0C;&#x9019;&#x500B;&#x8CC7;&#x6599;&#x593E;&#x6703;&#x7528;&#x4F86;&#x5B58;&#x653E;&#x6240;&#x6709;&#x4E8B;&#x4EF6;&#x7684;&#x6A94;&#x6848;&#x3002;&#x76EE;&#x524D;&#x6211;&#x5011;&#x6709;ClientReady&#x8207;InteractionCreate&#x5169;&#x7A2E;&#x4E8B;&#x4EF6;&#xFF0C;&#x56E0;&#x6B64;&#x6211;&#x5011;&#x5728;events&#x5167;&#x65B0;&#x589E;ready.js&#x8207;interactionCreate.js&#x5169;&#x500B;&#x6A94;&#x6848;&#x3002;</p>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#x4EE5;ready.js&#x70BA;&#x4F8B;&#xFF0C;&#x6211;&#x5011;&#x4E00;&#x6A23;&#x4F7F;&#x7528;module.exports&#x4F86;&#x532F;&#x51FA;&#x6240;&#x6709;&#x9700;&#x8981;&#x7684;&#x6771;&#x897F;&#xFF0C;&#x53EA;&#x4E0D;&#x904E;&#x5167;&#x5BB9;&#x6703;&#x548C;&#x6307;&#x4EE4;&#x6709;&#x4E00;&#x9EDE;&#x9EDE;&#x4E0D;&#x4E00;&#x6A23;&#xFF0C;&#x5B8C;&#x6574;&#x7684;&#x6A94;&#x6848;&#x6703;&#x9577;&#x9019;&#x6A23;&#xFF1A;</p>
<pre><code class="language-javascript">module.exports = {
    name: &apos;ready&apos;,
    once: true,
    async execute (client) {
        console.log (`&#x6B61;&#x8FCE;&#x767B;&#x5165; ${client.user.username}`);
    }
}
</code></pre>
<p>&#x2003;&#x2003;&#x76E3;&#x807D;&#x4E8B;&#x4EF6;&#x548C;&#x6307;&#x4EE4;&#x4E00;&#x6A23;&#xFF0C;&#x90FD;&#x662F;&#x5728;execute&#x5167;&#x57F7;&#x884C;&#x76F8;&#x61C9;&#x7684;&#x52D5;&#x4F5C;&#x3002;&#x4F60;&#x53EF;&#x80FD;&#x6CE8;&#x610F;&#x5230;&#x9019;&#x908A;&#x6709;&#x591A;&#x4E00;&#x500B;once&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>client.on ()</code>&#x4F86;&#x8A3B;&#x518A;&#x4E8B;&#x4EF6;&#xFF0C;&#x6216;&#x662F;&#x4F7F;&#x7528;<code>client.once ()</code>&#x4F86;&#x8A3B;&#x518A;&#x6700;&#x591A;&#x53EA;&#x6703;&#x89F8;&#x767C;&#x4E00;&#x6B21;&#x7684;&#x4E8B;&#x4EF6;&#xFF0C;ClientReady&#x5C31;&#x662F;&#x5C6C;&#x65BC;&#x9019;&#x7A2E;&#x4E8B;&#x4EF6;&#xFF0C;&#x6240;&#x4EE5;&#x9019;&#x88E1;&#x4F7F;&#x7528;once&#x3002;</p>
<p>&#x2003;&#x2003;&#x6839;&#x64DA;&#x9019;&#x500B;&#x683C;&#x5F0F;&#xFF0C;&#x63A5;&#x4E0B;&#x4F86;&#x6211;&#x5011;&#x4F86;&#x5B8C;&#x6210;interactionCreate.js&#xFF1A;</p>
<pre><code class="language-javascript">module.exports = {
    name: &apos;interactionCreate&apos;,
    async execute (interaction) {
        let reaction;
        if (interaction.isChatInputCommand()) {
            reaction = interaction.client.commands.get(interaction.commandName);
        }

        try {
            if (interaction.replied) return
            reaction.execute(interaction);
        }
        catch (error) {
            console.error(error);
        }
    }
}
</code></pre>
<h1 id="2-%E5%8F%AA%E5%89%A9%E8%A8%BB%E5%86%8A%E4%BA%8B%E4%BB%B6%E4%BA%86">2. &#x53EA;&#x5269;&#x8A3B;&#x518A;&#x4E8B;&#x4EF6;&#x4E86;</h1>
<p>&#x2003;&#x2003;&#x524D;&#x9762;&#x6211;&#x5011;&#x5DF2;&#x7D93;&#x628A;&#x4E8B;&#x4EF6;&#x90FD;&#x62C6;&#x958B;&#x4F86;&#x4E86;&#xFF0C;&#x63A5;&#x4E0B;&#x4F86;&#x4E5F;&#x548C;&#x6307;&#x4EE4;&#x4E00;&#x6A23;&#xFF0C;&#x8981;&#x53D6;&#x5F97;events&#x8CC7;&#x6599;&#x593E;&#x5167;&#x7684;&#x6240;&#x6709;&#x4E8B;&#x4EF6;&#x4E26;&#x4E00;&#x4E00;&#x8A3B;&#x518A;&#x3002;&#x4E8B;&#x4EF6;&#x76F8;&#x6BD4;&#x6307;&#x4EE4;&#x55AE;&#x7D14;&#x8A31;&#x591A;&#xFF0C;&#x6240;&#x4EE5;&#x9019;&#x908A;&#x5C31;&#x4E0D;&#x53E6;&#x5916;&#x4F7F;&#x7528;function&#x8655;&#x7406;&#x4E86;&#x3002;&#x8A3B;&#x518A;&#x4E8B;&#x4EF6;&#x7684;&#x90E8;&#x5206;&#x6703;&#x9577;&#x9019;&#x6A23;&#xFF1A;</p>
<pre><code class="language-javascript">const eventsPath = path.join (__dirname, &apos;events&apos;);
const eventFiles = fs.readdirSync (eventsPath).filter (file =&gt; file.endsWith (&apos;.js&apos;));

for (const file of eventFiles) {
    const filePath = path.join (eventsPath, file);
    const event = require (filePath);
    if (event.once) {
        client.once (event.name, (...args) =&gt; event.execute (...args));
    }
    else {
        client.on (event.name, (...args) =&gt; event.execute (...args));
    }
}
</code></pre>
<p>&#x2003;&#x2003;&#x5230;&#x9019;&#x88E1;&#xFF0C;&#x6211;&#x5011;&#x7684;&#x6539;&#x5584;&#x5DE5;&#x4F5C;&#x5DF2;&#x7D93;&#x5B8C;&#x6210;&#xFF0C;&#x4E4B;&#x5F8C;&#x5982;&#x679C;&#x60F3;&#x8981;&#x589E;&#x52A0;&#x76E3;&#x807D;&#x7684;&#x4E8B;&#x4EF6;&#xFF0C;&#x53EA;&#x8981;&#x5728;events&#x8CC7;&#x6599;&#x593E;&#x5167;&#x6309;&#x7167;&#x4E0A;&#x9762;&#x7684;&#x683C;&#x5F0F;&#x65B0;&#x589E;&#x6A94;&#x6848;&#x5373;&#x53EF;&#x3002;&#x4F60;&#x53EF;&#x4EE5;&#x958B;&#x59CB;&#x904B;&#x884C;&#x4F60;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#x4E86;&#x3002;</p>
<h1 id="3-%E6%8E%A5%E4%B8%8B%E4%BE%86%E8%A6%81%E5%81%9A%E7%9A%84%E4%BA%8B%E6%83%85">3. &#x63A5;&#x4E0B;&#x4F86;&#x8981;&#x505A;&#x7684;&#x4E8B;&#x60C5;</h1>
<p>&#x2003;&#x2003;&#x672C;&#x7CFB;&#x5217;&#x6709;&#x95DC;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x57FA;&#x790E;&#x67B6;&#x69CB;&#x5DF2;&#x7D93;&#x5B8C;&#x6210;&#xFF0C;&#x5230;&#x73FE;&#x5728;&#x5DF2;&#x7D93;&#x53EF;&#x4EE5;&#x5BEB;&#x51FA;&#x4E00;&#x96BB;&#x5B8C;&#x6574;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#x4E86;&#x3002;&#x6240;&#x4EE5;&#x5F8C;&#x7E8C;&#x7684;&#x5167;&#x5BB9;&#x6703;&#x504F;&#x5411;&#x4ECB;&#x7D39;&#x5176;&#x4ED6;&#x53EF;&#x4EE5;&#x73A9;&#x7684;&#x529F;&#x80FD;&#xFF0C;&#x4F8B;&#x5982;&#x6309;&#x9215;&#x3001;&#x8868;&#x55AE;&#x3001;&#x4E0B;&#x62C9;&#x5F0F;&#x9078;&#x55AE;&#x7B49;Components&#xFF0C;&#x6216;&#x662F;&#x80FD;&#x5920;&#x8B93;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x56DE;&#x61C9;&#x66F4;&#x52A0;&#x7F8E;&#x89C0;&#x7684;Embeds&#x7B49;&#x3002;</p>
<p>&#x2003;&#x2003;&#x611F;&#x8B1D;&#x4F60;&#x770B;&#x5230;&#x9019;&#x908A;&#xFF0C;&#x6211;&#x5011;&#x4E0B;&#x6B21;&#x898B;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[從零開始的Discord機器人(3) - 改善指令架構]]></title><description><![CDATA[本篇會將改善目前Discord機器人的指令架構，使其更易於擴充與維護。]]></description><link>https://blog.anisile.cc/discord-bot-3/</link><guid isPermaLink="false">6502c9de869f86000163d04e</guid><category><![CDATA[Discord.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[從零開始的Discord機器人]]></category><dc:creator><![CDATA[Anisile]]></dc:creator><pubDate>Fri, 15 Sep 2023 06:09:54 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x2003;&#x2003;&#x5728;&#x4E0A;&#x4E00;&#x7BC7;&#x4E2D;&#xFF0C;&#x6211;&#x5011;&#x5E6B;&#x6A5F;&#x5668;&#x4EBA;&#x52A0;&#x4E0A;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x76EE;&#x524D;&#x6A5F;&#x5668;&#x4EBA;&#x5DF2;&#x7D93;&#x5177;&#x6709;&#x63A5;&#x6536;&#x6307;&#x4EE4;&#x8207;&#x56DE;&#x8986;&#x7684;&#x80FD;&#x529B;&#x4E86;&#x3002;&#x4F46;&#x6211;&#x76F8;&#x4FE1;&#x4F60;&#x4E00;&#x5B9A;&#x4E0D;&#x6EFF;&#x8DB3;&#x65BC;&#x73FE;&#x72C0;&#xFF0C;&#x6253;&#x7B97;&#x5E6B;&#x6A5F;&#x5668;&#x4EBA;&#x52A0;&#x4E0A;&#x66F4;&#x591A;&#x6307;&#x4EE4;&#x3002;</p>
<p>&#x2003;&#x2003;&#x7136;&#x800C;&#x5F88;&#x5FEB;&#x5730;&#x4F60;&#x767C;&#x73FE;&#x4E86;&#x554F;&#x984C;&#xFF1A;&#x4E00;&#x958B;&#x59CB;&#x52A0;&#x4E0A;&#x4E00;&#x5169;&#x500B;&#x6307;&#x4EE4;&#xFF0C;&#x597D;&#x50CF;&#x6C92;&#x9047;&#x5230;&#x4EC0;&#x9EBC;&#x554F;&#x984C;&#xFF0C;&#x4F46;&#x96A8;&#x8457;&#x6307;&#x4EE4;&#x8D8A;&#x52A0;&#x8D8A;&#x591A;&#xFF0C;&#x6F38;&#x6F38;&#x5730;&#x6574;&#x500B;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x7A0B;&#x5F0F;&#x78BC;&#x8B8A;&#x5F97;&#x53C8;&#x81ED;&#x53C8;&#x9577;&#xFF0C;&#x4E0D;&#x50C5;&#x4E0D;&#x5229;&#x65BC;&#x7DAD;&#x8B77;&#xFF0C;&#x540C;&#x6642;&#x4E5F;&#x96E3;&#x4EE5;&#x64F4;&#x5145;&#x3002;&#x56E0;&#x6B64;&#x5728;&#x672C;&#x6587;&#x4E2D;&#xFF0C;&#x6211;&#x5011;&#x5C07;&#x6703;&#x6539;&#x5584;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x6307;&#x4EE4;&#x67B6;&#x69CB;&#xFF0C;&#x8B93;&#x6A5F;&#x5668;&#x4EBA;&#x672C;&#x9AD4;&#x8207;&#x6307;&#x4EE4;&#x5206;&#x958B;&#xFF0C;&#x4EE5;&#x5229;&#x65BC;&#x64F4;&#x5145;&#x6307;&#x4EE4;&#x3002;</p>
<h1 id="1-%E5%BE%9E%E6%8C%87%E4%BB%A4%E6%9C%AC%E9%AB%94%E9%96%8B%E5%A7%8B">1. &#x5F9E;&#x6307;&#x4EE4;&#x672C;&#x9AD4;&#x958B;&#x59CB;</h1>
<p>&#x2003;&#x2003;&#x9996;&#x5148;&#xFF0C;&#x6211;&#x5011;&#x5148;&#x4F86;&#x8655;&#x7406;&#x6307;&#x4EE4;&#x672C;&#x9AD4;&#x7684;&#x90E8;&#x5206;&#x3002;</p>
<p>&#x2003;&#x2003;&#x5230;&#x76EE;&#x524D;&#x70BA;&#x6B62;&#xFF0C;&#x6211;&#x5011;&#x65B0;&#x589E;&#x6307;&#x4EE4;&#x7684;&#x65B9;&#x5F0F;&#x90FD;&#x662F;&#x5168;&#x90E8;&#x5BEB;&#x5728;index.js&#x88E1;&#x3002;&#x5982;&#x679C;&#x53EA;&#x6709;&#x5C11;&#x5C11;&#x5E7E;&#x500B;&#x6307;&#x4EE4;&#x7684;&#x8A71;&#x9084;&#x884C;&#xFF0C;&#x7576;&#x6307;&#x4EE4;&#x8D8A;&#x4F86;&#x8D8A;&#x591A;&#x6642;&#x4FBF;&#x6703;&#x96E3;&#x4EE5;&#x95B1;&#x8B80;&#x8207;&#x7DAD;&#x8B77;&#x3002;&#x6240;&#x4EE5;&#x63A5;&#x4E0B;&#x4F86;&#x6211;&#x5011;&#x8981;&#x628A;&#x6307;&#x4EE4;&#x90FD;&#x62C6;&#x5206;&#x6210;&#x5404;&#x81EA;&#x7684;&#x6A94;&#x6848;&#x3002;</p>
<p>&#x2003;&#x2003;&#x65B0;&#x589E;&#x4E00;&#x500B;commands&#x8CC7;&#x6599;&#x593E;&#xFF0C;&#x9019;&#x500B;&#x8CC7;&#x6599;&#x593E;&#x6703;&#x7528;&#x4F86;&#x5B58;&#x653E;&#x6240;&#x6709;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x7684;&#x6A94;&#x6848;&#x3002;&#x76EE;&#x524D;&#x6211;&#x5011;&#x6709;ping&#x8207;hello&#x5169;&#x500B;&#x6307;&#x4EE4;&#xFF0C;&#x56E0;&#x6B64;&#x6211;&#x5011;&#x5728;commands&#x5167;&#x65B0;&#x589E;ping.js&#x8207;hello.js&#x5169;&#x500B;&#x6A94;&#x6848;&#x3002;</p>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#x4EE5;ping.js&#x70BA;&#x4F8B;&#xFF0C;&#x6211;&#x5011;&#x8981;&#x4F7F;&#x7528;module.exports&#x4F86;&#x532F;&#x51FA;&#x6240;&#x6709;&#x9700;&#x8981;&#x7684;&#x6771;&#x897F;&#xFF0C;&#x5305;&#x542B;SlashCommandBuilder&#x4EE5;&#x53CA;&#x63A5;&#x6536;interactionCreate&#x7684;&#x4E8B;&#x4EF6;&#x8981;&#x57F7;&#x884C;&#x7684;&#x52D5;&#x4F5C;&#xFF0C;&#x5B8C;&#x6574;&#x7684;&#x6A94;&#x6848;&#x6703;&#x9577;&#x9019;&#x6A23;&#xFF1A;</p>
<pre><code class="language-javascript">const { SlashCommandBuilder } = require (&apos;discord.js&apos;)

module.exports = {
    data: new SlashCommandBuilder()
    .setName (&apos;ping&apos;)
    .setDescription(&apos;Replies with &quot;Pong!&quot;&apos;)
    .setDefaultMemberPermissions(&apos;0&apos;),

    async execute (interaction) {
        interaction.reply(&apos;pong!&apos;)
    }
}
</code></pre>
<p>&#x2003;&#x2003;&#x4E4B;&#x5F8C;&#x8981;&#x65B0;&#x589E;&#x6307;&#x4EE4;&#x6642;&#xFF0C;&#x53EA;&#x8981;&#x4F9D;&#x7167;&#x548C;&#x4E0A;&#x9762;SlashCommandBuilder&#x8207;execute&#x7684;&#x7D50;&#x69CB;&#x5C31;&#x53EF;&#x4EE5;&#x8F15;&#x6613;&#x64F4;&#x5145;&#x4E86;&#x3002;&#x8B93;&#x6211;&#x5011;&#x4E5F;&#x5B8C;&#x6210;hello.js&#x7684;&#x90E8;&#x5206;&#x5427;&#xFF1A;</p>
<pre><code class="language-javascript">const { SlashCommandBuilder } = require (&apos;discord.js&apos;)

module.exports = {
    data: new SlashCommandBuilder()
    .setName (&apos;hello&apos;)
    .setDescription(&apos;Say hello to someone&quot;&apos;)
    .setDefaultMemberPermissions(&apos;0&apos;)
    .addUserOption(option =&gt;
        option
            .setName(&apos;user&apos;)
            .setDescription(&apos;The user to say hi to&apos;)
            .setRequired(false)
    ),

    async execute (interaction) {
        let user = interaction.options.getUser(&apos;user&apos;)
        interaction.reply(`Hello &lt;@${user.id}&gt;!`)
    }
}
</code></pre>
<h1 id="2-%E8%A8%BB%E5%86%8A%E6%8C%87%E4%BB%A4%E4%B9%9F%E8%A6%81%E8%81%B0%E6%98%8E%E4%B8%80%E9%BB%9E">2. &#x8A3B;&#x518A;&#x6307;&#x4EE4;&#x4E5F;&#x8981;&#x8070;&#x660E;&#x4E00;&#x9EDE;</h1>
<p>&#x2003;&#x2003;&#x9664;&#x4E86;&#x6307;&#x4EE4;&#x4E4B;&#x5916;&#xFF0C;&#x6211;&#x5011;&#x6BCF;&#x65B0;&#x589E;&#x4E00;&#x500B;&#x6307;&#x4EE4;&#x6642;&#xFF0C;&#x90FD;&#x6703;&#x4F7F;&#x7528;<code>client.application.commands.create</code>&#x4F86;&#x8A3B;&#x518A;&#x6307;&#x4EE4;&#xFF0C;&#x4F46;&#x96A8;&#x8457;&#x5F8C;&#x7E8C;&#x6307;&#x4EE4;&#x7684;&#x589E;&#x52A0;&#xFF0C;&#x6BCF;&#x6B21;&#x65B0;&#x589E;&#x6307;&#x4EE4;&#x90FD;&#x8981;&#x52A0;&#x4E0A;&#x4E00;&#x689D;&#x8A3B;&#x518A;&#x6307;&#x4EE4;&#x986F;&#x7136;&#x4E0D;&#x662F;&#x4E00;&#x500B;&#x597D;&#x505A;&#x6CD5;&#x3002;</p>
<p>&#x2003;&#x2003;&#x6211;&#x5011;&#x5148;&#x4F86;&#x505A;&#x4E00;&#x9EDE;&#x4E8B;&#x524D;&#x6E96;&#x5099;&#x3002;&#x7531;&#x65BC;&#x9019;&#x6B21;&#x7684;&#x76EE;&#x6A19;&#x662F;&#x4F7F;&#x7528;&#x5728;&#x55AE;&#x4E00;&#x4F3A;&#x670D;&#x5668;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#xFF0C;&#x56E0;&#x6B64;&#x6211;&#x5011;&#x76F4;&#x63A5;&#x628A;&#x4F3A;&#x670D;&#x5668;&#x7684;&#x983B;&#x9053;ID&#x5BEB;&#x5728;config.js&#x5167;&#x3002;&#x53E6;&#x5916;&#xFF0C;&#x6211;&#x5011;&#x9084;&#x9700;&#x8981;&#x5230;<a href="https://discord.com/developers/applications?ref=blog.anisile.cc">Discord Developer Portal</a>&#x8907;&#x88FD;&#x6A5F;&#x5668;&#x4EBA;&#x7684;General Information&#x5167;&#x7684;Application ID&#xFF0C;&#x9019;&#x5169;&#x500B;&#x503C;&#x90FD;&#x662F;&#x6211;&#x5011;&#x4E4B;&#x5F8C;&#x6703;&#x7528;&#x5230;&#x7684;&#x3002;&#x73FE;&#x5728;&#x7684;config.js&#x61C9;&#x8A72;&#x6703;&#x9577;&#x9019;&#x6A23;&#xFF1A;</p>
<pre><code class="language-json">{
    &quot;token&quot;: &quot;&#x586B;&#x5165;&#x6A5F;&#x5668;&#x4EBA;&#x7684;Token&quot;,
    &quot;guildId&quot;: &quot;&#x586B;&#x5165;&#x4F3A;&#x670D;&#x5668;&#x7684;ID&quot;,
    &quot;applicationId&quot;: &quot;&#x586B;&#x5165;&#x525B;&#x525B;&#x53D6;&#x5F97;&#x7684;Application ID&quot;,
}
</code></pre>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#xFF0C;&#x8B93;&#x6211;&#x5011;&#x65B0;&#x589E;&#x4E00;&#x500B;&#x6A94;&#x6848;deploy-commands.js&#xFF0C;&#x9996;&#x5148;&#x662F;require&#xFF1A;</p>
<pre><code class="language-javascript">const fs = require(&apos;node:fs&apos;)
const path = require(&apos;node:path&apos;)
const { REST } = require(&quot;@discordjs/rest&quot;)
const { Routes } = require(&quot;discord.js&quot;)
const {token, applicationId, guildId} = require(&apos;./config.json&apos;)
</code></pre>
<p>&#x2003;&#x2003;&#x518D;&#x4F86;&#xFF0C;&#x6211;&#x5011;&#x8981;&#x65B0;&#x589E;&#x4E00;&#x500B;function&#x4F86;&#x5E6B;&#x52A9;&#x6211;&#x5011;&#x53D6;&#x5F97;&#x6A94;&#x6848;&#xFF1A;</p>
<pre><code class="language-javascript">function getFiles (dir) {
    const files = fs.readdirSync (dir, {
        withFileTypes: true
    })
    let commandFiles = [];

    for (const file of files) {
        if (file.isDirectory()) {
            commandFiles = [
                ...commandFiles,
                ...getFiles(`${dir}/${file.name}`)
            ]
        }
        else if (file.name.endsWith(&quot;.js&quot;)) {
            commandFiles.push (`${dir}/${file.name}`)
        }
    }
    return commandFiles
}
</code></pre>
<p>&#x2003;&#x2003;&#x9019;&#x500B;getFiles&#x7684;&#x529F;&#x80FD;&#x662F;&#xFF0C;&#x6307;&#x5B9A;&#x4E00;&#x500B;&#x8CC7;&#x6599;&#x593E;&#x8DEF;&#x5F91;&#xFF0C;function&#x6703;&#x5E6B;&#x6211;&#x5011;&#x628A;&#x6307;&#x5B9A;&#x8DEF;&#x5F91;&#x5167;&#x6240;&#x6709;&#x7684;JS&#x6A94;&#x90FD;&#x627E;&#x51FA;&#x4F86;&#xFF08;&#x5305;&#x542B;&#x6240;&#x6709;&#x5B50;&#x76EE;&#x9304;&#xFF09;&#x3002;&#x6211;&#x5011;&#x63A5;&#x4E0B;&#x4F86;&#x8981;&#x505A;&#x7684;&#x4E8B;&#x60C5;&#x662F;&#xFF0C;&#x7528;getFiles&#x4F86;&#x53D6;&#x5F97;commands&#x8CC7;&#x6599;&#x593E;&#x5167;&#x7684;&#x6240;&#x6709;&#x6307;&#x4EE4;&#x4E26;&#x4E00;&#x4E00;&#x8A3B;&#x518A;&#x3002;&#x9996;&#x5148;&#x662F;&#x53D6;&#x5F97;&#x6307;&#x4EE4;&#x7684;&#x8CC7;&#x6599;&#xFF1A;</p>
<pre><code class="language-javascript">let commands = [];
const commandFiles = getFiles (&apos;./commands&apos;);

for (const file of commandFiles) {
    const command = require (file);
    commands.push (command.data.toJSON ());
}
</code></pre>
<p>&#x2003;&#x2003;&#x6709;&#x4E86;&#x6307;&#x4EE4;&#x7684;&#x8CC7;&#x6599;&#xFF0C;&#x6211;&#x5011;&#x5C31;&#x53EF;&#x4EE5;&#x958B;&#x59CB;&#x8A3B;&#x518A;&#x6307;&#x4EE4;&#x4E86;&#xFF1A;</p>
<pre><code class="language-javascript">const rest = new REST ({version: &apos;10&apos;}).setToken (token)

rest.put (Routes.applicationGuildCommands (applicationId, guildId), { body: commands })
    .then (() =&gt; console.log (&apos;Successfully registered application commands!&apos;))
    .catch (console.error)
</code></pre>
<p>&#x2003;&#x2003;&#x5982;&#x679C;&#x4F60;&#x60F3;&#x8981;&#x8B93;&#x6240;&#x6709;&#x4F3A;&#x670D;&#x5668;&#x90FD;&#x80FD;&#x4F7F;&#x7528;&#x6307;&#x4EE4;&#xFF0C;&#x53EA;&#x8981;&#x5C07;<code>Routes.applicationGuildCommands</code>&#x6539;&#x6210;<code>Routes.applicationCommands</code>&#xFF0C;&#x5982;&#x6B64;&#x4E00;&#x4F86;&#x5C31;&#x4E0D;&#x9700;&#x8981;&#x7528;&#x5230;guildId&#x3002;&#x4E4B;&#x5F8C;&#x7576;&#x6211;&#x5011;&#x65B0;&#x589E;&#x6307;&#x4EE4;&#x4E4B;&#x5F8C;&#xFF0C;&#x53EA;&#x8981;&#x57F7;&#x884C;&#x4E00;&#x6B21;<code>node deploy-commands.js</code>&#xFF0C;&#x5C31;&#x80FD;&#x4E00;&#x6B21;&#x8A3B;&#x518A;&#x6240;&#x6709;&#x6307;&#x4EE4;&#x4E86;&#x3002;</p>
<h1 id="3-%E5%9F%B7%E8%A1%8C%E7%9A%84%E9%83%A8%E5%88%86%E4%B9%9F%E8%A6%81%E6%94%B9%E5%AF%AB">3. &#x57F7;&#x884C;&#x7684;&#x90E8;&#x5206;&#x4E5F;&#x8981;&#x6539;&#x5BEB;</h1>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#xFF0C;&#x6211;&#x5011;&#x4E5F;&#x4F86;&#x6539;&#x5BEB;&#x4E00;&#x4E0B;InteractionCreate&#x7684;&#x90E8;&#x5206;&#xFF0C;&#x76EE;&#x524D;&#x61C9;&#x8A72;&#x662F;&#x9577;&#x9019;&#x6A23;&#xFF1A;</p>
<pre><code class="language-javascript">client.on(Events.InteractionCreate, interaction =&gt; {
    if (!interaction.isChatInputCommand ()) return;
    if (interaction.commandName === &quot;ping&quot;) {
        interaction.reply (&quot;Pong!&quot;);
    }
    if (interaction.commandName === &quot;hello&quot;) {
        const user = interaction.options.getUser (&apos;user&apos;);
        interaction.reply (`Hello &lt;@${user.id}&gt;`);
    }
});
</code></pre>
<p>&#x2003;&#x2003;&#x5728;&#x9019;&#x88E1;&#xFF0C;&#x6211;&#x5011;&#x6703;&#x6839;&#x64DA;interaction&#x7684;commandName&#x4F86;&#x505A;&#x76F8;&#x5C0D;&#x61C9;&#x7684;&#x52D5;&#x4F5C;&#xFF0C;&#x4F46;&#x56E0;&#x70BA;&#x6211;&#x5011;&#x5728;&#x4E0A;&#x9762;&#x5DF2;&#x7D93;&#x628A;&#x6BCF;&#x500B;&#x6307;&#x4EE4;&#x8981;&#x57F7;&#x884C;&#x7684;&#x52D5;&#x4F5C;&#x90FD;&#x653E;&#x5728;&#x5404;&#x81EA;&#x7684;execute&#x88E1;&#x9762;&#x4E86;&#xFF0C;&#x6240;&#x4EE5;&#x6211;&#x5011;&#x53EF;&#x4EE5;&#x6539;&#x5BEB;&#x6210;&#x6839;&#x64DA;commandName&#x627E;&#x5230;&#x76F8;&#x5C0D;&#x61C9;&#x7684;&#x6307;&#x4EE4;&#x4E26;&#x547C;&#x53EB;execute&#x3002;&#x5728;&#x9019;&#x88E1;&#x6211;&#x5011;&#x8981;&#x4F7F;&#x7528;Discord.js&#x5167;&#x7684;<code>Collection</code>&#x5BE6;&#x73FE;&#x9019;&#x4E00;&#x529F;&#x80FD;&#x3002;</p>
<p>&#x2003;&#x2003;Collection&#x5176;&#x5BE6;&#x5C31;&#x662F;JavaScript&#x5167;&#x5EFA;&#x7684;Map&#x7269;&#x4EF6;&#x7684;&#x64F4;&#x5145;&#x3002;&#x7C21;&#x77ED;&#x8AAA;&#x660E;&#x4E00;&#x4E0B;&#xFF0C;Map&#x662F;&#x4E00;&#x7A2E;&#x9375;&#x503C;&#x5C0D;&#xFF08;key-value pairs&#xFF09;&#x7684;&#x7269;&#x4EF6;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;Map&#x5167;&#x6BCF;&#x4E00;&#x500B;key&#x90FD;&#x6709;&#x5176;&#x5C0D;&#x61C9;&#x7684;value&#x3002;&#x6240;&#x4EE5;&#x6211;&#x5011;&#x53EF;&#x4EE5;&#x5229;&#x7528;Collection&#xFF08;&#x6216;&#x8005;&#x8AAA;Map&#xFF09;&#x9019;&#x7A2E;&#x7279;&#x6027;&#xFF0C;&#x7576;&#x6211;&#x5011;&#x4EE5;commandName&#x70BA;key&#x6642;&#xFF0C;&#x5C31;&#x80FD;&#x5F97;&#x5230;&#x76F8;&#x5C0D;&#x61C9;&#x7684;&#x6307;&#x4EE4;&#x4E86;&#x3002;</p>
<p>&#x2003;&#x2003;&#x9996;&#x5148;&#x6211;&#x5011;&#x5148;&#x4F86;&#x5EFA;&#x7ACB;&#x4E00;&#x500B;&#x53EF;&#x4EE5;&#x751F;&#x6210;&#x6211;&#x5011;&#x9700;&#x8981;&#x7684;Collection&#x7684;function&#x5427;&#xFF1A;</p>
<pre><code class="language-javascript">function getCommands (dir) {
    let commands = new Collection ();
    const commandFiles = getFiles (dir);
    
    for (const commandFile of commandFiles) {
        const command = require (commandFile);
        commands.set (command.data.toJSON ().name, command);
    }
    return commands;
}
</code></pre>
<p>&#x2003;&#x2003;&#x5728;&#x9019;&#x88E1;&#x4E5F;&#x6709;&#x4F7F;&#x7528;&#x5230;getFiles&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x5C07;getFiles&#x8207;getCommands&#x90FD;&#x6574;&#x7406;&#x5230;&#x4E00;&#x500B;&#x984D;&#x5916;&#x7684;JS&#x6A94;&#x5167;&#xFF0C;&#x4E4B;&#x5F8C;&#x5728;&#x5176;&#x4ED6;JS&#x6A94;&#x5167;&#x53EA;&#x8981;require&#x5C31;&#x80FD;&#x91CD;&#x8907;&#x4F7F;&#x7528;&#xFF0C;&#x4F46;&#x7919;&#x65BC;&#x7BC7;&#x5E45;&#x95DC;&#x4FC2;&#x9019;&#x88E1;&#x5C31;&#x4E0D;&#x7279;&#x5225;&#x6574;&#x7406;&#x4E86;&#x3002;</p>
<p>&#x2003;&#x2003;&#x6709;&#x4E86;getCommands&#x4E4B;&#x5F8C;&#x5C31;&#x80FD;&#x751F;&#x6210;Collection&#x4E86;&#xFF0C;&#x6211;&#x5011;&#x5C07;&#x5B83;&#x653E;&#x5728;<code>client.commands</code>&#x5167;&#xFF1A;</p>
<pre><code>client.commands = getCommands (&apos;./commands&apos;);
</code></pre>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#x662F;&#x6539;&#x5BEB;InteractionCreate&#x7684;&#x90E8;&#x5206;&#xFF0C;&#x9996;&#x5148;&#x6211;&#x5011;&#x6839;&#x64DA;<code>interaction.commandName</code>&#x5F9E;<code>client.commands</code>&#x5167;&#x5F97;&#x5230;&#x76F8;&#x61C9;&#x7684;command&#x4E26;&#x547C;&#x53EB;&#x5176;execute&#x5C31;&#x5B8C;&#x6210;&#x4E86;&#x3002;&#x6539;&#x5BEB;&#x4E4B;&#x5F8C;&#x6703;&#x9577;&#x9019;&#x6A23;&#xFF1A;</p>
<pre><code class="language-javascript">client.on(Events.InteractionCreate, interaction =&gt; {
    let reaction;
    if (interaction.isChatInputCommand()) {
        reaction = client.commands.get(interaction.commandName);
    }

    try {
        if (interaction.replied) return
        reaction.execute(interaction);
    }
    catch (error) {
        console.error(error);
    }
});
</code></pre>
<p>&#x2003;&#x2003;&#x9019;&#x88E1;&#x6709;&#x9806;&#x4FBF;&#x505A;&#x4E00;&#x4E9B;&#x5C0F;&#x8ABF;&#x6574;&#xFF0C;&#x4E4B;&#x524D;&#x7684;&#x5BEB;&#x6CD5;&#x4E2D;&#xFF0C;&#x5982;&#x679C;&#x53D6;&#x5F97;&#x7684;interaction&#x4E0D;&#x662F;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x5C31;&#x6703;&#x76F4;&#x63A5;&#x7D50;&#x675F;&#x3002;&#x8ABF;&#x6574;&#x5F8C;&#xFF0C;&#x5982;&#x679C;&#x662F;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x5C31;&#x6703;&#x53D6;&#x5F97;&#x76F8;&#x61C9;&#x7684;reaction&#x3002;&#x9019;&#x662F;&#x70BA;&#x4E86;&#x5F8C;&#x7E8C;&#x80FD;&#x5920;&#x65B9;&#x4FBF;&#x64F4;&#x5145;&#xFF0C;&#x4E4B;&#x5F8C;&#x4E5F;&#x80FD;&#x6839;&#x64DA;interaction&#x7684;&#x985E;&#x578B;&#x4E0D;&#x540C;&#xFF08;Button&#x3001;Modal&#x7B49;&#xFF09;&#xFF0C;&#x5230;&#x4E0D;&#x540C;&#x7684;Collection&#x5167;&#x53D6;&#x5F97;&#x76F8;&#x61C9;&#x7684;&#x8CC7;&#x6599;&#x4E26;&#x57F7;&#x884C;&#x3002;</p>
<p>&#x2003;&#x2003;&#x6700;&#x5F8C;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x958B;&#x59CB;&#x904B;&#x4F5C;&#x4F60;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#x4E86;&#x3002;</p>
<h1 id="4-%E6%8E%A5%E4%B8%8B%E4%BE%86%E8%A6%81%E5%81%9A%E7%9A%84%E4%BA%8B%E6%83%85">4. &#x63A5;&#x4E0B;&#x4F86;&#x8981;&#x505A;&#x7684;&#x4E8B;&#x60C5;</h1>
<p>&#x2003;&#x2003;&#x5230;&#x76EE;&#x524D;&#x70BA;&#x6B62;&#xFF0C;&#x6211;&#x5011;&#x6539;&#x5584;&#x4E86;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x67B6;&#x69CB;&#xFF0C;&#x5F8C;&#x7E8C;&#x5982;&#x679C;&#x9700;&#x8981;&#x65B0;&#x589E;&#x6216;&#x7BA1;&#x7406;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x90FD;&#x53EA;&#x6703;&#x5728;commands&#x8CC7;&#x6599;&#x593E;&#x7684;&#x7BC4;&#x570D;&#x5167;&#x64CD;&#x4F5C;&#xFF0C;&#x4E0D;&#x6703;&#x5F71;&#x97FF;&#x5230;&#x6A5F;&#x5668;&#x4EBA;&#x672C;&#x9AD4;&#x3002;&#x4F46;&#x63A5;&#x4E0B;&#x4F86;&#x9084;&#x6709;&#x53EF;&#x4EE5;&#x6539;&#x5584;&#x7684;&#x5730;&#x65B9;&#xFF0C;&#x4E5F;&#x8A31;&#x4F60;&#x6709;&#x767C;&#x73FE;&#xFF0C;&#x6A5F;&#x5668;&#x4EBA;&#x53EF;&#x4EE5;&#x76E3;&#x807D;&#x7684;&#x4E8B;&#x4EF6;&#x5176;&#x5BE6;&#x6709;&#x5F88;&#x591A;&#xFF0C;&#x4E26;&#x4E0D;&#x53EA;&#x6709;ClientReady&#x8207;InteractionCreate&#xFF0C;&#x53EA;&#x8981;&#x662F;&#x4F7F;&#x7528;&#x8005;&#x7684;&#x64CD;&#x4F5C;&#x57FA;&#x672C;&#x4E0A;&#x6A5F;&#x5668;&#x4EBA;&#x90FD;&#x80FD;&#x76E3;&#x807D;&#x3002;</p>
<p>&#x2003;&#x2003;&#x56E0;&#x6B64;&#xFF0C;&#x63A5;&#x4E0B;&#x4F86;&#x6211;&#x5011;&#x4E5F;&#x6703;&#x50CF;&#x62C6;&#x5206;&#x6307;&#x4EE4;&#x90A3;&#x6A23;&#xFF0C;&#x5C07;&#x76E3;&#x807D;&#x4E8B;&#x4EF6;&#x5F9E;&#x6A5F;&#x5668;&#x4EBA;&#x672C;&#x9AD4;&#x5206;&#x96E2;&#x3002;&#x5982;&#x6B64;&#x4E00;&#x4F86;&#xFF0C;&#x6574;&#x7406;&#x6A5F;&#x5668;&#x4EBA;&#x67B6;&#x69CB;&#x5C31;&#x7B97;&#x5B8C;&#x6210;&#x4E86;&#x3002;</p>
<p>&#x2003;&#x2003;&#x611F;&#x8B1D;&#x4F60;&#x770B;&#x5230;&#x9019;&#x908A;&#xFF0C;&#x6211;&#x5011;&#x4E0B;&#x6B21;&#x898B;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[從零開始的Discord機器人(2) - 斜線指令]]></title><description><![CDATA[本篇會幫Discord機器人新增斜線指令，並能根據指令做出回應。]]></description><link>https://blog.anisile.cc/discord-bot-2/</link><guid isPermaLink="false">6502a7e5869f86000163d02d</guid><category><![CDATA[Discord.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[從零開始的Discord機器人]]></category><dc:creator><![CDATA[Anisile]]></dc:creator><pubDate>Thu, 14 Sep 2023 06:29:53 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x2003;&#x2003;&#x5728;&#x4E0A;&#x4E00;&#x7BC7;&#x4E2D;&#xFF0C;&#x6211;&#x5011;&#x5DF2;&#x7D93;&#x9806;&#x5229;&#x5EFA;&#x7ACB;&#x597D;&#x74B0;&#x5883;&#x3001;&#x65B0;&#x589E;&#x4E00;&#x500B;&#x6A5F;&#x5668;&#x4EBA;&#x5E33;&#x865F;&#xFF0C;&#x4E26;&#x6210;&#x529F;&#x8B93;&#x5B83;&#x767B;&#x5165;&#x4E86;&#x3002;&#x63A5;&#x4E0B;&#x4F86;&#x6211;&#x5011;&#x8981;&#x5E6B;&#x6A5F;&#x5668;&#x4EBA;&#x52A0;&#x4E0A;&#x91CD;&#x9EDE;&#x7684;&#x529F;&#x80FD;&#x2500;&#x2500;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF08;Slash Commands&#xFF09;&#x3002;</p>
<p>&#x2003;&#x2003;&#x65E9;&#x671F;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#x901A;&#x5E38;&#x662F;&#x63A5;&#x6536;&#x6210;&#x54E1;&#x50B3;&#x9001;&#x7684;&#x8A0A;&#x606F;&#xFF0C;&#x5206;&#x89E3;&#x8A0A;&#x606F;&#x7684;&#x5167;&#x5BB9;&#xFF0C;&#x78BA;&#x8A8D;&#x6210;&#x54E1;&#x8981;&#x57F7;&#x884C;&#x4EC0;&#x9EBC;&#x6307;&#x4EE4;&#x4E26;&#x505A;&#x51FA;&#x76F8;&#x61C9;&#x7684;&#x884C;&#x70BA;&#x3002;&#x4F60;&#x9700;&#x8981;&#x76F4;&#x63A5;&#x9001;&#x51FA;&#x4F8B;&#x5982;<code>/hello @&#x6210;&#x54E1;</code>&#x6216;&#x662F;<code>!join</code>&#x4E4B;&#x985E;&#x7684;&#x8A0A;&#x606F;&#xFF0C;&#x4F46;&#x5982;&#x679C;&#x6C92;&#x6709;&#x770B;&#x904E;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x6587;&#x4EF6;&#x8AAA;&#x660E;&#xFF0C;&#x4F60;&#x6839;&#x672C;&#x7121;&#x5F9E;&#x5F97;&#x77E5;&#x6A5F;&#x5668;&#x4EBA;&#x6709;&#x4EC0;&#x9EBC;&#x6307;&#x4EE4;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x3002;</p>
<p>&#x2003;&#x2003;&#x65BC;&#x662F;Discord&#x5728;2022&#x5E74;9&#x6708;&#x63A8;&#x51FA;&#x4E86;&#x5168;&#x65B0;&#x7684;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x4F5C;&#x70BA;&#x4E92;&#x52D5;&#x7684;&#x65B0;&#x6A19;&#x6E96;&#xFF0C;&#x53EA;&#x8981;&#x8F38;&#x5165;&#x300C;/&#x300D;&#x5C31;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x700F;&#x89BD;&#x80FD;&#x5920;&#x4F7F;&#x7528;&#x7684;&#x6307;&#x4EE4;&#xFF0C;&#x4F7F;&#x7528;&#x8005;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x9EDE;&#x64CA;&#x547D;&#x4EE4;&#x4E26;&#x8F38;&#x5165;&#x53C3;&#x6578;&#x4F86;&#x4F7F;&#x7528;&#xFF0C;&#x76F8;&#x6BD4;&#x50B3;&#x7D71;&#x7684;&#x6587;&#x5B57;&#x6307;&#x4EE4;&#x66F4;&#x52A0;&#x4E00;&#x76EE;&#x4E86;&#x7136;&#x3002;</p>
<p>&#x2003;&#x2003;&#x5728;&#x672C;&#x6587;&#x4E2D;&#xFF0C;&#x6211;&#x5011;&#x5C07;&#x4E00;&#x6B65;&#x6B65;&#x5E6B;&#x6A5F;&#x5668;&#x4EBA;&#x52A0;&#x4E0A;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x7B49;&#x5230;&#x719F;&#x6089;&#x4E4B;&#x5F8C;&#xFF0C;&#x4F60;&#x4E5F;&#x53EF;&#x4EE5;&#x5E6B;&#x6A5F;&#x5668;&#x4EBA;&#x52A0;&#x4E0A;&#x5404;&#x5F0F;&#x5404;&#x6A23;&#x7684;&#x6307;&#x4EE4;&#x56C9;&#xFF01;</p>
<h1 id="1-%E6%96%B0%E5%A2%9E%E4%B8%80%E5%80%8B%E6%96%9C%E7%B7%9A%E6%8C%87%E4%BB%A4">1. &#x65B0;&#x589E;&#x4E00;&#x500B;&#x659C;&#x7DDA;&#x6307;&#x4EE4;</h1>
<p>&#x2003;&#x2003;&#x5728;discord.js v14&#x4E2D;&#xFF0C;&#x8981;&#x65B0;&#x589E;&#x4E00;&#x500B;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x6211;&#x5011;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;SlashCommandBuilder&#x4F86;&#x5E6B;&#x52A9;&#x6211;&#x5011;&#x5B8C;&#x6210;&#x3002;&#x9996;&#x5148;&#x5148;&#x5728;&#x6700;&#x4E0A;&#x9762;&#x7684;require&#x4E2D;&#x52A0;&#x5165;SlashCommandBuilder&#xFF1A;</p>
<pre><code class="language-javascript">// ---------------START---------------
const { Client, Events, GatewayIntentBits } = require (&apos;discord.js&apos;);
// ----------------END----------------
</code></pre>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#xFF0C;&#x6211;&#x5011;&#x5728;ClientReady&#x9019;&#x908A;&#x65B0;&#x589E;&#x4E00;&#x500B;SlashCommandBuilder&#x4F86;&#x5EFA;&#x7ACB;&#x65B0;&#x7684;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x3002;</p>
<pre><code class="language-javascript">client.once (Events.ClientReady, c =&gt; {
    console.log (`&#x6B61;&#x8FCE;&#x767B;&#x5165; ${c.user.username}`);
// ---------------START---------------
    new SlashCommandBuilder ()
        .setName (&apos;ping&apos;)
        .setDescription (&apos;Replies with &quot;Pong!&quot;&apos;);
// ----------------END----------------
});
</code></pre>
<p>&#x2003;&#x2003;&#x63A5;&#x8457;&#xFF0C;&#x6211;&#x5011;&#x8981;&#x8B93;&#x6A5F;&#x5668;&#x4EBA;&#x76E3;&#x807D;InteractionCreate&#x7684;&#x4E8B;&#x4EF6;&#x3002;&#x4E0D;&#x7BA1;&#x662F;&#x89F8;&#x767C;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x3001;&#x9001;&#x51FA;&#x4E92;&#x52D5;&#x8996;&#x7A97;&#x3001;&#x9EDE;&#x64CA;&#x6309;&#x9215;&#x3001;&#x6216;&#x662F;&#x4F7F;&#x7528;&#x4E0B;&#x62C9;&#x9078;&#x55AE;&#xFF0C;&#x5168;&#x90E8;&#x90FD;&#x662F;&#x5C6C;&#x65BC;InteractionCreate&#x7684;&#x4E8B;&#x4EF6;&#x3002;&#x6211;&#x5011;&#x4F86;&#x65B0;&#x589E;&#x4EE5;&#x4E0B;&#x5167;&#x5BB9;&#xFF1A;</p>
<pre><code class="language-javascript">// ---------------START---------------
client.on(Events.InteractionCreate, interaction =&gt; {
    if (!interaction.isChatInputCommand ()) return;
    if (interaction.commandName === &quot;ping&quot;) {
        interaction.reply (&quot;Pong!&quot;);
    }
});
// ----------------END----------------
</code></pre>
<p>&#x2003;&#x2003;&#x6709;&#x4EBA;&#x4F7F;&#x7528;&#x4E86;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x7B49;&#x4E00;&#x7CFB;&#x5217;&#x52D5;&#x4F5C;&#x89F8;&#x767C;InteractionCreate&#x7684;&#x4E8B;&#x4EF6;&#x5F8C;&#xFF0C;&#x6703;&#x5F97;&#x5230;&#x4E00;&#x500B;interaction&#xFF0C;&#x7576;&#x6211;&#x5011;&#x6839;&#x64DA;&#x6307;&#x4EE4;&#x5B8C;&#x6210;&#x5DE5;&#x4F5C;&#x5F8C;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;interaction&#x7684;<code>reply ()</code>&#x4F86;&#x56DE;&#x61C9;&#x4F7F;&#x7528;&#x8005;&#x3002;</p>
<p>&#x2003;&#x2003;&#x7279;&#x5225;&#x9700;&#x8981;&#x63D0;&#x5230;&#x7684;&#x662F;&#xFF0C;interaction&#x7684;<code>reply ()</code>&#x53EA;&#x6709;3&#x79D2;&#xFF0C;&#x8D85;&#x904E;&#x6642;&#x9593;&#x5C31;&#x6703;&#x88AB;&#x7576;&#x4F5C;&#x6C92;&#x6709;&#x56DE;&#x61C9;&#x3002;&#x5982;&#x679C;&#x78BA;&#x5B9A;&#x56DE;&#x61C9;&#x6642;&#x9593;&#x6703;&#x8D85;&#x904E;3&#x79D2;&#x7684;&#x8A71;&#xFF0C;&#x6709;&#x5E7E;&#x7A2E;&#x65B9;&#x6CD5;&#x53EF;&#x4EE5;&#x89E3;&#x6C7A;&#xFF1A;</p>
<ol>
<li>&#x5148;&#x9001;&#x51FA;&#x4E00;&#x500B;<code>reply ()</code>&#xFF0C;&#x7B49;&#x52D5;&#x4F5C;&#x5B8C;&#x6210;&#x5F8C;&#x518D;&#x4F7F;&#x7528;<code>editReply ()</code>&#x7DE8;&#x8F2F;&#x8A72;&#x56DE;&#x61C9;&#x3002;</li>
<li>&#x4F7F;&#x7528;<code>deferReply ()</code>&#xFF0C;Discord&#x6703;&#x5E6B;&#x4F60;&#x50B3;&#x9001;&#x4E00;&#x500B;&#x300C;&#x6A5F;&#x5668;&#x4EBA;&#x6B63;&#x5728;&#x601D;&#x8003;&#x300D;&#x7684;&#x8A0A;&#x606F;&#xFF0C;&#x4E26;&#x4E14;&#x5EF6;&#x9577;&#x5230;15&#x5206;&#x9418;&#x5167;&#x90FD;&#x53EF;&#x4EE5;&#x518D;&#x7DE8;&#x8F2F;&#x56DE;&#x61C9;&#x3002;</li>
<li>&#x5148;&#x9001;&#x51FA;&#x4E00;&#x500B;<code>reply ()</code>&#xFF0C;&#x7B49;&#x52D5;&#x4F5C;&#x5B8C;&#x6210;&#x5F8C;&#x518D;&#x4F7F;&#x7528;<code>followUp ()</code>&#x50B3;&#x9001;&#x7B2C;&#x4E8C;&#x5247;&#x56DE;&#x61C9;&#x3002;&#x7576;&#x4F60;&#x4F7F;&#x7528;<code>deferReply ()</code>&#x518D;&#x4F7F;&#x7528;<code>followUp ()</code>&#xFF0C;&#x6B64;&#x6642;&#x4E26;&#x4E0D;&#x6703;&#x50B3;&#x9001;&#x7B2C;&#x4E8C;&#x5247;&#x56DE;&#x61C9;&#xFF0C;&#x800C;&#x662F;&#x76F4;&#x63A5;&#x7DE8;&#x8F2F;&#x300C;&#x6A5F;&#x5668;&#x4EBA;&#x6B63;&#x5728;&#x601D;&#x8003;&#x300D;&#x7684;&#x8A0A;&#x606F;&#x3002;</li>
</ol>
<p>&#x2003;&#x2003;&#x6211;&#x5011;&#x65B0;&#x589E;&#x4E86;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x4E26;&#x4E14;&#x6A5F;&#x5668;&#x4EBA;&#x767B;&#x5165;&#x4E4B;&#x5F8C;&#x6703;&#x958B;&#x59CB;&#x76E3;&#x807D;InteractionCreate&#x4E8B;&#x4EF6;&#x4E26;&#x505A;&#x51FA;&#x56DE;&#x61C9;&#xFF0C;&#x4E5F;&#x8A31;&#x9019;&#x6642;&#x5019;&#x4F60;&#x6703;&#x60F3;&#x8A66;&#x8457;&#x4F7F;&#x7528;&#x770B;&#x770B;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x4E86;&#x3002;&#x4F46;&#x4F60;&#x5BE6;&#x969B;&#x4E0A;&#x5230;&#x4F3A;&#x670D;&#x5668;&#x8F38;&#x5165;&#x300C;/&#x300D;&#x4E4B;&#x5F8C;&#xFF0C;&#x4E26;&#x6C92;&#x6709;&#x6211;&#x5011;&#x525B;&#x525B;&#x65B0;&#x589E;&#x7684;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#xFF0C;&#x9019;&#x662F;&#x70BA;&#x4EC0;&#x9EBC;&#x5462;&#xFF1F;</p>
<p>&#x2003;&#x2003;&#x9664;&#x4E86;&#x5728;&#x9019;&#x88E1;&#x65B0;&#x589E;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x4E4B;&#x5916;&#xFF0C;&#x6211;&#x5011;&#x9084;&#x5FC5;&#x9808;&#x53E6;&#x5916;&#x5411;Discord&#x8A3B;&#x518A;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x9019;&#x6A23;Discord&#x624D;&#x77E5;&#x9053;&#x6211;&#x5011;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#x8EAB;&#x4E0A;&#x6709;&#x4EC0;&#x9EBC;&#x6307;&#x4EE4;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x3002;&#x60F3;&#x8981;&#x8A3B;&#x518A;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x7684;&#x8A71;&#xFF0C;&#x6211;&#x5011;&#x53EF;&#x4EE5;&#x9019;&#x9EBC;&#x505A;&#xFF1A;</p>
<pre><code class="language-javascript">client.once (Events.ClientReady, c =&gt; {
    console.log (`&#x6B61;&#x8FCE;&#x767B;&#x5165; ${c.user.username}`);

    const ping = new SlashCommandBuilder ()
        .setName (&apos;ping&apos;)
        .setDescription (&apos;Replies with &quot;Pong!&quot;&apos;);
// ---------------START---------------
    client.application.commands.create (ping, &quot;&#x586B;&#x5165;&#x4F3A;&#x670D;&#x5668;&#x7684;ID&quot;);
// ----------------END----------------
});
</code></pre>
<p>&#x2003;&#x2003;&#x5982;&#x6B64;&#x4E00;&#x4F86;&#xFF0C;&#x6211;&#x5011;&#x5C31;&#x6210;&#x529F;&#x8A3B;&#x518A;&#x4E86;&#x4E00;&#x500B;&#x5728;&#x4F3A;&#x670D;&#x5668;&#x5167;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x7684;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x5728;&#x4F3A;&#x670D;&#x5668;&#x5167;&#x4F7F;&#x7528;&#x525B;&#x525B;&#x65B0;&#x589E;&#x7684;&#x6307;&#x4EE4;&#x4E86;&#xFF01;</p>
<p>&#x2003;&#x2003;&#xFF08;&#x8ACB;&#x6CE8;&#x610F;&#x9019;&#x88E1;&#x5C07;&#x6307;&#x4EE4;&#x8A3B;&#x518A;&#x7D66;&#x6307;&#x5B9A;&#x4F3A;&#x670D;&#x5668;&#xFF0C;&#x5728;&#x5176;&#x4ED6;&#x4F3A;&#x670D;&#x5668;&#x5167;&#x662F;&#x7121;&#x6CD5;&#x4F7F;&#x7528;&#x9019;&#x500B;&#x6307;&#x4EE4;&#x7684;&#xFF0C;&#x5F8C;&#x7E8C;&#x6703;&#x8AAA;&#x660E;&#x5982;&#x4F55;&#x8A3B;&#x518A;&#x6307;&#x4EE4;&#x8B93;&#x6240;&#x6709;&#x4F3A;&#x670D;&#x5668;&#x90FD;&#x80FD;&#x4F7F;&#x7528;&#x3002;&#xFF09;</p>
<h1 id="2-%E5%86%8D%E6%96%B0%E5%A2%9E%E4%B8%80%E5%80%8B%E6%96%9C%E7%B7%9A%E6%8C%87%E4%BB%A4">2. &#x518D;&#x65B0;&#x589E;&#x4E00;&#x500B;&#x659C;&#x7DDA;&#x6307;&#x4EE4;</h1>
<p>&#x2003;&#x2003;&#x73FE;&#x5728;&#x6A5F;&#x5668;&#x4EBA;&#x6709;&#x4E86;&#x7B2C;&#x4E00;&#x500B;&#x6307;&#x4EE4;&#xFF0C;&#x5C31;&#x8B93;&#x6211;&#x5011;&#x518D;&#x65B0;&#x589E;&#x4E00;&#x500B;&#x65B0;&#x7684;&#x6307;&#x4EE4;&#x5427;&#x3002;&#x9019;&#x6B21;&#x6211;&#x5011;&#x4F86;&#x65B0;&#x589E;&#x4E00;&#x500B;&#x5E36;&#x6709;&#x53C3;&#x6578;&#x7684;&#x6307;&#x4EE4;&#xFF0C;&#x8B93;&#x6A5F;&#x5668;&#x4EBA;&#x53EF;&#x4EE5;&#x7372;&#x5F97;&#x6210;&#x54E1;&#x8F38;&#x5165;&#x7684;&#x53C3;&#x6578;&#x4E26;&#x52A0;&#x4EE5;&#x5229;&#x7528;&#xFF1A;</p>
<pre><code class="language-javascript">client.once (Events.ClientReady, c =&gt; {
    console.log (`&#x6B61;&#x8FCE;&#x767B;&#x5165; ${c.user.username}`);

    const ping = new SlashCommandBuilder ()
        .setName (&apos;ping&apos;)
        .setDescription (&apos;Replies with &quot;Pong!&quot;&apos;);
// ---------------START---------------
    const hello = new SlashCommandBuilder ()
        .setName (&apos;hello&apos;)
        .setDescription (&apos;Say hello to someone!&apos;)
        .addUserOption (option =&gt;
            option
                .setName (&apos;user&apos;)
                .setDescription (&apos;The user you want to say hi to&apos;)
                .setRequired (true)
        );
// ----------------END----------------

    client.application.commands.create (ping, &quot;&#x586B;&#x5165;&#x4F3A;&#x670D;&#x5668;&#x7684;ID&quot;);
// ---------------START---------------
    client.application.commands.create (hello, &quot;&#x586B;&#x5165;&#x4F3A;&#x670D;&#x5668;&#x7684;ID&quot;);
// ----------------END----------------
});
</code></pre>
<p>&#x2003;&#x2003;&#x5728;&#x65B0;&#x7684;&#x6307;&#x4EE4;&#x4E2D;&#x52A0;&#x5165;&#x4E86;&#x65B0;&#x7684;&#x90E8;&#x5206;<code>addUserOption</code>&#xFF0C;&#x5B83;&#x7684;&#x4F5C;&#x7528;&#x662F;&#x53EF;&#x4EE5;&#x65B0;&#x589E;&#x4E00;&#x500B;&#x8B93;&#x4F7F;&#x7528;&#x8005;&#x8F38;&#x5165;&#x6210;&#x54E1;&#x9032;&#x53BB;&#x7684;&#x53C3;&#x6578;&#x3002;&#x9664;&#x4E86;&#x6210;&#x54E1;&#x4E4B;&#x5916;&#xFF0C;Discord&#x5171;&#x63D0;&#x4F9B;&#x4E86;&#x4EE5;&#x4E0B;&#x985E;&#x578B;&#x7684;&#x53C3;&#x6578;&#xFF1A;</p>
<ul>
<li><code>addSubcommand</code> &#x5B50;&#x547D;&#x4EE4;</li>
<li><code>addSubcommandGroup</code> &#x5B50;&#x547D;&#x4EE4;&#x7FA4;&#x7D44;</li>
<li><code>addStringOption</code> &#x5B57;&#x4E32;</li>
<li><code>addIntegerOption</code> &#x6574;&#x6578;</li>
<li><code>addBooleanOption</code> &#x5E03;&#x6797;&#x503C;</li>
<li><code>addUserOption</code> @&#x6210;&#x54E1; &#x6216; &#x6210;&#x54E1;&#x7684;ID</li>
<li><code>addChannelOption</code> #&#x983B;&#x9053; &#x6216; &#x983B;&#x9053;&#x7684;ID</li>
<li><code>addRoleOption</code> @&#x8EAB;&#x5206;&#x7D44; &#x6216; &#x8EAB;&#x5206;&#x7D44;&#x7684;ID</li>
<li><code>addMentionableOption</code> @&#x6210;&#x54E1;/@&#x8EAB;&#x5206;&#x7D44; &#x6216; &#x6210;&#x54E1;/&#x8EAB;&#x5206;&#x7D44;&#x7684;ID</li>
<li><code>addNumberOption</code> &#x6D6E;&#x9EDE;&#x6578;</li>
<li><code>addAttachmentOption</code> &#x9644;&#x52A0;&#x6A94;&#x6848;</li>
</ul>
<p>&#x2003;&#x2003;&#x5982;&#x679C;&#x9700;&#x8981;&#x64F4;&#x5145;&#x53C3;&#x6578;&#xFF0C;&#x6211;&#x5011;&#x53EA;&#x8981;&#x6839;&#x64DA;&#x9700;&#x8981;&#x586B;&#x5165;&#x7684;&#x53C3;&#x6578;&#xFF0C;&#x5728;&#x6700;&#x5F8C;&#x9762;&#x63D2;&#x5165;&#x76F8;&#x5C0D;&#x61C9;&#x7684;&#x65B9;&#x6CD5;&#x5373;&#x53EF;&#x3002;&#x4F60;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x53C3;&#x6578;&#x672C;&#x8EAB;&#x4E5F;&#x53EF;&#x4EE5;&#x8A2D;&#x5B9A;&#x540D;&#x7A31;&#x8207;&#x8AAA;&#x660E;&#xFF0C;&#x5728;&#x6211;&#x5011;&#x525B;&#x525B;&#x65B0;&#x589E;&#x7684;&#x6307;&#x4EE4;&#x4E2D;&#xFF0C;&#x586B;&#x5165;&#x6210;&#x54E1;&#x7684;&#x53C3;&#x6578;&#x4F7F;&#x7528;&#x4E86;<code>setRequired</code> &#x5C07;&#x53C3;&#x6578;&#x8A2D;&#x70BA;&#x5FC5;&#x586B;&#xFF0C;&#x5982;&#x679C;&#x4F7F;&#x7528;&#x8005;&#x6C92;&#x6709;&#x586B;&#x5165;&#x5167;&#x5BB9;&#x5C07;&#x7121;&#x6CD5;&#x9001;&#x51FA;&#x6307;&#x4EE4;&#x3002;&#x7531;&#x65BC;&#x6307;&#x4EE4;&#x8207;&#x6BCF;&#x4E00;&#x7A2E;&#x53C3;&#x6578;&#x6240;&#x5305;&#x542B;&#x7684;&#x65B9;&#x6CD5;&#x592A;&#x591A;&#xFF0C;&#x9019;&#x908A;&#x5C31;&#x4E0D;&#x4E00;&#x4E00;&#x5217;&#x8209;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x9700;&#x8981;&#x53EF;&#x4EE5;&#x95B1;&#x8B80;<a href="https://discord.js.org/docs/packages/builders/main/SlashCommandBuilder:Class?ref=blog.anisile.cc">&#x5B98;&#x65B9;&#x6587;&#x4EF6;</a>&#x78BA;&#x8A8D;&#x3002;</p>
<p>&#x2003;&#x2003;&#x5B50;&#x547D;&#x4EE4;&#x8207;&#x5B50;&#x547D;&#x4EE4;&#x7FA4;&#x7D44;&#x53EF;&#x4EE5;&#x8B93;&#x4F60;&#x5C07;&#x540C;&#x4E00;&#x985E;&#x7684;&#x547D;&#x4EE4;&#x5305;&#x6210;&#x4E00;&#x500B;&#x7FA4;&#x7D44;&#x3002;&#x4F8B;&#x5982;Ban&#x4EBA;&#x8207;&#x8E22;&#x4EBA;&#x6307;&#x4EE4;&#xFF0C;&#x53EF;&#x4EE5;&#x5305;&#x6210;<code>/manage</code>&#x6307;&#x4EE4;&#x5E95;&#x4E0B;&#x7684;<code>user</code>&#x5B50;&#x547D;&#x4EE4;&#x7FA4;&#x7D44;&#x7684;<code>Ban</code>&#x5B50;&#x547D;&#x4EE4;&#x8207;<code>kick</code>&#x5B50;&#x547D;&#x4EE4;&#xFF0C;&#x4E4B;&#x5F8C;&#x7576;&#x4F60;&#x60F3;&#x5C0B;&#x627E;&#x7BA1;&#x7406;&#x4F7F;&#x7528;&#x8005;&#x76F8;&#x95DC;&#x7684;&#x6307;&#x4EE4;&#x6642;&#xFF0C;&#x53EA;&#x8981;&#x8F38;&#x5165;<code>/manage user</code>&#x4FBF;&#x6703;&#x5217;&#x51FA;&#x5E95;&#x4E0B;&#x6240;&#x6709;&#x7684;&#x5B50;&#x547D;&#x4EE4;&#xFF0C;&#x662F;&#x4E0D;&#x662F;&#x5F88;&#x65B9;&#x4FBF;&#x5462;&#xFF01;</p>
<p>&#x2003;&#x2003;&#x4E0D;&#x597D;&#x610F;&#x601D;&#xFF0C;&#x626F;&#x5F97;&#x6709;&#x9EDE;&#x9060;&#x4E86;&#x3002;&#x8B93;&#x6211;&#x5011;&#x7E7C;&#x7E8C;&#x628A;&#x6A5F;&#x5668;&#x4EBA;&#x63A5;&#x6536;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x5F8C;&#x56DE;&#x61C9;&#x7684;&#x90E8;&#x5206;&#x5B8C;&#x6210;&#x5427;&#xFF1A;</p>
<pre><code class="language-javascript">client.on(Events.InteractionCreate, interaction =&gt; {
    if (!interaction.isChatInputCommand ()) return;
    if (interaction.commandName === &quot;ping&quot;) {
        interaction.reply (&quot;Pong!&quot;);
    }
// ---------------START---------------
    if (interaction.commandName === &quot;hello&quot;) {
        const user = interaction.options.getUser (&apos;user&apos;);
        interaction.reply (`Hello &lt;@${user.id}&gt;`);
    }
// ----------------END----------------
});
</code></pre>
<p>&#x2003;&#x2003;&#x7576;&#x4F7F;&#x7528;&#x4E86;&#x5E36;&#x6709;&#x53C3;&#x6578;&#x7684;&#x6307;&#x4EE4;&#xFF0C;&#x6211;&#x5011;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>interaction.options</code>&#x5167;&#x7684;&#x4E00;&#x7CFB;&#x5217;get&#x65B9;&#x6CD5;&#x53BB;&#x53D6;&#x5F97;&#x90A3;&#x4E9B;&#x53C3;&#x6578;&#x7684;&#x503C;&#x3002;&#x4F8B;&#x5982;&#x6211;&#x5011;&#x7684;&#x6307;&#x4EE4;&#x6240;&#x5305;&#x542B;&#x7684;&#x53C3;&#x6578;&#x662F;&#x586B;&#x5165;&#x6210;&#x54E1;&#xFF0C;&#x56E0;&#x6B64;&#x6211;&#x5011;&#x4F7F;&#x7528;<code>getUser</code>&#x4F86;&#x63A5;&#x6536;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x770B;&#x5230;<code>getUser</code>&#x7684;&#x5F15;&#x6578;&#x662F;&#x586B;&#x5165;&#x6211;&#x5011;&#x525B;&#x525B;&#x5E6B;option&#x8A2D;&#x5B9A;&#x7684;&#x540D;&#x7A31;&#xFF0C;&#x9019;&#x6A23;&#x6211;&#x5011;&#x5C31;&#x80FD;&#x6293;&#x5230;&#x60F3;&#x8981;&#x7684;&#x53C3;&#x6578;&#x4E86;&#x3002;</p>
<h1 id="3-%E6%8E%A5%E4%B8%8B%E4%BE%86%E8%A6%81%E5%81%9A%E7%9A%84%E4%BA%8B%E6%83%85">3. &#x63A5;&#x4E0B;&#x4F86;&#x8981;&#x505A;&#x7684;&#x4E8B;&#x60C5;</h1>
<p>&#x2003;&#x2003;&#x5230;&#x76EE;&#x524D;&#x70BA;&#x6B62;&#xFF0C;&#x6211;&#x5011;&#x5E6B;&#x6A5F;&#x5668;&#x4EBA;&#x65B0;&#x589E;&#x4E86;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x4E26;&#x4E14;&#x4F7F;&#x7528;&#x8005;&#x53EF;&#x4EE5;&#x50B3;&#x905E;&#x53C3;&#x6578;&#x7D66;&#x6A5F;&#x5668;&#x4EBA;&#x4F7F;&#x7528;&#xFF0C;&#x57FA;&#x672C;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#x529F;&#x80FD;&#x5DF2;&#x7D93;&#x7B97;&#x662F;&#x5B8C;&#x6210;&#x4E86;&#x3002;&#x4F46;&#x4F60;&#x53EF;&#x80FD;&#x6703;&#x767C;&#x73FE;&#xFF0C;&#x5982;&#x679C;&#x7E7C;&#x7E8C;&#x64F4;&#x5145;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x6307;&#x4EE4;&#xFF0C;&#x73FE;&#x5728;&#x7684;&#x5BEB;&#x6CD5;&#x5C07;&#x6703;&#x8B8A;&#x5F97;&#x5F88;&#x96E3;&#x7DAD;&#x8B77;&#x3002;&#x63A5;&#x4E0B;&#x4F86;&#x6211;&#x5011;&#x6703;&#x6539;&#x5584;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x67B6;&#x69CB;&#xFF0C;&#x8B93;&#x4F60;&#x53EF;&#x4EE5;&#x65B9;&#x4FBF;&#x64F4;&#x5145;&#x8207;&#x7DAD;&#x8B77;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x529F;&#x80FD;&#x3002;</p>
<p>&#x2003;&#x2003;&#x611F;&#x8B1D;&#x4F60;&#x770B;&#x5230;&#x9019;&#x908A;&#xFF0C;&#x6211;&#x5011;&#x4E0B;&#x6B21;&#x898B;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[從零開始的Discord機器人(1) - 建立機器人本體]]></title><description><![CDATA[本篇會建置Discord機器人所需的環境、完成機器人基本的架構並使其能夠運行。]]></description><link>https://blog.anisile.cc/discord-bot-1/</link><guid isPermaLink="false">6502a593869f86000163cfcf</guid><category><![CDATA[Discord.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[從零開始的Discord機器人]]></category><dc:creator><![CDATA[Anisile]]></dc:creator><pubDate>Thu, 14 Sep 2023 06:27:21 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x2003;&#x2003;&#x6700;&#x8FD1;&#x525B;&#x597D;&#x6709;&#x5EFA;&#x7ACB;Discord&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x9700;&#x6C42;&#xFF0C;&#x7531;&#x65BC;Discord.js&#x76EE;&#x524D;&#x5DF2;&#x7D93;&#x66F4;&#x65B0;&#x5230;&#x4E86;v14&#xFF0C;&#x4E26;&#x4E14;Discord&#x5F8C;&#x7E8C;&#x63A8;&#x51FA;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF08;Slash Commands&#xFF09;&#x4F86;&#x53D6;&#x4EE3;&#x4EE5;&#x524D;&#x8F03;&#x5E38;&#x51FA;&#x73FE;&#x7684;Prefix&#x6307;&#x4EE4;&#xFF0C;&#x52A0;&#x4E0A;&#x4EE5;&#x524D;&#x5BEB;&#x7684;Discord&#x6A5F;&#x5668;&#x4EBA;&#x4E0D;&#x50C5;&#x4E0D;&#x597D;&#x64F4;&#x5145;&#xFF0C;&#x4E5F;&#x6C92;&#x6709;&#x597D;&#x7684;&#x67B6;&#x69CB;&#xFF0C;&#x56E0;&#x6B64;&#x6C7A;&#x5B9A;&#x5F9E;&#x96F6;&#x958B;&#x59CB;&#x5B78;&#x7FD2;Discord.js v14&#x4E26;&#x5EFA;&#x7ACB;&#x4E00;&#x652F;&#x6A5F;&#x5668;&#x4EBA;&#x3002;</p>
<h1 id="1-%E7%92%B0%E5%A2%83%E5%BB%BA%E7%AB%8B">1. &#x74B0;&#x5883;&#x5EFA;&#x7ACB;</h1>
<p>&#x2003;&#x2003;&#x9996;&#x5148;&#x6211;&#x5011;&#x9700;&#x8981;&#x4E0B;&#x8F09;<a href="https://nodejs.org/en?ref=blog.anisile.cc">Node.js</a>&#x4E26;&#x5B89;&#x88DD;&#x5230;&#x96FB;&#x8166;&#x4E0A;&#x3002;&#x65B0;&#x5EFA;&#x4E00;&#x500B;&#x8CC7;&#x6599;&#x593E;&#x4F5C;&#x70BA;Discord&#x6A5F;&#x5668;&#x4EBA;&#x7A0B;&#x5F0F;&#x78BC;&#x5B58;&#x653E;&#x7684;&#x4F4D;&#x7F6E;&#xFF0C;&#x958B;&#x555F;Terminal&#x5728;&#x6B64;&#x8CC7;&#x6599;&#x593E;&#x5167;&#x4F7F;&#x7528;&#x6307;&#x4EE4;<code>npm init</code>&#x4E26;&#x6309;&#x7167;&#x63D0;&#x793A;&#x5B8C;&#x6210;&#x64CD;&#x4F5C;&#x3002;</p>
<!--kg-card-end: markdown--><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">&#x9019;&#x88E1;&#x63A8;&#x85A6;&#x4F7F;&#x7528;Visual Studio Code&#x4F5C;&#x70BA;&#x672C;&#x6B21;&#x7684;IDE&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x5728;VS Code&#x5167;&#x958B;&#x555F;Terminal&#xFF0C;&#x4E0D;&#x7528;&#x5207;&#x63DB;&#x5230;Terminal&#x5B89;&#x88DD;package&#x8207;&#x57F7;&#x884C;&#xFF0C;&#x80FD;&#x7701;&#x4E0B;&#x5F88;&#x591A;&#x6642;&#x9593;&#x3002;</div></div><!--kg-card-begin: markdown--><p>&#x2003;&#x2003;&#x5B8C;&#x6210;&#x5F8C;&#x6211;&#x5011;&#x5C31;&#x53EF;&#x4EE5;&#x4F86;&#x4E0B;&#x8F09;discord.js&#x4E86;&#xFF0C;&#x5728;Terminal&#x5167;&#x8F38;&#x5165;<code>npm install discord.js</code>&#x4E26;&#x7B49;&#x4ED6;&#x8DD1;&#x5B8C;&#x3002;&#x5B8C;&#x6210;&#x4E4B;&#x5F8C;&#x8CC7;&#x6599;&#x593E;&#x5167;&#x61C9;&#x8A72;&#x6703;&#x51FA;&#x73FE;&#x4E09;&#x500B;&#x65B0;&#x6771;&#x897F;&#xFF0C;&#x5206;&#x5225;&#x662F;&#xFF1A;</p>
<ul>
<li>node_modules&#xFF1A;&#x6240;&#x6709;&#x4E0B;&#x8F09;&#x7684;package&#x5B58;&#x653E;&#x7684;&#x4F4D;&#x7F6E;&#x3002;</li>
<li>package.json&#xFF1A;&#x7528;&#x4F86;&#x63CF;&#x8FF0;&#x76EE;&#x524D;&#x9805;&#x76EE;&#x7684;&#x57FA;&#x672C;&#x8CC7;&#x8A0A;&#x3001;&#x6240;&#x4F9D;&#x8CF4;&#x7684;package&#x3002;</li>
<li>package-lock.json&#xFF1A;&#x7528;&#x4F86;&#x8A18;&#x9304;&#x6240;&#x6709;package&#x7684;&#x5177;&#x9AD4;&#x4F86;&#x6E90;&#x8207;&#x7248;&#x672C;&#x865F;&#x3002;</li>
</ul>
<p>&#x2003;&#x2003;&#x5982;&#x679C;&#x4F60;&#x89BA;&#x5F97;&#x5F88;&#x8907;&#x96DC;&#x4E5F;&#x6C92;&#x95DC;&#x4FC2;&#xFF0C;&#x6211;&#x5011;&#x76EE;&#x524D;&#x53EA;&#x8981;&#x95DC;&#x6CE8;package.json&#x5C31;&#x597D;&#x4E86;&#x3002;&#x7576;&#x4F60;&#x6253;&#x958B;package.json&#x6642;&#xFF0C;&#x9664;&#x4E86;&#x57FA;&#x672C;&#x8CC7;&#x8A0A;&#x4E4B;&#x5916;&#xFF0C;&#x61C9;&#x8A72;&#x6703;&#x770B;&#x5230;&#x9019;&#x4E00;&#x9805;&#xFF1A;</p>
<pre><code class="language-jsx">&quot;main&quot;: &quot;index.js&quot;
</code></pre>
<p>&#x2003;&#x2003;&#x9019;&#x662F;&#x6211;&#x5011;Discord&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x9032;&#x5165;&#x9EDE;&#xFF0C;&#x6240;&#x4EE5;&#x6211;&#x5011;&#x8981;&#x65B0;&#x5EFA;&#x4E00;&#x500B;index.js&#x3002;&#x65B0;&#x5EFA;&#x5B8C;&#x6210;&#x4E4B;&#x5F8C;&#xFF0C;&#x76EE;&#x524D;&#x4F60;&#x53EF;&#x4EE5;&#x5148;&#x8F38;&#x5165;&#x6C38;&#x9060;&#x7684;&#x7D93;&#x5178;&#x505A;&#x70BA;&#x6E2C;&#x8A66;&#xFF1A;</p>
<pre><code class="language-jsx">// ---------------START---------------
console.log(&quot;Hello World!&quot;);
// ----------------END----------------
</code></pre>
<p>&#x2003;&#x2003;&#x5B8C;&#x6210;&#x4E4B;&#x5F8C;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x5617;&#x8A66;&#x5728;Terminal&#x57F7;&#x884C;<code>node .</code>&#x6216;<code>node index.js</code>&#xFF0C;&#x5982;&#x679C;&#x4F60;&#x80FD;&#x9806;&#x5229;&#x770B;&#x5230;Hello World&#xFF0C;&#x4EE3;&#x8868;&#x6211;&#x5011;&#x7684;&#x74B0;&#x5883;&#x5DF2;&#x7D93;&#x5EFA;&#x7ACB;&#x5B8C;&#x6210;&#x4E86;&#x3002;</p>
<h1 id="2-%E6%96%B0%E5%A2%9E%E6%A9%9F%E5%99%A8%E4%BA%BA%E5%B8%B3%E8%99%9F">2. &#x65B0;&#x589E;&#x6A5F;&#x5668;&#x4EBA;&#x5E33;&#x865F;</h1>
<p>&#x2003;&#x2003;&#x74B0;&#x5883;&#x5EFA;&#x7ACB;&#x597D;&#x4E86;&#x4E4B;&#x5F8C;&#xFF0C;&#x6700;&#x91CD;&#x8981;&#x7684;&#x7576;&#x7136;&#x662F;&#x8DDF;Discord&#x65B0;&#x589E;&#x4E00;&#x500B;&#x6A5F;&#x5668;&#x4EBA;&#x5E33;&#x865F;&#x3002;&#x7576;&#x7136;&#x6211;&#x5011;&#x4E26;&#x4E0D;&#x9700;&#x8981;&#x70BA;&#x4E86;&#x6A5F;&#x5668;&#x4EBA;&#x984D;&#x5916;&#x8FA6;&#x4E00;&#x500B;&#x5E33;&#x865F;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x5728;<a href="https://discord.com/developers/applications?ref=blog.anisile.cc">Discord Developer Portal</a>&#x5EFA;&#x7ACB;&#x4E00;&#x500B;&#x65B0;&#x7684;Application&#x5373;&#x53EF;&#x3002;</p>
<p>&#x2003;&#x2003;&#x5728;Application&#x5167;&#x9EDE;&#x64CA;&#x53F3;&#x4E0A;&#x89D2;&#x7684;New Application&#xFF0C;&#x96A8;&#x610F;&#x8F38;&#x5165;Application&#x7684;&#x540D;&#x7A31;&#x4E26;&#x6309;&#x4E0B;&#x78BA;&#x5B9A;&#x3002;&#x5EFA;&#x7ACB;&#x5B8C;&#x6210;&#x4E4B;&#x5F8C;&#xFF0C;&#x9032;&#x5165;&#x5DE6;&#x908A;&#x7684;Bot&#x4E26;&#x9EDE;&#x64CA;Add Bot&#xFF0C;&#x5982;&#x6B64;&#x4E00;&#x4F86;&#x6211;&#x5011;&#x5C31;&#x5EFA;&#x7ACB;&#x597D;&#x4E86;&#x6A5F;&#x5668;&#x4EBA;&#x3002;</p>
<p>&#x2003;&#x2003;&#x4F60;&#x53EF;&#x4EE5;&#x5E6B;&#x6A5F;&#x5668;&#x4EBA;&#x53D6;&#x540D;&#x3001;&#x66F4;&#x63DB;&#x982D;&#x8CBC;&#xFF0C;&#x66F4;&#x91CD;&#x8981;&#x7684;&#x662F;&#x5C07;Previleged Gateway Intents&#x5E95;&#x4E0B;&#x7684;&#x4E09;&#x500B;&#x9078;&#x9805;&#x90FD;&#x6253;&#x958B;&#xFF0C;&#x9019;&#x6A23;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x8A2D;&#x5B9A;&#x5C31;&#x544A;&#x4E00;&#x6BB5;&#x843D;&#x4E86;&#x3002;# 3. &#x8B93;&#x6A5F;&#x5668;&#x4EBA;&#x53EF;&#x4EE5;&#x767B;&#x5165;&#x63A5;&#x4E0B;&#x4F86;&#xFF0C;&#x6211;&#x5011;&#x9700;&#x8981;&#x628A;&#x6211;&#x5011;&#x6703;&#x7528;&#x5230;&#x7684;&#x4E00;&#x4E9B;&#x95DC;&#x65BC;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x53C3;&#x6578;&#x90FD;&#x5B58;&#x8D77;&#x4F86;&#x3002;&#x5728;&#x6A5F;&#x5668;&#x4EBA;&#x7684;&#x8CC7;&#x6599;&#x593E;&#x5167;&#x65B0;&#x589E;&#x4E00;&#x500B;config.json&#xFF0C;&#x4E26;&#x8F38;&#x5165;&#x4EE5;&#x4E0B;&#x5167;&#x5BB9;&#xFF1A;</p>
<pre><code class="language-json">{
    &quot;token&quot;: &quot;&#x5728;&#x4E0A;&#x9762;Application&#x7684;Bot&#x5167;&#x751F;&#x6210;&#x4E00;&#x500B;Token&#xFF0C;&#x4E26;&#x5728;&#x9019;&#x88E1;&#x8CBC;&#x4E0A;&#x6A5F;&#x5668;&#x4EBA;&#x7684;Token&quot;,
}
</code></pre>
<p>&#x2003;&#x2003;&#x63A5;&#x4E0B;&#x4F86;&#x6211;&#x5011;&#x5C31;&#x80FD;&#x66FF;index.js&#x5BEB;&#x4E00;&#x4E9B;&#x6771;&#x897F;&#x4E86;&#x3002;&#x8F38;&#x5165;&#x4EE5;&#x4E0B;&#x5167;&#x5BB9;&#xFF1A;</p>
<pre><code class="language-jsx">// ---------------START---------------
const { token } = require (&apos;./config.json&apos;);
const { Client, Events, GatewayIntentBits } = require (&apos;discord.js&apos;);

const client = new Client ({intents: [GatewayIntentBits.Guilds]});
client.once (Events.ClientReady, c =&gt; {
    console.log (`&#x6B61;&#x8FCE;&#x767B;&#x5165; ${c.user.username}`);
});
client.login (token);
// ----------------END----------------
</code></pre>
<p>&#x2003;&#x2003;&#x9019;&#x908A;&#x505A;&#x7684;&#x4E8B;&#x60C5;&#x5F88;&#x7C21;&#x55AE;&#xFF0C;&#x65B0;&#x589E;&#x4E00;&#x500B;client&#xFF0C;&#x76E3;&#x807D;ClientReady&#x7684;&#x4E8B;&#x4EF6;&#xFF08;&#x7576;&#x6211;&#x5011;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#x6210;&#x529F;&#x767B;&#x5165;&#x4E4B;&#x5F8C;&#xFF0C;Discord&#x6703;&#x89F8;&#x767C;ClientReady&#x7684;&#x4E8B;&#x4EF6;&#x7D66;&#x6A5F;&#x5668;&#x4EBA;&#xFF0C;&#x6A5F;&#x5668;&#x4EBA;&#x63A5;&#x6536;&#x5230;&#x4FBF;&#x53EF;&#x4EE5;&#x505A;&#x76F8;&#x61C9;&#x7684;&#x884C;&#x52D5;&#x3002;&#x76EE;&#x524D;&#x6211;&#x5011;&#x53EA;&#x8B93;&#x4ED6;&#x5370;&#x4E00;&#x500B;log&#x4F5C;&#x70BA;&#x901A;&#x77E5;&#xFF09;&#xFF0C;&#x7136;&#x5F8C;&#x767B;&#x5165;client&#x3002;</p>
<p>&#x2003;&#x2003;&#x6700;&#x5F8C;&#x5C07;&#x6A5F;&#x5668;&#x4EBA;&#x9080;&#x8ACB;&#x5230;&#x4F3A;&#x670D;&#x5668;&#x5167;&#xFF0C;&#x4E26;&#x5728;Terminal&#x57F7;&#x884C;<code>node .</code>&#xFF0C;&#x53EA;&#x8981;&#x770B;&#x5230;&#x6A5F;&#x5668;&#x4EBA;&#x4E0A;&#x7DDA;&#x4E26;&#x5728;Terminal&#x4E2D;&#x770B;&#x5230;log&#xFF0C;&#x4EE3;&#x8868;&#x6211;&#x5011;&#x7684;&#x6A5F;&#x5668;&#x4EBA;&#x5DF2;&#x7D93;&#x6210;&#x529F;&#x767B;&#x5165;&#x56C9;&#xFF01;</p>
<h1 id="4-%E6%8E%A5%E4%B8%8B%E4%BE%86%E8%A6%81%E5%81%9A%E7%9A%84%E4%BA%8B%E6%83%85">4. &#x63A5;&#x4E0B;&#x4F86;&#x8981;&#x505A;&#x7684;&#x4E8B;&#x60C5;</h1>
<p>&#x2003;&#x2003;&#x5230;&#x76EE;&#x524D;&#x70BA;&#x6B62;&#xFF0C;&#x6211;&#x5011;&#x5DF2;&#x7D93;&#x6210;&#x529F;&#x5EFA;&#x7ACB;&#x4E00;&#x96BB;&#x6A5F;&#x5668;&#x4EBA;&#xFF0C;&#x4E26;&#x4E14;&#x80FD;&#x5920;&#x8B93;&#x5B83;&#x4E0A;&#x7DDA;&#x4E86;&#x3002;&#x63A5;&#x4E0B;&#x4F86;&#x6211;&#x5011;&#x8981;&#x505A;&#x7684;&#x4E8B;&#x60C5;&#x5C31;&#x662F;&#x65B0;&#x589E;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#xFF0C;&#x4F46;&#x7531;&#x65BC;&#x9019;&#x90E8;&#x5206;&#x7BC7;&#x5E45;&#x6703;&#x6BD4;&#x8F03;&#x9577;&#xFF0C;&#x56E0;&#x6B64;&#x7559;&#x5230;&#x4E4B;&#x5F8C;&#x518D;&#x8A73;&#x7D30;&#x8AAA;&#x660E;&#x3002;</p>
<p>&#x2003;&#x2003;&#x9664;&#x4E86;&#x659C;&#x7DDA;&#x6307;&#x4EE4;&#x4E4B;&#x5916;&#xFF0C;&#x5F8C;&#x7E8C;&#x4E5F;&#x6703;&#x8AAA;&#x660E;&#x5982;&#x4F55;&#x65B0;&#x589E;&#x4E92;&#x52D5;&#x8996;&#x7A97;&#xFF08;Modal&#xFF09;&#x8207;&#x6309;&#x9215;&#xFF08;Button&#xFF09;&#x4EE5;&#x589E;&#x52A0;&#x66F4;&#x591A;&#x4E92;&#x52D5;&#x6027;&#xFF0C;&#x4E5F;&#x6703;&#x5C07;&#x6A5F;&#x5668;&#x4EBA;&#x6574;&#x7406;&#x6210;&#x53EF;&#x4EE5;&#x65B9;&#x4FBF;&#x64F4;&#x5145;&#x7684;&#x72C0;&#x614B;&#x3002;&#x611F;&#x8B1D;&#x4F60;&#x770B;&#x5230;&#x9019;&#x908A;&#xFF0C;&#x6211;&#x5011;&#x4E0B;&#x6B21;&#x898B;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>