NCP 콘솔에서 AI/Naver API 사용 신청을 해두어야 사용 가능함. 도메인 등록 시 백엔드에서 접근해서 사용할 것이므로 localhost:3000
을 등록해두자.
배포 시에도 동일하게 포트를 열기 때문에 잘 작동할 것으로 기대됨(안되면 알아보고 추가 등록 필요)
그러면 요기서 인증 정보(API KEY ID와 SECRET)를 확인할 수 있다.
nest g resource sentiment
별도의 모듈로 구성하기 위해 setiment라는 이름의 리소스를 생성
import { Body, Controller, Post } from '@nestjs/common';
import { SentimentService } from './sentiment.service';
import { GetSentimentDto } from './dto/get-sentiment.dto';
@Controller('sentiment')
export class SentimentController {
constructor(private readonly sentimentService: SentimentService) {}
@Post()
getSentiment(@Body() body: GetSentimentDto) {
return this.sentimentService.getSentiment(body);
}
}
컨트롤러는 본문 내용을 사용자나 통신 단에서 탈취할 가능성이 있는 공격자로부터 숨겨야하기 때문에 POST 방식으로 json으로 전달.
POST /sentiment
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { GetSentimentDto } from './dto/get-sentiment.dto';
import { clovaConfig } from 'src/config/clova.config';
@Injectable()
export class SentimentService {
async getSentiment(body: GetSentimentDto) {
const { content } = body;
const response = await fetch(clovaConfig.url, {
method: 'POST',
headers: {
'X-NCP-APIGW-API-KEY-ID': clovaConfig.api_key_id,
'X-NCP-APIGW-API-KEY': clovaConfig.api_key_secret,
'Content-Type': 'application/json',
},
body: JSON.stringify({
content: content,
}),
});
const result = await response.json();
// 에러 발생한 경우 internal server error
if (result.error || !result.document) {
throw new InternalServerErrorException('네이버 감성분석 API 오류');
}
// 감성분석 결과(result.document)가 있는 경우
const { positive, negative, neutral } = result.document.confidence;
// 값이 없거나 숫자로 변환이 안될 경우 에러 리턴
if (
!positive ||
!negative ||
!neutral ||
isNaN(positive) ||
isNaN(negative) ||
isNaN(neutral)
) {
throw new InternalServerErrorException('네이버 감성분석 API 오류');
}
// 0~100 사이의 positive, negative, neutral을 각각 0x00~0xFF 사이의 R, G, B 값으로 변환
const positiveColor = Math.round((Number(positive) / 100) * 0xff);
const negativeColor = Math.round((Number(negative) / 100) * 0xff);
const neutralColor = Math.round((Number(neutral) / 100) * 0xff);
// 무조건 두자리 숫자의 string으로 변환
const toHex = (color: number) => {
const hex = color.toString(16);
return hex.length === 1 ? `0${hex}` : hex;
};
// #RRGGBB 형식으로 변환
const colorRecommendation =
`#` + toHex(positiveColor) + toHex(neutralColor) + toHex(negativeColor);
return { color: colorRecommendation };
}
}
학습 메모 2의 감정분석 API 공식문서를 보고 위와 같이 데이터를 받아오도록 구성했다.
전달 받은 데이터 중 document의 confidence 속성 내에 있는
통합 1의 긍정(positive), 부정(negative), 중립(neutral) 백분위를 확인하여 이 값을 적절한 색상으로 변환해야 한다.
색상 변환은 0~100 사이의 긍정, 부정, 중립 값을 각각 0~255(0xFF) 사이의 2자리수 16진수로 치환하고, 이를 RGB 컬러 코드인 #RRGGBB
형태의 string으로 만든 후 반환하는 형태로 이루어진다.
import { configDotenv } from 'dotenv';
configDotenv();
export const clovaConfig = {
url: process.env.CLOVA_URL,
api_key_id: process.env.CLOVA_API_KEY_ID,
api_key_secret: process.env.CLOVA_API_KEY_SECRET,
};
마지막으로 API KEY, URL, SECRET 등은 process.env로 보안처리하여 github secret에도 저장해둔다.