- 投稿日:2020-02-27T21:53:16+09:00
Microsoft Teamsで使えるQualityForward Botを作る
Microsoft TeamsはMicrosoftの提供するチャットツールです。ビジネス界隈で利用が広がっています。他のチャットサービスと同様に、他社のサービスと簡単に連携できます。今回はMicrosoft Teamsと連携できるQualityForward用ボットを作成してみました。
利用するAPIについて
Microsoft Teamsのボットは5秒以内にレスポンスを返さないといけないという縛りがあります。Web APIを何度も叩いていると5秒以内にレスポンスが返せない可能性があるので、以前作成したGoogle Apps Script上で動作するWeb APIを利用します。
QualityForwardのテスト集計を返すSlackコマンドを作ってみた - Qiita
このWeb APIであればGoogle Apps Scriptを呼び出すだけなので処理は高速になります。ただし、Google Apps Scriptのリダイレクトする仕組みではMicrosoft Teamsのボットがうまくレスポンスを受け取れませんでした。そのため、直接Google Apps Scriptを呼び出すのではなく、Node.jsサーバ(今回はGlitchを利用)から呼び出す方式にしています。
ボットについて
Microsoft Teamsのボットは簡単に作成できます。今回はWebhookを利用しています。Webhookはあらかじめ作成したボットに対してメッセージを送ると、指定したURLへPOSTメソッドを投げてくれます。レスポンスで返したJSONをボットからの返信として表示してくれます。
コードについて
Node.js(Express利用)のコードは次のようになります。Google Apps Script上で作成しているAPIを実行し、そのレスポンスを返しているだけです。
const express = require("express"); const app = express(); // POSTのボディ解析用 app.use(express.json()) app.use(express.urlencoded({ extended: true })); // HTTPクライアントw追加 const client = require('superagent'); app.use(express.static("public")); app.get("/", (request, response) => { response.sendFile(__dirname + "/views/index.html"); }); // ボットからデータを受け取る処理 app.post("/post", async (request, response) => { // メッセージ内にある日付部分を取得 const date = request.body.text.replace(/^.*?<\/at>(.*)\n.*/s, "$1"); // Google Apps ScriptのAPIを呼び出し const url = `https://script.google.com/macros/s/AKf...IGt/exec?text=${date}`; const res = await client.get(url) // レスポンスを返す response.json({ "type": "message", "text": res.text }); }); const listener = app.listen(process.env.PORT, () => { console.log("Your app is listening on port " + listener.address().port); });これでボットに対して日付を送ると、その日付における処理件数を返してくれるようになりました。
まとめ
今回の仕組みは自前のサーバを立てることなく、サーバレスで構築しています。GlitchもGoogle Apps Scriptも安定していますので、メンテナンス不要で動作できる仕組みは便利です。Microsoft Teamsで情報共有しているプロジェクトでは、この仕組みを試してみてください。
- 投稿日:2020-02-27T19:10:19+09:00
AIに歌を聞かせた。そした彼は笑顔?になった。(COTOHA-情分析API)
概要
歌を聞かせた。
彼はその歌を聴き、
Positiveな感情になると笑い?、
Negativeな感情になると怒り?、
Neutralな感情になると。。。?COTOHAの感情分析APIを使って、歌の歌詞からどのような感情をくみ取るのかを試した。COTOHA API for Developersに登録してすぐに、感情分析APIを試せるようWEBアプリも作った。)
結果
とりあえず歴代CDシングル売り上げ枚数ランキングを聞かせた。
「1位から順に!カウントアップ!?」1.(457.7万枚)およげ!たいやきくん
?"sentiment": "Negative" "score": 0.5
Response
{ "result": { "sentiment": "Negative", "score": 0.5, "emotional_phrase": [ { "form": "こころがはずむ", "emotion": "喜ぶ" }, { "form": "たのしい", "emotion": "P" }, { "form": "おもい", "emotion": "N" }, { "form": "ひろいぜ", "emotion": "PN" }, { "form": "いじめられる", "emotion": "N" }, { "form": "もがいて", "emotion": "N" }, { "form": "こげある", "emotion": "N" }, { "form": "うまそう", "emotion": "P" } ] }, "status": 0, "message": "OK" }2.(325.6万枚)女のみち
?"sentiment": "Negative" "score": 0.2011977885862898
Response
{ "result": { "sentiment": "Negative", "score": 0.2011977885862898, "emotional_phrase": [ { "form": "みちならば暗い", "emotion": "N" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "幸せ", "emotion": "P" }, { "form": "つらい", "emotion": "N" }, { "form": "泣", "emotion": "喜ぶ,悲しい,切ない" }, { "form": "すがって泣いたうぶな", "emotion": "PN" }, { "form": "いけない", "emotion": "N" }, { "form": "みちならば", "emotion": "PN" }, { "form": "捨てた", "emotion": "N" }, { "form": "いじめる", "emotion": "N" } ] }, "status": 0, "message": "OK" }3.(313.2万枚)世界に一つだけの花
?"sentiment": "Positive" "score": 0.08995079776388203
Response
{ "result": { "sentiment": "Positive", "score": 0.08995079776388203, "emotional_phrase": [ { "form": "うれしそうな", "emotion": "P" }, { "form": "笑顔", "emotion": "安心" }, { "form": "好み", "emotion": "好ましい" }, { "form": "困った", "emotion": "N" }, { "form": "迷", "emotion": "不安" }, { "form": "笑い", "emotion": "喜ぶ" }, { "form": "もともと特別な", "emotion": "PN" }, { "form": "ひとそれぞれ", "emotion": "PN" }, { "form": "きれいだ", "emotion": "P" }, { "form": "争う", "emotion": "N" }, { "form": "誇らしげ", "emotion": "P" }, { "form": "咲かせる", "emotion": "P" }, { "form": "一生懸命", "emotion": "PN" }, { "form": "頑張って", "emotion": "P" }, { "form": "仕方ないね", "emotion": "N" }, { "form": "色とりどり", "emotion": "P" }, { "form": "気づかない", "emotion": "N" }, { "form": "小さい", "emotion": "PN" }, { "form": "同じものはない", "emotion": "PN" } ] }, "status": 0, "message": "OK" }4.(293.6万枚)TSUNAMI
?"sentiment": "Negative" "score": 0.10121480950551423
Response
{ "result": { "sentiment": "Negative", "score": 0.10121480950551423, "emotional_phrase": [ { "form": "愛", "emotion": "安心,好ましい" }, { "form": "愛しい", "emotion": "P" }, { "form": "怯えてる", "emotion": "不安" }, { "form": "悲しみ", "emotion": "悲しい" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "好きな", "emotion": "P" }, { "form": "戸惑う", "emotion": "N" }, { "form": "泣いた", "emotion": "N" }, { "form": "涙", "emotion": "喜ぶ,不安,悲しい,切ない" }, { "form": "微笑", "emotion": "安心" }, { "form": "弱気な", "emotion": "N" }, { "form": "すがる", "emotion": "N" }, { "form": "涙もろい", "emotion": "PN" }, { "form": "清か", "emotion": "P" }, { "form": "魔性", "emotion": "N" }, { "form": "彷徨う", "emotion": "N" }, { "form": "枯れる", "emotion": "N" }, { "form": "素直に", "emotion": "P" }, { "form": "侘しさ", "emotion": "PN" }, { "form": "鏡のような", "emotion": "P" }, { "form": "深い", "emotion": "PN" }, { "form": "気付いてる", "emotion": "P" }, { "form": "張り裂けそうな", "emotion": "N" } ] }, "status": 0, "message": "OK" }5.(291.8万枚)だんご3兄弟
?"sentiment": "Negative" "score": 0.06456371454543736
Response
{ "result": { "sentiment": "Negative", "score": 0.06456371454543736, "emotional_phrase": [ { "form": "かたくな", "emotion": "不安" }, { "form": "ささって", "emotion": "P" }, { "form": "まれ", "emotion": "PN" }, { "form": "たくさん", "emotion": "PN" }, { "form": "こげ", "emotion": "N" }, { "form": "かたくなりました", "emotion": "PN" } ] }, "status": 0, "message": "OK" }6.(289.5万枚)君がいるだけで
?"sentiment": "Positive" "score": 0.009547567550434202
Response
{ "result": { "sentiment": "Positive", "score": 0.009547567550434202, "emotional_phrase": [ { "form": "憧れ", "emotion": "P" }, { "form": "笑顔", "emotion": "安心" }, { "form": "くやしい", "emotion": "N" }, { "form": "何より大切な", "emotion": "P" }, { "form": "涙", "emotion": "喜ぶ,切ない,不安,悲しい" }, { "form": "儚い", "emotion": "PN" }, { "form": "強く", "emotion": "PN" }, { "form": "気付かせてくれたね", "emotion": "P" }, { "form": "ありがちな", "emotion": "PN" }, { "form": "つい引き込まれ", "emotion": "P" }, { "form": "弱さ", "emotion": "N" }, { "form": "忘れてた", "emotion": "PN" }, { "form": "もっと素直になれなかった", "emotion": "N" }, { "form": "わかって", "emotion": "P" } ] }, "status": 0, "message": "OK" }7.(282.2万枚)SAY YES
?"sentiment": "Negative" "score": 0.2490204168421342
Response
{ "result": { "sentiment": "Negative", "score": 0.2490204168421342, "emotional_phrase": [ { "form": "愛", "emotion": "好ましい,安心" }, { "form": "愛してる", "emotion": "P" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "寂しい", "emotion": "N" }, { "form": "切なさ", "emotion": "PN" }, { "form": "迷", "emotion": "不安" }, { "form": "ワガママ", "emotion": "N" }, { "form": "余計な", "emotion": "N" }, { "form": "何げなく暮らさない", "emotion": "PN" }, { "form": "あふれてる", "emotion": "N" }, { "form": "勝てない", "emotion": "N" }, { "form": "消えない", "emotion": "P" } ] }, "status": 0, "message": "OK" }8.(276.6万枚)Tomorrow never knows
?"sentiment": "Positive" "score": 0.007165278534051281
Response
{ "result": { "sentiment": "Positive", "score": 0.007165278534051281, "emotional_phrase": [ { "form": "愛した", "emotion": "P" }, { "form": "悲しい", "emotion": "N" }, { "form": "孤独な", "emotion": "PN" }, { "form": "寂しい", "emotion": "N" }, { "form": "愛される喜び", "emotion": "P" }, { "form": "消えた帰らぬ", "emotion": "P" }, { "form": "すれ違う", "emotion": "N" }, { "form": "無邪気に", "emotion": "P" }, { "form": "裏切れる", "emotion": "N" }, { "form": "欲しがっていた", "emotion": "P" }, { "form": "分かり合えた", "emotion": "P" }, { "form": "夢中で駆け抜ける", "emotion": "P" }, { "form": "勝利", "emotion": "P" }, { "form": "敗北もない", "emotion": "P" }, { "form": "忘れてゆく", "emotion": "PN" }, { "form": "避けて通れない", "emotion": "P" }, { "form": "果てしない", "emotion": "P" }, { "form": "優しさ", "emotion": "P" }, { "form": "長い", "emotion": "PN" }, { "form": "癒える", "emotion": "P" }, { "form": "少し", "emotion": "PN" } ] }, "status": 0, "message": "OK" }9.(258.8万枚)ラブ・ストーリーは突然に
?"sentiment": "Positive" "score": 0.060429544970368884
Response
{ "result": { "sentiment": "Positive", "score": 0.060429544970368884, "emotional_phrase": [ { "form": "もっと好き", "emotion": "P" }, { "form": "もう心揺れたりしないで切ない", "emotion": "PN" }, { "form": "揺れたり", "emotion": "興奮" }, { "form": "いい", "emotion": "P" }, { "form": "分からない", "emotion": "N" }, { "form": "消えてゆく", "emotion": "N" }, { "form": "あんまりすてきだ", "emotion": "P" }, { "form": "甘く", "emotion": "PN" }, { "form": "やわらかく", "emotion": "PN" }, { "form": "心が動いた", "emotion": "P" }, { "form": "忘れない", "emotion": "PN" }, { "form": "心揺れたりしないで", "emotion": "PN" } ] }, "status": 0, "message": "OK" }10.(248.9万枚)LOVE LOVE LOVE
?"sentiment": "Positive" "score": 0.24542462771149284
Response
{ "result": { "sentiment": "Positive", "score": 0.24542462771149284, "emotional_phrase": [ { "form": "愛", "emotion": "安心,好ましい" }, { "form": "愛してる", "emotion": "P" }, { "form": "すごく好きな", "emotion": "P" }, { "form": "涙", "emotion": "喜ぶ,切ない,不安,悲しい" }, { "form": "すっごく", "emotion": "PN" }, { "form": "うまく", "emotion": "P" }, { "form": "願う", "emotion": "P" }, { "form": "少しずつ思い出になって", "emotion": "P" } ] }, "status": 0, "message": "OK" }番外編(何となく気になった曲)
大きなのっぽの古時計
?"sentiment": "Positive" "score": 0.30601098537139876
Response
{ "result": { "sentiment": "Positive", "score": 0.30601098537139876, "emotional_phrase": [ { "form": "うれしい", "emotion": "P" }, { "form": "かなしい", "emotion": "N" }, { "form": "のっぽの", "emotion": "PN" }, { "form": "ごじまんの", "emotion": "PN" }, { "form": "きれいな", "emotion": "P" } ] }, "status": 0, "message": "OK" }千の風になって
?"sentiment": "Positive" "score": 0.14780720679775194,
Response
{ "result": { "sentiment": "Positive" "score": 0.14780720679775194, "emotional_phrase": [ { "form": "泣かないでください", "emotion": "P" }, { "form": "きらめく", "emotion": "P" }, { "form": "見守る", "emotion": "P" } ] }, "status": 0, "message": "OK" }パプリカ
?"sentiment": "Positive" "score": 0.01385186275421083
Response
{ "result": { "sentiment": "Positive", "score": 0.01385186275421083, "emotional_phrase": [ { "form": "泣いてた", "emotion": "N" }, { "form": "喜び", "emotion": "P" }, { "form": "晴れた", "emotion": "P" }, { "form": "燻り", "emotion": "N" }, { "form": "慰める", "emotion": "P" }, { "form": "まれ", "emotion": "PN" } ] }, "status": 0, "message": "OK" }WEBアプリ化
COTOHA API for Developersに登録した人限定ではあるが、同じ遊びが出来るようにした。(簡単に登録可)
以下URLで遊ぶには、登録後に取得できる、Client IDとClient secretが必要。
https://cotoha-demo.now.sh/
Client IDとClient secretは、画面リフレッシュのたびに入力しなおすのは面倒。なので、ブラウザのlocalstrageにて情報を保持している。
技術
サービス化に伴い、以下の技術を使用。
- Nuxt.js【JavaScript framework】
- ant-design-vue【Css framework】
- Now【Deploy】
- Express【API】
server.js
server.jsconst express = require('express') const request = require('request') const app = express() // server const port = process.env.PORT || 5000 app.listen(port, err => { if (err) throw err console.log(`> Ready On Server http://localhost:${port}`) }) // API app.get('/getToken', function(req, res, next) { (() => { return new Promise(r => { if (req.query.ClientID && req.query.Clientsecret && req.query.AccessTokenPublishURL){ const AccessTokenPublishURL = req.query.AccessTokenPublishURL const ClientID = req.query.ClientID const Clientsecret = req.query.Clientsecret const headers = { 'Content-Type': 'application/json' } const data = { 'grantType': 'client_credentials', 'clientId': ClientID, 'clientSecret': Clientsecret } const options = { url: AccessTokenPublishURL, method: 'POST', headers: headers, json: data } request(options, (error, response, body) => { return r(body) }) }else{ r('Parameter is incorrect') } }) })().then(data => { res.send(data) }).catch(error => { res.send(error) }) }) app.get('/cotohaApiSimilarity', function(req, res, next) { (() => { return new Promise(r => { if (req.query.sentence && req.query.token){ const sentence = req.query.sentence const token = req.query.token const headers = { 'Content-Type': 'application/json;charset=UTF-8', 'Authorization': `Bearer ${token}` } const data = { 'sentence': sentence, } const options = { url: 'https://api.ce-cotoha.com/api/dev/nlp/v1/sentiment', method: 'POST', headers: headers, json: data } request(options, (error, response, body) => { return r(body) }) }else{ r('Parameter is incorrect') } }) })().then(data => { res.send(data) }).catch(error => { res.send(error) }) })あとがき
他のAPIと組み合わせれば、話す内容によって表情を変えるbotが簡単に出来そう。
あと要約(β)API・キーワード抽出API・言い淀み除去(β)・音声認識誤り検知(β)・音声認識API ここら辺のを使って、音声データから議事録を作るWEBアプリ(WEBサービス)作りたい。。。時間が欲しい。。。
おまけ
Q. さて、これは誰が歌っているのさくらの結果でしょうか???↓
さくら
?"sentiment": "Positive", "score": 0.0010436678748683892,
Response
{ "result": { "sentiment": "Positive", "score": 0.0010436678748683892, "emotional_phrase": [ { "form": "また気になる", "emotion": "PN" }, { "form": "忘れた", "emotion": "PN" }, { "form": "淡い", "emotion": "PN" }, { "form": "意味なく", "emotion": "N" }, { "form": "変わらない", "emotion": "PN" }, { "form": "甦る", "emotion": "PN" }, { "form": "長い", "emotion": "PN" }, { "form": "たわいない", "emotion": "PN" }, { "form": "気付けば", "emotion": "P" }, { "form": "誘われ", "emotion": "P" }, { "form": "すり抜けた", "emotion": "PN" }, { "form": "分からなかった", "emotion": "N" }, { "form": "若かった", "emotion": "P" }, { "form": "香る", "emotion": "P" }, { "form": "暖かい", "emotion": "P" }, { "form": "こぼれる", "emotion": "N" }, { "form": "消えてしまうよ", "emotion": "N" } ] }, "status": 0, "message": "OK" }
- 投稿日:2020-02-27T19:10:19+09:00
AIに歌を聞かせた。そして彼は笑顔?になった。(COTOHA-情分析API)
概要
歌を聞かせた。
彼はその歌を聴き、
Positiveな感情になると笑い?、
Negativeな感情になると怒り?、
Neutralな感情になると。。。?COTOHAの感情分析APIを使って、歌の歌詞からどのような感情をくみ取るのかを試した。COTOHA API for Developersに登録してすぐに、感情分析APIを試せるようWEBアプリも作った。)
結果
とりあえず歴代CDシングル売り上げ枚数ランキングを聞かせた。
「1位から順に!カウントアップ!?」1.(457.7万枚)およげ!たいやきくん
?"sentiment": "Negative" "score": 0.5
Response
{ "result": { "sentiment": "Negative", "score": 0.5, "emotional_phrase": [ { "form": "こころがはずむ", "emotion": "喜ぶ" }, { "form": "たのしい", "emotion": "P" }, { "form": "おもい", "emotion": "N" }, { "form": "ひろいぜ", "emotion": "PN" }, { "form": "いじめられる", "emotion": "N" }, { "form": "もがいて", "emotion": "N" }, { "form": "こげある", "emotion": "N" }, { "form": "うまそう", "emotion": "P" } ] }, "status": 0, "message": "OK" }2.(325.6万枚)女のみち
?"sentiment": "Negative" "score": 0.2011977885862898
Response
{ "result": { "sentiment": "Negative", "score": 0.2011977885862898, "emotional_phrase": [ { "form": "みちならば暗い", "emotion": "N" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "幸せ", "emotion": "P" }, { "form": "つらい", "emotion": "N" }, { "form": "泣", "emotion": "喜ぶ,悲しい,切ない" }, { "form": "すがって泣いたうぶな", "emotion": "PN" }, { "form": "いけない", "emotion": "N" }, { "form": "みちならば", "emotion": "PN" }, { "form": "捨てた", "emotion": "N" }, { "form": "いじめる", "emotion": "N" } ] }, "status": 0, "message": "OK" }3.(313.2万枚)世界に一つだけの花
?"sentiment": "Positive" "score": 0.08995079776388203
Response
{ "result": { "sentiment": "Positive", "score": 0.08995079776388203, "emotional_phrase": [ { "form": "うれしそうな", "emotion": "P" }, { "form": "笑顔", "emotion": "安心" }, { "form": "好み", "emotion": "好ましい" }, { "form": "困った", "emotion": "N" }, { "form": "迷", "emotion": "不安" }, { "form": "笑い", "emotion": "喜ぶ" }, { "form": "もともと特別な", "emotion": "PN" }, { "form": "ひとそれぞれ", "emotion": "PN" }, { "form": "きれいだ", "emotion": "P" }, { "form": "争う", "emotion": "N" }, { "form": "誇らしげ", "emotion": "P" }, { "form": "咲かせる", "emotion": "P" }, { "form": "一生懸命", "emotion": "PN" }, { "form": "頑張って", "emotion": "P" }, { "form": "仕方ないね", "emotion": "N" }, { "form": "色とりどり", "emotion": "P" }, { "form": "気づかない", "emotion": "N" }, { "form": "小さい", "emotion": "PN" }, { "form": "同じものはない", "emotion": "PN" } ] }, "status": 0, "message": "OK" }4.(293.6万枚)TSUNAMI
?"sentiment": "Negative" "score": 0.10121480950551423
Response
{ "result": { "sentiment": "Negative", "score": 0.10121480950551423, "emotional_phrase": [ { "form": "愛", "emotion": "安心,好ましい" }, { "form": "愛しい", "emotion": "P" }, { "form": "怯えてる", "emotion": "不安" }, { "form": "悲しみ", "emotion": "悲しい" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "好きな", "emotion": "P" }, { "form": "戸惑う", "emotion": "N" }, { "form": "泣いた", "emotion": "N" }, { "form": "涙", "emotion": "喜ぶ,不安,悲しい,切ない" }, { "form": "微笑", "emotion": "安心" }, { "form": "弱気な", "emotion": "N" }, { "form": "すがる", "emotion": "N" }, { "form": "涙もろい", "emotion": "PN" }, { "form": "清か", "emotion": "P" }, { "form": "魔性", "emotion": "N" }, { "form": "彷徨う", "emotion": "N" }, { "form": "枯れる", "emotion": "N" }, { "form": "素直に", "emotion": "P" }, { "form": "侘しさ", "emotion": "PN" }, { "form": "鏡のような", "emotion": "P" }, { "form": "深い", "emotion": "PN" }, { "form": "気付いてる", "emotion": "P" }, { "form": "張り裂けそうな", "emotion": "N" } ] }, "status": 0, "message": "OK" }5.(291.8万枚)だんご3兄弟
?"sentiment": "Negative" "score": 0.06456371454543736
Response
{ "result": { "sentiment": "Negative", "score": 0.06456371454543736, "emotional_phrase": [ { "form": "かたくな", "emotion": "不安" }, { "form": "ささって", "emotion": "P" }, { "form": "まれ", "emotion": "PN" }, { "form": "たくさん", "emotion": "PN" }, { "form": "こげ", "emotion": "N" }, { "form": "かたくなりました", "emotion": "PN" } ] }, "status": 0, "message": "OK" }6.(289.5万枚)君がいるだけで
?"sentiment": "Positive" "score": 0.009547567550434202
Response
{ "result": { "sentiment": "Positive", "score": 0.009547567550434202, "emotional_phrase": [ { "form": "憧れ", "emotion": "P" }, { "form": "笑顔", "emotion": "安心" }, { "form": "くやしい", "emotion": "N" }, { "form": "何より大切な", "emotion": "P" }, { "form": "涙", "emotion": "喜ぶ,切ない,不安,悲しい" }, { "form": "儚い", "emotion": "PN" }, { "form": "強く", "emotion": "PN" }, { "form": "気付かせてくれたね", "emotion": "P" }, { "form": "ありがちな", "emotion": "PN" }, { "form": "つい引き込まれ", "emotion": "P" }, { "form": "弱さ", "emotion": "N" }, { "form": "忘れてた", "emotion": "PN" }, { "form": "もっと素直になれなかった", "emotion": "N" }, { "form": "わかって", "emotion": "P" } ] }, "status": 0, "message": "OK" }7.(282.2万枚)SAY YES
?"sentiment": "Negative" "score": 0.2490204168421342
Response
{ "result": { "sentiment": "Negative", "score": 0.2490204168421342, "emotional_phrase": [ { "form": "愛", "emotion": "好ましい,安心" }, { "form": "愛してる", "emotion": "P" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "寂しい", "emotion": "N" }, { "form": "切なさ", "emotion": "PN" }, { "form": "迷", "emotion": "不安" }, { "form": "ワガママ", "emotion": "N" }, { "form": "余計な", "emotion": "N" }, { "form": "何げなく暮らさない", "emotion": "PN" }, { "form": "あふれてる", "emotion": "N" }, { "form": "勝てない", "emotion": "N" }, { "form": "消えない", "emotion": "P" } ] }, "status": 0, "message": "OK" }8.(276.6万枚)Tomorrow never knows
?"sentiment": "Positive" "score": 0.007165278534051281
Response
{ "result": { "sentiment": "Positive", "score": 0.007165278534051281, "emotional_phrase": [ { "form": "愛した", "emotion": "P" }, { "form": "悲しい", "emotion": "N" }, { "form": "孤独な", "emotion": "PN" }, { "form": "寂しい", "emotion": "N" }, { "form": "愛される喜び", "emotion": "P" }, { "form": "消えた帰らぬ", "emotion": "P" }, { "form": "すれ違う", "emotion": "N" }, { "form": "無邪気に", "emotion": "P" }, { "form": "裏切れる", "emotion": "N" }, { "form": "欲しがっていた", "emotion": "P" }, { "form": "分かり合えた", "emotion": "P" }, { "form": "夢中で駆け抜ける", "emotion": "P" }, { "form": "勝利", "emotion": "P" }, { "form": "敗北もない", "emotion": "P" }, { "form": "忘れてゆく", "emotion": "PN" }, { "form": "避けて通れない", "emotion": "P" }, { "form": "果てしない", "emotion": "P" }, { "form": "優しさ", "emotion": "P" }, { "form": "長い", "emotion": "PN" }, { "form": "癒える", "emotion": "P" }, { "form": "少し", "emotion": "PN" } ] }, "status": 0, "message": "OK" }9.(258.8万枚)ラブ・ストーリーは突然に
?"sentiment": "Positive" "score": 0.060429544970368884
Response
{ "result": { "sentiment": "Positive", "score": 0.060429544970368884, "emotional_phrase": [ { "form": "もっと好き", "emotion": "P" }, { "form": "もう心揺れたりしないで切ない", "emotion": "PN" }, { "form": "揺れたり", "emotion": "興奮" }, { "form": "いい", "emotion": "P" }, { "form": "分からない", "emotion": "N" }, { "form": "消えてゆく", "emotion": "N" }, { "form": "あんまりすてきだ", "emotion": "P" }, { "form": "甘く", "emotion": "PN" }, { "form": "やわらかく", "emotion": "PN" }, { "form": "心が動いた", "emotion": "P" }, { "form": "忘れない", "emotion": "PN" }, { "form": "心揺れたりしないで", "emotion": "PN" } ] }, "status": 0, "message": "OK" }10.(248.9万枚)LOVE LOVE LOVE
?"sentiment": "Positive" "score": 0.24542462771149284
Response
{ "result": { "sentiment": "Positive", "score": 0.24542462771149284, "emotional_phrase": [ { "form": "愛", "emotion": "安心,好ましい" }, { "form": "愛してる", "emotion": "P" }, { "form": "すごく好きな", "emotion": "P" }, { "form": "涙", "emotion": "喜ぶ,切ない,不安,悲しい" }, { "form": "すっごく", "emotion": "PN" }, { "form": "うまく", "emotion": "P" }, { "form": "願う", "emotion": "P" }, { "form": "少しずつ思い出になって", "emotion": "P" } ] }, "status": 0, "message": "OK" }番外編(何となく気になった曲)
大きなのっぽの古時計
?"sentiment": "Positive" "score": 0.30601098537139876
Response
{ "result": { "sentiment": "Positive", "score": 0.30601098537139876, "emotional_phrase": [ { "form": "うれしい", "emotion": "P" }, { "form": "かなしい", "emotion": "N" }, { "form": "のっぽの", "emotion": "PN" }, { "form": "ごじまんの", "emotion": "PN" }, { "form": "きれいな", "emotion": "P" } ] }, "status": 0, "message": "OK" }千の風になって
?"sentiment": "Positive" "score": 0.14780720679775194,
Response
{ "result": { "sentiment": "Positive" "score": 0.14780720679775194, "emotional_phrase": [ { "form": "泣かないでください", "emotion": "P" }, { "form": "きらめく", "emotion": "P" }, { "form": "見守る", "emotion": "P" } ] }, "status": 0, "message": "OK" }パプリカ
?"sentiment": "Positive" "score": 0.01385186275421083
Response
{ "result": { "sentiment": "Positive", "score": 0.01385186275421083, "emotional_phrase": [ { "form": "泣いてた", "emotion": "N" }, { "form": "喜び", "emotion": "P" }, { "form": "晴れた", "emotion": "P" }, { "form": "燻り", "emotion": "N" }, { "form": "慰める", "emotion": "P" }, { "form": "まれ", "emotion": "PN" } ] }, "status": 0, "message": "OK" }WEBアプリ化
COTOHA API for Developersに登録した人限定ではあるが、同じ遊びが出来るようにした。(簡単に登録可)
以下URLで遊ぶには、登録後に取得できる、Client IDとClient secretが必要。
https://cotoha-demo.now.sh/
Client IDとClient secretは、画面リフレッシュのたびに入力しなおすのは面倒。なので、ブラウザのlocalstrageにて情報を保持している。
技術
サービス化に伴い、以下の技術を使用。
- Nuxt.js【JavaScript framework】
- ant-design-vue【Css framework】
- Now【Deploy】
- Express【API】
server.js
server.jsconst express = require('express') const request = require('request') const app = express() // server const port = process.env.PORT || 5000 app.listen(port, err => { if (err) throw err console.log(`> Ready On Server http://localhost:${port}`) }) // API app.get('/getToken', function(req, res, next) { (() => { return new Promise(r => { if (req.query.ClientID && req.query.Clientsecret && req.query.AccessTokenPublishURL){ const AccessTokenPublishURL = req.query.AccessTokenPublishURL const ClientID = req.query.ClientID const Clientsecret = req.query.Clientsecret const headers = { 'Content-Type': 'application/json' } const data = { 'grantType': 'client_credentials', 'clientId': ClientID, 'clientSecret': Clientsecret } const options = { url: AccessTokenPublishURL, method: 'POST', headers: headers, json: data } request(options, (error, response, body) => { return r(body) }) }else{ r('Parameter is incorrect') } }) })().then(data => { res.send(data) }).catch(error => { res.send(error) }) }) app.get('/cotohaApiSimilarity', function(req, res, next) { (() => { return new Promise(r => { if (req.query.sentence && req.query.token){ const sentence = req.query.sentence const token = req.query.token const headers = { 'Content-Type': 'application/json;charset=UTF-8', 'Authorization': `Bearer ${token}` } const data = { 'sentence': sentence, } const options = { url: 'https://api.ce-cotoha.com/api/dev/nlp/v1/sentiment', method: 'POST', headers: headers, json: data } request(options, (error, response, body) => { return r(body) }) }else{ r('Parameter is incorrect') } }) })().then(data => { res.send(data) }).catch(error => { res.send(error) }) })あとがき
他のAPIと組み合わせれば、話す内容によって表情を変えるbotが簡単に出来そう。
あと要約(β)API・キーワード抽出API・言い淀み除去(β)・音声認識誤り検知(β)・音声認識API ここら辺のを使って、音声データから議事録を作るWEBアプリ(WEBサービス)作りたい。。。時間が欲しい。。。
おまけ
Q. さて、これは誰が歌っているのさくらの結果でしょうか???↓
さくら
?"sentiment": "Positive", "score": 0.0010436678748683892,
Response
{ "result": { "sentiment": "Positive", "score": 0.0010436678748683892, "emotional_phrase": [ { "form": "また気になる", "emotion": "PN" }, { "form": "忘れた", "emotion": "PN" }, { "form": "淡い", "emotion": "PN" }, { "form": "意味なく", "emotion": "N" }, { "form": "変わらない", "emotion": "PN" }, { "form": "甦る", "emotion": "PN" }, { "form": "長い", "emotion": "PN" }, { "form": "たわいない", "emotion": "PN" }, { "form": "気付けば", "emotion": "P" }, { "form": "誘われ", "emotion": "P" }, { "form": "すり抜けた", "emotion": "PN" }, { "form": "分からなかった", "emotion": "N" }, { "form": "若かった", "emotion": "P" }, { "form": "香る", "emotion": "P" }, { "form": "暖かい", "emotion": "P" }, { "form": "こぼれる", "emotion": "N" }, { "form": "消えてしまうよ", "emotion": "N" } ] }, "status": 0, "message": "OK" }
- 投稿日:2020-02-27T19:10:19+09:00
AIに歌を聞かせた。そして彼は笑顔?になった。(COTOHA-感情分析API)
概要
歌を聞かせた。
彼はその歌を聴き、
Positiveな感情になると笑い?、
Negativeな感情になると怒り?、
Neutralな感情になると。。。?(COTOHAの感情分析APIを使って、歌の歌詞からどのような感情をくみ取るのかを試した。COTOHA API for Developersに登録してすぐに、感情分析APIを試せるようWEBアプリも作った。)
結果
とりあえず歴代CDシングル売り上げ枚数ランキングを聞かせた。
「1位から順に!カウントアップ!?」1.(457.7万枚)およげ!たいやきくん
?"sentiment": "Negative" "score": 0.5
Response
{ "result": { "sentiment": "Negative", "score": 0.5, "emotional_phrase": [ { "form": "こころがはずむ", "emotion": "喜ぶ" }, { "form": "たのしい", "emotion": "P" }, { "form": "おもい", "emotion": "N" }, { "form": "ひろいぜ", "emotion": "PN" }, { "form": "いじめられる", "emotion": "N" }, { "form": "もがいて", "emotion": "N" }, { "form": "こげある", "emotion": "N" }, { "form": "うまそう", "emotion": "P" } ] }, "status": 0, "message": "OK" }2.(325.6万枚)女のみち
?"sentiment": "Negative" "score": 0.2011977885862898
Response
{ "result": { "sentiment": "Negative", "score": 0.2011977885862898, "emotional_phrase": [ { "form": "みちならば暗い", "emotion": "N" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "幸せ", "emotion": "P" }, { "form": "つらい", "emotion": "N" }, { "form": "泣", "emotion": "喜ぶ,悲しい,切ない" }, { "form": "すがって泣いたうぶな", "emotion": "PN" }, { "form": "いけない", "emotion": "N" }, { "form": "みちならば", "emotion": "PN" }, { "form": "捨てた", "emotion": "N" }, { "form": "いじめる", "emotion": "N" } ] }, "status": 0, "message": "OK" }3.(313.2万枚)世界に一つだけの花
?"sentiment": "Positive" "score": 0.08995079776388203
Response
{ "result": { "sentiment": "Positive", "score": 0.08995079776388203, "emotional_phrase": [ { "form": "うれしそうな", "emotion": "P" }, { "form": "笑顔", "emotion": "安心" }, { "form": "好み", "emotion": "好ましい" }, { "form": "困った", "emotion": "N" }, { "form": "迷", "emotion": "不安" }, { "form": "笑い", "emotion": "喜ぶ" }, { "form": "もともと特別な", "emotion": "PN" }, { "form": "ひとそれぞれ", "emotion": "PN" }, { "form": "きれいだ", "emotion": "P" }, { "form": "争う", "emotion": "N" }, { "form": "誇らしげ", "emotion": "P" }, { "form": "咲かせる", "emotion": "P" }, { "form": "一生懸命", "emotion": "PN" }, { "form": "頑張って", "emotion": "P" }, { "form": "仕方ないね", "emotion": "N" }, { "form": "色とりどり", "emotion": "P" }, { "form": "気づかない", "emotion": "N" }, { "form": "小さい", "emotion": "PN" }, { "form": "同じものはない", "emotion": "PN" } ] }, "status": 0, "message": "OK" }4.(293.6万枚)TSUNAMI
?"sentiment": "Negative" "score": 0.10121480950551423
Response
{ "result": { "sentiment": "Negative", "score": 0.10121480950551423, "emotional_phrase": [ { "form": "愛", "emotion": "安心,好ましい" }, { "form": "愛しい", "emotion": "P" }, { "form": "怯えてる", "emotion": "不安" }, { "form": "悲しみ", "emotion": "悲しい" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "好きな", "emotion": "P" }, { "form": "戸惑う", "emotion": "N" }, { "form": "泣いた", "emotion": "N" }, { "form": "涙", "emotion": "喜ぶ,不安,悲しい,切ない" }, { "form": "微笑", "emotion": "安心" }, { "form": "弱気な", "emotion": "N" }, { "form": "すがる", "emotion": "N" }, { "form": "涙もろい", "emotion": "PN" }, { "form": "清か", "emotion": "P" }, { "form": "魔性", "emotion": "N" }, { "form": "彷徨う", "emotion": "N" }, { "form": "枯れる", "emotion": "N" }, { "form": "素直に", "emotion": "P" }, { "form": "侘しさ", "emotion": "PN" }, { "form": "鏡のような", "emotion": "P" }, { "form": "深い", "emotion": "PN" }, { "form": "気付いてる", "emotion": "P" }, { "form": "張り裂けそうな", "emotion": "N" } ] }, "status": 0, "message": "OK" }5.(291.8万枚)だんご3兄弟
?"sentiment": "Negative" "score": 0.06456371454543736
Response
{ "result": { "sentiment": "Negative", "score": 0.06456371454543736, "emotional_phrase": [ { "form": "かたくな", "emotion": "不安" }, { "form": "ささって", "emotion": "P" }, { "form": "まれ", "emotion": "PN" }, { "form": "たくさん", "emotion": "PN" }, { "form": "こげ", "emotion": "N" }, { "form": "かたくなりました", "emotion": "PN" } ] }, "status": 0, "message": "OK" }6.(289.5万枚)君がいるだけで
?"sentiment": "Positive" "score": 0.009547567550434202
Response
{ "result": { "sentiment": "Positive", "score": 0.009547567550434202, "emotional_phrase": [ { "form": "憧れ", "emotion": "P" }, { "form": "笑顔", "emotion": "安心" }, { "form": "くやしい", "emotion": "N" }, { "form": "何より大切な", "emotion": "P" }, { "form": "涙", "emotion": "喜ぶ,切ない,不安,悲しい" }, { "form": "儚い", "emotion": "PN" }, { "form": "強く", "emotion": "PN" }, { "form": "気付かせてくれたね", "emotion": "P" }, { "form": "ありがちな", "emotion": "PN" }, { "form": "つい引き込まれ", "emotion": "P" }, { "form": "弱さ", "emotion": "N" }, { "form": "忘れてた", "emotion": "PN" }, { "form": "もっと素直になれなかった", "emotion": "N" }, { "form": "わかって", "emotion": "P" } ] }, "status": 0, "message": "OK" }7.(282.2万枚)SAY YES
?"sentiment": "Negative" "score": 0.2490204168421342
Response
{ "result": { "sentiment": "Negative", "score": 0.2490204168421342, "emotional_phrase": [ { "form": "愛", "emotion": "好ましい,安心" }, { "form": "愛してる", "emotion": "P" }, { "form": "恋", "emotion": "好ましい,切ない" }, { "form": "寂しい", "emotion": "N" }, { "form": "切なさ", "emotion": "PN" }, { "form": "迷", "emotion": "不安" }, { "form": "ワガママ", "emotion": "N" }, { "form": "余計な", "emotion": "N" }, { "form": "何げなく暮らさない", "emotion": "PN" }, { "form": "あふれてる", "emotion": "N" }, { "form": "勝てない", "emotion": "N" }, { "form": "消えない", "emotion": "P" } ] }, "status": 0, "message": "OK" }8.(276.6万枚)Tomorrow never knows
?"sentiment": "Positive" "score": 0.007165278534051281
Response
{ "result": { "sentiment": "Positive", "score": 0.007165278534051281, "emotional_phrase": [ { "form": "愛した", "emotion": "P" }, { "form": "悲しい", "emotion": "N" }, { "form": "孤独な", "emotion": "PN" }, { "form": "寂しい", "emotion": "N" }, { "form": "愛される喜び", "emotion": "P" }, { "form": "消えた帰らぬ", "emotion": "P" }, { "form": "すれ違う", "emotion": "N" }, { "form": "無邪気に", "emotion": "P" }, { "form": "裏切れる", "emotion": "N" }, { "form": "欲しがっていた", "emotion": "P" }, { "form": "分かり合えた", "emotion": "P" }, { "form": "夢中で駆け抜ける", "emotion": "P" }, { "form": "勝利", "emotion": "P" }, { "form": "敗北もない", "emotion": "P" }, { "form": "忘れてゆく", "emotion": "PN" }, { "form": "避けて通れない", "emotion": "P" }, { "form": "果てしない", "emotion": "P" }, { "form": "優しさ", "emotion": "P" }, { "form": "長い", "emotion": "PN" }, { "form": "癒える", "emotion": "P" }, { "form": "少し", "emotion": "PN" } ] }, "status": 0, "message": "OK" }9.(258.8万枚)ラブ・ストーリーは突然に
?"sentiment": "Positive" "score": 0.060429544970368884
Response
{ "result": { "sentiment": "Positive", "score": 0.060429544970368884, "emotional_phrase": [ { "form": "もっと好き", "emotion": "P" }, { "form": "もう心揺れたりしないで切ない", "emotion": "PN" }, { "form": "揺れたり", "emotion": "興奮" }, { "form": "いい", "emotion": "P" }, { "form": "分からない", "emotion": "N" }, { "form": "消えてゆく", "emotion": "N" }, { "form": "あんまりすてきだ", "emotion": "P" }, { "form": "甘く", "emotion": "PN" }, { "form": "やわらかく", "emotion": "PN" }, { "form": "心が動いた", "emotion": "P" }, { "form": "忘れない", "emotion": "PN" }, { "form": "心揺れたりしないで", "emotion": "PN" } ] }, "status": 0, "message": "OK" }10.(248.9万枚)LOVE LOVE LOVE
?"sentiment": "Positive" "score": 0.24542462771149284
Response
{ "result": { "sentiment": "Positive", "score": 0.24542462771149284, "emotional_phrase": [ { "form": "愛", "emotion": "安心,好ましい" }, { "form": "愛してる", "emotion": "P" }, { "form": "すごく好きな", "emotion": "P" }, { "form": "涙", "emotion": "喜ぶ,切ない,不安,悲しい" }, { "form": "すっごく", "emotion": "PN" }, { "form": "うまく", "emotion": "P" }, { "form": "願う", "emotion": "P" }, { "form": "少しずつ思い出になって", "emotion": "P" } ] }, "status": 0, "message": "OK" }番外編(何となく気になった曲)
大きなのっぽの古時計
?"sentiment": "Positive" "score": 0.30601098537139876
Response
{ "result": { "sentiment": "Positive", "score": 0.30601098537139876, "emotional_phrase": [ { "form": "うれしい", "emotion": "P" }, { "form": "かなしい", "emotion": "N" }, { "form": "のっぽの", "emotion": "PN" }, { "form": "ごじまんの", "emotion": "PN" }, { "form": "きれいな", "emotion": "P" } ] }, "status": 0, "message": "OK" }千の風になって
?"sentiment": "Positive" "score": 0.14780720679775194,
Response
{ "result": { "sentiment": "Positive" "score": 0.14780720679775194, "emotional_phrase": [ { "form": "泣かないでください", "emotion": "P" }, { "form": "きらめく", "emotion": "P" }, { "form": "見守る", "emotion": "P" } ] }, "status": 0, "message": "OK" }パプリカ
?"sentiment": "Positive" "score": 0.01385186275421083
Response
{ "result": { "sentiment": "Positive", "score": 0.01385186275421083, "emotional_phrase": [ { "form": "泣いてた", "emotion": "N" }, { "form": "喜び", "emotion": "P" }, { "form": "晴れた", "emotion": "P" }, { "form": "燻り", "emotion": "N" }, { "form": "慰める", "emotion": "P" }, { "form": "まれ", "emotion": "PN" } ] }, "status": 0, "message": "OK" }WEBアプリ化
COTOHA API for Developersに登録した人限定ではあるが、同じ遊びが出来るようにした。(簡単に登録可)
以下URLで遊ぶには、登録後に取得できる、Client IDとClient secretが必要。
https://cotoha-demo.now.sh/
Client IDとClient secretは、画面リフレッシュのたびに入力しなおすのは面倒。なので、ブラウザのlocalstrageにて情報を保持している。
技術
アプリ化に伴い、以下の技術を使用。
- Nuxt.js【JavaScript framework】
- ant-design-vue【Css framework】
- Now【Deploy】
- Express【API】
server.js
server.jsconst express = require('express') const request = require('request') const app = express() // server const port = process.env.PORT || 5000 app.listen(port, err => { if (err) throw err console.log(`> Ready On Server http://localhost:${port}`) }) // API app.get('/getToken', function(req, res, next) { (() => { return new Promise(r => { if (req.query.ClientID && req.query.Clientsecret && req.query.AccessTokenPublishURL){ const AccessTokenPublishURL = req.query.AccessTokenPublishURL const ClientID = req.query.ClientID const Clientsecret = req.query.Clientsecret const headers = { 'Content-Type': 'application/json' } const data = { 'grantType': 'client_credentials', 'clientId': ClientID, 'clientSecret': Clientsecret } const options = { url: AccessTokenPublishURL, method: 'POST', headers: headers, json: data } request(options, (error, response, body) => { return r(body) }) }else{ r('Parameter is incorrect') } }) })().then(data => { res.send(data) }).catch(error => { res.send(error) }) }) app.get('/cotohaApiSimilarity', function(req, res, next) { (() => { return new Promise(r => { if (req.query.sentence && req.query.token){ const sentence = req.query.sentence const token = req.query.token const headers = { 'Content-Type': 'application/json;charset=UTF-8', 'Authorization': `Bearer ${token}` } const data = { 'sentence': sentence, } const options = { url: 'https://api.ce-cotoha.com/api/dev/nlp/v1/sentiment', method: 'POST', headers: headers, json: data } request(options, (error, response, body) => { return r(body) }) }else{ r('Parameter is incorrect') } }) })().then(data => { res.send(data) }).catch(error => { res.send(error) }) })あとがき
他のAPIと組み合わせれば、話す内容によって表情を変えるbotが簡単に出来そう。
あと要約(β)API・キーワード抽出API・言い淀み除去(β)・音声認識誤り検知(β)・音声認識API ここら辺のを使って、音声データから議事録を作るWEBアプリ(WEBサービス)作りたい。。。時間が欲しい。。。
おまけ
Q. さて、これは誰が歌っているのさくらの結果でしょうか???↓
さくら
?"sentiment": "Positive", "score": 0.0010436678748683892,
Response
{ "result": { "sentiment": "Positive", "score": 0.0010436678748683892, "emotional_phrase": [ { "form": "また気になる", "emotion": "PN" }, { "form": "忘れた", "emotion": "PN" }, { "form": "淡い", "emotion": "PN" }, { "form": "意味なく", "emotion": "N" }, { "form": "変わらない", "emotion": "PN" }, { "form": "甦る", "emotion": "PN" }, { "form": "長い", "emotion": "PN" }, { "form": "たわいない", "emotion": "PN" }, { "form": "気付けば", "emotion": "P" }, { "form": "誘われ", "emotion": "P" }, { "form": "すり抜けた", "emotion": "PN" }, { "form": "分からなかった", "emotion": "N" }, { "form": "若かった", "emotion": "P" }, { "form": "香る", "emotion": "P" }, { "form": "暖かい", "emotion": "P" }, { "form": "こぼれる", "emotion": "N" }, { "form": "消えてしまうよ", "emotion": "N" } ] }, "status": 0, "message": "OK" }
- 投稿日:2020-02-27T17:12:37+09:00
Windowsでnpm startしたときに「内部コマンドまたは外部コマンド」と出てくる現象と戦う
1. 問題発生
Webpackをglobalにインストールすることが非推奨であることを知り、
> npm remove -g webpack webpack-cliとしたところ、既存のプロジェクトにて
> npm run build 'webpack' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。と出てしまった。
package.json の scripts はこんな感じpackage.json"scripts": { "build": "webpack --mode development", },ひとまずこれは再度グローバルにインストールすることで回避していたが、
ある日、Reactの勉強を始めようとしたところ、> npx create-react-app pwa-sample > cd pwa-sample > yarn start 'react-scripts' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。と、こちらもNG。
どういうことなの?2. 試したこと
- node_modules と packege-lock.json を削除して
npm install
・・・ NG- コマンドプロンプトやPowerShellを管理者で起動して ・・・ NG
- node_modules/.bin の中に webpack.cmd(react-scripts.cmd) が存在するか確認 ・・・ 存在する
- npx コマンドでstart ・・・ OK
- package.json 内の webpack や react-scripts コマンドのパス書き換え ・・・ OK
つまり、 node_modules/.bin のパスを理解していない ということか?
この時点での解決策は以下になるが、これではMacやLinuxと共通化ができずに面倒くさいしイマイチ美しくない。package.json"scripts": { "build": "node_modules\\.bin\\webpack.cmd --mode development" // webpackの場合 "start": "node_modules\\.bin\\react-scripts.cmd start" // react-scriptの場合 }通常、私はプロジェクト用のディレクトリは
D:\projects
というパスに設置しているが、
ちょっと気分を変えてC:\Users\hogehoge\Documents(マイドキュメント)
にて作業してみた。>yarn start yarn run v1.22.0 $ react-scripts start Starting the development server... Compiled successfully!あれ?通った?
3. 原因判明
CドライブとDドライブで何が違うんだろう・・・とパーミッションやnpmグローバルディレクトリを覗いていたがよくわからない。
C:\Users\hogehoge\AppData\Roaming\npm-cache\_logs
も見るがパスは通っているように見える。
(PATHの行に プロジェクトディレクトリ/node_modules/.bin が含まれている)後は何が問題なのだろうか、ドライブ間で何か特別な操作をしただろうか?
1つだけあった
それは以前に 大文字小文字を区別する設定をしていた ことだった。試しにこれを解除して再チャレンジ
> fsutil.exe file SetCaseSensitiveInfo D:\project disable > yarn start yarn run v1.22.0 $ react-scripts start Starting the development server... Compiled successfully!問題なく通りました。
もちろんwebpackもOK。つまり、webpack や react-scripts コマンドは webpack.cmd や react-scripts.cmd ではなく、webpack.CMD や react-scripts.CMD を探していた、ということらしい。
皆さん、楽がしたいからと大きいディレクトリでSetCaseSensitiveInfoを有効にしないように注意しましょう。
ただ、これが有効になっていないと困るケースもあるので悩ましい・・・
- 投稿日:2020-02-27T17:12:37+09:00
Windowsでnpm startしたときに「内部コマンドまたは外部コマンド~」と出てくる現象と戦う
1. 問題発生
Webpackをglobalにインストールすることが非推奨であることを知り、
> npm remove -g webpack webpack-cliとしたところ、既存のプロジェクトにて
> npm run build 'webpack' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。と出てしまった。
package.json の scripts はこんな感じpackage.json"scripts": { "build": "webpack --mode development", }ひとまずこれは再度グローバルにインストールすることで回避していたが、
ある日、Reactの勉強を始めようとしたところ、> npx create-react-app pwa-sample > cd pwa-sample > yarn start 'react-scripts' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。と、こちらもNG。
どういうことなの?2. 試したこと
- node_modules と packege-lock.json を削除して
npm install
・・・ NG- コマンドプロンプトやPowerShellを管理者で起動して ・・・ NG
- node_modules/.bin の中に webpack.cmd(react-scripts.cmd) が存在するか確認 ・・・ 存在する
- npx コマンドでstart ・・・ OK
- package.json 内の webpack や react-scripts コマンドのパス書き換え ・・・ OK
つまり、 node_modules/.bin のパスを理解していない ということか?
この時点での解決策は以下になるが、これではMacやLinuxと共通化ができずに面倒くさいしイマイチ美しくない。package.json"scripts": { "build": "node_modules\\.bin\\webpack.cmd --mode development" // webpackの場合 "start": "node_modules\\.bin\\react-scripts.cmd start" // react-scriptの場合 }通常、私はプロジェクト用のディレクトリは
D:\projects
というパスに設置しているが、
ちょっと気分を変えてC:\Users\hogehoge\Documents(マイドキュメント)
にて作業してみた。>yarn start yarn run v1.22.0 $ react-scripts start Starting the development server... Compiled successfully!あれ?通った?
3. 原因判明
CドライブとDドライブで何が違うんだろう・・・とパーミッションやnpmグローバルディレクトリを覗いていたがよくわからない。
C:\Users\hogehoge\AppData\Roaming\npm-cache\_logs
も見るがパスは通っているように見える。
(PATHの行に プロジェクトディレクトリ/node_modules/.bin が含まれている)後は何が問題なのだろうか、ドライブ間で何か特別な操作をしただろうか?
1つだけあった
それは以前に 大文字小文字を区別する設定をしていた ことだった。# 管理者で実行 > fsutil.exe file SetCaseSensitiveInfo D:\projects ディレクトリ D:\projects の大文字と小文字を区別する属性が有効になっています。試しにこれを解除して再チャレンジ
# 管理者で実行 > fsutil.exe file SetCaseSensitiveInfo D:\project disable ディレクトリ D:\project の大文字と小文字を区別する属性が無効になっています。 # 通常ユーザーで実行 > yarn start yarn run v1.22.0 $ react-scripts start Starting the development server... Compiled successfully!問題なく通りました。
もちろんwebpackもOK。どうやら、webpack や react-scripts コマンドは webpack.cmd や react-scripts.cmd ではなく、webpack.CMD や react-scripts.CMD を探していた、ということらしい。
安易にSetCaseSensitiveInfoを有効にしないように注意しましょう。
ただ、これが有効になっていないと困るケースもあるので悩ましい・・・
状況により中段に書いたnode_modules\\.bin\\webpack.cmd
と併用することになりそう。
- 投稿日:2020-02-27T02:30:07+09:00
RESTサーバのMockを簡単に作る方法
node.jsのjson-serverを利用する
json-serverというライブラリが素敵な感じ。
導入
ローカルに導入するとして。。。
1. 展開場所確保
npm init
2. インストール
npm install json-server
3. キック用にpackage.jason書き換えpackage.json"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "json-server": "json-server" },4.mockデータファイル用意。例えばこんな感じのjsonだとするとtop下の階層がエンドポイントになる感じ。
mockdata.json{ "movies": [ { "title": "マトリックス", "rating": 9.1}, { "title": "タイタニック", "rating": 8.8} ], "user": [ {"name": "fukuhara", "age": 35, "sex": "male"}, {"name": "sugiyama", "age": 42, "sex": "male"} ] }5.mockサーバ起動
npm run json-server -- --watch mockdata.jsonnpm WARN lifecycle The node binary used for scripts is C:\Program Files (x86)\Nodist\bin\node.exe but npm is using C:\Program Files (x86)\Nodist\v-x64\10.15.3\node.exe itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed with. > restmock@1.0.0 json-server H:\work\restmock > json-server "--watch" "mockdata.json" \{^_^}/ hi! Loading mockdata.json Done Resources http://localhost:3000/movies http://localhost:3000/user Home http://localhost:3000 Type s + enter at any time to create a snapshot of the database Watching...6.Curlでちょっと叩いてみる
curl -X GET "http://localhost:3000/movies" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 126 100 126 0 0 126 0 0:00:01 --:--:-- 0:00:01 473[ { "title": "マトリックス", "rating": 9.1 }, { "title": "タイタニック", "rating": 8.8 } ]できること
登録/更新/削除操作ができる
登録
curl -X POST -H "Content-Type: application/json" -d '{ "title": "test1", "id":1 }' "http://localhost:3000/movies" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 65 100 33 100 32 33 32 0:00:01 --:--:-- 0:00:01 277{ "title": "test1", "id": 1 } curl -X GET "http://localhost:3000/movies/" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 169 100 169 0 0 169 0 0:00:01 --:--:-- 0:00:01 722[ { "title": "マトリックス", "rating": 9.1 }, { "title": "タイタニック", "rating": 8.8 }, { "title": "test1", "id": 1 } ] curl -X GET "http://localhost:3000/movies/1" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 33 100 33 0 0 33 0 0:00:01 --:--:-- 0:00:01 150{ "title": "test1", "id": 1 }
- 更新系作業時は「id」ってフィールド無いとダメっぽい。
- 逆に「id」フィールドさえあれば他はチェックしてないくさい
更新されたmockデータのjsonをスナップショットとして保存できる
ctrl+s
Saved snapshot to db-1582737815807.json