20220119のNode.jsに関する記事は10件です。

Node.js 【MySQL 8.0 に接続できない。】

Node.js 【MySQL 8.0 に接続できない。】 DBからデータ取得ができずに詰まったので備忘録。 起きたこと node.jsのパッケージ使って、MySQL8.0に接続しようとするとエラー発生 Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client エラー:ER_NOT_SUPPORTED_AUTH_MODE:クライアントはサーバーから要求された認証プロトコルをサポートしていません。 MySQLクライアントのアップグレードを検討してください (Google翻訳) 原因 MySQL8.0のパスワード認証形式の違いが原因。 MySQL8.0の認証プラグイン caching_sha2_password (MySQL5.7までは、mysql_native_password) mysql> SELECT user, host, plugin FROM mysql.user; +------------------+-----------+-----------------------+ | user | host | plugin | +------------------+-----------+-----------------------+ | mysql.infoschema | localhost | caching_sha2_password | | mysql.session | localhost | caching_sha2_password | | mysql.sys | localhost | caching_sha2_password | | root | localhost | caching_sha2_password | +------------------+-----------+-----------------------+ 4 rows in set (0.00 sec) 解決策 root(user), localhost(host)の plugin を変更。 caching_sha2_password → mysql_native_password plugin変更 mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; 特権を更新 flush privileges; 確認 mysql> SELECT user, host, plugin FROM mysql.user; +------------------+-----------+-----------------------+ | user | host | plugin | +------------------+-----------+-----------------------+ | mysql.infoschema | localhost | caching_sha2_password | | mysql.session | localhost | caching_sha2_password | | mysql.sys | localhost | caching_sha2_password | | root | localhost | mysql_native_password | +------------------+-----------+-----------------------+ 4 rows in set (0.00 sec) その後、DBからデータ取得が取得できるようになりました。 おわりに。 こちらの記事 mysql2 をインストールするという手もあるようです。 npm install mysql2 caching_sha2_password の状態でも接続できるようです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Webpackerでerror Command "webpack-dev-server" not foundになる

はじめに 最近Railsの開発環境を作成しています。 こちらの記事で構築手順を載せています。 そこで、GitにリポジトリをあげたコードをCloneして起動したところうまく起動できない事態が発生したため手直しのさいに解決した方法をまとめます。また、この記事とは別にWebpackerの問題がもう一つ起きています。 以下の記事から確認ください。 問題 DockerでWebpackerを環境を作成して起動したところ以下のエラーが発生しました。 webpacker_1 | error Command "webpack-dev-server" not found. 何度か起動するとエラーが消えて、git cloneしてくると初回は発生しました。 解決方法 これはyarn installされた際に自動生成される/node_modulesがないためにおこるエラーです。 本来であればWebpackerコンテナの中にyarn installされた時点で/node_modules/webpack-dev-serverが作成されます。しかし、Git clone時はローカルにnode_modulesが存在しないため(gitignoreされているため)ファイルマウントがおきずにこのようなエラーになります。 そこで、Dockerfile内でyarn installをすることでエラーを解決しました。 FROM ruby:alpine3.13 ARG UID RUN adduser -D app -u ${UID:-1000} && \ apk update \ && apk add --no-cache gcc make libc-dev g++ mariadb-dev tzdata nodejs~=14 yarn WORKDIR /myapp COPY Gemfile . COPY Gemfile.lock . RUN bundle install COPY --chown=app:app . /myapp RUN yarn install # 追加 COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] # EXPOSE 3000 # CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"] USER app RUN mkdir -p tmp/sockets RUN mkdir -p tmp/pids そして、このコンテナ内で作成されたnode_modulesを使えばよいのですが、docker-compose.ymlでボリュームを設定していないとコンテナ内のnode_modulesは勝手に削除されます。 【Docker】docker compose upするとnode_modulesがマウントされて消える問題 こちらの記事通りにdocker-compose.ymlでvolumesマウントして消えないようにします。 またRailsコンテナでもnode_modulesは必要なので(yarn installしたライブラリを利用するので)、こちらにもvolumeを追加します。 docker-compose.yml version: "3.3" services: rails: build: . container_name: rails command: bundle exec puma -C config/puma.rb volumes: - .:/myapp - public-data:/myapp/public - tmp-data:/myapp/tmp - log-data:/myapp/log - /myapp/node_modules # 追加 env_file: - .env depends_on: - db environment: WEBPACKER_DEV_SERVER_HOST: webpacker webpacker: build: . volumes: - .:/myapp - /myapp/node_modules # 追加 command: ./bin/webpack-dev-server environment: WEBPACKER_DEV_SERVER_HOST: 0.0.0.0 ports: - "3035:3035" おわりに yarnやpackage.jsonについて初めて勉強したのでかなり沼りました。 また、ネットにもほしい情報はなく検証をかなりして解決することができました。 このあとにWebapackのCSSやVueが読み込まれなかったり、Template Errorが発生するトラブルを解決していますので困った方は確認してみてください。 参考 【Docker】docker compose upするとnode_modulesがマウントされて消える問題
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

