papago API를 사용해서 Slack 번역 어플리케이션을 만들어보았습니다

NAVER의 번역 서비스 papago의 오픈 API를 사용해서 API Gateway와 Lambda로 Slack의 어플리케이션을 만들어보았습니다.
2020.08.20

안녕하세요 클래스메소드 송영진입니다.

NAVER의 번역서비스 papago의 오픈API를 사용해서 Amazon API Gateway와 AWS Lambda로 Slack 어플리케이션을 만들어보았습니다.

papago란?

papago는 NAVER에서 무료로 제공하는 기계번역 서비스로 NAVER LABS에서 독자적으로 개발한 인공신경망인 NMT(Neural Machine Translation)를 베이스로 하는 번역 서비스입니다.

서비스되는 언어는 한국어, 영어, 일본어, 중국어, 프랑스어, 스페인어, 베트남어, 태국어, 인도네시아어, 러시아어, 독일어, 이탈리아어입니다.

한국에서는 구글 번역보다 대중적으로 쓰이는 번역 서비스이기 때문에 이번 어플리케이션에서 사용해봤습니다.

어플리케이션 구성

구성은 다음과 같습니다.

 

 

 

 

 

 

 

 

 

 

 

사용한 서비스는 다 해서 5가지입니다. 서비스와 역할은 다음과 같습니다.

  • Slack : 메세지를 인코딩시켜서 만들어진 URL을 전송
  • Amazon API Gateway : 인코딩된 URL을 JSON 형식으로 변환해서 Lambda로 전송
  • Amazon Comprehend : 텍스트에서 어떤 언어인지 인식해서 LanguageCode를 돌려줌
  • papago API : 텍스트와 소스언어, 타겟언어 코드를 갖고 번역된 텍스트를 돌려줌
  • AWS Lambda : JSON 형식의 데이터를 파싱해서 텍스트를 Comprehend와 papago API에 전송하고 번역된 텍스트를 받아서 Slack에 POST로 전송

 

papago API

papago API의 레퍼런스는 링크에서 확인하실 수 있습니다.

papago API를 쓰기 위해서는 애플리케이션 등록이 필요합니다. 등록을 하게되면 하루에 1만자까지 무료로 번역이 가능합니다.

등록하시면 API 호출에 필요한 클라이언트 ID와 Secret이 발행됩니다.

Lambda

Lambda 코드는 Python 3.7로 작성했습니다. 코드의 내용은 다음과 같습니다.

from botocore.vendored import requests
import boto3
import json

def create_slack_payload(text):
    return {
    "blocks": [
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": text
            }
        }
    ]
    }

def get_translate(text):
    client_id = "?????????????" # papago API Client ID 
    client_secret = "?????????????" # papago API Client Secret 
    
    header = {"X-Naver-Client-Id":client_id,
              "X-Naver-Client-Secret":client_secret}
    
    url = "https://openapi.naver.com/v1/papago/n2mt" # API url
    
    client = boto3.client('comprehend')
    res = client.detect_dominant_language(Text = text) 
    source = res['Languages'][0]['LanguageCode'] # get LanguageCode for source language
    print("source : ", source)
    
    data = {'text' : text,
            'source' : source,
            'target': 'ko'} # translate to Korean

    response = requests.post(url, headers=header, data=data)
    rescode = response.status_code

    if(rescode==200):
        t_data = response.json()
        print(t_data['message']['result']['translatedText'])
        return t_data['message']['result']['translatedText']
    else:
        print("n2mt Error Code:" , rescode)

def lambda_handler(event, context):
    msg = event['message']['text']
    response_url = event['response_url']
     
    print("original text:" + msg)
    print("response_url:" + response_url)
    print(json.dumps(create_slack_payload(msg)))
    
    translated_text = get_translate(msg)
    
    print("translated text:" + translated_text)
    r = requests.post(response_url, data=json.dumps(create_slack_payload(translated_text))) # post to slack
    return r.json()

테스트는 JSON 형식으로 변환된 Slack 메세지입니다.

{
    "type": "message_action",
    "token": "ABCDEFGHIJKabcdefghijk",
    "action_ts": "123456789.012345",
    "team": {
        "id": "ABCDE12345",
        "domain": "slack-domain"
    },
    "user": {
        "id": "ZZAABBCC12",
        "name": "username"
    },
    "channel": {
        "id": "ABCDEFG123",
        "name": "directmessage"
    },
    "callback_id": "callback_id",
    "trigger_id": "123412341234.123412341234.12341234asdf1234asdf",
    "message_ts": "123412341234.0000000",
    "message": {
        "client_msg_id": "a1b2c3-a123-b456-b631-1191f49ab175",
        "type": "message",
        "text": "こんにちは!このメッセージを韓国語にしたいです!",
        "user": "ZZAABBCC12",
        "ts": "123412341234.0000000",
        "team": "ABCDEFG1234"
    },
    "response_url": "https://hooks.slack.com/app/ABCDE/12312341234/12341234asdfaf"
}

테스트 하기 전에 Lambda에서 역할에 CopmprehendReadOnly 폴리시를 추가해야 Comprehend API를 사용할 수 있습니다.

API Gateway

REST API를 만듭니다.

[작업] -> [메서드 생성]에서 [POST] 메소드를 선택하고 체크 버튼으로 생성합니다.

POST의 설정에서 만들어두었던 Lambda 함수를 선택합니다.

인코딩된 URL 데이터를 JSON으로 변환하기 위해서 매핑 템플릿을 지정해야 합니다.

[통합 요청] -> [매핑 템플릿]에 다음과 같은 템플릿을 생성합니다.

application/x-www-form-urlencoded

#set ($test = $input.body.substring(0,8))
#if ($test == "payload=")
#set ($encodedJSON = $input.body.substring(8))
$util.urlDecode(${encodedJSON})
#end

다음으로 [작업] -> [API 배포] 버튼으로 배포하고 스테이지를 정해주면 다음과 같은 URL이 만들어집니다.

만들어진 URL은 Slack API에서 만들 어플리케이션에 사용됩니다.

Slack app

https://api.slack.com/apps에서 어플리케이션을 만들 수 있습니다.

[Create an App]에서 앱의 이름과 앱이 사용될 Workspace를 결정하면, [Interactivity & Shortcuts]에서 스위치 토글을 켜고 API Gateway에서 만들었던 URL을 [Request URL]에 넣습니다.

[Create New Shortcut] -> [On messages]에서 Slack에서 보여질 버튼의 이름과 설명, 콜백 ID를 결정합니다.

[Save Chances]에서 세이브하면 Slack에서 숏컷 버튼이 만들어집니다.

이런 느낌으로 번역된 메세지가 자신에게만 보이게 됩니다.

감상

사실 동기인 이시바시상이 먼저 만들었던 앱인데 Amazon Translate의 성능보다 파파고의 성능이 더 좋을 것 같아서 번역 API만 바꿔본겁니다. ㅋㅋㅋㅋ 그래도 직접 코드를 써보고 만들어보니까 안하는 것보다 훨씬 공부가 많이 되었습니다. Lambda가 어떤 서비스고 어떻게 돌아가는지는 머리속으로 알고는 있었지만 이번에 처음 직접 써보니까 더 이해도가 높아진 것 같습니다.

레퍼런스

API GatewayとLambdaでSlack翻訳アプリを作成してみました

Amazon Comprehend Developer Guide

AWS Lambda Developer Guide

(python)파파고 API 이용해서 번역기 만들기