민프
[DevOps][NCP] Slack말고 네이버 웍스(naver works) API를 이용한 푸시 알림을 해보자 본문
원래 항상 Slack을 이용하여 서부 내부적인 알림을 보냈었는데
회사에서 works를 이용하자는 제안에 이번엔 works를 통하여 알림을 보내려고 한다.
앱추가
https://dev.worksmobile.com/kr/console/openapi/v2/app/list/view
https://auth.worksmobile.com/login/login?accessUrl=http%3A%2F%2Fdev.worksmobile.com%3A80%2Fconsole%2Fopenapi%2Fv2%2Fapp%2Flist%2Fview
auth.worksmobile.com
Bot 추가
단체 채팅방에 봇을 사용하려면 Bot 정책 - 조직/그룹, 1:N 메세지방 초대 기능을 체크해야합니다.
Bot 연동
https://admin.worksmobile.com/service/bot
Admin
admin.worksmobile.com
1. 서비스 > 위에서 생성한 Bot 체크 후 Bot 추가 클릭
2. 서비스 > 위에서 추가한 Bot 클릭 후 > 수정 > 공개 설정 활성화 후 저장
3. OAuth Scopes > 관리 > 아래 3개 항목 선택 후 저장
4. Bot No 확인 및 채팅방에 Bot추가
API를 사용해 메세지를 보내려면 아래의 Bot No가 필요합니다.
3. 코드 (Python)
아래 APi문서를 참고하여 보내면 됩니다.
https://developers.worksmobile.com/kr/docs/bot-api
Developers
developers.worksmobile.com
디렉토리 구조
├── main.py
├── works/
│ ├── __init__.py
│ ├── config.py # Works 인증 정보 저장
│ └── notifier.py # 메시지 전송 기능 구현
config.py
WORKS_BOT = {
"client_id": "----", # 아래 이미지 부분에서 확인 가능
"client_secret": "----", # 아래 이미지 부분에서 확인 가능
"bot_no": "----", # 봇 등록 시 발급받은 봇 번호
"account_id": "----", # 메시지 받을 사용자 or 그룹의 ID,works 채팅방에서 확인 가능
"service_account": "----", # 서비스 계정 인증 정보에서 확인 가능
"iss": "-=----" # client_id와 같음
"private_key": Path("---.key").read_text() # 서비스 계정 인증 정보에서 확인 가능
}
notifier.py
import jwt
from datetime import datetime, timedelta
import requests
import json
from works.config import WORKS_BOT
def get_server_token():
headers = {
"alg": "RS256",
"typ": "JWT"
}
iat = datetime.utcnow()
exp = iat + timedelta(minutes=10)
payload = {
"iss": WORKS_BOT["iss"],
"sub": WORKS_BOT["service_account"],
"iat": int(iat.timestamp()),
"exp": int(exp.timestamp())
}
print("JWT Payload:", json.dumps(payload, indent=2))
try:
assertion = jwt.encode(
payload,
WORKS_BOT["private_key"],
algorithm="RS256",
headers=headers
)
print("JWT Assertion 생성 완료")
except Exception as e:
print("JWT 인코딩 실패:", e)
raise
return assertion
def get_access_token():
try:
assertion = get_server_token()
print("JWT Assertion 길이:", len(assertion))
except Exception as e:
print("Assertion 생성 실패:", e)
raise
token_data = {
"assertion": assertion,
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"client_id": WORKS_BOT["client_id"],
"client_secret": WORKS_BOT["client_secret"],
"scope": "bot"
}
print("AccessToken 요청 중...")
try:
response = requests.post("https://auth.worksmobile.com/oauth2/v2.0/token", data=token_data)
print("응답 코드:", response.status_code)
print("응답 내용:", response.text)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print("AccessToken 요청 실패:", e)
raise
token_json = response.json()
print("🔑 Access Token 발급 완료:", token_json.get("access_token"))
return token_json["access_token"]
def send_channel_message(text: str):
try:
token = get_access_token()
except Exception as e:
print("토큰 획득 실패:", e)
return
url = f"https://www.worksapis.com/v1.0/bots/{WORKS_BOT['bot_no']}/channels/{WORKS_BOT['account_id']}/messages"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
body = {
"content": {
"type": "text",
"text": text
}
}
print("채널 메시지 전송 중...")
print("요청 바디:", json.dumps(body, indent=2))
try:
res = requests.post(url, headers=headers, json=body)
print("응답 코드:", res.status_code)
print("응답 내용:", res.text)
res.raise_for_status()
print("메시지 전송 성공")
except requests.exceptions.RequestException as e:
print("메시지 전송 실패:", e)
raise
결과
'DevOps > [NCP]' 카테고리의 다른 글
[DevOps][NCP] NCP-Server + Docker + NCP-Container Register로 Nestjs어플리케이션 배포하기 (feat. CICD-github Actions) (2) | 2025.04.08 |
---|---|
[Devops][NCP] Server 구축 (2) | 2025.04.07 |
[DevOps][NCP] Cloud DB for MySQL 생성하기, 로컬에서 접속하기(VPC 설정) (1) | 2025.04.07 |
[DevOps][NCP] VPC, 서브넷 생성하기 (0) | 2025.04.07 |
Comments