`@google-cloud/bigquery` などのライブラリを利用する際に発生する型エラーについて

起こった現象 Node.js で @google-cloud/bigquery を利用していると、ある日突然このような型エラーが発生するようになった。 node_modules/@google-cloud/paginator/build/src/resource-stream.d.ts:37:5 - error TS2416: Property 'end' in type 'ResourceStream<T>' is not assignable to the same property in base type 'Transform'. Type '(...args: any[]) => void' is not assignable to type '{ (cb?: (() => void) | undefined): this; (chunk: any, cb?: (() => void) | undefined): this; (chunk: any, encoding?: BufferEncoding | undefined, cb?: (() => void) | undefined): this; }'. Type 'void' is not assignable to type 'this'. 'this' could be instantiated with an arbitrary type which could be unrelated to 'void'. 37 end(...args: any[]): void; ~~~ 原因は @types/node の https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更で、これは readable.destroy() と readable.end() の返り値が、Node.js の仕様上は this であるのに対し、 @types/node 上の型定義だと void になってしまっている問題を修正するもの。 2022/01/19 時点では @google-cloud/paginator の型定義がこの変更に追従できておらず、型エラーを起こしてしまっている。 回避策 @types/node はマイナーバージョンまでは Node.js のバージョンと一致してるが、パッチバージョンは修正があるたびにインクリメントする事になっている。 そのため、この問題を回避するには https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更が行われる前の @types/node のパッチバージョンに固定すると良い(健全ではない)。 具体的には 12.20.39 と 14.18.3 が直前のバージョンに該当する。 よくわからん @types/node と Node.js の LTS の関係をよく知らないのでわからなかったけど、この変更は現在の Node.js の LTS であるところの v16 系には含まれていない。なんでなんだろ PR を出そうと思ったが、 @google-cloud/paginator の現在の Node.js のバージョンが v16 系になっており、 https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更が降ってこないのでどうしたものか……となってしまった
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

`@google-cloud/bigquery` などのライブラリを利用した際に発生する型エラーについて

