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

【LINE BOT + COTOHA API】君の文章は相手を不快にしていないか?COTOHA先生にチェックしてもらおうぜ

0. はじめに

チャットツール、SNSが普及した今、文章でのコミュニケーションが爆発的に増えましたよね。
チャット(Slack)でしか関わったことのないお客さんと初めてお会いしたとき、こんなお話を頂きました。

「全く怒っているつもりないんですけど、チャットだとそんな印象与えてしまうんですよね~。」

いやーありますあります。お仕事だけでなく、プライベートでもありますよね!
印象の悪い文章が、印象の悪い返事を生み、負のスパイラルとなる。これって非常に悲しいことですよね。
ネガティブワードの存在は、無意識のうちに相手の心にダメージを与えます。
SNSの誹謗中傷とか最悪ですよね。

そんな文章を取り締まるべく、COTOHA先生というものを作ってみました!

COTOHA APIを使ってこんなのも作ってます!

ちなみに息子(2歳)へのクリスマスプレゼントを華麗に失敗した私が狙うのは「作ろうきのこの山」です。:santa:

1. COTOHA先生って?

COTOHA API感情分析を使って、LINEで入力したメッセージにネガティブなワードが含まれていないかチェックするLINE BOTです。COTOHA先生が結果をリプライしてくれます。
結果は以下のパターンに分類されます。

  • 「ネガティブワード有の場合」
  • 「ネガティブワード無」かつ「ポジティブワード無」の場合
  • 「ネガティブワード無」かつ「ポジティブワード有」の場合

2. 環境

  • Python 3.8.1
  • COTOHA API
  • LINE Messaging API
  • Heroku

3. 参考

LINE BOTの作り方は以下の記事を参考にさせて頂きました。ありがとうございます!

4. プログラム

line.py
import cotoha
import json
from codecs import decode
from os import environ, getenv
from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage

app = Flask(__name__)
handler = WebhookHandler(environ["LINE_CHANNEL_SECRET"])
linebot_api = LineBotApi(environ["LINE_CHANNEL_ACCESS_TOKEN"])
cotoha_api = cotoha.CotohaApi()

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    sentiment = cotoha_api.sentiment(event.message.text)
    reply_message = make_reply_message(sentiment["result"])
    linebot_api.reply_message(event.reply_token, reply_message)

def make_reply_message(sentiment_result):
    positive_words = ""
    negative_words = ""

    for phrase in sentiment_result['emotional_phrase']:
        if phrase['emotion'] == 'P':
            positive_words = positive_words + '・' + phrase['form'] + '\n'
        if phrase['emotion'] == 'N':
            negative_words = negative_words + '・' + phrase['form'] + '\n'

    if len(negative_words) > 0:
        message = "君の文章、相手を不快にする可能性があります。\n以下のワードは使わないでちょ\uDBC0\uDC9E\n" + negative_words
    elif len(positive_words) < 1:
        message = "君の文章、悪くはないです。\nでもポジティブワードを1つは入れてちょ\uDBC0\uDC9D"
    else:
        message = "君の文章、完璧です。\n以下のワードがGood\uDBC0\uDC7F\n" + positive_words

    return TextSendMessage(text=message)

if __name__ == "__main__":
    port = int(getenv("PORT"))
    app.run(host="0.0.0.0", port=port)
cotoha.py
import requests
import json
from os import environ
from codecs import decode

class CotohaApi:

    DEVELOPER_API_BASE_URL = "https://api.ce-cotoha.com/api/dev/nlp/"
    DEVELOPER_API_SENTIMENT_URL = DEVELOPER_API_BASE_URL + "v1/sentiment"
    ACCESS_TOKEN_PUBLISH_URL = "https://api.ce-cotoha.com/v1/oauth/accesstokens"

    def __init__(self, client_id = "", client_secret = ""):
        self.client_id = environ["CLIENT_ID"] if not client_id else client_id
        self.client_secret = environ["CLIENT_SECRET"] if not client_secret else client_secret

    def get_access_token(self):
        headers = {
            "Content-Type": "application/json;charset=UTF-8"
        }

        data = {
            "grantType": "client_credentials",
            "clientId": self.client_id,
            "clientSecret": self.client_secret
        }

        response = requests.post(self.ACCESS_TOKEN_PUBLISH_URL, headers=headers, data=json.dumps(data))
        return response.json()["access_token"]

    def sentiment(self, sentence):
        headers = {
            "Authorization": "Bearer " + self.get_access_token(),
            "Content-Type": "application/json;charset=UTF-8",
        }

        data = {
            "sentence": sentence
        }

        response = requests.post(self.DEVELOPER_API_SENTIMENT_URL, headers=headers, data=json.dumps(data))
        return response.json()

if __name__ == "__main__":
    # 以下のパラメータを設定して「python .\cotoha.py」を実行すれば、
    # 当モジュール単体での結果確認が可能
    client_id = ""
    client_secret = ""
    text = "今日は楽しい1日でした。"

    cotoha_api = CotohaApi(client_id, client_secret)
    sentiment_result = cotoha_api.sentiment(text)
    sentiment_formated = json.dumps(sentiment_result, indent=4)
    print (decode(sentiment_formated, 'unicode-escape'))

5. デモ

COTOHA先生.gif

6. おわりに

感情分析などの技術が普及して、インターネットの世界から誹謗中傷を無くしていきたいですね!



あれっ?
COTOHA先生2.gif

Why not register and get more from Qiita?
  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
No 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
ユーザーは見つかりませんでした