20220116のNode.jsに関する記事は11件です。

ReactとNode.js、AWSで社内システムを構築するまで 1/2

こんばんは。natariです。 社内システムの構築プロジェクトが終わったので、日記風にどんなことをやったかを書いていきます。 まず、プロジェクトの概要ですが、社内でExcelで管理している出社状況データ(今日は○○さんはテレワークだよーとか、〇日はお休みだよーとか、部の出社率とかを管理するもの)のweb化でした。 上長からこんな技術使ってとか、こんな風に作ってという指定はありませんでした。 なのでまずは社内の集会などを利用して、どんなシステムを作ったらいいかという皆さんの要望を聞き出すヒアリングから開始しました。 大体20人くらいの方から意見を頂き、すべての意見を反映させることは出来ないので、要望の数が多いものをピックアップして、あとはExcelで管理していたデータをそのままweb上で再現することとしました。 ここで僕にとって幸福だったのは、使用技術の指定がなかったことです。ちょうどプライベートでReactやTypeScript、Node.js、AWSあたりを勉強していたので、SPAでWebアプリを作ってみようと思い、この4つの技術を使うこととしました。 SPAについて簡単に説明すると、従来のよくあるフレームワークでのWebアプリの作り方とは異なり、クライアントとサーバーサイドを独立させて、データのみをやり取りする手法です。 ちなみに現在はGolangで別途APIサーバを作ってこんな感じで機能追加する予定です。 (プライベートで) まず、React(クライアント側)ですが、stateとpropsを使っていきます(当たり前)。 社内には部署が4つあります。そのため部署1~4のstateが必要です。 そしてカレンダーは月ごとに管理しているので、年(2022とか)と月(1~12)のstateも必要です。 次にログイン機能です。ログイン機能の作成についてはこちらの記事で詳しく説明しています。 https://qiita.com/natarisan/items/b43219f03566da8d0a66 ログインしているクライアント情報を保持するstateも必要です。 これらのstateをprops(場合によってはuseContextとか)を用いてうまいことコンポーネント間で共有します。 そして、各stateが変わったとき、そのstate応じたデータをfetchメソッドやaxiosメソッドでNodeサーバと通信して取ってきます。こんな感じで、fetchメソッドの中に現在のstateを当てはめる形でサーバにリクエストを送りました。 データベースもstateに対応するよう作成し、stateに対応するデータを返すようにしました。 同じくサーバ側で対応するデータの出社率計算機能も作成し、ひとまずアプリは完成です。 React-routerなども用いてやっとSPAっぽくなったなあという印象でした。 続いての記事は、作成したアプリをAWSにデプロイするまでを書いていきます。 今回は以上です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Discord.jsでDiscordの新機能のTimeoutを実装する

