「Discord bot」の版間の差分
Notion-MW |
Notion-MW |
||
| 98行目: | 98行目: | ||
[https://zenn.dev/azechi/scraps/a98add131e8410 DiscordのSlash Commandをwebhookで受信する方式で作ってみる]にある[https://github.com/discord/discord-interactions-js https://github.com/discord/discord-interactions-js]を使うとよさそう。これをNetlify(AWS Lambda)向けに書き換えて、以下のようになる(前述サイトの内容に加えて、使用された対象のメッセージリンクを送るようにしている)。これが動作するかどうか、まずはテストしてみよう。 | [https://zenn.dev/azechi/scraps/a98add131e8410 DiscordのSlash Commandをwebhookで受信する方式で作ってみる]にある[https://github.com/discord/discord-interactions-js https://github.com/discord/discord-interactions-js]を使うとよさそう。これをNetlify(AWS Lambda)向けに書き換えて、以下のようになる(前述サイトの内容に加えて、使用された対象のメッセージリンクを送るようにしている)。これが動作するかどうか、まずはテストしてみよう。 | ||
< | <pre class="visual">const { InteractionResponseType, InteractionType, verifyKey } = require('discord-interactions') | ||
const CLIENT_PUBLIC_KEY = process.env.CLIENT_PUBLIC_KEY; | const CLIENT_PUBLIC_KEY = process.env.CLIENT_PUBLIC_KEY; | ||
exports.handler = async (event, context) = | exports.handler = async (event, context) => { | ||
console.log(event) | console.log(event) | ||
const signature = event.headers['x-signature-ed25519']; | const signature = event.headers['x-signature-ed25519']; | ||
const timestamp = event.headers['x-signature-timestamp']; | const timestamp = event.headers['x-signature-timestamp']; | ||
console.log(signature, timestamp) | console.log(signature, timestamp) | ||
console.log(event[ | console.log(event["body"]) | ||
const isValidRequest = verifyKey(event[ | const isValidRequest = verifyKey(event["body"], signature, timestamp, CLIENT_PUBLIC_KEY); | ||
if (!isValidRequest) { | if (!isValidRequest) { | ||
console.log( | console.log("! returning 401") | ||
return { | return { | ||
statusCode: 401, | statusCode: 401, | ||
body: 'Bad request signature'} | body: 'Bad request signature'} | ||
} | } | ||
const interaction = JSON.parse(event[ | const interaction = JSON.parse(event["body"]); | ||
if(interaction && interaction.type === InteractionType.APPLICATION_COMMAND) { | if(interaction && interaction.type === InteractionType.APPLICATION_COMMAND) { | ||
const guild_id = interaction.guild_id | const guild_id = interaction.guild_id | ||
const mess = interaction.data.resolved.messages | const mess = interaction.data.resolved.messages | ||
| 129行目: | 129行目: | ||
return {statusCode: 200,'headers': {'Content-Type': 'application/json'},body: ret} | return {statusCode: 200,'headers': {'Content-Type': 'application/json'},body: ret} | ||
} else { | } else { | ||
console.log( | console.log("! returning pong") | ||
return {statusCode: 200, body: JSON.stringify({type: InteractionResponseType.PONG} )}; | return {statusCode: 200, body: JSON.stringify({type: InteractionResponseType.PONG} )}; | ||
} | } | ||
}</ | }</pre> | ||
CLIENT_PUBLIC_KEYはnetlifyの画面の環境変数から設定する(よくあるやつ)。 | CLIENT_PUBLIC_KEYはnetlifyの画面の環境変数から設定する(よくあるやつ)。 | ||
<ul> | <ul> | ||
<li><p>最初試していたとき、Netlify上では応答を返すところまで上手くいっているのに「インタラクションに失敗しました」interaction failed(一旦画面移動してから見ると「アプリケーションが応答しませんでした」application did not respondに変わっている)と出続けていたが、応答に</p> | <li><p>最初試していたとき、Netlify上では応答を返すところまで上手くいっているのに「インタラクションに失敗しました」interaction failed(一旦画面移動してから見ると「アプリケーションが応答しませんでした」application did not respondに変わっている)と出続けていたが、応答に</p> | ||
< | <pre class="visual">'headers': { | ||
'Content-Type': 'application/json', | |||
},</pre> | |||
< | <p>を付けたら通った…</p></li> | ||
<li><p>関連リンク</p> | |||
<ul> | |||
<li>[https://zenn.dev/azu0925/scraps/a6daaf258432dd discord botのinterationsのセキュリティ]</li> | |||
<li>[https://gammalab.net/blog/pky623yr9s6th/ Discordのslash commandでSQSにメッセージを送る - GammaLab]</li></ul> | |||
</li></ul> | |||
=== エンドポイントの分割 === | === エンドポイントの分割 === | ||