20211015のNode.jsに関する記事は4件です。

discord.js-v13でdiscordbot (スレッド周りの機能実装)

はじめに 当記事は筆者の忘備録であり、完全なチュートリアルではないことをご理解ください。 スレッド周りのみを見たい方はこちらを 開発環境 Node.js - 16.11.0 discord.js - 13.2.0 環境構築 Node.js 公式サイト discord.js 公式Guide まずは適当な場所に新規フォルダを作成し、そのフォルダ内で npm init -y を実行、完了したら同フォルダ内で npm install discord.js 上記二つが完了すればひとまず開発環境は構築できました。 botの招待 discord developer portal その1 ログイン後New Application buttonをクリックし、Appを作成してください 作成が完了したらページ左側にあるBot項目をクリックし、Add Botをクリックします。 ここでTOKENという項目と青色のボタンが現れると思うので左側のCopyをクリックしトークンを控えておいてください。 今控えたトークンは必ず他人に教えないでください。またGithub等にトークンが記載されたファイルを 上げることも控えてください。当警告を無視した結果起こりえる被害について筆者は責任を負いかねます。 その2 ページ左側のOAuth2をクリック ここが重要で SCOPEの中にあるbotとapplications.commandsに必ずチェックを入れてください。 後々追加することも可能ですが思わぬエラーと無駄な時間を過ごすことになります。 チェックを入れると下側にBOT PERMISSIONSという項目が出てくるので 皆様の用途に合った設定をしてください。 全てにチェックを終えたら、先ほどのSCOPEにURLが表示されていると思うのでコピーし踏んでください。 これで導入は完了! ファイル作成 discord.js Guide(Initial files) トークン管理ですが、ここではひとまずローカル環境での動作を目的としているので 最初に作成したフォルダのルートディレクトリにconfig.jsonファイルを作成してください。 以下中身 config.json { "token": "先ほど控えたトークンを張り付けてください。" } gitignoreも作成します。 node_modules .env config.json ようやくメインファイルであるindex.jsを作成します。 以下中身 index.js const { Client, Intents } = require('discord.js'); const { token } = require('./config.json'); const client = new Client({ intents: [Intents.FLAGS.GUILDS] }); client.once('ready', () => { console.log('Ready!'); }); client.login(token); 作成が完了したらターミナル(コマンドプロンプト)で node index.js を実行してみてください。ターミナル上にReady!と表示されたらひとまず作業は完了です。 終了はCtrl + cです。 コマンド作成 ここではv13から追加されたスラッシュコマンドを作成します。 まずは以下画像を見てください。 このように/を入力するとコマンド一覧が現れますよね?botがいないサーバーで入力してもビルドインコマンドが表示されます。 これらを今から作成します。 ちなみにですが、ここでapplications.commandsにチェックを入れていない場合次の作業を行った時に 必ずエラーが発生します。だからチェックをいれる必要があったんですね! 本題ですが、まずはプロジェクトフォルダ内で npm install @discordjs/builders @discordjs/rest discord-api-types を行ってください。これらはスラッシュコマンドを作成するときに必須な物です。 インストールが完了したら、先ほど作成したconfig.jsonを以下のように修正します config.json { "clientId": "123456789012345678", "guildId": "876543210987654321", "token": "your-token-goes-here" } clientIdとguildIdはそれぞれ - clientId ⇒ https://discord.com/developers/applications のOAuth2タブにCLIENT IDが記載されていますのでそれを張り付けてください。 - guildId ⇒ botを参加させたサーバーのIDです。サーバーを開いて名前を右クリックするとIDをコピーと出てきますのでコピペ。 次に核となるdeploy-commands.jsを作成します。 以下中身 deploy-commands.js const { SlashCommandBuilder } = require('@discordjs/builders'); const { REST } = require('@discordjs/rest'); const { Routes } = require('discord-api-types/v9'); const { clientId, guildId, token } = require('./config.json'); const commands = [ new SlashCommandBuilder().setName('ping').setDescription('Replies with pong!'), new SlashCommandBuilder().setName('server').setDescription('Replies with server info!'), new SlashCommandBuilder().setName('user').setDescription('Replies with user info!'), ] .map(command => command.toJSON()); const rest = new REST({ version: '9' }).setToken(token); rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands }) .then(() => console.log('Successfully registered application commands.')) .catch(console.error); 少しだけ解説をば - setName ⇒ コマンド名。setName('ping')であれば/pingと入力することができるようになります。 - setDescription ⇒ コマンドの説明文です。先ほどの画像でコマンド名の下に出てきてたやつです。 オプションは他にも沢山あります。詳細はこちら 後ほど記述するスレッド周りのコマンドも他オプションを利用します。 作成出来たら ファイルがあるディレクトリで node deploy-commands.js を実行してください。完了したら自身のサーバーで/を入力してみてください。コマンド一覧が出てきます。 ただ、現状はコマンドを登録できただけで機能は実装していないので次項からいよいよ実装に入ります。 コマンドに対しての機能実装 公式ガイド ここではコマンドに対して起こる機能を実装します。index.jsを開いて以下のように編集してください。 index.js client.once('ready', () => { console.log('Ready!'); }); //以下追加 client.on('interactionCreate', async interaction => { if (!interaction.isCommand()) return; const { commandName } = interaction; if (commandName === 'ping') { await interaction.reply('Pong!'); } else if (commandName === 'server') { await interaction.reply('Server info.'); } else if (commandName === 'user') { await interaction.reply('User info.'); } }); // ここまで client.login(token); 一応解説 if (commandName === 'ping') { await interaction.reply('Pong!'); // もしコマンド名が 'ping' だったら 'Pong!' を返します 詳しくは以下画像を見てください。 interactionってなんぞや?って人はここを参照してください。 返信内容に引っ張ってきたデータを入れたい場合はシングルクォーテーションで囲うのではなくバッククォートで囲って await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`); このように記述すると こんな感じで出せます。 ひとまず・・・ 以上で簡単なbotは作成完了しました。お疲れさまでした。 コマンドが増えていくとコマンド事にファイルを分ける等の作業が必要になりますがそれらはここでは解説しません。 次項からは応用編としてタイトルにもあるようにスレッド周りの実装を行います。 元気な方は引き続き頑張りましょう。 スレッド周りの実装 はじめに 当項目はスレッド周りの実装をしてみようと思った矢先、日本語記事が全くなくとてもつらい思い(ドキュメント漁り)をしたので こうして日本語記事として残そうと思った次第です。 ソース index.js else if (commandName === 'ct') { const thread = await interaction.channel.threads.create({ name: `${interaction.options.getString('name')}`, autoArchiveDuration: 60, reason: 'Needed a separate thread for food', }); interaction.reply({ content: `${thread.name}が立ちました。`, ephemeral: true });; } deploy-commands.js new SlashCommandBuilder().setName('ct').setDescription('create thread').addStringOption(option => option.setName('name').setDescription('スレッド名を入力してください。')) 解説 まずはdeploy-commands.jsの方から deploy-commands.js .addStringOption(option => option.setName('name').setDescription('スレッド名を入力してください。')) .addStringOptionでコマンドに対して以下の画像のようにオプションをつけることができます ここではオプションの名前をnameとしています。 ここで入力されたhelloは後ほど使います。 続いてindex.js index.js if (commandName === 'ct') { const thread = await interaction.channel.threads.create({ name: `${interaction.options.getString('name')}`, autoArchiveDuration: 60, reason: 'Needed a separate thread for food', }); interaction.reply({ content: `${thread.name}が立ちました。`, ephemeral: true });; } await interaction.channel.threads.create // コマンドが送信されたチャンネルにスレッドを作成します 以下channel.threads.createのオプション name: `${interaction.options.getString('name')}` // interaction.options.getString('ここに(option.setNameで付けた名前を入れます)') // こうすることで先ほどオプションで入力させた'hello'がこれから立ち上がるスレッドの名前になります autoArchiveDuration: 60, // 何分で自動アーカイブするかの設定です reason: 'Needed a separate thread for food', // これよくわからないんですよね...() interaction.reply({ content: `${thread.name}が立ちました。`, ephemeral: true });; // この部分、実はなくてもスレッドは立ちますがこれを記述しないと以下画像のようにエラーを吐きます。 // ephemeralは初期値だとFalseですがtrueにすることでbotからのメッセージがコマンドを打った人間にしか見えなくなります。 まとめ ここまで見てくださった皆様、お疲れ様でした。そしてご覧いただきありがとうございます。 雑な解説ではありましたがどなたかのお役に立てたなら幸いです。 私自身discord.pyを過去に使っていて最近discord.jsにやってきた身なのでまだまだ分からないことだらけですが頑張ってこれからも開発していけたらなぁと思っています。 また、そのうち本記事では紹介できなかった部分も記事に起こすつもりなのでまた良ければお願いします。 さいごに 当記事は公式のGuideをもとに個人的な解釈を含めて解説したものです。 なのでもちろん正しい完璧な記事とは言えないのでもし問題・質問等ありましたらお気軽にコメントしてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitHub Actionsを使ってGithub PagesにOpen APIのRedocドキュメントを出力したメモ

