Help us understand the problem. What is going on with this article?

Amazon Translateを使ってSlackで翻訳できるようにしてみた

こんにちは。@j_nakayamaです。

つくった背景

よく仕事の息抜きに業務が効率化するようなbotや新しい技術を遊びながら使ってみたりしてます。
今回もそんな延長線上でまだ試していなかったAmazon TranslateのAPIを使用してSlackとの連携機能を作ってみました。
Slackでの会話の中で英語記事の引用が時々あります。
その際、Google翻訳を開いたりするのが面倒だったのでSlack完結で翻訳できるようにしました。

つくるもの

SlackのSlash Commandsを使用し、入力した文章を翻訳して結果をSlackチャンネルへ返します。
今回は投稿された文字が日本語か英語かを判断してどちらにも変換できるようにします。


Slackの投稿フォームに入力
/translate Hello

指定チャンネルへ翻訳した結果が返される
こんにちは

システム概要

言語 : Python3.6
aws translate_slack連携.png

手順

  1. [AWS] IAMロール作成
  2. [AWS] Lambda関数の作成
  3. [AWS] API Gatewayの作成
  4. [Slack] Slack APIのtoken作成
  5. [Slack] Slash Commandsの作成
  6. [AWS] Lambda関数の環境変数を設定

さっそく作ってみる

1. IAMロール作成

まずはLambdaからAmazon Translateへのアクセス権限を付与するための設定を行います。
また、CloudWatchへログも確認したいのでCloudWatchLogsのアクセス権限も付与します。

1-1. awsのマネージメントコンソールから [サービス] > [IAM] > 左ペイン[ロール] を選択
1-2. 「ロールの作成」ボタンをクリック
1-3. 「このロールを使用するサービスを選択」でLambdaを選択し「次のステップ:アクセス権限」ボタンをクリック
IAM1.png
1-4. 「Attachアクセス権限ポリシー」で下記のポリシーを選択し「次のステップ:タグ」ボタンをクリック

  • TranslateReadOnly
  • CloudWatchLogsFullAccess

IAM2.png
1-5. 「タグの追加」はそのままで「次のステップ:確認」ボタンをクリック
1-6. ロール名を入力し「ロールの作成」ボタンをクリック
  このときポリシーに1-4で選択したものが入っていればOK
IAM3.png
  ロール名 : 任意(ここでは「translate_test」で設定)

2. Lambda関数の作成

Amazon Translateの対応リージョンは今現在、下記の5地点のみのため今回は 「米国東部(北バージニア)」 リージョンで作成します。

  • 米国東部(バージニア北部)
  • 米国東部(オハイオ)
  • 米国西部(オレゴン)
  • GovCloud (米国西部)
  • EU(アイルランド)

2-1. awsのマネージメントコンソールから [サービス] > [Lambda] > 「関数の作成」 を選択
2-2. 「一から作成」を選択し、「名前」などを入力
lambda1.png
  名前 : 任意(ここでは「translate」で設定)
  ランタイム : Python3.6
  ロール : 既存のロールを選択
  既存のロール : 手順「1. IAMロール作成」で作成したロールを選択

2-3. 「関数の作成」ボタンクリック
2-4. 関数作成の画面にて下記コードをインラインにて入力し、「保存」ボタンで保存

lambda_handler.py
# coding: UTF-8
import boto3
import json
import logging
import os
import urllib
import unicodedata

ENCRYPTED_EXPECTED_TOKEN = os.environ['kmsEncryptedToken']
SLACK_TOKEN = os.environ['slackToken']

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    params = urllib.parse.parse_qs(event['body'])
    token = params['token'][0]

    # トークン確認
    if token != ENCRYPTED_EXPECTED_TOKEN:
        logger.error("Request token (%s) does not match", token)

    if params.get('text') is None:
        logger.error("Request text undefine!!!!!")
        return {
            'text': "翻訳したい文字を入力してください"
        }

    return respond(params, None)

def respond(params, err, res=None):
    message = params['text'][0]
    channel = params['channel_id'][0]

    # 日本語の場合、英語に変換
    if is_ja(message):
        SourceCode='ja'
        TargetCode='en'
    else :
        SourceCode='en'
        TargetCode='ja'

    # 翻訳
    translate = boto3.client('translate')
    response = translate.translate_text(
        Text=message,
        SourceLanguageCode=SourceCode,
        TargetLanguageCode=TargetCode
    )

    # Slackへpost
    slack_message(channel, response['TranslatedText'])

    # Slash Commandsへreturn
    return {
        'text': "Input: " + message
    }

def is_ja(string):
    for char in string:
        name = unicodedata.name(char) 
        if "CJK UNIFIED" in name or "HIRAGANA" in name or "KATAKANA" in name:
            return True
    return False

