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

ZEIT NowでNode.jsのバージョン指定をする

NowへのデプロイでNodeのバージョンに起因するエラーが起きた

Error: @grpc/grpc-js only works on Node ^8.13.0 || >=10.10.0

上記のエラーが起きて困った。

:bomb: 原因

要するに8.13.0 から 10.10.0 の間のバージョンじゃないと動かないよということだと思う。

:star: 解決策

じゃあNodeのバージョンをこっちで指定してあげようということになる。

英語の情報しか出てこないが漁っていると、「now.json」で「engine」という項目を指定するみたいな情報が出てくるがこれが罠である。

ZEIT NowのNode.jsバージョン指定は「now.json」ではなく「package.json」で指定する

package.json
"engines": {
  "node": "10.x"
}

これでOK。

ただし、バージョンは何でもかんでも指定出来る訳ではなく提供されているものだけ。

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

トーク Bot とのトークルームをたくさん作る

LINEWORKS Advent Calendar 2019 の 5日目を担当させていただきます!
どうぞよろしくおねがいしますm( )m

最近見つけた、ちょっとした小ネタを紹介しますね~。

トーク Bot とのトークルームをたくさん作る

タイトルの通りなのですが、トーク Bot とのトークルームをたくさん作ります。
つまり、こんな感じ。
1574306918.png
仕組みとしては単純です。
1:1トークルームではなくて、Bot と2人きりの1:N トークルームを作っているだけです。
なので、この方法を使うときは DeveloperConsole で Bot の Bot ポリシーの「複数人のトークルームに招待可」に必ずチェックを入れておいてくださいね(*'▽')

Bot とのトークルームの作り方

トークルームの作り方はみなさんご存じだと思いますので、さささっと説明しちゃいますが、
トーク画面の左上の追加ボタンを押すと Bot を招待することができます。

1574300569.png

このとき、Bot を1つしか選ばないと1:1のトークルームになってしまうので、別の Bot も一緒に招待します。
それで、1:N のトークルームが出来上がったらいらない方の Bot をトークルームから退出させます!
1574311849.png
1574312222.png

('Д')ドイヒー

そうすると Bot 二人きりのトークルームになるので、これを繰り返すと Bot とのトークルームをたくさん作ることができます。

( ^ω^)・・・うん、めんどくさいですね!

API を使って、Bot とのトークルームをたくさん作る

面倒なことは自動でやれるようにすればいいのです。
Bot を含むトークルーム作成 APIメッセージ送信 API を駆使して一気に作っちゃいましょう!(^^)/

node.js でのコードになります。
あらかじめ request-promise モジュールをインストールしておいてくださいませ。

> npm install request-promise

API ID などの Key はご自身のものを入力してください。

makeManyTalkRooms.js
const request = require("request-promise");

const apiId = "API ID";
const botNo = "部屋をいっぱい作りたい Bot の botNo";
const headers = {
    Authorization: "Bearer " + "Token",
    consumerKey: "consumerKey",
    "Content-Type": "application/json"
};
const url = "https://apis.worksmobile.com/r/" + apiId + "/message/v1/bot/" + botNo;
const titles = [ "room A", "room B", "room C", "room D", "room E"];

titles.forEach((title) => {
    let options = {
        url: url + "/room",
        headers: headers,
        json: {
            accountIds: [ "accountId" ],
            title: title
        }
    };
    request.post(options).then((body) => {
        let options = {
            url: url + "/message/push",
            headers: headers,
            json: {
                roomId: body.roomId,
                content: { type: "text", text: "To " + title }
            }
        };
        request.post(options).catch((error) => { throw new Error(error) }); 
    }).catch((error) => { throw new Error(error) });
});