概要 Github Pagesがorganizationでprivateに対応していたので 業務で使ってるOpen APIの定義をpushされた時に自動デプロイするようにしてみました swagger-viewerとかで見るのがめんどかったので ソースコード 構成 ├── .github │   └── workflows │   └── gh-pages.yml ├── docs │   └── index.html ├── package-lock.json ├── package.json └── petstore.yaml : from https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore.yaml workflows gh-pages.yml name: github pages on: branch push: branches: [ main ] # 手動実行できるようにするため workflow_dispatch: jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: ref: main # 手動実行時のブランチを指定しておく - uses: actions/setup-node@v2 with: node-version: '16' cache: 'npm' - run: npm ci - name: bundle run: npm run bundle - name: pages deploy uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs workflowが実行されるとgh-pagesブランチが作られるので first-deployment-with-github_token@actions-gh-pagesを参考に Settings > Pagesを開いて Sourceにgh-pagesを設定する 再度workflowを実行する デプロイを確認する つまった所 npm install - uses: actions/setup-node@v2 with: node-version: '14' cache: 'npm' - run: npm install -g redoc-cli - name: bundle run: redoc-cli bundle petstore.yaml npm install -gしたらいけるだと思ったらエラー Error: Dependencies lock file is not found nodeのバージョン 参考にしてnode-version: '14'にしたらエラー internal/modules/cjs/loader.js:905 throw err; ^ Error: Cannot find module 'react-is' Require stack: ... node-version: '16'にしました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ESP32とIRリモートおよび手動制御を使用したAlexaホームオートメーション-IoTプロジェクト2021

