LoginSignup
2
1

More than 5 years have passed since last update.

Node-REDを使ってブラウザに喋った内容を各SNSに通知する

Last updated at Posted at 2019-05-02

はじめに

やりたいこと

  • スマホにしゃべるとメールやslackやlineやカレンダーに通知したい
  • 基本的な使い方は関連記事を参照してください。

Node-REDのまとめ記事

動作環境

  • IBM bluemix Node-RED : v0.20.5

免責事項

  • 検証をして確実と思われる情報を載せておりますが、誤っている可能性もゼロではないので、参考程度にご利用ください
  • 本来はコードと実行結果のコンソールログも載せるべきなのですが、数と量が多いので、一旦は画面イメージまでとさせてください。

本編

画面

図2.png

処理の流れ

  1. 画面を開くとWebSocketを使ってサーバとの通信を確立
  2. ボタンを押すと音声を認識できる状態になる
  3. WebSpeechAPIを使って、ブラウザに向かって話した内容を文字列化
  4. 文字列をサーバに送る
  5. 文字列をもとに条件分岐などをして、送信先SNSと送るデータを決める
  6. SNSに送る
  7. 送った旨のメッセージをWebSocketを使ってブラウザに返す
  8. WebSpeechAPIを使って喋らせる

フロー

図1.png

各SNSへのアクセス

実際はググると山程でてきますし、ここに書いてもすぐに古くなるので、各APIを参照ください。
一応いまいま時点でどんなことをしたのかは残しておきます

  • slack : IncommingWebHookを使い実現。URLに対してデータを送っています
  • Line : DeveloperのMessaging APIを使って実現。WebHookにデータを送っています
  • メール:シンプルにメールのノードで実現。
  • googleカレンダー:googleカレンダーのノードを使って実現。node-red-node-googleの指示に従い、アカウントとアクセス許可などを設定

補足

  • 送る文章は 面倒なので 文章全体。↑の例だと 遅刻しますって LINE して とすべて送られます。
  • カレンダーは今から1時間(デフォルト)でスケジュールが作成されるため、あまり実用的でないです。
  • はっきり言って、Node-REDからみると文字列を受け取り、SNSに通知して、文字列を送り返しているだけです!

ブラウザ側の実装

このあたりを参考にさせていただきました
* ブラウザで音声操作をする。(Speech Recognition API)
* Webページでブラウザの音声認識機能を使おう - Web Speech API Speech Recognition

本家の方とほとんど変わらないので、オリジナルの方を見ていただくほうが良いかと思いますが、一応重要な部分のソースです

ブラウザのhtml内のjs
    const startBtn = document.querySelector('#start-btn');
    const resultDiv = document.querySelector('#speak-text');

    SpeechRecognition = webkitSpeechRecognition || SpeechRecognition;
    let recognition = new SpeechRecognition();

    recognition.lang = 'ja-JP';
    recognition.interimResults = true;
    recognition.continuous = false;

    let finalTranscript = ''; 
    recognition.onresult = (event) => {
      let interimTranscript = '';
      for (let i = event.resultIndex; i < event.results.length; i++) {
        let transcript = event.results[i][0].transcript;
        if (event.results[i].isFinal) {
          finalTranscript += transcript;
        } else {
          interimTranscript = transcript;
        }
      }
      resultDiv.innerHTML = finalTranscript + '<i style="color:#ddd;">' + interimTranscript + '</i>';
    }

    // 文字列の送信
    recognition.onend = (event) => {
      recognition.stop();
      const speakText = $("#speak-text").text()
      sock.send(speakText);
    }

    // 開始ボタンのクリック
    startBtn.onclick = () => {
      speechSynthesis.cancel();
      $('#status').text('please speak');
      $("#speak-text").empty();
      $("#response-text").empty();
      finalTranscript = '';
      recognition.start();
    }

    //Websocketの確立と各種イベント
    var socketaddy = "wss://" + window.location.host + "/ws/speaker";
    $(document).ready(function () {
      sock = new WebSocket(socketaddy);
      sock.onopen = function () {
        $('#status').text('connected');
      };
      sock.onerror = function () {
        $('#status').text('error');
      };
      sock.onclose = function () {
        $('#status').text('closed please reload page!!')
      }
      sock.onmessage = function (evt) {
        $('#status').text('response received');
        $("#response-text").html(evt.data);
        var speakText = $("#response-text").text();

        // 発言を作成
        const uttr = new SpeechSynthesisUtterance(speakText);
        uttr.rate = 1.3;
        uttr.lang = "ja-JP";
        speechSynthesis.speak(uttr);
      };
    });

しゃべるデータをいったんhtmlにしてから取り出しているのは、 brタグ などを喋られないようにするためです(笑)
見栄えでは2行にしたいけど、タグを喋られると気持ちが悪いので。。。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1