トークルーム名は 11 行目の titles に格納されています。
titles の要素を増やせばいくらでもトークルームを作ることが可能です!ヾ(´∀`)ノ

トークルームをたくさん作ることによってできること

言っておいてなんなのですが、あまり思いつきませんね。。。
ルームを分けるということは、処理によって対応を分ける必要があるということだと思うのですけど、それなら Bot を複数作った方がわかりやすいですよね。
Bot の利用範囲の制限もできるし、メンバーのメンテナンスも LINEWORKS のメンバー管理と紐づけられるし。

ひとつだけ思いついたのは、外部ユーザへの問い合わせ対応的なものでしょうか?
外部ユーザとのトークルームには LINEWORKS Bot を招待できないので。
例えば、LINE 公式アカウントにトークすると担当者の LINEWORKS に専用トークルームが作られて、そこへトークされる。
そのトークルームに担当者が返事を書くと、LINE 公式アカウントが LINE ユーザに返事をする。
みたいな?

1574321110.png

  • LINE ユーザは LINE 公式アカウントへ話しかける
  • LINE 公式アカウントへのトーク内容を LINEWORKS Bot が LINEWROKS 担当者へトークする
  • そのとき、個別のトークルームにトークする(例:ユーザ A のトークはルーム A に送信)
  • LINE の userId と LINEWORKS の roomId を紐づかせて保持しておく
  • 個別のトークルームでのトークは紐づいた LINE ユーザへ送信される(例:ルーム A のトークはユーザ A に送信)

メリットとしては、担当者の匿名性が保てることでしょうか。
あとは、担当者が複数居た場合に、誰が返事をしても公式アカウントからの返答になることですかね。

んー、どんなシチュエーションですかね。
この仕組みでサービスとして実現できたら、ぜひ教えてくださいm( )m

おわりに

ここまでお付き合いいただきありがとうございました。

そして、LINEWORKS Advent Calendar 2019 の 5日目として参加させていただきありがとうございました。

Advent Calendar の後半、まだ空いてるから今回の仕組み、作ってみようかな~。
間に合わないから無理かな~( ゚Д゚)

ではまた!(^^)/

参考にさせていただきましたm(_ _)m

LINEWORKS Developers

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

QualityForward APIとNode.jsライブラリを使って一日の作業件数を集計する

QualityForwardはクラウドベースのテスト管理サービスです。Web APIを提供しています。そのWeb APIを使いやすくするため、Node.jsライブラリも開発中です。

今回はそのNode.jsライブラリを使って、一日の作業件数を集計してみます。

準備

まずはライブラリを読み込みます。APIキーは.envファイルに書き出しています。

import * as dotenv from 'dotenv';
dotenv.config();

import { QualityForward} from 'qualityforward-node';

必要な変数の準備

まず今日の作業分を集計するので、必要な変数と当てはまるテストケースを格納する変数を用意します。

(async () => {
  const toDay = new Date;
  let result = [];
  // 後の処理もこの中に記述
})();

QualityForwardオブジェクトの初期化をします。

const client = new QualityForward(process.env.API_KEY);

テストフェーズの取得

最初にテストフェーズをすべて取得します。

const testPhases = await client.getTestPhases();

次にすべてのテストフェーズについて、テストケースを取得します。

for (const testPhase of testPhases) {
  for (const testSuiteAssignment of testPhase.test_suite_assignments) {
    const testCycles = await testSuiteAssignment.getTestCycles();
    // : 次の処理はこの中に記述
  }
}

テスト結果の取得

すべてのテストサイクルについて、テスト結果を取得します。テスト結果の中で本日作業分をフィルタリングします。

for (const testCycle of testCycles) {
  const testResults = await testCycle.getTestResults();
  const ary = testResults.filter(t => {
    if (t.executed_at.getFullYear() === toDay.getFullYear() &&
        t.executed_at.getMonth() === toDay.getMonth() &&
        t.executed_at.getDate() === toDay.getDate()) {
      return t;
    }
  });
  Array.prototype.push.apply(result, ary);
}

テスト結果ごとにグルーピングする

TestResultが取得できたら、例えばテスト結果ごとにグルーピングしてみます。

const group = {};
for (let testResult of result) {
  if (!group[testResult.result]) group[testResult.result] = 0;
  group[testResult.result]++;
}
console.log(`本日の作業結果`);
for (let result in group) {
  console.log(`  ${result} : ${group[result]}件`);
}

そうすると以下のような出力が得られます。

$ npx ts-node test.ts 
本日の作業結果
  pass : 4件
  fail : 1件
  skip : 1件
  cut : 1件
  block : 1件
  qa : 1件

作業件数を蓄積していくことで、品質の可視化にも繋がるでしょう。

まとめ

QualityForwardを使えばExcelなどで行っていた煩雑なテスト管理がクラウドベースでできるようになります。ライブラリを使うことで既存システムとの連携も用意です。ぜひお試しください!

QualityForward

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

Node.jsでプロファイリングをする方法

node --prof index.js

--profはプロファイリングと呼ばれる、処理に時間がかかっている様子やどれ位メモリを使っているのかを調べる方法を提供するオプションです。

console
$ node --prof index.js

とすると、index.jsが入っているディレクトリに、

index.jsが入っているディレクトリ
isolate-0x103002a00-v8.log

以上のようなログファイルが生成されます。
しかし、このログファイルは人間が見てもよくわかりません。
そこで、このログファイルを以下のように人間が見やすいファイルにします。

console
$ node --prof-process isolate-0x103002a00-v8.log

すると、コンソールに以下の表示が出ます。

console
>
Statistical profiling result from isolate-0x103002a00-v8.log, (382 ticks, 37 unaccounted, 0 excluded).

 [Shared libraries]:
   ticks  total  nonlib   name
     15    3.9%          /usr/lib/system/libsystem_platform.dylib
      3    0.8%          /usr/lib/system/libdyld.dylib
      2    0.5%          /usr/lib/system/libsystem_pthread.dylib
      1    0.3%          /usr/lib/system/libsystem_malloc.dylib
      1    0.3%          /usr/lib/system/libsystem_kernel.dylib

 [JavaScript]:
   ticks  total  nonlib   name
      1    0.3%    0.3%  Script: ~bootstrapInternalLoaders internal/bootstrap/loaders.js:42:35
      1    0.3%    0.3%  LazyCompile: ~realpathSync fs.js:1380:22
      1    0.3%    0.3%  LazyCompile: ~getOptionValue internal/options.js:6:24
      1    0.3%    0.3%  LazyCompile: ~binding internal/bootstrap/loaders.js:77:39
      1    0.3%    0.3%  LazyCompile: ~QuickSort native array.js:530:19
      1    0.3%    0.3%  Builtin: LoadIC_Uninitialized
      1    0.3%    0.3%  Builtin: Construct {1}

 [C++]:
   ticks  total  nonlib   name
(中略)
[Summary]:
   ticks  total  nonlib   name
      7    1.8%    1.9%  JavaScript
    316   82.7%   87.8%  C++
      7    1.8%    1.9%  GC
     22    5.8%          Shared libraries
     37    9.7%          Unaccounted

この[Summary]という部分に注目すると、どの処理に一番時間がかかっているのか調べることができます。
今回の処理では、C++の処理が全体の87.8%なので、C++の処理を改善すれば良いことがわかります。
その他にも[Bottom up (heavy) profile]という部分には時間のかかった処理が書かれています。

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

Node.jsで簡易テストをできるassert.equal()

assert.equal()

assert.equalは、アサーションというnode.jsが提供する簡易テストのモジュールです。

const assert = require('assert');
assert.equal(50, 50); //OK
assert.equal(50, "50"); //OK
assert.equal(50, 70); /*AssertionError: 50 == 70 */

//関数と答えの比較もできます
function addition(n) {
  let result = n + 1;
  return result;
}
//第三引数に、エラーが出た場合のエラー表示の設定をできる。
assert.equal(addition(1), 3, `1 + 2の答えは3ですが、計算は${additon(1)}でした`)
//AssertionError: 1 + 2の答えは3ですが、計算は${additon(1)}でした`

assert.deepEqual()

assert.deepEqualは配列オブジェクトの深い比較まで行ってくれます。
例えば、assert.deepEqual([50], [50]);はOKなのに対して、
assert.equal([50], [50]); ではエラーが出てしまいます。
これは、JavaScriptでは配列やオブジェクトを == 演算子で比較した際、同じオブジェクト同士でないとfalseになってしまうからです。

const assert = require('assert');
assert.deepEqual(50, 50); //OK
assert.deepEqual(50, "50"); //OK
assert.deepEqual(50, 70); /*AssertionError: 50 == 70 */
assert.deepEqual([50], [50]); //OK
assert.equal([50], [50]); /*AssertionError: [ 50 ] == [ 50 ] */
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.jsで簡易テストをができるassert.equal()

assert.equal()

assert.equalは、アサーションというnode.jsが提供する簡易テストのモジュールです。

const assert = require('assert');
assert.equal(50, 50); //OK
assert.equal(50, "50"); //OK
assert.equal(50, 70); /*AssertionError: 50 == 70 */

//関数と答えの比較もできます
function addition(n) {
  let result = n + 1;
  return result;
}
//第三引数に、エラーが出た場合のエラー表示の設定をできる。
assert.equal(addition(1), 3, `1 + 2の答えは3ですが、計算は${additon(1)}でした`)
//AssertionError: 1 + 2の答えは3ですが、計算は${additon(1)}でした`
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.jsのprocess.argv[i]とは

Node.jsのファイルで以下のような記述がありました。

index.js
'use strict';
const number = process.argv[2] || 0;
let sum = 0;
for (let i = 1; i <= number; i++) {
  sum = sum + i;
}
console.log(sum);

それに対して、いかのような記述をすると、

console
$ node index.js 3
> 7

となります。
つまり、node index.js 3の3の部分が、process.argv[2]に当てはまるということです。
process.argv[0]だったら、node
process.argv[1]だったら、index.js
を意味します。

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

Node.jsでのリクエストIDのログ出力(express, log4js, request-context)

概要

Node.jsのexpressベースのWebアプリで、リクエストIDをログ出力します。
今回、log4js、request-contextを使用しました。

request-contextで、リクエスト毎にリクエストIDを保持します。
log4jsのtokensに、リクエストIDをセットして、patternでリクエストIDを出力するようにしています。

参照情報

参考にさせていただいたページは下記です。

注意点

request-contextは、下記の通り、Node.jsのdeprecatedになっているdomainに依存しています。参照先2でも指摘されており、より詳しく記載されています。
request-context

See the Domain Docs for further information on error handling for domains. Note that the domain module is pending deprecation!

サンプルコード

今回は、リクエスト毎に、uuidでリクエストを発行するようにしています。
contextService.setのところでリクエストIDを保持させています。

app.js
const express = require('express');
const app = express();
const contextService = require('request-context');
const uuid = require('uuid/v4');
const logger = require("./logger").logger();

app.use(contextService.middleware('request'));
app.use((req, res, next) => {
  const requestId = uuid();
  contextService.set('request:requestId', requestId);
  logger.info("Start API.", req.method, req.originalUrl);
  next();
});

app.get('/', function (req, res) {
  res.send('hello world');
  logger.info("End API.");
})

app.listen(3000)

getRequestIdで、保持しているリクエストIDを取得しています。
layoutのpatternの%x{requestId}がリクエストIDです。

logger.js
const log4js = require("log4js");
const contextService = require('request-context');
const getRequestId = function() {
  return contextService.get('request:requestId');
};

log4js.configure({
  appenders: {
    console:{
      type:'console',
      layout:{
        type:'pattern',
        pattern:'[%d] [%x{requestId}] %[[%p]%] [%c] %m',
        tokens: {
          requestId: getRequestId
        }
      }
    }
  },
  categories:{
    default:{appenders:['console'], level:'info'}
  }
});

exports.logger = function(){
  const logger = log4js.getLogger('default');
  return logger;
};

ログ出力結果

下記のようにリクエスト毎に、リクエストIDが出力されます。

[2019-11-26T11:24:46.451] [ef9b0c23-53f2-4c7b-bce3-0def665fbc08] [INFO] [default] Start API. GET /
[2019-11-26T11:24:46.460] [ef9b0c23-53f2-4c7b-bce3-0def665fbc08] [INFO] [default] End API.
[2019-11-26T11:24:49.588] [4af4ffed-a22f-4b81-806a-1cdcff4b7c22] [INFO] [default] Start API. GET /
[2019-11-26T11:24:49.590] [4af4ffed-a22f-4b81-806a-1cdcff4b7c22] [INFO] [default] End API.
[2019-11-26T11:24:51.226] [360033c9-e6eb-405c-b3a7-6ac9e20b3fa4] [INFO] [default] Start API. GET /
[2019-11-26T11:24:51.227] [360033c9-e6eb-405c-b3a7-6ac9e20b3fa4] [INFO] [default] End API.
[2019-11-26T11:24:53.371] [048a8ce6-1bd8-4514-89df-aa467419e0ce] [INFO] [default] Start API. GET /
[2019-11-26T11:24:53.372] [048a8ce6-1bd8-4514-89df-aa467419e0ce] [INFO] [default] End API.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

QualityForward用Node.jsライブラリのバージョンアップ(1.0.3)

QualityForwardはテスト管理をクラウドで提供しています。そして、多くのクラウドサービスと同様にAPIを提供しています。現在、下記のデータを取得または新規作成、更新、削除できます。

  • プロジェクト
  • テストケース
  • テストサイクル
  • テストフェーズ
  • テスト結果
  • テストスイート
  • テストスイートバージョン
  • ユーザ

これらのデータを扱うためのNode.jsライブラリを開発しています。1.0.3での対応範囲を紹介します。

使い方

npmパッケージとして公開していますので、package.jsonで指定して取り込んでください。APIキーはプロジェクトの設定で取得できます。

import { QualityForward } from 'qualityforward-node';
const API_KEY = '0aa...340';
const client = new QualityForward(API_KEY);

各データの取得が可能に

上記で示した各データがオブジェクトになりました。

  • プロジェクト / Project
  • テストケース / TestCase
  • テストサイクル / TestCycle
  • テストフェーズ / TestPhase
  • テスト結果 / TestResult
  • テストスイート / TestSuite
  • テストスイートバージョン / TestSuiteVersion
  • ユーザ / User

テストスイートの取得

例えばテストスイートの取得は次のように行います。

const testSuites: TestSuite[] = await client.getTestSuites();

テストケースバージョンの取得

テストケースバージョンはテストケースに紐付くので、次のように行います。

for (let key in testSuites) {
  const testSuite = testSuites[key];
  const versions = await testSuite.getVersions();
}

テストケースの取得

さらにテストケースはテストケースバージョンから取得できます。

for (let k in versions) {
  const version = versions[k];
  const testCases = await version.getTestCases();
  if (testCases.length === 0) continue;
}

このように階層的な構造になっているので注意してください。

テスト結果の取得

テスト結果を取得する場合も階層的に取得する必要があります。テストフレーズ -> テストスイートアサインメント -> テストサイクル -> テスト結果といった具合です。

const testPhases: TestPhase[] = await client.getTestPhases();
for (let testPhase of testPhases) {
  if (testPhase.test_suite_assignments.length === 0) continue;
  const testSuiteAssignment = testPhase.test_suite_assignments[0];
  const testCycles = await testSuiteAssignment.getTestCycles();
  if (testCycles.length === 0) continue;
  const testResults = await testCycles[0].getTestResults();
  // console.log(testResults[0])
}

まとめ

1.0.3で、QualityForwardのデータについて一通り取得できるようになりました。今後、データの作成であったり、集計などに便利なメソッドを追加していきます。コードはgoofmint/qualityforward-nodeで公開しており、MIT Licenseとなっています。

QualityForward

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

Nodejs Send Email Using Nodemailer

Email is use to send notification or information to the user.This nodejs tutorial help to send email using nodemailer. You can send mail as a plain text, HTML body and email with attachment.I will demonstrate all flavors of email using node Nodemailer.

https://www.js-tutorials.com/nodejs-tutorial/nodejs-send-email-using-nodemailer/

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