初めに 少し前にDiscordにTimeoutが実装されましたね 最近はテスト勉強などで忙しくて開発をしていませんでしたが今日から復活です! Timeoutに対して詳しくはこちら Docs https://discord.js.org/#/docs/main/stable/class/GuildMember?scrollTo=timeout released https://github.com/discordjs/discord.js/releases/tag/13.5.0 必要なもの Discord.js v13.5.0以降 Node.js v16以降 コード const {Client,Intents} = require('discord.js'); //面倒くさいので分割代入 new Client({intents: [ Intents.FLAGS.GUILD_MESSAGES,Intents.FLAGS.GUILDS]}) //インスタンス作る .on('messageCreate', message => { //メッセージイベントを発火する(interactionでも可) if(message.content.startsWith("!timeout")){ //メッセージのコンテンツが!timeoutから始めっていたら if(!message.member.permissions.has("MODERATE_MEMBERS")||!message.channel.permissionsFor(message.guild.me).has("MODERATE_MEMBERS")) return message.reply("権限不足"); //多分timeoutはモデレイトメンバー権限だと思うから自分とコマンド実行者にその権限があるか条件処理をする const args = message.content.split(" "),member = message.mentions.members.first()??message.guild.members.cache.get(args[1]); //argsにメッセージコンテンツの空白ごとに配列にした値を代入する(splitメソッドを使ってる) //memberにGuildMember classを代入する(詳しく言うとまずメンションされたユーザーを取得undefinedで返ったらメッセージが打たれたチャンネルでユーザーID{args[1](1番目の配列[splitメソッドで空白ごとに配列にしてある]<=0も含める場合0番目の配列)}をもとにユーザーを検索する if(!member) return message.reply(`ユーザーが見つかりませんでした`); //memberがundefinedで返ってきたらその有無を知らせる if(isNaN(args[2])) return message.reply(`数字を入れてください`); //args[2](2番目の配列<=0も含める場合1番目の配列[splitメソッドで空白ごとに配列にしてある])が数字かどうか判断すると同時にしっかり書いてあるか確認 member.timeout(Number(args[2]) * 60 * 1000, args.slice(3)?.join(" ")||`なし`) //memberに代入された値をもとに対象ユーザーをtimeoutするtimeの仕組みは1行前と同じ(isNaNをNumberで文字列から数値にしてるだけ) 理由の部分は(3番目以降[splitメソッドで空白ごとに配列にしてある]<=0も含める場合2番目以降)はあったらそのままなかったらなしと設定する .then(message.reply(`正常にタイムアウトしました\n詳細\n対象ユーザー:${member} 時間:${args[2]}分 理由:${args.slice(3)?.join(" ")||"なし"}`)) //timeoutに成功したらその詳細を知らせる .catch(e=>message.reply(`エラー:${e}`)); //失敗したら失敗した理由を乗せる } if(message.content.startsWith("!offtimeout")){ //上とほぼ同じ if(!message.member.permissions.has("MODERATE_MEMBERS")||!message.channel.permissionsFor(message.guild.me).has("MODERATE_MEMBERS")) return message.reply("権限不足"); const args = message.content.split(" ")[1],member = message.mentions.members.first()??message.guild.members.cache.get(args); if(!member) return message.reply(`ユーザーが見つかりませんでした`); member.timeout(0) .then(message.reply(`正常にタイムアウトを解除しました\n対象ユーザー${member}`)) .catch(e=>message.reply(`エラー:${e}`)); } }) .login("YOUTOKEN") //ログインする(ログイン関数を実行する) .then(console.log("login")) //成功したらloginとconsoleに表示する .catch(e=>console.log(`ログインエラー:${e.message}`)); //失敗したらエラー内容を出す 説明 コード内にコメントアウトした 間違ってる部分あったら教えて 最後に おやすみ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Lambdaで日付の差分を算出する [ Node.js・Python ]