起こった現象 Node.js で @google-cloud/bigquery を利用していると、ある日突然このような型エラーが発生するようになった。 node_modules/@google-cloud/paginator/build/src/resource-stream.d.ts:37:5 - error TS2416: Property 'end' in type 'ResourceStream<T>' is not assignable to the same property in base type 'Transform'. Type '(...args: any[]) => void' is not assignable to type '{ (cb?: (() => void) | undefined): this; (chunk: any, cb?: (() => void) | undefined): this; (chunk: any, encoding?: BufferEncoding | undefined, cb?: (() => void) | undefined): this; }'. Type 'void' is not assignable to type 'this'. 'this' could be instantiated with an arbitrary type which could be unrelated to 'void'. 37 end(...args: any[]): void; ~~~ 原因は @types/node の https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更で、これは readable.destroy() と readable.end() の返り値が、Node.js の仕様上は this であるのに対し、 @types/node 上の型定義だと void になってしまっている問題を修正するもの。 2022/01/19 時点では @google-cloud/paginator の型定義がこの変更に追従できておらず、型エラーを起こしてしまっている。 回避策 @types/node はマイナーバージョンまでは Node.js のバージョンと一致してるが、パッチバージョンは修正があるたびにインクリメントする事になっている。 そのため、この問題を回避するには https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更が行われる前の @types/node のパッチバージョンに固定すると良い(健全ではない)。 具体的には 12.20.39 と 14.18.3 が直前のバージョンに該当する。 よくわからん @types/node と Node.js の LTS の関係をよく知らないのでわからなかったけど、この変更は現在の Node.js の LTS であるところの v16 系には含まれていない。なんでなんだろ PR を出そうと思ったが、 @google-cloud/paginator の現在の Node.js のバージョンが v16 系になっており、 https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更が降ってこないのでどうしたものか……となってしまった 本来はどうなるべきなの? 本来はすべてが Node.js の仕様に準ずる形になるのが妥当ですが、影響範囲が広すぎるので、https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473#issuecomment-1010494671 でも提案されているように Base type has relaxed definitions like end(): this | void. It might miss some errors of type usage. あたりの落とし所が実現すると世界が平和になるなあと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

@google-cloud/bigquery などのライブラリを利用した際に発生した「Type 'void' is not assignable to type 'this'」的な型エラーについて

起こった現象 Node.js で @google-cloud/bigquery を利用していると、ある日突然このような型エラーが発生するようになった。 node_modules/@google-cloud/paginator/build/src/resource-stream.d.ts:37:5 - error TS2416: Property 'end' in type 'ResourceStream<T>' is not assignable to the same property in base type 'Transform'. Type '(...args: any[]) => void' is not assignable to type '{ (cb?: (() => void) | undefined): this; (chunk: any, cb?: (() => void) | undefined): this; (chunk: any, encoding?: BufferEncoding | undefined, cb?: (() => void) | undefined): this; }'. Type 'void' is not assignable to type 'this'. 'this' could be instantiated with an arbitrary type which could be unrelated to 'void'. 37 end(...args: any[]): void; ~~~ 原因は @types/node の https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更で、これは readable.destroy() と readable.end() の返り値が、Node.js の仕様上は this であるのに対し、 @types/node 上の型定義だと void になってしまっている問題を修正するもの。 2022/01/19 時点では @google-cloud/paginator の型定義がこの変更に追従できておらず、型エラーを起こしてしまっている。 回避策 @types/node はマイナーバージョンまでは Node.js のバージョンと一致してるが、パッチバージョンは修正があるたびにインクリメントする事になっている。 そのため、この問題を回避するには https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更が行われる前の @types/node のパッチバージョンに固定すると良い(健全ではない)。 具体的には 12.20.39 と 14.18.3 が直前のバージョンに該当する。 よくわからん @types/node と Node.js の LTS の関係をよく知らないのでわからなかったけど、この変更は現在の Node.js の LTS であるところの v16 系には含まれていない。なんでなんだろ PR を出そうと思ったが、 @google-cloud/paginator の現在の Node.js のバージョンが v16 系になっており、 https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473 の変更が降ってこないのでどうしたものか……となってしまった 本来はどうなるべきなの? 本来はすべてが Node.js の仕様に準ずる形になるのが妥当ですが、影響範囲が広すぎるので、https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57473#issuecomment-1010494671 でも提案されているように Base type has relaxed definitions like end(): this | void. It might miss some errors of type usage. あたりの落とし所が実現すると世界が平和になるなあと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】LambdaからCognitoユーザーを削除する