def slack_message(channel, message):

    url = 'https://slack.com/api/chat.postMessage'
    headers = {
        'Authorization': 'Bearer ' + SLACK_TOKEN,
        'Content-Type': 'application/json; charset=utf-8'
    }
    method = 'POST'
    data = {
        "channel": channel,
        'text': message,
        'username': 'translate',
        'icon_emoji': ':neko_02:',
        'link_names': 1,
    }

    req = urllib.request.Request(url, json.dumps(data).encode(), headers, method)
    res = urllib.request.urlopen(req, timeout=5)

    return

※ この時点では環境変数から取得する「kmsEncryptedToken」と「slackToken」が設定されていないのでまだ動きません。こちらは最後に設定します。

3. API Gatewayの作成

ここではAPI Gatewayを設定し、API Gatewayから先程作成したLambda関数を起動するように設定します。

3-1. Lambda関数を設定した画面内でトリガーを追加
リストから「API Gateway」をクリック
lambda_APIgateway1.png

トリガーにセットされ、「トリガーの設定」も合わせて表示される
lambda_APIgateway2.png

3-2. 「トリガーの設定」に下記入力し「追加」ボタンクリック
  API : 新規APIの作成
  セキュリティ : オープン
  (▼追加の設定クリック)
  API名 : 任意(ここでは「translate」で設定)
  デプロイされるステージ : 任意(ここでは「prod」で設定)

3-3. このままでは保存されていないのでLambdaの「保存」ボタンもクリック
3-4. 保存されると「トリガー設定」の表示が変わるのでAPI名(translate-API)でをクリック
3-5. API Gatewayのコンソール画面に移動するので「統合リクエスト」をクリック
APIGateway1.png
Lambda プロキシ統合の使用 : チェックをはずす
それ以外はデフォルトのまま

3-6. 「マッピングテンプレート」をクリックし、下記を入力し保存
リクエスト本文のパススルー : テンプレートが定義されていない場合(推奨)

  Content-Type : application/x-www-form-urlencoded
  テンプレート : { “body”: $util.urlDecode($input.json(“$”)) }
APIGateway2.png

3-7. APIをデプロイする
リソース横の「アクション」ボタン > 「APIのデプロイ」
デプロイされるステージ : 任意(ここでは「prod」)
その後、「デプロイ」ボタンクリック
デプロイされるとAPI GatewayのエンドポイントURLが表示されるのでメモしておく

エンドポイントURLはこんな感じ↓
https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/translate

4. Slack APIのtoken作成

翻訳された結果をSlackへ返すためSlack APIでtokenを生成します。
このトークンを指定することでアプリ内でSlack messageの送信が可能になります。

4-1. Slack API( https://api.slack.com/ ) へアクセス
slack_token.png
4-2. 「Start Building」ボタンクリック
4-3. Create a Slack Appの画面で下記を入力し「Create App」ボタンをクリック
slack_token1.png
  App Name : 任意(ここではtranslate)
  Development Slack Workspace : 任意(postしたいSlack名)

4-4. Building Apps for Slack内 の Add features and functionalityから「Permissions」ボタンをクリック
slack_token6.png
4-5. [Scopes] のプルダウン内で下記を選択し「Save Changes」ボタンをクリック
slack_token2.png

  • Send messages as test (chat:write:bot)
  • Send messages as user (chat:write:user)

4-6. 同ページ内一番上の「Install App to Workspace」ボタンがアクティブになるのでクリック
slack_token3.png
4-7. アプリとSlackの連携画面が出てくるので「Authorize」ボタンをクリック
slack_token4.png
4-8. OAuth Access Tokenに表示される値をメモしておく
slack_token5.png

5. Slash Commandsの作成

翻訳したい文章や単語を「/translate xxxxx」のような形式でSlackに入力するための設定を行います。

5-1. Slackの管理画面 [Custom Integrations] > [Slash Commands]
ここでは「/translate xxxxx」で入力させたいのでChoose a Commandに「/translate」と入力
slash_commands1.png
5-2. Slash Commandsの詳細設定を行う
slash_commands2.png
下記を入力し「Save Settings」ボタンクリック

  URL : 3-7でメモしたエンドポイントURL
  それ以外はデフォルトのまま
  Tokenの値はメモしておく

6. Lambda関数の環境変数を設定

Lambdaの設定で残っていた環境変数を設定します。

6-1. awsのマネージメントコンソールから [サービス] > [Lambda] を選択
6-2. [2. Lambda関数の作成]で作成した関数をクリック
6-3. 関数の設定画面の「環境変数」に下記を入力し「保存」ボタンクリック
lambda2.png

  slackToken : 4-8でメモしたURL
  kmsEncryptedToken : 5-2でメモしたtoken

動かしてみる

/translate Helloを入力
translate1.png

/translate こんにちはを入力
translate2.png

/translate The weather is good today, is not itを入力
translate3.png

/translate 今日はいい天気ですねを入力
translate4.png

まとめ

Amazon Translateで日本語が使えるようになって半年くらい経過してしまい、今更ながらに触ってみましたがとても簡単に使えました。
日本語→英語はまだマシですが、英語→日本語の精度が気になります。
機械学習が主流ですし、もう少し精度が上がってくるだろうと期待してます。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away