はじめ Lambdaで、当日の日付を20220116の形にし、5日後の日付20220121を引くと、5という数字が出せるようにすることを目的として、Lambdaを作成したため、まとめます。 Lambdaコードの流れ 当日の日付 2022-01-16 11:41:21.282791(タイムゾーンはUTC) ↓UTCをJSTに変換する 2022-01-16 11:41:21.282791(タイムゾーンはUTC) ↓タイムスタンプに変更 1642765665851 ↓年、月、日のみに変換。(時間、分、秒は、切り捨て) 20210116 5日後の日付 2022-01-16 11:41:21.282791(タイムゾーンはUTC) ↓日付を5日進める 2022-01-21 11:41:21.282791(タイムゾーンはUTC) ↓UTCをJSTに変換する 2022-01-21 11:41:21.282791(タイムゾーンはUTC) ↓タイムスタンプに変更 1642765665851 ↓年、月、日のみに変換。(時間、分、秒は、切り捨て) 20210121 Lambdaの設定 Node.jsとPythonそれぞれ作成します。 Node.js Node.js exports.handler = async (event) => { // UTCの日付 "2022-01-16T11:31:09.498Z" const dateUTC = new Date(); const fivedateUTC = new Date().setDate(dateUTC.getDate() + 5); // JSTに変更後、タイムスタンプに変える const dateJST = new Date(dateUTC.getTime() + 32400000); // 5日進める const FivedateJST = new Date(fivedateUTC + 32400000); // タイムスタンプを日付の年月日に変える。時間は切り捨て let year = dateJST.getFullYear(); let month = dateJST.getMonth()+1; let day = dateJST.getDate(); let FiveLateryear = FivedateJST.getFullYear(); let FiveLatermonth = FivedateJST.getMonth()+1; let FiveLaterday = FivedateJST.getDate(); // 値が1桁であれば '0'を追加 if (month < 10) month = '0' + month; if (day < 10) day = '0' + day; if (FiveLatermonth < 10) FiveLatermonth = '0' + FiveLatermonth; if (FiveLaterday < 10) FiveLaterday = '0' + FiveLaterday; //"20220116" const dateTimeString = year + month + day; //"20220121" const FiveDaysLaterTimeString = FiveLateryear + FiveLatermonth + FiveLaterday; //20220116 const today = Number(dateTimeString); //20220121 const FiveDaysLater = Number(FiveDaysLaterTimeString); return FiveDaysLater - today; }; Python Python from datetime import datetime, timedelta def lambda_handler(event, context): # 2022-01-16 20:54:05.134159 dateJST = datetime.today() + timedelta(hours=9) dateJSTFiveDaysLater = dateJST + timedelta(days=5) #現在の日本の日付 20220116 today = int(dateJST.strftime("%Y%m%d")) # 5日後 20220121 fiveDaysLater = int(dateJSTFiveDaysLater.strftime("%Y%m%d")) return fiveDaysLater - today Pythonの方がすでにLambdaでインストール済みのライブラリが豊富なため、コードが少なくていいですね。 どちらも20220121 - 20220116 = 5という結果になりました。 参考 Node.js Python
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Lambdaで当日との日付の差分を算出する [ Node.js・Python ]

はじめ Lambdaで、当日の日付を20220116の形にし、5日後の日付20220121を引くと、5という数字が出せるようにすることを目的として、Lambdaを作成したため、まとめます。 Lambdaコードの流れ 当日の日付 2022-01-16 11:41:21.282791(タイムゾーンはUTC) ↓UTCをJSTに変換する 2022-01-16 11:41:21.282791(タイムゾーンはUTC) ↓タイムスタンプに変更 1642765665851 ↓年、月、日のみに変換。(時間、分、秒は、切り捨て) 20210116 5日後の日付 2022-01-16 11:41:21.282791(タイムゾーンはUTC) ↓日付を5日進める 2022-01-21 11:41:21.282791(タイムゾーンはUTC) ↓UTCをJSTに変換する 2022-01-21 11:41:21.282791(タイムゾーンはUTC) ↓タイムスタンプに変更 1642765665851 ↓年、月、日のみに変換。(時間、分、秒は、切り捨て) 20210121 Lambdaの設定 Node.jsとPythonそれぞれ作成します。 Node.js Node.js exports.handler = async (event) => { // UTCの日付 "2022-01-16T11:31:09.498Z" const dateUTC = new Date(); const fivedateUTC = new Date().setDate(dateUTC.getDate() + 5); // JSTに変更後、タイムスタンプに変える const dateJST = new Date(dateUTC.getTime() + 32400000); // 5日進める const FivedateJST = new Date(fivedateUTC + 32400000); // タイムスタンプを日付の年月日に変える。時間は切り捨て let year = dateJST.getFullYear(); let month = dateJST.getMonth()+1; let day = dateJST.getDate(); let FiveLateryear = FivedateJST.getFullYear(); let FiveLatermonth = FivedateJST.getMonth()+1; let FiveLaterday = FivedateJST.getDate(); // 値が1桁であれば '0'を追加 if (month < 10) month = '0' + month; if (day < 10) day = '0' + day; if (FiveLatermonth < 10) FiveLatermonth = '0' + FiveLatermonth; if (FiveLaterday < 10) FiveLaterday = '0' + FiveLaterday; //"20220116" const dateTimeString = year + month + day; //"20220121" const FiveDaysLaterTimeString = FiveLateryear + FiveLatermonth + FiveLaterday; //20220116 const today = Number(dateTimeString); //20220121 const FiveDaysLater = Number(FiveDaysLaterTimeString); return FiveDaysLater - today; }; Python Python from datetime import datetime, timedelta def lambda_handler(event, context): # 2022-01-16 20:54:05.134159 dateJST = datetime.today() + timedelta(hours=9) dateJSTFiveDaysLater = dateJST + timedelta(days=5) #現在の日本の日付 20220116 today = int(dateJST.strftime("%Y%m%d")) # 5日後 20220121 fiveDaysLater = int(dateJSTFiveDaysLater.strftime("%Y%m%d")) return fiveDaysLater - today Pythonの方がすでにLambdaでインストール済みのライブラリが豊富なため、コードが少なくていいですね。 どちらも20220121 - 20220116 = 5という結果になりました。 参考 Node.js Python
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

みんなが「それな」と思える事柄を開発業務未経験エンジニアが作ってみた【個人開発】

2021/11/30ごろに、みんなの共感を集めるアプリ「SORENA」をβリリースしました。 SESでのお仕事をしながらアプリのβリリースまで行うことができました。 この記事では『SORENA』のサービス内容や使い方、技術とのご紹介をさせていただきます。 また、βリリースにあたってフィードバックも頂いたので、これからのアプリの課題も書こうと思います。 目次 サービスの紹介  -何をするアプリなのか?  -メインページ  -結果画面 技術の紹介  -フロントエンド  -バックエンド  -ホストサービス  -使用データベース  -テーブル設計  -主な使用技術 悩んだポイント  -カードスワイプ  -node.jsのノンブロッキング処理  -MySQLの自動的切断問題 アプリの課題、将来的な実装  -なぜ、βの状態でリリースしたのか?  -これからのアプリの課題(フロント)  -これからのアプリの課題(サーバー) サービスの紹介 何をするアプリなのか? サイトURL:https://sorena-aruaru.com/ 実際に「これあるよねー」という事柄を「あるある」「ないない」を答えてもらい、その結果を収集するアプリです。 今はエンジニアのみですが、後々デザイナー等のカテゴリを増やしていく予定です。 メインページ カードに書かれている事柄に対して共感するならば右へスワイプ、しないならば左へスワイプというように直感的に「YES」「NO」を判断できるようなUIとなっています。 結果画面 メインページで判断した結果を最後に表示しています。 また、一番右には「今までどのくらい共感されたのか?」という共感された数をパーセントで表しています。 以下GitHubのコードです。 フロントエンド バックエンド 技術の紹介 ここからは技術のご紹介をいたします。 フロントエンド "nuxt": "^2.15.3" "@nuxtjs/axios": "^5.13.1" "swing": "^3.1.4" "vue-swing": "^0.0.10" "vuex": "^3.6.2" "@nuxtjs/vuetify": "^1.11.3" バックエンド node.js -v v14.18.1 "cors": "^2.8.5" "cross-env": "^7.0.3" "dotenv": "^10.0.0" "express": "^4.17.1" "mysql2": "^2.3.2" "nodemon": "^2.0.14" ホストサービス Netlify(フロントエンド) Heroku(バックエンド) データベース ClearDB ※Herokuのアドオンとして使用 テーブル設計 status_count 今までの問題IDに紐づいて「はい」「いいえ」の情報を貯めるテーブルです。 こちらはトランザクションテーブルの扱いにしています。 question_table 事柄の問題を貯めておくテーブルです。 今現在はマスターテーブルの扱いにしていますが後述するアップデートでトランザクションテーブルの扱いにする予定です。 将来的には以下のテーブルでスケールアップしていきたいと考えています。 count_logs status_countを膨大にため込まないためのテーブルです。 1日ごとに集計をして1日単位での結果レコードを生成します。 処理はバッチ処理として起動させます。 categories_table 「エンジニアあるある」や「デザイナーあるある」などのカテゴリ分けを行うテーブルです。category_idとquestion_tableをつなげて問題ごとのカテゴリ分けを行っています。 appled_questions Twitterから応募された問題をAPIを通してため込むテーブルです。 以下の画像のように、つぶやきから投稿された問題をTwitterAPIを通してタグで判断、カテゴリ分けをしてため込む形になります。 (DBスケール時に実装) また、クラッシュログなどサービス運用に必要なログも作成していく予定です。  ・主な使用技術 Nuxt.jsはnode.js+expressでサーバーAPIを構築しています。 問題回答と結果送信の反応 悩んだポイント カードスワイプ カードスワイプはvue-swingいうライブラリを使用して実装していきました。 「はい」か「いいえ」を判断する座標、カードを消すなどのイベントを書くときにオブジェクトプロパティが必要なのでconsole.logを使用してオブジェクトの中身を確認しながら実装していきました。 node.jsのノンブロッキングコーディング node.jsはノンブロッキングを前提としたコーディングが必要です。 node.jsを触られた方は分かると思いますが、手続き型の形で書いていくと、A=>B=>Cという関数の順番に実行させたいのにA=>C=>Bの順番で実行してしまう場合があります。 今現在は非同期で行う処理はありませんが、今後検索機能などを実装していくうえで必要となる処理となるのでPromissなどのノンブロッキングメソッドを意識したコードを書いていく必要があります。 MySQLの自動的切断問題 mysqlは仕様上、接続したまま自動的に接続が切られる仕組みとなっています。 これは、問題内容をリクエストする場合、何らかの原因でレスポンス応答が遅くなった場合、自動的に接続を切断され レスポンスエラーが起こる恐れがあります。 最初はコネクトエラーが起こった場合再度接続を行うというポーリングを書いていましたが、MySQLの接続プールは持続的に接続されると聞いて以下のようなモジュールを作成しました pool.js const mysql = require("mysql2"); const pool = mysql.createPool({ host: process.env.DB_HOSTNAME, user: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, }); module.exports = pool; このモジュールを使用し以下のように問題を呼び出していく処理を書いていきました getData.js const res = require("../app") const mysql = require("mysql2"); const pool = require("../dbController/pool"); function getData(res){ pool.getConnection(function(err,connection){ pool.query( "SELECT * FROM question_table;", (error, results) => { if (error) { console.log("error connecting: " + error.stack); return; } //makeQuestionsは問題を抽出する関数 const data = makeQuestions(results); res.header({'Content-Type': 'application/json'}); connection.release(); return res.json(data); } ); }) } 接続プールを使用するとトランザクション処理はできなくなるのですが、その処理をする場合は 接続=>処理=>リリース=>処理 というコードにしていく形になります。 コード、DB等の規則を作成してないリスクを考えてなかった 作成前に命名規則やCSSの構造規則を規定してなかったため、少し作成から離れたら「この変数って何?」という余計な時間を使うことになってしまいました。 また、DB名も「question_table」ではなく「questions_table」などの細かい部分での命名も決めてませんでした。 こちらはチーム開発を経験してないために雑になってしまったことが原因ですね、、、 リーダブルコード読んで出直してきます、、、 アプリの課題、将来的な実装 なぜ、βの状態でリリースしたのか? メイン機能を動かせる範囲で、 どの部分を改善するべきかの指標を明確化したいので、β版を公開した後はユーザーにアプリを使ってみて実際に感じたことを聞いていきました。 結果、 ・ファーストビューで何をするアプリなのかわからない ・スワイプ時にカードをリリースする距離が長くスマホだとやりにくかった ・はい、いいえが表示される画像のレスポンスが遅く、どちらの などのご意見を頂けました。 気づいたこと、こうしたほうがいいよねというご意見を色々いただけたのでよかったです。 これからのアプリの課題(フロント) ・作成中 これからのアプリの課題(サーバー) ・作成中
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Node.js][PostgreSQL] too many connections for role の解決

設定 PostgreSQL 13.5 Node.js 14.16.1 pg(node-postgres) 8.7.1 問題 Node.jsからDBに対するクエリのレスポンスが返ってこない 以下のコードのresultsが返らない model.js exports.getUserByUserId = async function (user_id) { var query = { text: "select * from users where user_id = $1;", values: [user_id], }; await pool.connect(); try { results = await pool.query(query); return results.rows[0]; } catch (e) { console.log(e); } }; psqlでCUIから接続しようとすると以下のエラーで接続できない psql: error: connection to server at [name] ([ip_address]), port [port_number] failed: FATAL: too many connections for role [name] ▸ psql exited with code 2 先行事例の調査 以下では解決できなかった FATAL: too many connections for role ..."に対して、自分がとった対策(Django/Heroku) - otkken2のプログラミング備忘録 原因 connectionが溜まっている 解決 connectionをreleaseする model.js exports.getGroupByGroupId = async function (group_id) { var query = { text: "select * from groups where group_id = $1;", values: [group_id], }; client = await pool.connect(); try { results = await client.query(query); client.release(); return results.rows[0]; } catch (e) { console.log(e); } }; 参考文献 pool.connect() => Promise
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Webの勉強はじめてみた その21 〜Slack上で動くbot作成1〜

N予備校の「プログラミング入門Webアプリ」を受講しています。 今回は第3章7〜9節です。 講義内ではTODOのbotでしたが、復習も兼ねて自分で作りました。 学んだ用語 CRUD クラッド ソフトウェアが情報の永続化をしようとしたときに出てくる操作、Create, Read, Update, Deleteの頭文字をとったもの。 リファクタリング ソースコードを見易くする。可読性の向上。 テスト駆動開発 実装や修正よりも先にテストを用意し、テストに適合するようにリファクタリングを繰り返すことでコードの品質を高めていく開発手法 とにかくほめてくれるbotを作る 要件 「ほめて」 : あらかじめ用意された配列からランダムで発言 「もっと ~」 : ~という内容を配列に登録。 「ほめないで ~」 : ~(インデックス)番のメッセージを削除 「見せて」 : 登録されているメッセージを一覧で表示 手順 praise-bot-testディレクトリを作成 1. yeomanのインストール(Dockerfileに記述) 2. yarn initで package.json を作成 3. index.js(モジュールを記述するファイル)とtest.js(テストを実行するファイル) 4. モジュールの実装 5. リファクタリング praise-botディレクトリ作成 1. yeomanのインストール(Dockerfile) 2. cp -r でpraise-bot-testをコピー 3. yo hubot --adapter=slack でbot作成 4. scriptsディレクトリに実行ファイル(index.js)を作成 5. 実装 6. slack上でhubotの作成 7. コンソール上で環境変数の指定と実行 Docker FROM --platform=linux/x86_64 node:14.15.4 RUN apt-get update RUN apt-get install -y locales RUN locale-gen ja_JP.UTF-8 RUN localedef -f UTF-8 -i ja_JP ja_JP ENV LANG ja_JP.UTF-8 ENV TZ Asia/Tokyo RUN yarn global add yo@3.0.0 RUN yarn global add generator-hubot@1.1.0 RUN yarn global add coffeescript@1.12.7 RUN useradd praise-bot -m USER praise-bot WORKDIR /home/praise-bot version: '3' services: app: build: . tty: true volumes: - .:/home/praise-bot モジュール 'use strict'; /** * slack上で欲しい言葉をくれるボット */ const praiseWords = [ {index:1, msg:"今日はよくがんばりました。すごいです。"}, {index:2, msg:"生きていてくれて嬉しいです。ありがとう。"}, {index:3, msg:"あなたの頑張りは私だけが知っています。お疲れ様でした。"}, {index:4, msg:"あなたの優しさはきっと届いています。"}, {index:5, msg:"今のあなたはイケてます。すごくいい感じです。"}, {index:6, msg:"たくさんがんばりましたね。今日もお疲れ様でした。"}, ]; /** * インデックスの最大値にプラス1をする * @returns 最大値 */ function maxIndex(){ let newInt = 1; //配列のindexのみ取得 const maxArray = praiseWords.map(m => m.index); //最大値 for(let max of maxArray){ if(max >= newInt){ newInt = max + 1; } } return newInt; } /** * メッセージの追加 * @param {integer} index * @param {string} msg メンションするメッセージ */ function addPraise(msg){ //indexの最大値取得 const newIndex = maxIndex(); praiseWords.push({index:newIndex, msg:msg}); } /** * 指定したインデックスでメッセージの削除 * @param {integer} index */ function delPraise(index){ //指定されたインデックスの存在チェック const indx = praiseWords.findIndex(p => p.index === index); if(indx !== -1){ praiseWords.splice(indx, 1); } } /** * 一覧を表示 * @returns index : メッセージ */ function listPraise(){ return praiseWords.map(w => w.index + " : " + w.msg); } /** * ランダムにメッセージを返す * @returns {string} メッセージ */ function praise(){ if(praiseWords.length > 0){ //ランダムな添字の取得 const randomIndex = Math.floor(Math.random() * praiseWords.length); return praiseWords[randomIndex].msg; }else{ return "ほめてもらいたい言葉が見つかりませんでした"; } } module.exports = { praise, add:addPraise, del:delPraise, list:listPraise } 'use strict'; // Description // 「ほめて」というとほめてくれるbot // Commands: // ほめて - 登録された言葉をランダムに発言する // もっと メッセージ内容 - ほめて欲しい言葉を登録する // ほめないで index番号 - 指定された番号の言葉を削除する // 見せて - 登録されている言葉を一覧表示 const praise = require('praise-bot'); module.exports = robot =>{ robot.hear(/ほめて/i, msg =>{ const words = praise.praise(); msg.send(words); }); robot.hear(/もっと (.+)/i, msg =>{ const words = msg.match[1].trim(); praise.add(words); msg.send("登録しました。もっとほめますね♪"); }); robot.hear(/ほめないで (.+)/i, msg =>{ const index = msg.match[1].trim(); praise.del(parseInt(index)); msg.send("削除しました。他の言葉でほめますね。"); }); robot.hear(/見せて/i, msg =>{ const words = praise.list().join('\n'); if(words.length === 0){ msg.send("登録されているメッセージがありません。") }else{ msg.send(words); } }); } コンソール上で実行するとき、APIトークンだけではうまくいかなかった HUBOT_SLACK_RTM_CLIENT_OPTS='{"dataStore":"false","useRtmConnect":"true"}' これを一緒に実行すると大丈夫みたい。 HubotのRTM?ちょっと詳しいことはわからないけれど後で調べたい。 最終的に下で実行するとよい。 env HUBOT_SLACK_TOKEN=xoxb-xxxxxxx HUBOT_SLACK_RTM_CLIENT_OPTS='{"dataStore":"false","useRtmConnect":"true"}' bin/hubot --adapter slack まとめ 実際に自分で考えて作って、ようやく全体の流れみたいなものが理解できた。作業量が増えてきてるので難しい。 次はbotの永続化とのことなので、とにかくほめるbotも引き続き改良したい。入力チェックも特にしてない状態なので。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.js Express ミドルウェア

【Node.js Express ミドルウェア】 Expressで足りないものは、ミドルウェアでカバー リクエストレスポンスに対して、任意の追加処理を行う関数のこと。 リクエストオブジェクトの変更 レスポンスオブジェクトの変更 リクエスト・レスポンスを用いた独自の追加処理 ...etc ミドルウェアの実装 通常処理 function (req, res, next) { //何かの処理 (次の処理を呼べるように next ) next(); }  エラー処理 function (err, req, res, next) { //何かの処理 (次の処理を呼べるように next ) ​ ​next(); } ミドルウェアの組み込み const express = require("express"); const app = express(); app.use((req, res, next) => { //アプリケーションレベルのミドルウェア }); app.listen(3000); ※ コードの上から順に、全てのリクエストに対して処理が実行される。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フロントエンドとNode.jsで繋いだ時のCORSエラーについて

フロントエンド(Angular)とバックエンドの繋ぎこみを行なった時にcorsエラーが表示され、それに対応した流れを書いていこうと思います。 エラーの内容 core.js:6498 ERROR Error: Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":"http://localhost:3000/some","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:3000/some: 0 Unknown Error","error":{"isTrusted":true}} at resolvePromise (zone.js:1213:1) at resolvePromise (zone.js:1167:1) at zone.js:1279:1 at ZoneDelegate.invokeTask (zone.js:406:1) at Object.onInvokeTask (core.js:28679:1) at ZoneDelegate.invokeTask (zone.js:405:1) at Zone.runTask (zone.js:178:1) at drainMicroTaskQueue (zone.js:582:1) at ZoneTask.invokeTask [as invoke] (zone.js:491:1) at invokeTask (zone.js:1600:1) フロントエンドは localhost:4200 で起動 バックエンドは localhost:3000 で起動しています。 したがってお互いのポートが異なるためにcorsエラーを引き起こしています。 やったこと node.js側でcorsのライブラリを入れました。 app.ts import express from 'express'; import cors from 'cors'; const app = express(); app.use(cors()); これにより、フロントエンド側でのcorsエラーを解消することができました。 corsのライブラリについての説明があったので下記にリンクを記載します。 express.jsのcors対応
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel Mix で ERR_OSSL_EVP_UNSUPPORTED が出た時の対策

npm run dev を行った時、次のようなエラーが出ます。 { opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ], library: 'digital envelope routines', reason: 'unsupported', code: 'ERR_OSSL_EVP_UNSUPPORTED' } これは次のバージョンで発生します。 Node.js v17.3.1 Node.js v17.3.0 Node.js v17.2.0 Node.js v17.0.0 次のバージョンでは発生しないことを確認しました。 Compiled Successfully v16.13.2 v16.10.0 v15.14.0 v15.0.0 v14.8.3 v14.8.2 v14.8.1
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.js on Dockerでエラー発生(Error: EACCES: permission denied, errno: -13)

はじめに DockerでNext.jsを使ってウェブページを作ろうとしたけど、npx create-next-app {name}の段階でglob errorっていうワケワカランのが発生した。テンションが下がった。 環境 Linux (KDE neon based on Ubuntu) Docker version 20.10.12 image node:17.3-alpine 問題 # コマンドをうちこむ docker-compose run --rm node npx create-next-app nextjs-tutorial Creating nextjs-tutorial_node_run ... done Creating a new Next.js app in /usr/src/app/nextjs-tutorial. Using npm. Installing dependencies: - react - react-dom - next #エラー❗❗❗なにこれ。 glob error [Error: EACCES: permission denied, scandir '/root/.npm/_logs'] { errno: -13, code: 'EACCES', syscall: 'scandir', path: '/root/.npm/_logs' } とりあえず権限が無いということはわかった。permission deniedとか出たときは大方ファイル権限かユーザー管理あたりが原因。 原因 DockerFileにUSER nodeの指定がないことが原因だった。これが何を意味するんだろうか? コマンドをrootで実行しなくなるということだから、とりあえずセキュリティリスクが低下することはなんとなくわかる。 とりあえず、参考したページでUSER nodeの指定をしろと書いてあったのでそうする。 解決策 DockerFileにUSERの指定を追記したら解決するらしい。 DockerFile FROM node:17.3-alpine WORKDIR /usr/src/app USER node こうすると、このイメージで作成されたコンテナは実行ユーザーがnodeになる。 あるいは、WORKDIRを/home/にしたらいいっぽい。 DockerFile FROM node:17.3-alpine WORKDIR /home/node/app やっぱりrootが絡むとよくないんだろうか。 理屈はわからんけどとりあえずヨシ! おわりに 理屈はまだ理解してないけれど、とりあえずこれを書いてるのが深夜3時過ぎで、このあと午前10時から予定があるので、理解は後回しにしようと思います。 誰かわかるよって人いたら教えてほしいです。よろしくおねがいします。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む