20210606のNode.jsに関する記事は8件です。

mockを使ったNode.js(Express)のAPIテスト

はじめに Jest・SupertestでAPIテストを作成した際に躓いたので、その実装の備忘録を残しておく。 この記事では時に、より実践的なテストにするためにはmockを用いるべきであるがどのようにmock化してWeb APIがcallされないようにするか?という部分について書き残す。 ※mockを用いず、ただ単にnode.js(Express)のAPIテスト(End Pointテスト)を実行できるようするための方法は、Jest・Supertestを使用したnode.js(Express)のAPIテスト app.listen()はエラーになるを参照。 以下で実装したテストの実行結果(GitHub Actionsの結果)は以下。 https://github.com/yuta-katayama-23/travel-app/runs/2757301572 なぜmock化する必要があるか? Node.js(Express)でServer Sideを構築する場合、外部のWeb APIを実行しデータを取得することも多くある。その際に、UnitTestやAPIテストで実際に通信を行ってしまうと、テストとして動作が不安定になるなどの問題が発生してしまうため。 詳細はこちらを参照。 外部のWeb APIの実行をmock化してAPIテストする ここで言うAPIテストはEnd Pointテストで、実際に期待されるEnd Pointがありそこから結果が返ってくるか?をテストする。 (実際には以下で取り上げるテスト内容もテストしているとも言えるが・・・。) この場合、Node.jsのmoduleをmock化し外部のWeb APIを実行させないようにする+supertestを用いてテストを実装できる。 正常系のテスト テスト対象のコードは以下。 app.js const express = require('express'); const app = express(); /* Middleware */ app.use(express.urlencoded({ extended: false })); app.use(express.json()); // Cors for cross origin allowance const cors = require('cors'); app.use(cors()); // Initialize the main project folder app.use(express.static('dist')) // dotenv const dotenv = require('dotenv') dotenv.config(); const axios = require('axios').default; // config for get countries and cities const axiosConfig = { baseURL: 'https://api.countrystatecity.in/v1/', timeout: 2500, headers: { 'X-CSCAPI-KEY': `${process.env.COUNTRYSTATECITY_API_KRY}` } } app.get('/allCountries', async (req, res) => { try { const countries = await axios.get('countries', axiosConfig) res.status(200).send({ countries: countries.data }) } catch (error) { errorHandler(res, error) } }) const errorHandler = (res, error) => { if (error.response) { res.status(500).send(error.response.data) } else { res.status(500).send({ error: error.message }) } } module.exports = app; テストコードは以下。 test.js const request = require('supertest') const app = require('../../../src/server/app') const axios = require('axios') jest.mock('axios') // ここでNode.jsのmodule(今回はaxios)をmock化している describe('axiosをmock化&supertestでrequestを飛ばしてテスト', () => { it('/allCountries', async () => { const resp = { data: [{ name: 'test' }] }; axios.get.mockResolvedValue(resp); // mock化したmoduleの実行結果を定義している https://jestjs.io/docs/mock-function-api#mockfnmockresolvedvaluevalue const res = await request(app).get('/allCountries') expect(res.status).toEqual(200) expect(res.body.countries[0].name).toEqual('test') }) }) ※テストコードの解説・注意事項  ・jest.mock(module)はrequire/importのスコープに記載する   jest公式にも以下のように書いてある通り、jest.mock(module)はrequire/importのスコープに記載しないとダメ。 Note: In order to mock properly, Jest needs jest.mock('moduleName') to be in the same scope as the require/import statement. 注: 適切にモックするために、Jest は jest.mock('moduleName') が require/import ステートメントと同じスコープにある必要があります。 route-mock.test.js // 省略 const axios = require('axios') describe('axiosをmock化&supertestでrequestを飛ばしてテスト Get Endpoints (mocking)', () => { it('/allCountries', async () => { jest.mock('axios') // ←このような実装はエラーになる // 省略 }) }) 異常系のテスト テスト対象のコードは上記と同じ。 テストコードは以下。 test.js const request = require('supertest') const app = require('../../../src/server/app') const axios = require('axios') jest.mock('axios') describe('axiosをmock化&supertestでrequestを飛ばしてテスト', () => { it('Abnormal pattern test of API /allCountries', async () => { const resp = new Error('error test'); axios.get.mockRejectedValueOnce(resp); const res = await request(app).get('/allCountries') expect(res.status).toEqual(500) expect(res.body.errorMsg).toEqual('error test') }) }) APIのエンドポイントがcallされた時に実行される処理をテスト ここで言うAPIテストはAPIのcall時に実行される処理のテストの事。 End Pintが存在するか?よりはそのEnd Pointをcallした時に実行される処理が期待される挙動であるか?を検証する。 この場合、単純にエイリアス(関数)を呼び出してテストしてあげればよいが、そのテストを実行できるようにNode.js(Express)のソースコードの構成もテストできる形にする必要がある。 プロジェクトの構成のリファクタリング まず、Node.js(Express)の構成だがMVCモデルに則り以下のようにする。 src ・・・ └── server ├── app.js ├── controllers │ └── controller.js ├── routes │ └── router.js └── server └── server.js すると、単純にエイリアス(関数)であるコードを書く事ができるので、テストを実行する際にはこの関数を呼び出すだけでいい。 controller.js const axios = require('axios').default; // dotenv const dotenv = require('dotenv') dotenv.config(); // config for get countries and cities const axiosConfig = { baseURL: 'https://api.countrystatecity.in/v1/', timeout: 2500, headers: { 'X-CSCAPI-KEY': `${process.env.COUNTRYSTATECITY_API_KRY}` } } const allCountries = async (req, res) => { try { const countries = await axios.get('countries', axiosConfig) res.status(200).send({ countries: countries.data }) } catch (error) { errorHandler(res, error) } } const errorHandler = (res, error) => { if (error.response) { res.status(error.response.status).send({ error: error.response.data, errorMsg: error.message }) } else { res.status(500).send({ errorMsg: error.message }) } } module.exports = { allCountries, }; 実際のテスト対象のソースコード全体は以下を参照。 テストコードの実装 上記で関数化できたのでテストコードは以下のようになる。 (テスト対象のコードは上記のallCountries関数。) 正常系のテスト test.js const { allCountries } = require('../../../src/server/controllers/controller') const axios = require('axios') jest.mock('axios') describe('axiosはmock化&関数のテストとしてテスト', () => { it('/allCountries', async () => { const resp = { data: [{ name: 'not use superttest' }] }; axios.get.mockResolvedValue(resp); const req = {} const res = { status: jest.fn().mockReturnThis(), send: jest.fn().mockReturnThis() } await allCountries(req, res) expect(res.status.mock.calls[0][0]).toBe(200) expect(res.send.mock.calls[0][0].countries[0].name).toEqual('not use superttest') }) }) ※テストコードの解説 jest.fn().mockReturnThis()axiosのresponseがres.status().send()というようなメソッドチェーンで使われるのでそれ自身(this)を返してあげる必要があるので.mockReturnThis()でthisを返すようにしている1 mock.calls[0][0]呼び出されたモックに対してmock.calls[n][m]で、n番目の引数に対してm回目の呼び出しで指定された引数を取り出すという意味で、今回は引数1つ&呼び出した回数も1回なので、mock.calls[0][0]に結果が可能されている上記のコードで言えば、res.status(200).send({ countries: countries.data })というテスト対象のコードが、mock化したそれぞれの関数(status: jest.fn()…とsend: jest.fn()…)に対し、・.status(200)で1回呼び出されその時の引数は200なのでres.status.mock.calls[0][0]で200が取り出せる・.send({ countries: countries.data })で1回呼び出されその時の引数は{ countries: countries.data }なのでres.send.mock.calls[0][0]で{ countries: [{ name: 'not use superttest' }] }が取り出せるという事。2 異常系のテスト test.js const { allCountries } = require('../../../src/server/controllers/controller') const axios = require('axios') jest.mock('axios') describe('axiosはmock化&関数のテストとしてテスト', () => { it('Abnormal pattern test of API /allCountries', async () => { const resp = new Error('error test'); axios.get.mockRejectedValue(resp); const req = {} const res = { status: jest.fn().mockReturnThis(), send: jest.fn().mockReturnThis() } await allCountries(req, res) expect(res.status.mock.calls[0][0]).toBe(500) expect(res.send.mock.calls[0][0].errorMsg).toEqual('error test') }) }) 参考文献 https://jestjs.io/docs/manual-mocks#mocking-node-modules https://jestjs.io/ja/docs/mock-functions#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%AE%E3%83%A2%E3%83%83%E3%82%AF https://www.agent-grow.com/self20percent/2019/03/25/only-express-and-jest-testing/ https://tech.bitbank.cc/lets-test-by-jest/ https://jestjs.io/ja/docs/mock-functions#%E3%83%A2%E3%83%83%E3%82%AF%E3%81%AE%E5%AE%9F%E8%A3%85 ↩ https://jestjs.io/ja/docs/mock-functions#mock-%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Stripe Connectで画像検証を登録する方法 | 子アカウントの本人確認 | Node.js