この記事はJLCPCBと共同で公開されています。JLCPCBはPCBのプロトタイプと製造の分野で10年以上の経験を持つ最も経験豊富なPCBメーカーのひとつであり、品質、納期、費用対効果など、さまざまな業界のお客様のニーズを満たすことに取り組んでいます。 このIoTプロジェクトでは、Alexa、IRリモート、スイッチを使用して、IoTベースのESP32ホームオートメーションを作成し、インターネットの有無にかかわらず8チャネルリレーモジュールを制御する方法を示しました。インターネットが利用できない場合は、IRリモートおよび手動スイッチから家電製品を制御できます。記事の中で、私はこのホームオートメーションシステムを作るために、すべてのステップを示しました。 このESP32制御リレーモジュールには、次の機能があります。 1.Alexa(音声制御)で家電製品を制御します。 2.IRRemoteで家電製品を制御します。 3.手動スイッチで家電製品を制御します。 4.Blynkアプリでリアルタイムのフィードバックを監視します。 5.IRリモコンやスイッチからインターネットを使わずに手動で家電製品を制御します。 PCBを使用したくない場合は、8チャネルリレーモジュール、ESP32、およびIRレシーバーセンサーを使用してこのIoTプロジェクトを作成することもできます。                                       Supplies(用品) 1.ESP32 DEVKIT 2.TSOP1838 IR receiver 3.Relays 5v (SPDT) (8 no) 4.BC547 Transistors (8 no) 5.PC817 Optocuplors (8 no) 6.510-ohm 0.25-watt Resistor (8 no) (R1 - R8) 7.1k 0.25-watt Resistors (10 no) (R9 - R18) 8.LED 5-mm (10 no) 9.1N4007 Diodes (8 no) (D1 - D8) 10.Push Buttons (8 no) or Switches 11.Terminal Connectors5V DC supply 12.Any Alexa devices like ECHO DOT                                   ステップ1:ESP32プロジェクトの回路図 これは、このホームオートメーションプロジェクトの完全な回路図です。チュートリアルビデオで回路を説明しました。 回路は非常に単純です。GPIOピンD23、D22、D21、D19、D18、D5、D25、およびD26を使用して8つのリレーを制御しました。 また、GPIOピンD13、D12、D14、D27、D33、D32、D15、およびD4は、スイッチに接続されて8つのリレーを手動で制御します。 また、IRレシーバーの出力ピンはGPIOD35に接続されています。 プルアップ抵抗を使用する代わりに、ArduinoIDEでINPUT_PULLUP関数を使用しました。 5V 5ADC電源を使用しました。                                   ステップ2:PCBを設計する前に回路をテストする PCBを設計する前に、私が使用して完全な回路を作ったESP32、8チャネルリレーモジュール、IR受信機、および手動スイッチ。 あなたが見ることができるように、リレーから制御することができる赤外線リモコン、手動スイッチ、およびアマゾンアレクサアプリケーション。次の手順では、プロジェクト全体を詳細に説明し、コードとPCBガーバーファイルも共有しました。このプロジェクトのコードをダウンロードします。                                ステップ3:Alexaを使用して音声コマンドでリレーを制御する ESP32モジュールがWiFiに接続されている場合は、Amazon Alexaアプリ、IRリモート、および手動スイッチから家電製品を制御できます。 Alexaアプリでリレーのリアルタイムステータスを制御、監視できます。ESP32、Amazon EchoDotは同じWiFiネットワークに接続する必要があります。                                   ステップ4:IRリモートを備えたESP32制御リレー IRリモコンからいつでもリレーを制御できます。このプロジェクトでは、任意のIRリモコンを使用できます。 次の手順で、リモコンからIRコード(HEXコード)を取得する方法を説明します。 また、ESP32がWi-Fiに接続されている場合は、AmazonAlexaアプリでリアルタイムのフィードバックを監視することもできます。                                                                    ステップ5:スイッチを使用してリレーを手動で制御する WiFiが利用できない場合は、手動スイッチからリレーを制御することもできます。 ESP32は3秒ごとにWiFiをチェックします。WiFiが利用可能になると、ESP32は自動的にWiFiに接続します。 手動スイッチの接続は回路図を参照してください。                                  ステップ6:このスマートホームシステムのPCBを設計する 回路をコンパクトにしてプロフェッショナルな外観にするために、スマートリレーモジュールのすべての機能をテストした後、PCBを設計しました。 このホームオートメーションプロジェクトのPCBGerberファイルは、次のリンクからダウンロードできます: https://drive.google.com/uc?export=download&id=1Y8rXnczq6baxAKOrBEE8aro-uqcK0J93                                         ステップ7:PCBを注文する ガーバーファイルをダウンロードした後、PCBを簡単に注文できます https://jlcpcb.com/JPA にアクセスし、サインイン/サインアップします [ QUOTENOW ]ボタンをクリックします。 3 [ガーバーファイルを追加]ボタンをクリックします。次に、ダウンロードしたガーバーファイルを参照して選択します。                                                                ステップ8:ガーバーファイルをアップロードしてパラメータを設定する 4.数量、PCBマスキングカラーなどの必要なパラメータを設定します 5.PCBのすべてのパラメーターを選択した後、[カートに保存]ボタンをクリックします。                                  ステップ9:配送先住所と支払いモードを選択します 6.配送先住所を入力します。 7.お客様に適した配送方法を選択してください。 8.注文を送信し、支払いを続行します。https://jlcpcb.com/JPA から注文を追跡することもできます。 私のPCBは、DHL配送オプションを使用して製造され、1週間以内に到着するまでに2日かかりました。 PCBは十分に梱包されており、この手頃な価格で品質は本当に良かった。 ステップ10:PCB上のすべてのコンポーネントをはんだ付けする その後、回路図に従ってすべてのコンポーネントをはんだ付けしました。 次に、ESP32ボードをPCBに接続します。 ステップ11:リモートからIRコード(HEXコード)を取得する ここで、リモートからHEXコードを取得するには、まず、IRレシーバーの出力ピンをGPIOD35に接続する必要があります。 そして、VCCとGNDの両端に5Vを与えます。IRレシーバは、金属製の筐体を持っている必要がありそうでない場合、あなたが問題に直面する可能性があり、。 次に、次の手順に従ってHEXコードを取得します 1.ArduinoIDEにIRremoteライブラリをインストールします 2.添付のコードをダウンロードして、ESP32にアップロードします。 3.ボーレート9600のシリアルモニターを開きます。 4.次に、IRリモートボタンを押します。 5.それぞれのHEXコードがシリアルモニターに入力されます。 すべてのHEXコードをテキストファイルに保存します。 Attachments Code_IR_Button_HEX_Code.inoDownload                                 ステップ12:BlynkESP32ホームオートメーションのコード スイッチ(ラッチ)を使用する場合は、スイッチのコードを参照してください。一時的なスイッチの場合は、押しボタンのコードを使用してください。 ArduinoIDEに次のライブラリをダウンロードしてインストールします ・IRremoteライブラリ ・AceButtonライブラリ ・エスパレクサライブラリ コード内のすべてのライブラリのダウンロードリンクを共有しました。 Attachments Code_ESP32_Alexa_IR_Manual_Button_8Relays.inoDownload Code_ESP32_Alexa_IR_Manual_Switch_8Relays.inoDownload                                  ステップ13:ArduinoIDEでESP32をプログラムする コードで入力してください無線LAN名、無線LANのパスワード&Blynk認証トークンを。 次に、チュートリアルビデオに示すように、ir_remote関数のHEXコードを更新します。 その後、DOIT ESP32 DEVKITV1ボードと適切なポートを選択します。 次に、コードをESP32ボードにアップロードします。 コードをESP32にアップロードしているときに、「Connecting ....___」というテキストが表示された場合は、ESP32のBOOTボタンを押します。                              ステップ14:スマートホームシステム用にAlexaアプリをセットアップする Amazon Alexaアプリを開き、次の手順に従います。 1.[デバイス]をタップします。次に、「+」アイコンをタップします。 2.「ライト」をタップし、「その他」を選択します。 3.Alexaに移動し、[デバイスの検出]をタップします。デバイスの追加には1分かかります。この間、ESP32はWiFiに接続する必要があります。 4.[デバイス]をタップし、[ライト]をタップしてすべてのデバイスを表示します。                                     ステップ15:AlexaでPCBをテストする コードをアップロードした後、ESP32がWiFiに接続すると、青いLEDが点灯します。 次に、Amazon AlexaAppからリレーモジュールを制御できます。                                      ステップ16:家電製品を接続する 回路図に従って8つの家電製品を接続します。 高電圧での作業中は、適切な安全対策を講じてください。 5ボルトのDC電源をPCBに接続します。                                      ステップ17:電源をオンにします 110V / 230V電源と5VDC電源をオンにします。                              ステップ18:ついに!! Alexaホームオートメーションシステムの準備ができました 今、あなたはスマートな方法であなたの家電製品を制御することができます。 このAlexaホームオートメーションプロジェクトを気に入っていただけたでしょうか。このプロジェクトに必要なすべての情報を共有しました。貴重なご意見をお寄せいただければ幸いです。 また、ご不明な点がございましたら、コメント欄にご記入ください。ありがとう&ハッピーラーニング。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javascriptのコールバック関数について

