Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What is going on with this article?
@achtacht1965

LINEBOTとCOTOHA APIで自分を励ましてみた。

最初に

LINE BOTの勉強がてら、NTTコミュニケーションズのCOTOHA APIを使ってみたので、やった事メモを残しておく。

環境

MacOS Catalina 10.15.7
Node.js 16.0.0
android 11

LINE設定

まず、LINEです。LINEアカウントを取得し、LINEデベロッパーに登録。
プロバイダーを作成
MessagingAPIの新規チャネルを作成
アンケートと規約に合意する。
webhook設定で、ngrokで作られる自分のPCの公開用URL+/webhookを指定する。

参考

COTOHA設定

COTOHA apiのデベロッパー登録を行う。
これでclientIdとClientSecretを取得できる。
さらにアクセストークンが必要なので、curlで行った。
アクセストークンの有効時間は24時間。
24時間経ったら取り直し。

 curl -X POST -H "Content-Type:application/json" -d '{
  "grantType": "client_credentials",
  "clientId": "[clientId]",
  "clientSecret": "[clientSecret]"
}' https://api.ce-cotoha.com/v1/oauth/accesstokens

参考

本家 https://api.ce-cotoha.com/contents/index.html

NGROK設定

LINEのWeb-hookを自分のPCに通すためNGROKを使用した。
以下インストールと起動。

nom i g ngrok
ngrok http 3000

参考

https://qiita.com/Marusoccer/items/7033c1bb9c85bf6789bd

Node.js アプリ

作ったアプリはこんな感じ。

server.js

'use strict';
// ########################################
//               初期設定など
// ########################################
// パッケージを使用します
const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const { message } = require('statuses');
const { response } = require('express');
// ローカル(自分のPC)でサーバーを公開するときのポート番号です
const PORT = process.env.PORT || 3000;

// Messaging APIで利用するクレデンシャル(秘匿情報)です。
const config = {
    channelSecret: 'foo',
    channelAccessToken: 'foo'
  };
// ########## ▼▼▼ サンプル関数 ▼▼▼ ##########
const sampleFunction = async (event) => {
    let postconfig = {
        headers: {
          'Content-Type' : 'application/json;charset=UTF-8',
          'Authorization' : 'curlで取得したCOTOHAのアクセストークン',
        }
      };
    let postdata = {
        "sentence" : event.message.text
      };
    let URL="https://api.ce-cotoha.com/api/dev/nlp/v1/sentiment";
    try {
        await axios
         .post(URL, postdata, postconfig)
         .then(response =>{
            const a = JSON.parse(JSON.stringify(response.data.result));
            console.log(a);
            switch (a.sentiment){
              case 'Negative':
                pushtext = "頑張ろー";
                break;
              case 'Positive':
                pushtext = "ノリノリですね"
                break;
              default:
                pushtext = "何か面白い事はないのですか。"
            }
        });
    } catch (error) {
        pushtext = '検索中にエラーが発生しました。ごめんね。';
        // APIからエラーが返ってきたらターミナルに表示する
        console.log(error);
    }
    return client.pushMessage(event.source.userId, {
        type: 'text',
        text: pushtext
    });
};
// ########################################
//  LINEサーバーからのWebhookデータを処理する部分
// ########################################

// LINE SDKを初期化します
const client = new line.Client(config);
let pushtext="";

// LINEサーバーからWebhookがあると「サーバー部分」から以下の "handleEvent" という関数が呼び出されます
async function handleEvent(event) {
    // 受信したWebhookが「テキストメッセージ以外」であればnullを返すことで無視します
    if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
    }
    // サンプル関数を実行します
    return sampleFunction(event);
}



// ########################################
//          Expressによるサーバー部分
// ########################################

// expressを初期化します
const app = express();

// HTTP POSTによって '/webhook' のパスにアクセスがあったら、POSTされた内容に応じて様々な処理をします
app.post('/webhook', line.middleware(config), (req, res) => {

  // 検証ボタンをクリックしたときに飛んできたWebhookを受信したときのみ以下のif文内を実行
  if (req.body.events.length === 0) {
    res.send('Hello LINE BOT! (HTTP POST)'); // LINEサーバーに返答します(なくてもよい)
    console.log('検証イベントを受信しました!'); // ターミナルに表示します
    return; // これより下は実行されません
  } else {
    // 通常のメッセージなど … Webhookの中身を確認用にターミナルに表示します
    console.log('受信しました:', req.body.events);
  }

  // あらかじめ宣言しておいた "handleEvent" 関数にWebhookの中身を渡して処理してもらい、
  // 関数から戻ってきたデータをそのままLINEサーバーに「レスポンス」として返します
  Promise.all(req.body.events.map(handleEvent)).then((result) => res.json(result));
});

// 最初に決めたポート番号でサーバーをPC内だけに公開します
// (環境によってはローカルネットワーク内にも公開されます)
app.listen(PORT);
console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);

結果

会話するとこんな感じ。
Screenshot (2021_05_04 1_05_40).png

cotohaの感情分析APIは文章をNegative、Positive、Neutralの3つに分類する。
今回は、Positiveなら、「ノリノリですね。」、Negativeなら「頑張ろー」、Neutralなら「何か面白い事はないのですか。」と返してみた。

「今日は彼女ができた。」はNeutralと判定されている。どうも、好きとか最高とかの形容詞がないとPositive判定されないようだ。

今回どハマりしたのは、COTOHAのレスポンスを解釈するところ。
結局下記URLの対処で切り抜けた。

もう一工夫欲しいかもだけど、今日はここまで。

3
Help us understand the problem. What is going on with this article?
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.
Sign Up
If you already have a Qiita account Login
3
Help us understand the problem. What is going on with this article?