自宅でリモートワークをしています。ディスプレイを2つ並べているので幅が1mを越しています。音楽を流しながら作業をしていると、同じディスプレイ上の Slack 通知ですらたまに見逃してしまう事があります。
そこで、OpenJTalk を使って Slack の発言を読み上げをさせてみたいと思います。
Slack 側の設定
まず、Slack の対象ワークスペースに「Bots」アプリを追加します。
API トークンが生成されますので、それを控えておきます。
次に、読み上げたいチャンネルに Bots を参加させます。Slack 側の設定はこれで完了。
ローカル側の設定
Ruby の Slack クライアント gem を調べていたところ、Slack の発言内容を Amazon Polly で読み上げるという、やりたい事ほぼそのままのコードが github にありました。最終コミットが5年前ですが、掲載されているコードをほとんど修正することなく動きました。先人の知恵にあやかりたいと思います。
source "https://rubygems.org"
gem 'slack-ruby-client'
gem 'async-websocket', '~> 0.8.0'
手元環境では async-websocket
の依存関係がアレだったので Gemfile を上のように変更しました。 main.rb もほぼそのままで、ローカルにある openjtalk
コマンドを呼び出して aplay
コマンドで再生しているだけです。
require 'slack-ruby-client'
Slack.configure do |config|
config.token = ENV['SLACK_TOKEN']
end
client = Slack::RealTime::Client.new
client.on :hello do
puts 'Successfully connected.'
end
client.on :message do |data|
if data['text'] && data['text'] != ''
puts "Got message : #{data['text']}"
message = data['text'].gsub(/`+[^`]+`+/m,'')
message.gsub!(/\n/, '')
`echo "#{message}" | openjtalk ... && aplay out.wav`
end
end
client.start!
上のコードでは openjtalk コマンドの引数が長くなるので省略しています。実行は、シェルから
$ SLACK_TOKEN="********" bundle exec ruby main.rb
のように、環境変数 SLACK_TOKEN
に Slack のトークンを設定して呼び出すだけ。実行すると Slack クライアントとして待機状態になり、Bots が参加しているチャットに発言があるたびに読み上げてくれました。簡単ですねー。
Ruby 側の Slack のメッセージが降ってくるようになったので、あとはメンション指定発言のみ読み上げさせるとか、OpenJTalk の辞書でも読み上げしやすい形に変換して投げるとか、いろいろ遊べそうです。