Javascriptのコールバック関数に関して、アウトプットのため本記事を投稿します。 Javascriptにおけるコールバック関数とは「将来のある時点で実行される関数」のことを指します。 簡易的な例 下記に例を記載します。 function a(callback) { callback(); } function b() { console.log("コールバック関数として呼び出されました"); } a(b); //実行結果 コールバック関数として呼び出されました 処理の流れを記載します。 ① aという関数を宣言します。(仮引数の名称は何でも大丈夫です) ② bという関数を宣言します。 ③ ②で宣言したbという関数を実引数として、①で宣言したaという関数を呼び出します。 ④ aの処理が実行され、bという関数が実行されます。 ⑤ bの処理が実行され、文字列が出力されます。 関数aの仮引数には、実引数である関数bが入るので、callback() と b()は同じ命令に変換されます。 このように、コールバック関数では、引数に関数を渡して任意のタイミングで呼び出すことができます。 複雑な例 次に、前章のコードよりも複雑になったコールバック関数を解説します。 function a(callbackB) { console.log("関数aが呼び出されました"); callbackB(); } function b(callbackC) { console.log("コールバック関数bが呼び出されました"); callbackC(); } function c(callback) { console.log("コールバック関数cが呼び出されました"); callback(); } a(function() { b(function() { c(function() { console.log("全ての処理が終了しました"); }); }); }); // 実行結果 関数aが呼び出されました コールバック関数bが呼び出されました コールバック関数cが呼び出されました 全ての処理が終了しました 処理の流れを記載します。 ① 関数a,b,cを宣言します。 ② 関数aを実行します。 ③ 関数aの仮引数「callbackB」に関数aの呼び出し元の実引数が渡されます。 関数aの呼び出し元の実引数は下記コードです。 function() { b(function() { c(function() { console.log("全ての処理が終了しました"); }); }); }) 関数bの実引数があるため分かりづらくなっていますが、関数bの呼び出し元の実引数は使用しないので、実質的な仮引数は下記のように、関数bを呼び出す無名関数になります。 function() { b(); }) ④ 「console.log("関数aが呼び出されました")」が実行されます。 ⑤ ③で渡された引数(callbackB)を実行します。   先ほど説明した通り、実引数は無名関数であるため、関数bを実行する処理になります。 ⑥ 関数bの仮引数「callbackC」に、関数bの実引数(関数cを呼び出す無名関数)が渡されます。 ⑦ 関数bが実行され、「console.log("コールバック関数bが呼び出されました")」が実行されます。 ⑧ ⑥で渡された引数(callbackC)を実行します。 ⑨ 関数cの仮引数「callback」に、関数bの実引数(無名関数)が渡されます。  実引数(無名関数)は以下です。 function() { console.log("全ての処理が終了しました") } ⑩ 関数cが実行され、「console.log("コールバック関数cが呼び出されました")」が実行されます。 ⑪ ⑨で渡された引数を実行します。 ⑫ 「console.log("全ての処理が終了しました")」が実行されます。 上記の様に、関数a,b,cを順番に実行することができます。 また、関数の呼び出し元は下記の様にアロー関数でも実行することができます。 a(() =>{ b(() =>{ c(() =>{ console.log("全ての処理が終了しました"); }); }); }); アロー関数の方が、記述がシンプルになり可読性が上がります。 setTimeoutメソッドを使用した例 setTimeoutメソッドを使用した際のコールバック関数の処理に関して記述します function a(callback) { setTimeout(callback, 3000); }; function b() { console.log("コールバック関数として呼び出されました"); }; a(b); console.log("関数呼び出し後"); // 実行結果 関数呼び出し後 コールバック関数として呼び出されました setTimeoutはノンブロッキングメソッドであるため、関数bが呼び出されるより先に、「console.log("関数呼び出し後")」が実行されます。 コールバック関数はあくまでも関数を順番に実行しするために使用するため、ブロッキングをして同期処理を実現いるわけではないことが分かります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む