ここでは
Slackで @textchan create 絵文字!
と送ると、
という画像をアップしてくれるbotを作ってみる。
つくる理由
Slackで カスタム絵文字が多用されているようなチーム では、
文字だけを収めたカスタム絵文字が多く存在する。
またそれは、ユーザーの手作りであることが多い。
特にエンジニアが大活躍するようなところでは、
各エンジニアがPhotoshop等のデザインツールを持っていないことも珍しくないだろう。
カスタム絵文字の製作時間で職務に影響がでることは間違いない。効率化すべきである。
何故、文字だけの絵文字が必要か
投稿に対して、すぐ読み取れるReactionを送ることができる
今の気持ちとして、IDの横にStatusとして表示しておくことができる
つくる
テキストから画像を起こすという処理をするのあたり、
Node.js 上で canvas を生成できる node-canvas
というのがいいと思った。
ウェブ上のJavaScriptで <canvas> を生成するのと同じ要領で使える。
のちのち、文字位置調整や、色、フォントの変更をする際も、比較的楽にできる。
また、Slack上で、Mentionを検知、画像をアップロードするために Botkit
を使用する。
# node-canvas を動かすためのライブラリのインストール
# こちらは MacでHomebrewでインストールする場合
# その他 https://github.com/Automattic/node-canvas#installation
brew install pkg-config cairo pango libpng jpeg giflib
# node packageのインストール
npm install --save node-canvas botkit
参考にするもの
-
BotKitを利用したSlack Botの開発環境を5分~15分位で構築する(Windows)
- Slack Bots Configurationの追加方法などもこちら
- SlackのBotkitでファイルをアップロードする方法
- Node.jsでCanvas(ImageData)を使った簡単な画像処理
- その他、いろいろなリポジトリ
GitHub Repository 有り
Qiita上のコードは一部簡略化している
const Botkit = require('botkit')
const canvas = require('./canvas')
if (!process.env.token) {
console.log('Error: Specify token in environment')
process.exit(1)
}
const controller = Botkit.slackbot({
debug: false
})
controller.spawn({
token: process.env.token
}).startRTM(function (err) {
if (err) {
throw new Error(err)
}
})
controller.hears('create(.*)', ['direct_message', 'direct_mention', 'mention'], function (bot, message) {
var setting = {
text: '',
color: '#000',
fontFamily: 'YuGothic'
}
var args = message.match[1]
var reg = /\s+(["“”][^"“”]+["“”]|[^ ]+)/g
var arg, i = 0
while (arg = reg.exec(args)) {
arg = arg[1].replace(/^["“”](.*)["“”]$/, '$1')
switch (i) {
case 0:
setting.text = arg
break
case 1:
setting.color = arg
break
case 2:
setting.fontFamily = arg
break
}
i++
}
canvas(setting).then(function (fileObj) {
var messageObj = fileObj
messageObj.channels = message.channel
bot.api.files.upload(messageObj, function (err, res) {
if (err) console.log(err)
})
})
})
▲Slack上でのMentionの検知や画像アップロードなどの処理などを記述
const Canvas = require('canvas')
const fs = require('fs')
var insertStr = function (str, index, insert) {
return str.slice(0, index) + insert + str.slice(index, str.length);
}
var canvas_to_base64 = function (c) {
return c.toDataURL().split(',')[1]
}
var decode_and_copy = function (string, filename) {
return new Promise(function (resolve, reject) {
var buffer = new Buffer(string, 'base64')
fs.writeFile(filename, buffer, function (err) {
if (err) {
reject(err)
return
}
resolve()
})
})
}
async function canvas(setting, next) {
setting = setting || {
text: 'えもじ!',
color: '#000',
fontFamily: 'YuGothic'
}
const text_n = insertStr(setting.text, 2, '\n')
const filename = './' + setting.text + '.png'
const c = new Canvas(128, 128)
const ctx = c.getContext('2d')
ctx.font = 'bold 60px ' + setting.fontFamily
ctx.textAlign = 'center'
ctx.fillStyle = setting.color
ctx.fillText(text_n, 64, 56)
await decode_and_copy(canvas_to_base64(c), filename)
const fileObj = {
file: fs.createReadStream(filename),
filename: setting.text + '.png',
title: setting.text
}
return fileObj
}
module.exports = canvas
▲テキストを画像にする処理を記述
今回は、全角4文字を 2文字・2文字の2行にする処理のみ
うごかす
# [Slack API Token] は適宜置き換え
token=[Slack API Token] node index.js
@textchan create 絵文字!
@textchan create 赤・明朝 red "YuMincho"
恐らくこれらが返ってくるので
一旦ダウンロードし カスタム絵文字 として追加する
課題
- 全角4文字以外でもキレイな画像を生成させる
- canvasを一度画像ファイルで保存し、その画像ファイルを読み込んでいるが、恐らく不要な作業
- 使用できるフォントが、マシンなりサーバーなりに依存する
- 自動でカスタム絵文字追加させたい
おわり
楽しいカスタム絵文字ライフを。