ハイテク好きが楽しめるwebメディア | off.tokyo -- スキルシェアのサービスを2020年から作り始めたのだが、完全に放置になってしまった。 でも、最近また開発を再開しました。 個人間取引の市場に対する情熱が、まだ潰えてないようです。 まあ、そんなことはどうでもいいのだが・・・ 色々とコードが動かなくなってて、Stripe周りが動かなくなってた。 やりたいことはC2Cのサービスで、ユーザーへの売り上げなどを口座へ振り込む際に、 そのユーザーの本人確認などの検証をしなければいけない。 住所や、本名や、免許証などの画像が必要です。 それで、今回は免許証などの画像を検証する方法を紹介します。 画像を作る Create a file const file = await stripe.files.create({ purpose: 'dispute_evidence', file: { data: fp, name: 'file.jpg', type: 'application/octet-stream', }, }); まず、画像ファイルをサーバーに送っておかないといけないので、上記みたいな感じで画像を作ります。 免許証などの画像ファイルをapiへ送って、返ってきたidを使って、別のapiを叩いて本人認証を依頼する感じです。 上記のようにapiを叩くと、レスポンスでidが帰ってくるので、これを使う。 { "id": "file_19yVPOfwefwefwefwefweO", "object": "file", idを使っていきますので、どこかの変数に取っておいてください。 本人確認を登録する Update an account ここはこの記事の本題なので、僕が実際に書いたコードを記します。 async function UpdateAccounts( stripe_user_id, HEAD_ID_STRIPE_IMG, BACK_ID_STRIPE_IMG ) { try { const account = await stripe.accounts.update( stripe_id_get_edit_connect_user, { individual: { verification:{document:{front: HEAD_ID_STRIPE_IMG, back: BACK_ID_STRIPE_IMG } }, }, }, ); console.log("アカウント") console.log(account) } catch (err) { console.log("エラー"); console.log(err); } } 上記の関数を呼び出します。 引数には、先ほど作っておいた画像ファイルのidと、Stripe Connectのユーザーのアカウントidを引数に渡してください。 Stripe Connectのユーザーアカウントのことはこの記事では説明しません。 それで、個人間取引なので、individual の中に書かれてるように画像のidをstringで渡します。 ちなみに、このオブジェクトの中には、その他にも住所や名前も入れることが出来ます。 ここら辺のパラメータの詳細は、公式ドキュメントで見れば、何がパラメータに入るのか知ることが出来ます。 この状態でapiを叩くと、optionalなパラメータしかapi定義にないので、そのままオブジェクトが正しければapiが通るはずです。 Stripeで確認 では、Stripeのダッシュボードで確認してみましょう。 下記の画像のようにdentity documentとIdentity document backがProvidedになってれば、 正しく画像のidがStripeのapiに送れてると思う。 あとは、しばらく待ってれば、個人情報が正しく認証されるか否かわかります。 -- ハイテク好きが楽しめるwebメディア | off.tokyo
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

App Engine(GAE)でサービスごとに複数ドメインを使用する方法

GAEのサービス GAEには「サービス」という概念があって、アプリをデプロイする際にサービス名を指定することで、複数のアプリを1つのプロジェクトで同時に立ち上げることができます。 また、各サービスにドメインを割り当てることもできるので、複数のアプリにそれぞれ異なった複数のドメインを割り当てることも可能です。 app.yamlでサービスを設定する 最初に、アプリごと別のサービスとして立ち上げるためにはapp.yamlにサービス名を指定する必要があります。 app.yaml service: SERVICE_NAME runtime: nodejs10 # ... これをデプロイすればGAEにサービスが立ち上がります。(コンソールのGAE⇨サービスで確認可能) dispatch.yamlでルーティングルールを変更する ここからようやく本題ですが、 dispatch.yamlを使ってドメインんとサービスを紐づけます。 dispatch.yaml dispatch: - url: "*www.example.com/*" service: default # ターゲットとなるサービス名 - url: "*app.example.com/*" service: backend # ターゲットとなるサービス名 この設定は1つのプロジェクト内で共通の設定とされるため、この場合だと、defaultかbackendどちらか1つのディレクトリからデプロイしておけば正しく動作します。 あとは、DNSでそれぞれのドメインをGAEサーバに向ければ完了です。 デメリット GAEで複数のサービスを立ち上げるのはとても便利ですが、その分注意しなければならないデメリットもあります。 コストの最適化のためにも以下の点に注意して適宜Cloud Functionを利用するなり他の選択肢を取ることも考慮すべきです。 サービスの分だけインスタンスが立ち上がる。 価格が高くなりがち
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.js: 高齢者等の都道府県別接種回数を数える

こちらにあるデータを加工して、高齢者等の都道府県別接種回数を数えます。 新型コロナワクチンの接種状況(高齢者等) 「都道府県別接種回数詳細」の prefecture.ndjson をダウンロードします。 sum_up.js #! /usr/bin/node // --------------------------------------------------------------- // sum_up.js // // Jun/06/2021 // --------------------------------------------------------------- 'use strict' const ndjson = require('ndjson') var fs = require("fs") const file_in=process.argv[2] const file_json=process.argv[3] console.log (file_in) var first = Array(47) var second = Array(47) first.fill(0) second.fill(0) fs.createReadStream(file_in) .pipe(ndjson.parse()) .on('data', function(obj) { const pref = obj.prefecture const index = parseInt(pref,10) - 1 if (obj.age == "65-") { if (obj.status == 1) { first[index] += obj.count } else if (obj.status == 2) { second[index] += obj.count } } }) .on('end', function() { var data_out = new Object() for (var it in first) { const jt = parseInt(it) + 1 const code_pref = ("00" + jt).slice( -2 ) var unit_aa = new Object() unit_aa["first"] = first[it] unit_aa["second"] = second[it] data_out[code_pref] = unit_aa } const json_str = JSON.stringify(data_out) fs.writeFile (file_json,json_str,function (err) { if (err) { console.error ("Error on write: " + err) } else { console.log("File written.") console.error ("*** 終了 ***") } }) // console.log ("num_first = " + first[8]) // console.log ("num_second = " + second[8]) console.log("*** end ***") }) // --------------------------------------------------------------- 実行コマンド export NODE_PATH=/usr/lib/node_modules /sum_up.js prefecture.ndjson korei.json 次のファイルが作成されます。 korei.json { "10": { "first": 131155, "second": 13156 }, "11": { "first": 364873, "second": 24304 }, "12": { "first": 327663, "second": 24921 }, "13": { "first": 741621, "second": 45711 }, "14": { "first": 367928, "second": 22566 }, (省略) 参考ページ Node.js: ndjson の使い方
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

爆速でLine Pay APIをNode.jsで使ってみる

今回は本物のお金による決済は行わずサンドボックスの中だけで処理をします。 使うツール ngrok line pay sandbox OS MacOS Catalina 準備 とりあえず必要なものをインストールします。 $ git clone -b web-only https://github.com/nkjm/line-pay-bootcamp.git $ cd line-pay-bootcamp/ $ npm install $ npm install -s dotenv line-pay memory-cache uuid コード web.jsに以下のコードをコピペします。 pay/reserveとpay/confirmの2つのエンドポイントを用意します。 また、参考にした記事と違うところとして、uuidをインポートするときは、require('uuid')にして、uuid.v4()で呼び出すようにします。 web.js "use strict"; // Import packages. const express = require("express"); const app = express(); // Launch server. app.listen(process.env.PORT || 5000, () => { console.log(`server is listening to ${process.env.PORT || 5000}...`); }); // Middleware configuration to serve static file. app.use(express.static(__dirname + "/public")); // Set ejs as template engine. app.set("view engine", "ejs"); // Router configuration to serve web page containing pay button. app.get("/", (req, res) => { res.render(__dirname + "/index"); }) // Import environment variables from .env file. require("dotenv").config(); // Import packages. const uuid = require("uuid"); const cache = require("memory-cache"); // Instanticate LINE Pay API SDK. const line_pay = require("line-pay"); const pay = new line_pay({ channelId: process.env.LINE_PAY_CHANNEL_ID, channelSecret: process.env.LINE_PAY_CHANNEL_SECRET, hostname: process.env.LINE_PAY_HOSTNAME, isSandbox: true }) // Router configuration to start payment. app.use("/pay/reserve", (req, res) => { let options = { productName: "チョコレート", amount: 1, currency: "JPY", orderId: uuid.v4(), confirmUrl: process.env.LINE_PAY_CONFIRM_URL } pay.reserve(options).then((response) => { let reservation = options; reservation.transactionId = response.info.transactionId; console.log(`Reservation was made. Detail is following.`); console.log(reservation); // Save order information cache.put(reservation.transactionId, reservation); res.redirect(response.info.paymentUrl.web); }) }) // Router configuration to receive notification when user approves payment. app.use("/pay/confirm", (req, res) => { if (!req.query.transactionId){ throw new Error("Transaction Id not found."); } // Retrieve the reservation from database. let reservation = cache.get(req.query.transactionId); if (!reservation){ throw new Error("Reservation not found."); } console.log(`Retrieved following reservation.`); console.log(reservation); let confirmation = { transactionId: req.query.transactionId, amount: reservation.amount, currency: reservation.currency } console.log(`Going to confirm payment with following options.`); console.log(confirmation); pay.confirm(confirmation).then((response) => { res.send("決済が完了しました。"); }); }) 走らせる ngrokでlocalhostを外部に公開します。 環境変数をセットした上でアプリを走らせないといけないので、ngrok => .env編集 => アプリスタート、という流れになります。 $ ngrok http 5000 ngrok by @inconshreveable (Ctrl+C to quit) Session Status online Session Expires 1 hour, 26 minutes Version 2.3.40 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://xxxxxx.ngrok.io -> http://localhost:5 Forwarding https://xxxxxx.ngrok.io -> http://localhost: Connections ttl opn rt1 rt5 p50 p90 14 0 0.00 0.01 7.19 9.35 表示された外部のURLを.envに記載します。 LINE_PAY_CHANNEL_ID=xxxxx LINE_PAY_CHANNEL_SECRET=xxxxxxx LINE_PAY_CONFIRM_URL=https://xxxxxx.ngrok.io/pay/confirm これでnode.jsアプリも走らせます! $ npm start ngrokのリンクをlineで開くと、決済のシミュレーションができます。 参考 この記事を読まなくても、以下の記事で事足りると思います、、、
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.js: ndjson の使い方

こちらにあるデータをサンプルとして使います。 新型コロナワクチンの接種状況(高齢者等) 「都道府県別接種回数詳細」 です。 prefecture.ndjson をダウンロードします。 これを、栃木県の 2021-06-05 だけのものにします。 awk '/"prefecture":"09"/{print $0}' prefecture.ndjson > tochigi.ndjson awk '/"date":"2021-06-05"/{print $0}' tochigi.ndjson > tochigi_jun05.ndjson tochigi_jun05.ndjson {"date":"2021-06-05","prefecture":"09","gender":"F","age":"-64","medical_worker":false,"status":1,"count":28} {"date":"2021-06-05","prefecture":"09","gender":"F","age":"-64","medical_worker":false,"status":2,"count":2} {"date":"2021-06-05","prefecture":"09","gender":"F","age":"65-","medical_worker":false,"status":1,"count":1380} {"date":"2021-06-05","prefecture":"09","gender":"F","age":"65-","medical_worker":false,"status":2,"count":245} {"date":"2021-06-05","prefecture":"09","gender":"M","age":"-64","medical_worker":false,"status":1,"count":28} {"date":"2021-06-05","prefecture":"09","gender":"M","age":"-64","medical_worker":false,"status":2,"count":4} {"date":"2021-06-05","prefecture":"09","gender":"M","age":"65-","medical_worker":false,"status":1,"count":1031} {"date":"2021-06-05","prefecture":"09","gender":"M","age":"65-","medical_worker":false,"status":2,"count":192} {"date":"2021-06-05","prefecture":"09","gender":"U","age":"UNK","medical_worker":false,"status":1,"count":1} 必要なライブラリーのインストール sudo npm install -g ndjson ex01.js #! /usr/bin/node // --------------------------------------------------------------- // ex01.js // // Jun/06/2021 // --------------------------------------------------------------- 'use strict' const ndjson = require('ndjson') var fs = require("fs") const file_in = 'tochigi_jun05.ndjson' fs.createReadStream(file_in) .pipe(ndjson.parse()) .on('data', function(obj) { // obj is a javascript object console.log(obj) }) // --------------------------------------------------------------- 実行 export NODE_PATH=/usr/lib/node_modules ./ex01.js
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.js Essentials

Addition Function const result = Number(process.argv[2]) + Number(process.argv[3]); console.log(result); Working with Timers#1 setInterval(() => {console.log('TCS');}, 5000); Working with Timers#2 setTimeout(() => {console.log('TCS');}, 2000); Working with Timers#3 const interval = setInterval(() => { console.log('TCS'); }, 2000); setTimeout(() => { clearInterval(interval); }, 10000); Working with callback functions let sum = 0; for(let i=0; i<=1000; i++) { if( i % 3 == 0 ){ sum = sum + i; } } for(let i=0; i<=1000; i++) { if( i % 5 == 0 ){ sum = sum + i; } } console.log(sum); read Stream const fs = require("fs"); var data = ""; const src = fs.createReadStream('Node-stream-handson/data_file.txt', 'utf8'); src.on('data', chunk => { console.log(chunk.length); } ); copy stream const fs = require("fs"); const src = fs.createReadStream('data_file.txt', 'utf8'); src.pipe( fs.createWriteStream('new_data_file.txt') ); Explore Modules var module = require('./module'); var App = require('./App'); const readline = require('readline'); const rs = fs.createReadStream('./input.csv'); //writestreamを作成 const ws = fs.createWriteStream('./output.csv'); const rl = readline.createInterface({ //読み込みたいストリームの設定 input: rs, //書き出したいストリームの設定 output: ws }); Events - file systems const fs = require("fs"); fs.mkdir('Node_folder', (err) => { if (err) { throw err; } console.log('testディレクトリが作成されました'); }); // 書き込むデータ準備 const data = "This is Node.js a powerful backend javascript used very widely in industry for developing web applications."; // 書き込み fs.writeFile("Node_folder/sample.txt", data, (err) => { if (err) throw err; console.log('正常に書き込みが完了しました'); }); Events - http module var http = require('http'); var server = http.createServer(function(request, response) { response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'}); response.end('Hello world'); }) App build - Server Setup var http = require('http'); var html = require('fs').readFileSync('Sample.html'); var server = http.createServer(function(request, response) { response.writeHead(200, {'Content-Type': 'text/html'}); response.end('Hello World'); }) server.listen(8000); App build - Routing const http = require('http'); var url = require('url'); const server = http.createServer((req, res) => { var pathname = url.parse(request.url).pathname; if( pathname == '/hi' ){ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('Hi Welcome'); res.end(); } else if( pathname == '/hello' ) { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('Hello Buddy'); res.end(); } else { res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('404 Page not Found'); res.end(); } }); const port = 8000; server.listen(port); App build - Routing2 const http = require('http'); var url = require('url'); const server = http.createServer((req, res) => { var pathname = url.parse(request.url).pathname; if( pathname == '/hi' ){ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('Hi Welcome'); res.end(); } else if( pathname == '/hello' ) { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('Hello Buddy'); res.end(); } else { res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('404 File not found error'); res.end(); } }); const port = 8000; server.listen(port); App build - Posting Data const http = require('http'); var url = require('url'); const server = http.createServer((req, res) => { var pathname = url.parse(request.url).pathname; if (pathname == '/hi') { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('Hi Welcome'); res.end(); } else if (pathname == '/hello') { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('Hello Buddy'); res.end(); } else { res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('404 Page not Found'); res.end(); } }); const port = 8000; server.listen(port); var http = require('http'); const querystring = require('querystring'); http .createServer(function (req, res) { if (req.method === 'POST') { res.writeHead(200, { 'Content-Type': 'text/html' }); var data = ''; //POSTデータを受けとる req .on('data', (chunk) => { data += chunk; }) .on('end', () => { var form = querystring.parse(data); res.end(form); }); } }) .listen(8000); App build - Handling Requests var server = require('./server.js'); var routers = require('./routers.js'); var handlers = require('./handlers.js'); App build - https request // App const https = require('https'); const fs = require('fs'); const options = { hostname: 'en.wikipedia.org', port: 443, path: '/wiki/Nodejs', method: 'GET', }; https .get(options, (resp) => { let data = ''; // A chunk of data has been received. resp.on('data', (chunk) => { data += chunk; }); // The whole response has been received. Print out the result. resp.on('end', () => { fs.writeFile('Nodejs.html', data, (err) => {console.log(err)}); }); }) .on('error', (err) => { console.log('Error: ' + err.message); }); Events - Working with Custom Events var events = require('events'); var eventEmitter = new events.EventEmitter(); //Create an event handler: var Myfunc = function () { console.log('HI THERE ! HAPPY LEARNING'); } eventEmitter.on('MyEvent', Myfunc); eventEmitter.emit('MyEvent'); Events - http module var http = require('http'); var html = require('fs').readFileSync('Sample.html'); var server = http.createServer(function(request, response) { response.writeHead(200, {'Content-Type': 'text/html'}); response.end(html); }) server.listen(8000); ======================== <!DOCTYPE html> Welcome ! what would you like to have Coffee Tea Milk Read Stream var fs = require('fs'); var stream; readerStream = fs.createReadStream('data_file.txt'); readerStream.setEncoding('UTF8'); readerStream.on('data', (chunk) => { console.log(chunk.length); }); Palindrome function largestPalindrome() { var arr = []; for (var i = 999; i > 100; i--) { for (var j = 999; j > 100; j--) { var mul = j * i; if (isPalin(mul)) { arr.push(j * i); } } } return Math.max.apply(Math, arr); } function isPalin(i) { return i.toString() == i.toString().split('').reverse().join(''); } console.log(largestPalindrome()); Evenly divisible number function findFactor(n, max) { for (let i = 2; i <= max; i++) { if (n % i !== 0) return false; } return true; } let n = 20; //measuring performance for (let i = n; true; i += n) { if (findFactor(i, n)) { console.log(i); break; } else if (i > 1e10) { console.log('Limit'); break; } } Fibonacci Series\ function sumFibs(num) { let previous = 0; let current = 1; let sum = 0; let next; for(current; current <= num;){ next = current + previous; previous = current; if(current % 2 === 0) { sum += current; } current = next; } return sum; } console.log(sumFibs(4000000)); // return 4613732 largest prime factor var divisor = 2; var number = 600851475143; while(number > 1){ if(number % divisor === 0){ number /= divisor; } else { divisor++; } } console.log(divisor); // the largest prime factor of 600851475143 Sum of Squares const sumSquareDifference = (n) => { const numbers = [...Array(n + 1).keys()]; const sumOfSquares = numbers.reduce( (accumulator, number) => accumulator + number ** 2 ); const squareOfSum = numbers.reduce((accumulator, number) => accumulator + number) ** 2; return squareOfSum - sumOfSquares; }; console.log(sumSquareDifference(100)); nth prime number function getPrimes(max) { let arr = new Array(max).fill(undefined); for (let i = 2; i < max; i++) { if (arr[i] === undefined) { arr[i] = true; for (let j = i + i; j < max; j += i) { arr[j] = false; } } } return arr.map((item, i) => (item ? i : false)).filter(Boolean); } let primes = getPrimes(150000); console.log(primes[10000]); Pythogorean triplet for (var a = 1; a < 500; a++) { for (var b = a; b < 1000; b++) { var c = Math.sqrt(a * a + b * b); if (c > b && Number.isInteger(c) && a + b + c == 1000) { console.log(a * b * c); } } } ============================= function isPrime(val){ //test if number is prime for(var i=2; i < val; i++){ if(val % i === 0){ return false; } } return true; } sum Primes function sumPrimes(num) { let arr = Array.from({length: num+1}, (v, k) => k).slice(2); let onlyPrimes = arr.filter( (n) => { let m = n-1; while (m > 1 && m >= Math.sqrt(n)) { if ((n % m) === 0) return false; m--; } return true; }); return onlyPrimes.reduce((a,b) => a+b); } Sum of Multiples let sum = 0; // loop max range const numRange = 1000; // common util function for checking multiples const isMultiple = (num, mode) => (num % mode ? false : true); // looping over an numbers below 1000 and adding 3 or 5 // multiples to sum for (let i = 0; i < numRange; i++) { if (isMultiple(i, 3) || isMultiple(i, 5)) sum += i; } // logs the sum of all the multiples of // 3 or 5 below 1000 => 233168 console.log(sum); console.log(sumPrimes(5)); sum Prime function sumPrime(x) { var array = [], sum=0; for (var i=2; i<x; i++) { if(typeof array[i] === 'undefined') { array[i]=true; for(var k = i+i; k<x; k+=i) { array[k]=false; } if (array[i]) { sum+=i; } } } return sum; } console.log(sumPrime(2000000)); // 142913828922
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[2021年対応] Slackのemojiを一括でダウンロード

今居るワークスペースに魅力的なemojiが一杯... そんな素敵emojiを別のワークスペースにも輸出したい! Qiitaで供養する 1. Slack API登録 App登録 Tokenが無いと始まりません。 xoxb ではじまるTokenを入手します。 https://api.slack.com/apps?new_app=1 から登録 ワークスペースを選んで作成 権限追加 左ペインの OAuth & Permissions から Scopes に emoji:read 権限を追加 Install to Workspace! ワークスペースにAppをインストール(これで動くようになる) こうなればOK Tokenゲットできたので 2. 試し打ち APIリファレンスからAPI試し打ちができるのでやってみる https://api.slack.com/methods/emoji.list/test Tokenをつけてリクエストすると、リクエスト時のパラメータとレスポンスが確認できる 3. Nodeでやろう 先にシェルでnpmで必要なものを揃えておく npm install fs npm install request jsファイルと同じ階層に image ディレクトリを作っておく touch slack-emoji-exporter.js mkdir image コードはここに https://gist.github.com/notchi590/9c62bcc6508f26c4dcde315a79520777 あとは slack-emoji-exporter.js に上書きして保存、実行すればOK 4. 謝辞 めちゃくちゃ参考にさせて頂きました https://qiita.com/ne-peer/items/cbdef4f02b1bb6103e51
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む