20200220のNode.jsに関する記事は7件です。

Node.jsでSQLServerにWindows認証で接続する(msnodesqlv8)

Node.jsでSQLServerにWindows認証で接続する

Node.jsでSQLServerに接続するパッケージとしてmssqlがありますが
何故かSQLServer認証で接続できないことがあります…
(私はPC変えて同じように設定したつもりが接続できず…備忘のため)

その場合にはmsnodesqlv8を使うとWindows認証で接続できます。

SQLServer認証を行う場合の接続情報
{
    "user": "(ユーザー名)",
    "password": "(パスワード)",
    "server": "localhost(またはサーバー名)",
    "database":"(DB名)",
    "options": {
        "encrypt": true
    }
}
Windows認証する場合の接続情報
{
    "server": "(サーバー名)",
    "database":"(DB名)",
    "options": {
        "trustedConnection": true
    }
}

あとはmsnodesqlv8のサンプルでは
const sql = require("msnodesqlv8");
となっていますが、それで接続ができなかった場合、
const sql = require('mssql/msnodesqlv8');
とすれば接続できます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

javascript(node.js)のrequest.on()を解説

reqest.on(イベント名, 関数);

イベント名
→ dataイベント
クライアントからデータを受け取ると発生するイベントです。

var body = '';

request.on('data',(data) => {
    body +=data;
}

この引数のdataは、送られてきたデータの事です。

→ endイベント
データの受け取りが完了すると発生するイベントです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

お気に入りのテレビ番組の有無を答えてくれるAlexaスキルを作ってみた

はじめに

日曜日の夜に日本テレビ系列で放送されている「世界の果てまでイッテQ!」見てますか? 面白いですよね。
娘もこの番組大好きで、週末になると毎日「今日イッテQある?」と聞いてきます。

だいたい毎週日曜日にはあるのですが、時々特番とかで放送なかったりで、その時の娘のガッカリ感ときたら…。

それはさておき、毎週末聞いてくるので、大好きなアレクサが答えてくれたら娘も喜ぶんじゃないかな、と思って、「今日イッテQある?」と聞いたら答えてくれるアレクサスキルを作ってみました。

要件

以下のようなものを目標にしてみました。

  • 「アレクサ、今日イッテQある?」と聞いたら
    • WEB上にある番組表から「イッテQ」というキーワードで検索。
    • 今日見つかったら「HH:MM〜HH:MMに世界の果てまでイッテQ…があります」と答える。
    • 今日はないけど見つかったら「MM/DDのHH:MMにあるようです」と答える。
    • 見つからなかったら「ありません」と答える。

実装方針

  • スキルの呼び出し名を「今日イッテQある」にする。
    • こうすると「アレクサ、今日イッテQあるを開いて」で起動する設定になりますが、「アレクサ、今日イッテQある?」でも起動できたので…。
    • たぶんスキル名にもよるのだと思いますが、もしこれで起動できなかった場合は、定型アクションを使うつもりでした。
  • いつもPythonの人なので、今回は自分自身の新たな取組としてNode.jsで書いてみる。
    • ほぼ初めてのNode.jsなので、お見苦しい点はお許しくださいませ。
  • 今回はLambda上で実装するする。
    • Alexa-hostedスキルでもできるのかもしれないですが、初めてNode.jsでアレクサスキルを作るということをやる上で、慣れない環境でハマるのもイヤだったので。

実装内容

Alexa Developer Console

※いくつかキャプチャを貼っていますが、作成済みのスキルの編集画面ですので、作成手順に沿っているわけではありません。

呼び出し名

方針に書いたように「今日イッテQある」にしました。
「呼び出し名は2名詞以上である必要があります。」と赤字でエラーっぽく書かれていますが、これで動いています。
※保存したらQが小文字になりました

Alexa Developer Console 呼び出し名

インテント

今回はスキル呼び出されたらそのまま回答して終了するスキルにするので、インテント用意しなくてもいいのかな…と思っていたのですが、何も設定していない状態だと、ビルドエラーが出てしまいます。

Alexa Developer Console ビルドエラー

何かしらサンプル発話を登録すればいい、ということなので、今回はビルトインインテントのAMAZON.StopIntentにサンプル発話を設定することで、ビルドが通るようになります。

Alexa Developer Console インテント

エンドポイント

ここは普通にLambdaを使ったAlexaスキル一般通り、LambdaのARNを指定してます。

AWS Lambda

Lambda側は以下方針で実装しました。

  • ASK ADK for Node.jsを使用。
  • 番組を調べるためのWebサービスとしてYahoo!テレビを使用させていただく。
    • 検索するのに使い勝手がよかったので…
  • スクレイピングするためのHTMLパースにはCheerioを使用。

ということでソースは以下の通りです。コメント入れているので何やっているかはわかるかと思います。

app.js
const Alexa = require('ask-sdk-core')
const Axios = require('axios')
const Cheerio = require('cheerio')
const Moment = require('moment-timezone')
const Moji = require('@eai/moji')

Moment.tz.setDefault('Asia/Tokyo')

// 最後のa=10が札幌を示している
const Url = 'https://tv.yahoo.co.jp/search/?q=%E3%82%A4%E3%83%83%E3%83%86Q&a=10'
const Title = '世界の果てまでイッテQ!'

// スキル起動ハンドラ
const LaunchRequestHandler = {
  canHandle (handlerInput) {
    // スキル起動時に反応する
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest'
  },
  async handle (handlerInput) {
    const response = await Axios.get(Url)
    const $ = Cheerio.load(response.data)
    const programInfos = $('.programlist li').map((index, elm) => {
      const left = $('div.leftarea', elm)
      const right = $('div.rightarea', elm)
      const dateString = $('p:first-of-type > em', left).text()
      const timeString = $('p:nth-of-type(2) > em', left).text()
      const titleString = $('p:first-of-type > a', right).text()
      return {
        date: dateString,
        time: timeString,
        // 番組表の文字列、全角半角の混ざり方が不規則なので、英数は半角、カナは全角に揃える
        title: Moji(titleString).convert('ZEtoHE').convert('HKtoZK').toString()
      }
    }).get().filter(x => x.title.indexOf(Title) === 0)
    // 特番とかだと違う番組が引っかかることがあるので、番組名先頭に「世界の果てまでイッテQ!」
    // と書かれているものを対象番組として扱うことにする

    // 今日あるかどうかの判断を行う
    const timestamp = Moment(handlerInput.requestEnvelope.request.timestamp)
    const dateString = timestamp.format('M/D')
    const filtered = programInfos.filter(x => x.date === dateString)

    let speechText

    if (filtered.length > 0) {
      // 今日ある場合は、番組詳細まで返す
      const subStr = filtered.map(x => {
        const timeString = x.time.replace('', 'から')
        const result = timeString + '' + x.title + ''
        return result
      }).join('')
      speechText = '今日は' + subStr + 'あります。'
    } else if (programInfos.length > 0) {
      // 今日はないけど、明日以降見つかったら、日付と時刻を返す。
      const subStr = programInfos.map(x => {
        const result = x.date.replace('/', '') + '' + x.time.replace('', 'から')
        return result
      }).join('と、')
      speechText = '今日はイッテQはありませんが、' + subStr + 'にあるようです。'
    } else {
      // ない
      speechText = '今日はイッテQはありません。'
    }

    return handlerInput.responseBuilder
      // 最後は全角で返さないとうまく読んでもらえない。
      .speak(Moji(speechText).convert('HEtoZE').toString())
      .getResponse()
  }
}
exports.handler = Alexa.SkillBuilders.custom()
  .addRequestHandlers(
    LaunchRequestHandler
  )
  .lambda()

ビルド、デプロイはAWS SAMを使いました。
特に特筆する内容はないですが、以下のようなテンプレートを使いました。

template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  alexa itteq
  今日イッテQがあるか答えるAlexaスキル

Globals:
  Function:
    Timeout: 30

Resources:
  AlexaItteqFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: app.handler
      Runtime: nodejs12.x
      Events:
        Alexa:
          Type: AlexaSkill

あとは、デザイナー画面の「Alexa Skills Kit」でスキルIDをセット。
スキルIDはAlexa Developers Consoleで確認可能。

作ってみての所感など…

今回作ったスキルは期待通り娘にも使ってもらえてよかった〜と感じです。

ただ、スキルを呼び出した後、返答が返ってくるまで少しタイムラグがあるのが気になりますね。
娘には「イッテQある?って聞かれてからアレクサは一所懸命調べたり考えたりしているんだよ〜」って説明して納得してくれていますが、やはりUX的には気になるところ…

番組表取得自体はデイリーとかで回してDynamoDBなりS3なりに保存しておいて、Alexaからの要求が来たときはDynamoDBなりS3なりを参照にする方がいいのかなぁ…
いずれにしてもX-RAYを仕掛けて、番組表取得で遅くなっているのか、その後の処理で遅くなっているのかなどを見極めたいと思っています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActionView::Template::Error (Autoprefixer doesn’t support Node v0.10.48. Update it.):

RailsアプリをEC2へデプロイする過程で遭遇したエラーです。調べるとnode.jsを入れ直せとのことなので、

$ sudo yum remove nodes

これで削除して

ActionView::Template::Error (No such file or directory - node):

エラーメッセージが変わりました。新しく入れ直します。

$ curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash -
$ sudo yum install -y nodejs

インストール完了です。

gem mini_racer

stackoverflowではmini_racerをインストールするように書かれていたものもありました。自分はこれでは解決しませんでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

create-nuxt-appでエラーが出る

起こった問題

以下の設定で create-nuxt-app した時に

% yarn create nuxt-app aiue

create-nuxt-app v2.14.0
✨  Generating Nuxt.js project in aiue
? Project name aiue
? Project description My impeccable Nuxt.js project
? Author name mur71mur
? Choose the package manager Yarn
? Choose UI framework Bulma
? Choose custom server framework Express
? Choose Nuxt.js modules Axios, Progressive Web App (PWA) Support
? Choose linting tools ESLint, Prettier
? Choose test framework Jest
? Choose rendering mode Single Page App
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
throw new SAOError(`Failed to install ${packageName} in ${cwd}`)

というエラーが出た。
この時のnodeのversionは

% node -v
v10.10.0

調査

設定をいじってたらeslintがある時にこのエラーが出てることが判明したので

% yarn add -D eslint

eslintだけをinstallしてみると

eslint@6.8.0: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "10.10.0"

nodeのversionがダメと言われる。

解決策

とりあえずエラー文に従って

% node -v
v12.6.0

にするとeslintを設定しても create-nuxt-app できる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Node.js】FetchでフォームデータをPOSTする

Node.jsアプリケーションなどでFechを用いてファイルなどのフォームデータをPOSTしてみる

FetchAPIのデフォルトのコンテンツタイプヘッダは Content-Type': 'application/json になっています

一方、HTML等のFormを用いてPOSTしたときのコンテンツタイプヘッダは Content-Type': 'multipart/form-data です

コンテンツタイプヘッダを指定してPOSTするのでは駄目

コンテンツタイプヘッダを Content-Type': 'multipart/form-data と指定してfetchしてみてもデータは送信できません。

multipart形式ではバイナリデータを転送できるため、サーバー側がフィールドデータがどこで終わり、次のフィールドデータがどこから始まるかを知る為に、ブラウザ側でboundaryというものを設定します。

そのため、コンテンツタイプヘッダをオーバーライドするだけではboundaryの設定が正常に出来ません。

解決策

コンテンツタイプヘッダをオーバーライドするだけでは上記のような問題が発生してしまうので
明示的にコンテンツタイプヘッダを明示的に削除してあげる必要があります。

index.js
const fileInput = document.querySelector('#your-file-input') ;
const formData = new FormData();

formData.append('file', fileInput.files[0]);

// 送信用データを設定
const options = {
  method: 'POST',
  body: formData,
  headers: {
    'Content-Type': 'multipart/form-data',
  },
};

// ここで明示的に消してあげる
delete options.headers['Content-Type'];

// 設定したデータをPOST
fetch('your-upload-url', options);

参考記事

この記事に助けられました。感謝してもしきれない。
Uploading files using 'fetch' and 'FormData'

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.js + Expressの環境構築をしてみた

1.はじめに

先日Node.js + Expressの環境を構築する機会がありました。せっかくなので、学んだことをOUTPUTしたいと思ってまとめることにしました。

1-1.Node.jsとExpress

1-2.PCの環境

  • Windows10 Version 1909
  • Node.js v12.13.1
  • npm v6.12.1

2.環境構築

2-1.Node.jsのインストール

まず、最初にNode.jsをインストールします。
▼Node.jsリンク
https://nodejs.org/ja/

Node.jsには、偶数系統と奇数系統があります。偶数系統がLTS(Long Term Support)版となるので、特に必要がない場合は、偶数系統のインストーラをダウンロードしてインストールすれば良いと思います。

インストールが完了したら、cmdを開いて次のコマンドを実行してください。Node.jsのバージョンを確認することができます。

node -v

2-2.Expressのインストール

node.jsがインストールできたら、次にExpress-generatorを利用してアプリケーションのひな型を生成します。

1.アプリケーションを作成したいディレクトリに移動
cd [アプリケーションを作成したいディレクトリ]
2.express-generatorのインストール
npm install -g express-generator
3.アプリケーションの生成
express [生成したいアプリケーション名]

上記コマンドを実行すると、カレントディレクトリ配下にアプリケーションのひな型が生成されます。
次のコマンドを実行すると、ファイルまで含めて生成された内容を確認できます。

tree /f
実行結果
└─api_app
    │  app.js :アプリケーション本体、最初に呼び出される。
    │  package.json :アプリケーションの環境設定 
    │
    ├─bin
    │      www :アプリケーションのエンドポイント
    │
    ├─public :フロントエンドで利用する画像やjs, cssを保管する場所
    │  ├─images
    │  ├─javascripts
    │  └─stylesheets
    │          style.css
    │
    ├─routes :ルーティングを行っている
    │      index.js
    │      users.js
    │
    └─views :jadeファイル
            error.jade
            index.jade
            layout.jade

2-3.express-generatorでアプリケーションのひな型を生成

node.jsがインストールできたら、次にExpress-generatorを利用してアプリケーションのひな型を生成します。

1.アプリケーションを作成したいディレクトリに移動
cd [アプリケーションを作成したいディレクトリ]
2.express-generatorのインストール
npm install -g express-generator
3.アプリケーションの生成
express api_app

api_appの部分は生成したいアプリケーション名を指定してください。
上記コマンドを実行すると、カレントディレクトリ配下にアプリケーションのひな型が生成されます。
次のコマンドを実行すると、カレントディレクトリ配下のファイルが確認できるので、生成された内容を確認します。

tree /f
実行結果
└─api_app
    │  app.js :アプリケーション本体、最初に呼び出される。
    │  package.json :アプリケーションの環境設定 
    │
    ├─bin
    │      www :アプリケーションのエンドポイント
    │
    ├─public :フロントエンドで利用する画像やjs, cssを保管する場所
    │  ├─images
    │  ├─javascripts
    │  └─stylesheets
    │          style.css
    │
    ├─routes :ルーティングを行っている
    │      index.js
    │      users.js
    │
    └─views :jadeファイル
            error.jade
            index.jade
            layout.jade

2-4.画面表示

アプリケーションのひな型が作成できたら、作成したアプリケーションを起動してみます。
まず、作成したアプリケーションにディレクトリを移動してから、npm installでpackage.jsonに記載されたパッケージがインストールされます。

1.install
cd api_app
npm install

npm installができたら、ブラウザからhttp://localhost:3000/にアクセスしてください。

2.アプリケーションの起動
npm start

正しくアプリケーションが起動できていると、次のような画面が表示されます。
image.png

アプリケーションを終了したい場合は、cmd上で「ctrl + C」を実行します。「バッチ ジョブを終了しますか (Y/N)?」と求めてきますので、yを選択すれば抜けることができます。

3.所感

とりあえず環境構築をすることろまではできました。次はAPI構築あたりの内容を書きたいです。

参考リンク

https://qiita.com/nkjm/items/723990c518acfee6e473
https://qiita.com/maitake9116/items/7825d90c09f3e2f87dea

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む