LambdaからCognitoユーザーを削除することがあり、少し手間取ったので残しておきます。 前提 Cognitoの削除が可能なポリシーをLambdaのロールにアタッチしていること。 ※今回はAWS管理ポリシーの AmazonCongitoPowerUser をLambdaのロールにアタッチしています。 LambdaのランタイムはNode.js 14.x です。 Lambdaのコード index.js let aws = require("aws-sdk"); exports.handler = async (event) => { // eventから削除するCognitoユーザーのユーザー名リストを受け取る let userNameList = event.userNameList; // Cognitoユーザーの無効化メソッドをコール await disalbeCognito(userNameList); const response = { statusCode: 200, }; return response; }; /** * Cognito情報を無効化し、ログインできないようにする */ async function disalbeCognito(userNameList){ if (userNameList.length > 0) { // Cognitoを使う準備 aws.config.update({ region: 'ap-northeast-1', }); const cognito = new aws.CognitoIdentityServiceProvider({ apiVersion: '2016-04-18' }); // 対象のCognitoユーザープールID const user_pool_id = "hogehoge"; for (let userName of userNameList) { // ユーザー削除 try { await cognito.adminDeleteUser({ UserPoolId: user_pool_id, Username: userName }).promise(); console.log("Success! userName : " + userName); } catch (err) { console.log("Failed! userName : " + userName); if (err.code == 'UserNotFoundException') { // ユーザープールにユーザーが存在していない場合 console.log('UserNotFoundException'); } else { // その他のエラー console.log(err, err.stack); } throw err; } } } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

N予備校「プログラミング入門Webアプリ」を受講しています。 今回は第三章10,11節です。 同期・非同期処理 Node.jsは非同期で処理が実行される。 for (let count = 0; count < 500; count++) { fs.appendFile(fileName, 'あ', 'utf8', () => { fs.appendFile(fileName, 'い', 'utf8', () => { fs.appendFile(fileName, 'う', 'utf8', () => { fs.appendFile(fileName, 'え', 'utf8', () => { fs.appendFile(fileName, 'お', 'utf8', () => { fs.appendFile(fileName, '\n', 'utf8', () => {}); }); }); }); }); }); } 「あいうえお」を順番に出力しようとするとネストが深くなる。 一見うまくいきそうだけれど、1回目のループで行われるfs.appendFile(fileName, 'あ', 'utf8', () => {} と2回目のループで行われるappendFileは非同期なので、うまくいかない。 これは解説を聞いて、なるほどと思った。 Promise 非同期に実行される未来の結果を表すオブジェクト const waitPromise = new Promise((resolve, reject) => { setTimeout(() => resolve(), 1000); //1秒まってresolveを実行 }); waitPromise.then(() => console.log('hoge')); console.log('fuga'); Promiseはあくまでオブジェクトで、thenのあとに実行したい処理を書く。そして、console.log('hoge')が引数のresolveに入る。 Promiseチェーン new Promise((resolve) => { const nowDate = new Date(); resolve(nowDate); }).then((v1) => { //v1は現在時刻 new Promise((resolve) => { const monthAndDate = { month: v1.getMonth(), date: v1.getDate() } resolve(monthAndDate); }).then((v2) => { //v2 は 日付の情報 new Promise((resolve) => { const text = `今日は${v2.month+1}月${v2.date}日です。`; resolve(text); }).then((v3) => { // v3 は日付を示す文章 console.log(v3); // 今日の日付に関する文章が出力される }); }); }); 正直わかりにくすぎて混乱します。 resolve(nowDate)の内容がthen以下になると。 最終的にconsole.log(v3)がresolve(nowDate)の処理になる。 async/await 非同期処理を同期的に動かせる。 async function内でしか awaitは使えない。 function appendFilePromise(fileName, str){ return new Promise((resolve) =>{ fs.appendFile(fileName, str, 'utf8', ()=> resolve()); }); } async function main(){ for(let count = 0; count < 500; count++){ await appendFilePromise(fileName, 'あ'); await appendFilePromise(fileName, 'い'); await appendFilePromise(fileName, 'う'); await appendFilePromise(fileName, 'え'); await appendFilePromise(fileName, 'お'); await appendFilePromise(fileName, '\n'); } } main(); わかりやすい。 botに登録したデータの読み書き 今回はJSONファイルに出力 JSON : JavaScriptで扱うオブジェクトや配列の書き方の形式 /** * 登録された言葉を保存する */ function saveWords(){ fs.writeFileSync(fileName, JSON.stringify(praiseWords), 'utf8'); } JSON.stringifyで配列をJSON形式に変換 try{ const data = fs.readFileSync(fileName, 'utf8'); praiseWords = JSON.parse(data); }catch(ignore){ console.log(fileName + 'から復元できませんでした'); } JSON.parseでJSONから配列に変換。 fs.unlink(fileName, err =>{ //削除した後の処理 }) 自分が作ったbotでは使わなかったけど削除処理。 まとめ Promiseチェーンの理解はちょっとあやふや。 async/awaitが使えるならそっちをできるだけ使いたい。 さて、今回でbot作成は終了。 次からhttpサーバーの節に入ります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel Mix の使いかた

こちらのページと同様のことを行いました。 Stand-Alone Projects 簡易サーバーのインストール sudo npm install http-server -g Mix のインストール mkdir my-app && cd my-app npm init -y npm install laravel-mix --save-dev Mix の設定ファイルを作成 webpack.mix.js let mix = require('laravel-mix'); mix.js('src/app.js', 'dist').setPublicPath('dist'); この時点でのフォルダーの構造 $ tree -L 1 . ├── node_modules ├── package.json ├── package-lock.json └── webpack.mix.js ソースファイルの作成 src/app.js alert('こんにちは') コンパイル npx mix HTML ファイルの作成 dist/index.html <!DOCTYPE html> <html lang="ja"> <head> <meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" /> </head> <body> <script src="app.js"></script> </body> </html> dist で簡易サーバーの起動 $ http-server Starting up http-server, serving ./ http-server version: 14.1.0 http-server settings: CORS: disabled Cache: 3600 seconds Connection Timeout: 120 seconds Directory Listings: visible AutoIndex: visible Serve GZIP Files: false Serve Brotli Files: false Default File Extension: none Available on: http://127.0.0.1:8080 http://192.168.1.15:8080 Hit CTRL-C to stop the server クライアントで http://127.0.0.1:8080 にアクセス
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nodemon【Node.jsアプリケーションを自動的に再起動ツール】

Nodemonとは… nodemonは、ディレクトリ内のファイルの変更を検出すると、自動的にnodeアプリケーションを再起動することで、node.jsベースのアプリケーションの開発を支援するツールです。 インストール方法 npmまたはyarnを利用してインストールすることができます。 開発環境のみで使用するので、ローカルインストールの方法でいいと思います。 グローバルインストール npm install -g nodemon yarn global add nodemon ローカルインストール npm install nodemon --save-dev yarn add nodemon --dev ローカルにインストールすると、コマンドラインから直接nodemonコマンドを使用できません。 package.json の scripts に設定すると、npmコマンド で起動できるようになります。 以下ではnpm devStartで利用できるように設定しました。 "scripts": { "devStart": "nodemon server.js", "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, 起動してみる >npm run devStart > sample-api@0.1.0 devStart > nodemon server.js [nodemon] 2.0.15 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `react-scripts start server.js` nodemon経由でserver.jsファイルが起動されました。 手動で再起動させたい時はrsでできます。 変更があると 以下のように自動でコマンドがはしり、コンパイルしてくれます。 Compiling..... Compiled successfully! 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LINE + AWS Lambda + API Gateway でおうむ返しBotを作る

野望 ・インターフェース:LINE公式アカウント ・処理:AWS Lambda(+API Gateway) ・DB:Notion として簡単なツールを作ろうとしています。 イメージはこんな感じ。 今回やったこと まずはLINE公式アカウントに対する投稿の取得とLambdaでのLINE Messaging API動作検証のため、投稿した内容をそっくりそのまま返すおうむ返しBot的なものを作りました。 前提 ・LINE Developersでユーザ登録を実施し、公式アカウントを作成している。 ・作成したアカウントを、お手元のLINEアプリで友達追加している。 ・AWSのコンソールが使用可能である。 ・Node.js 14.x 手順 ①API Gateway + Lambdaを設定して、ブラウザから関数を呼び出せるようにする。 ②LINEからAPI Gatewayを呼び出せるようにする。 ③LambdaでLINE投稿ができるように設定する ①API Gateway + Lambdaを設定して、ブラウザから関数を呼び出せるようにする。 https://qiita.com/DJROU/items/8b04f1fc2ce1a1dc5954 に別だししました。 「適当」な部分は適当なままでOKです。 ②LINEからAPI Gatewayを呼び出せるようにする。 ここではLINEのWebhookURL欄を利用して、先ほどまでブラウザで呼び出していたLambdaをLINEの投稿によって呼び出しできるようにします。 LINE Developerのコンソール画面より トップ > (作成した公式アカウント) > Messaging API設定 > Webhook設定欄を見ます。 ここで①のAPI Gatewayにて作成したURLを貼り付けます。 保存後、「検証」を押下して「成功」が表示されればOKです。 Lambdaが本当に呼び出されたのかも見てみましょう。 Lambdaにて関数の編集画面を開き、タブ「モニタリング」から「CloudWatchのログを表示」を押下します。 CloudWatchの画面に遷移するので、最新の実行が「検証」ボタンを押した時間であることを確認できればLINEからのLambda呼び出しは成功です。 ③LambdaでLINE投稿ができるように設定する 先ほど作ったLambdaの中身を味付けします。 LINEに投稿されたテキストを取得、そのまま返せるようにします。 testfunc.js 'use strict'; const line = require('@line/bot-sdk'); exports.handler = (event, context, callback) => { console.log("event.body:", event.body); const client = new line.Client({ channelAccessToken: 'LINE公式アカウントのチャネルアクセストークン' }); const message = { type: 'text', text: JSON.parse(event.body).events[0].message.text }; const replyToken =JSON.parse(event.body).events[0].replyToken; client.replyMessage(replyToken, message).then((data) => { console.log(data); callback(null, event); }).catch((err) => { console.log("だめでし"); callback(err, "NG"); }); }; 以下、プチ補足です。 モジュールのインポート testfunc.js const line = require('@line/bot-sdk'); node.jsのモジュールはLambda Layersを使用しています。 https://qiita.com/DJROU/items/bcdc2902757e606e9226 チャネルアクセストークン testfunc.js const client = new line.Client({ channelAccessToken: 'LINE公式アカウントのチャネルアクセストークン' }); LINE Developerのコンソール画面より トップ > (作成した公式アカウント) > Messaging API設定 の一番下にある、チャネルアクセストークンを発行して貼り付けます。 受信テキストの取得と送信フォーマット testfunc.js const message = { type: 'text', text: JSON.parse(event.body).events[0].message.text }; const replyToken =JSON.parse(event.body).events[0].replyToken; client.replyMessage(replyToken, message).then((data) => { console.log(data); callback(null, event); }).catch((err) => { console.log("だめでし"); callback(err, "NG"); }); JSON.parse(event.body).events[0].message.text でLINEから送られてきたテキストをゲットできました。 LINEから送られてくるデータの形式を見るにはevent.bodyを出力してみるとよいです。 また、replyMessageについて公式ドキュメントを見ると、送信パラメータが上記のmessageの形式で指定されています。 replyTokenはreplyMessageの第一引数ですが、受信したデータの中に仕込まれています。 同じくevent.bodyで確認しましょう。 どのメッセージに対する応答かってことですよね、きっと。(適当) 以上でLINEから適当なメッセージを送るとそっくりそのまま返してくれる、かわいいおうむさんができるはずです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む