Create Slack bot to Generate text image
Tags: node, bot, slack
Published: 2017-12-10 14:53:15

---
title: Create Slack bot to Generate text image
published: true
description: Create Slack bot to Generate text image
tags: node.js,bot,slack
---

*Japanese posted on [dev.to](https://dev.to/amotarao/slackbot-376), [Qiita](https://qiita.com/amotarao/items/6bbb58ca74b4d9d1fae8)*

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 <img width="64" alt="絵文字！" src="https://qiita-image-store.s3.amazonaws.com/0/99161/05e1dd90-233a-7bec-f373-65cbb451227e.png">
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:
<img width="214" alt="Reaction" src="https://qiita-image-store.s3.amazonaws.com/0/99161/2bc82e29-71f3-29e8-9202-0c82efa3da5f.png">
すごいね means 'You are amazing'. 嬉 means 'glad'.

And for status:
<img width="192" alt="Status" src="https://qiita-image-store.s3.amazonaws.com/0/99161/4b2bde77-2e5e-9d14-32be-36fcf6aa03b8.png">
登校 means 'go to school'. 大学 means 'university'.


# Install libraries
Today, use `node-canvas` to generate images and `Botkit` to connect Slack.

```shell
# 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

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

```javascript
// 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

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

`@textchan create 絵文字！`
<img width="64" alt="絵文字！" src="https://qiita-image-store.s3.amazonaws.com/0/99161/fa83ec48-c92c-44d2-5fc5-a8e23c8ba323.png" style="margin-left: 0;">

`@textchan create 赤・明朝 red "YuMincho"`
<img width="64" alt="赤・明朝" src="https://qiita-image-store.s3.amazonaws.com/0/99161/f186a220-858c-c435-5c9a-2f106c2457ef.png" style="margin-left: 0;">

# Finally

GitHub repository is [here](https://github.com/amotarao/textchan).

Emoji is amazing!!!