DEV Community

amotarao
amotarao

Posted on

6 2

Slackで送った文字を画像で返すbot作った

Qiita記事 のコピペ

ここでは

Slackで @textchan create 絵文字! と送ると、

絵文字!

という画像をアップしてくれるbotを作ってみる。

つくる理由

Slackで カスタム絵文字が多用されているようなチーム では、
文字だけを収めたカスタム絵文字が多く存在する。
またそれは、ユーザーの手作りであることが多い。

特にエンジニアが大活躍するようなところでは、
各エンジニアがPhotoshop等のデザインツールを持っていないことも珍しくないだろう。
カスタム絵文字の製作時間で職務に影響がでることは間違いない。効率化すべきである。

例)

/ 嬉しいときに


登校 / 登校したときに

何故、文字だけの絵文字が必要か

投稿に対して、すぐ読み取れるReactionを送ることができる
Reactionの例

今の気持ちとして、IDの横にStatusとして表示しておくことができる
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
Enter fullscreen mode Exit fullscreen mode

参考にするもの

GitHub Repository 有り
Qiita上のコードは一部簡略化している

// index.js
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)
    })
  })
})
Enter fullscreen mode Exit fullscreen mode

▲Slack上でのMentionの検知や画像アップロードなどの処理などを記述

// canvas.js
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
Enter fullscreen mode Exit fullscreen mode

▲テキストを画像にする処理を記述
今回は、全角4文字を 2文字・2文字の2行にする処理のみ

うごかす

# [Slack API Token] は適宜置き換え
token=[Slack API Token] node index.js
Enter fullscreen mode Exit fullscreen mode
@textchan create 絵文字!
@textchan create 赤・明朝 red "YuMincho"
Enter fullscreen mode Exit fullscreen mode

絵文字! 赤・明朝

恐らくこれらが返ってくるので
一旦ダウンロードし カスタム絵文字 として追加する

課題

  • 全角4文字以外でもキレイな画像を生成させる
  • canvasを一度画像ファイルで保存し、その画像ファイルを読み込んでいるが、恐らく不要な作業
  • 使用できるフォントが、マシンなりサーバーなりに依存する
  • 自動でカスタム絵文字追加させたい

おわり

楽しいカスタム絵文字ライフを。

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post