DEV Community

amotarao
amotarao

Posted on

Create Slack bot to Generate text image

Japanese posted on dev.to, Qiita

I am Japanese. My English level is πŸ’©. Thank you.

Let's create Slack bot using Node.js

This time, I will create Slack bot that sends text and generates images.
Images is used for text emoji.

For example,
Send @textchan create 硡文字!
Bot returns 硡文字!
Note: textchan is bot name. η΅΅ζ–‡ε­— means 'emoji'.

What's text emoji?

It consists only of text.

On Slack, text emoji is important and amazing.

For reaction:
Reaction
すごいね means 'You are amazing'. 嬉 means 'glad'.

And for status:
Status
η™»ζ ‘ means 'go to school'. 倧学 means 'university'.

Install libraries

Today, use node-canvas to generate images and Botkit to connect Slack.

# Install libraries for node-canvas on Mac.
# Guide for other OS: https://github.com/Automattic/node-canvas#installation 
brew install pkg-config cairo pango libpng jpeg giflib

# Install node packages.
npm install --save node-canvas botkit

Write programs

// 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)
    })
  })
})
// 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

Run

# [Slack API Token] is Slack Bots Integration's API Token
token=[Slack API Token] node index.js

@textchan create 硡文字!
硡文字!

@textchan create θ΅€γƒ»ζ˜Žζœ red "YuMincho"
θ΅€γƒ»ζ˜Žζœ

Finally

GitHub repository is here.

Emoji is amazing!!!

Top comments (0)