[과제] Dooray API를 이용한 태스크 생성 자동화

강세준·2023년 1월 19일
0

스터디


1. curl

curl은 다양한 통신 프로토콜을 사용하여 데이터를 전송하거나 받아올 수 있는 command line용 data transfer tool입니다.

option 기능
-xrequest 커맨드를 사용할 수 있습니다
(GET, POST, PUT, DELETE,PATCH)
-d데이터를 전달합니다.
-hHTTP header를 보냅니다.
-v자세한 옵션을 출력합니다
-T로컬 file을 전송합니다.
-o받은 데이터를 stdout(출력) 하지 않고 파일에 저장합니다.
-O파일 저장시 remote file 이름으로 저장합니다.


2. date 명령어

mac환경에서 date 명령어를 통한 시간 포멧 출력 방법

date -v '[+/-][time]' "+%[time]"
  • -v 옵션을 통해 시간을 조절할 수 있다.
  • "+%[time]"을 통해 출력 포멧을 자유롭게 조작할 수 있다. %[time] = %d or %y or %m or %a(요일)

3. jq

jq는 json 포멧의 데이터를 다루기 위한 command line utilty 입니다.

  • mac에서 jq 설치
brew install jq

4. Crontab

Crontab은 Linux 환경에서 배치 작업 스케쥴링등을 관리하는 프로그램입니다.

#할당된 작업 리스트들을 수정하기 위한 명령어
sudo crontab -e

#할당된 작업 리스트들을 확인하는 명령어 
sudo crontab -l

등록 방법

* * * * * [작업 경로] >> [기록할 로그 파일 경로]

# 첫번째 별표(*)부터 분(0-59) -> 시(0-23) -> 일(1-31) -> 월(1-12) -> 요일(0-7)을 의미한다. 
# 요일은 0,7은 일요일 1은 월요일 6은 토요일로 순차적으로 의미한다.

주의 사항
환경에 따라 sudo crontab에 등록해야 되는 경우가 존재한다.


Error : Operation not permitted
mac에서 OPeration not permitted에러가 발생할 경우

  • mac -> 시스템 환경설정 -> 보안 및 개인 정보 보호 -> 개인 정보 보호 -> 전체 디스크 접근 권한 선택
  • 자물쇠를 풀고 +버튼을 누른후 shift + cmd + G를 눌러 /usr/sbin/cron을 등록해준다.

설치한 라이브러리를 Crontab이 인식하지 못할 때(jq)
크론탭의 PATH를 user PATH와 같이 설정해준다

  • echo $PATH
  • crontab 최상단에 PATH=[$PATH에 나온 경로값]을 넣어준다.
  • crontab SHELL, PATH, MAILTO, HOME
    • SHELL : 명령을 실행할 때 사용할 셸 지정가능
    • PATH : PATH 환경변수를 통해 셸이 실행 가능한 프로그램을 찾는 파일 시스템 디렉토리 지정
    • MAILTO : 메일을 통해 작업이 실행될때 알림을 받고 생성 된 출력을 볼 수 있도록 메일 수신인을 지정할 수 있다.
    • HOME : HOME 환경변수를 통해 crontab 파일이 사용중인 사용자의 홈 디렉토리를 지정할 수 있다.

5. 셸스크립트에서 json 데이터 저장 방법

var=$(cat <<EOF
{json 데이터}
EOF
)

6.커맨드가 따옴표('')를 필요로 할때 변수 선언법 및 따옴표 출력방법

#!/usr/bin/env bash

var1="hello"

echo "case1 : ${var1}"
echo `echo case2 | sed 's/case2/case2 : ${var1}/g'`
echo `echo case3 | sed 's/case3/case3 : '${var1}'/g'`
echo `echo case4 | sed 's/case4/case4 : "'${var1}'"/g'`
echo `echo case5 | sed 's/case5/case5 : '"'${var1}'"'/g'
결과

sed커맨드같은 경우 따옴표를 필요로 하는데 따옴표 안에서 변수를 사용할때는 따옴표로 한번 더 감싸 주어야 제대로 값이 나온다.
그외에 큰 따옴표나 작은 따옴표도 같이 출력하려면 위와 같이 각 따옴표로 한번 더 감싸주면 된다.

환경 세팅


OScpu 아키텍처
MacOSintel 7i / x86_64
  • jq 설치 필요
  • GNU sed가 기본 sed 커맨드로 설정되어 있어야 한다.

자동화 시키기 위한 작업들 설명


일일 스크럼 : 매일 기록하는 작업 일지 다음날 리뷰를 위해 사용
일일 스크럼 작성 방법 : 퇴근 전 만들어진 일일 스크럼 태스크 댓글에 오늘 수행한 작업, 다음에 수행할 작업, 기타 사항 등을 작성
주간업무회의 : 주간으로 매 주 수행하는 회의(월요일에 한다고 가정)


구현사항


1. 일주일 뒤의 일일 스크럼 태스크 자동 생성 및 등록 셸(일주일 전에 미리 다음 주의 스크럼 생성)
2. 오늘의 일일 스크럼 태스크 생성 확인 및 자동 등록 셸(오늘자 스크럼이 있을 경우 생성하지 않고 갱신하여 오늘 업무에 볼 수 있게 한다.)
3. 어제 스크럼 진행상황 자동으로 완료 표시로 전환해주는 셸
4. Local PC에서 markdown으로 작성한 일일 스크럼 내용을 Dooray 태스크에 전달하여 일일 스크럼이 작성되도록 하는 셸
5. 다음 주의 주간업무회의 태스크를 자동 생성 및 등록 셸
6. 이번 주 주간업무회의 생성 확인 및 자동 등록 셸

구현내용


mac_create_auto_scrum.sh
일주일 뒤의 일일 스크럼 태스크 자동 생성 및 등록 셸
(일주일 전에 미리 다음 주의 스크럼 생성)

#!/usr/bin/env bash

title_info=`date -v "+7d" "+[20%y/%m/%d (%a) 일일 스크럼]"`
target_scrum_date_info=`date -v "+7d" "+20%y/%m/%d"`
parentPost_id=[상위 업무의 id]
parent_scrum_month=[상위 업무의 스크럼 month]
create_scrum_month=`date -v "+7d" "+%m"`
project_id=[태스크를 등록하고자 하는 프로젝트의 id]
user_token=[Dooray api를 통해 제공받은 사용자 인증 토큰]
tag_ids=[검색하고자 하는 태그의 id]
content_type="Content-Type: application/json"
task_member=[담당자로 등록할 멤버들 -> txt파일에 저장하여 cat을 통해 불러와 저장하는 방식 사용]


posts_url="https://api.dooray.com/project/v1/projects/${project_id}/posts"

#상위 스크럼 등록을 위한 스크럼 날짜 비교
if [ ${parent_scrum_month} != ${create_scrum_month} ]; then
	parentPost_id=""
fi

#스크럼이 있는지 찾아 개수를 저장하는 함수
scrum_check=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | grep ''${target_scrum_date_info}'' | wc -l | tr -d ' '`

posts_info=$(cat <<EOF
[보낼 json 형식 데이터]
EOF
)

#스크럼이 있는 지 검사
if [ ${scrum_check} -ge 1 ]; then
	echo "이미 ${target_scrum_date_info} 스크럼이 만들어져 있습니다."
else
	echo `curl -d "${posts_info}"  -X POST -H "${content_type}" -H 'Authorization: dooray-api '${user_token}'' ${posts_url}`
	echo "일주일 후의 새로운 스크럼을 만들었습니다."
fi

mac_checkCreate_today_scrum.sh
오늘의 일일 스크럼 태스크 생성 확인 및 자동 등록 셸
(오늘자 스크럼이 있을 경우 생성하지 않고 갱신하여 오늘 업무에 볼 수 있게 한다.)

#!/usr/bin/env bash

title_info=`date "+[20%y/%m/%d (%a) 일일 스크럼]"`
today_scrum_date_info=`date "+20%y/%m/%d"`
parentPost_id=[상위 업무의 id]
parent_scrum_month=[상위 업무의 스크럼 month]
create_scrum_month=`date"+%m"`
project_id=[태스크를 등록하고자 하는 프로젝트의 id]
user_token=[Dooray api를 통해 제공받은 사용자 인증 토큰]
tag_ids=[검색하고자 하는 태그의 id]
content_type="Content-Type: application/json"
task_member=[담당자로 등록할 멤버들 -> txt파일에 저장하여 cat을 통해 불러와 저장하는 방식 사용]

posts_url="https://api.dooray.com/project/v1/projects/${project_id}/posts"

#상위 스크럼 등록을 위한 스크럼 날짜 비교
if [ ${parent_scrum_month} != ${create_scrum_month} ]; then
        parentPost_id=""
fi

#오늘 스크럼이 만들어져 있는지 검사
scrum_check=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | grep ''${today_scrum_date_info}'' | wc -l | tr -d ' '`

posts_info=$(cat <<EOF
[보낼 json 형식 데이터]
EOF
)


comments_info=$(cat <<EOF
{"body" : {
"content": "스크럼 갱신",
"mimeType": "text/x-markdown"
}
}
EOF
)


echo "잡힌 스크럼의 개수는 : ${scrum_check}개 입니다."
if [ ${scrum_check} -ge 1 ]; then
	echo "오늘 일일 스크럼은 만들어져 있습니다."

	#오늘 날짜의 스크럼 id를 찾는 로직
	today_scrum_id_index=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | grep -n ''${today_scrum_date_info}'' | cut -d ':' -f1 | awk '{print $1 -1}'`
	today_scrum_id=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | sed -n ''${today_scrum_id_index}'p' | cut -d ':' -f2 | tr -d ' ' | tr -d ',' | tr -d '"' `

	#일일 스크럼을 갱신하는 로직
	comment_url="https://api.dooray.com/project/v1/projects/${project_id}/posts/${today_scrum_id}/logs"
	echo `curl -d "${comments_info}" -X POST -H "${content_type}" -H 'Authorization: dooray-api '${user_token}'' ${comment_url}`
	recent_comment_id=`curl -G -H 'Authorization: dooray-api '${user_token}'' ${comment_url}\?order\=-createdAt\&size\=1 | jq | grep id | awk 'NR==1 {print $0}' | cut -d ':' -f2 | tr -d '"' | tr -d ',' | tr -d ' '`
	echo `curl -X DELETE -H 'Authorization: dooray-api '${user_token}'' ${comment_url}/${recent_comment_id}`
	echo "일일 스크럼을 갱신했습니다."
else
	echo `curl -d "${posts_info}" -X POST -H "${content_type}" -H 'Authorization: dooray-api '${user_token}'' ${posts_url}`
	echo "오늘 일일 스크럼을 제작합니다."
fi

mac_complete_auto_scrum.sh
어제 스크럼 진행상황 자동으로 완료 표시로 전환해주는 셸
(공휴일과 같이 어제 스크럼이 없을 경우 오늘 날짜보다 뒤에 있는 스크럼 중 가장 최신의 스크럼을 완료 표시로 전환)

#!/usr/bin/env bash

target_scrum_date_info=`date -v "-1d" "+20%y/%m/%d"`
today_info=`date "+20%y%m%d"`
project_id=[태스크를 등록하고자 하는 프로젝트의 id]
user_token=[Dooray api를 통해 제공받은 사용자 인증 토큰]
tag_ids=[검색하고자 하는 태그의 id]
workflow_ids=[workflow의 상태를 나타내는 id]

posts_url="https://api.dooray.com/project/v1/projects/${project_id}/posts"

#전날 완료가 안된 스크럼이 있었는지 검사하는 로직
scrum_check=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&postWorkflowIds\=${workflow_ids}\&order\=-createdAt\&size\=10 | jq | grep -n ''${target_scrum_date_info}'' | wc -l | tr -d ' '`

if [ ${scrum_check} -ge 1 ]; then
	# 해당 날짜에 해당하는 스크럼의 project ID를 찾는 로직
	scrum_id_index=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | grep -n ''${target_scrum_date_info}'' | cut -d ':' -f1 | awk '{print $1 -1}'`
	scrum_id=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | sed -n ''${scrum_id_index}'p' | cut -d ':' -f2 | tr -d ' ' | tr -d ',' | tr -d '"' `
	# 자동으로 완료로 바꾸는 로직
	echo `curl -X POST -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}/${scrum_id}/set-done`
	echo "전날의 스크럼은 완료로 변경되었습니다."
else
	# 가장 최근에 완료가 안된 스크럼을 찾아 날짜를 검사하는 로직
	uncomplete_scrum_date=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&postWorkflowIds\=${workflow_ids}\&order\=createdAt\&size\=10 | jq | grep -n '일일 스크럼' | head -1 | cut -d '[' -f2 | cut -d ' ' -f1 | tr -d '/'`
	if [ ${uncomplete_scrum_date} -ge ${today_info} ]; then
		echo "상태를 변경할 스크럼은 없습니다."

	else
	# 가장 최근에 완료가 안된 스크럼의 project ID를 찾는 로직
	incomplete_scrum_id_index=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&postWorkflowIds\=${workflow_ids}\&order\=createdAt\&size\=10 | jq | grep -n '일일 스크럼' | head -1 | cut -d ':' -f1 | awk '{print $1 - 1}'`
	incomplete_scrum_id=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}\?tagIds\=${tag_ids}\&postWorkflowIds\=${workflow_ids}\&order\=createdAt\&size\=10 | jq |  sed -n ''${incomplete_scrum_id_index}'p' | cut -d ':' -f2 | tr -d ' ' | tr -d ',' | tr -d '"' `
        # 자동으로 완료로 바꾸는 로직
        echo `curl -X POST -H 'Authorization: dooray-api '${user_token}' ' ${posts_url}/${incomplete_scrum_id}/set-done`
	echo "${uncompletel_scrum_date} 스크럼 완료로 변경"
	fi
fi

mac_scrum_auto_write.sh
Local PC에서 markdown으로 작성한 일일 스크럼 내용을 Dooray 태스크에 전달하여 일일 스크럼이 작성되도록 하는 셸

project_id=[태스크를 등록하고자 하는 프로젝트의 id]
user_token=[Dooray api를 통해 제공받은 사용자 인증 토큰]
absolute_path=[markdown 파일의 경로]
tag_ids=[검색하고자 하는 태그의 id]
content_type="Content-Type: application/json"
scrum_comment=`cat ${absolute_path}/todayScrum.md | awk '{print $0, "\\\\n"}' | tr -d '\n' | tr -d '\t'`

comments_info=$(cat <<EOF
[보낼 json 형식 데이터]
EOF
)

#오늘 날짜의 스크럼 id를 찾는 로직
today_scrum_id_index=`curl -G -H 'Authorization: dooray-api '${user_token}' ' https://api.dooray.com/project/v1/projects/${project_id}/posts\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | grep -n ''${today_scrum_date_info}'' | tail -1 | cut -d ':' -f1 | awk '{print $1 -1}'`

today_scrum_id=`curl -G -H 'Authorization: dooray-api '${user_token}' ' https://api.dooray.com/project/v1/projects/${project_id}/posts\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | sed -n ''${today_scrum_id_index}'p' | cut -d ':' -f2 | tr -d ' ' | tr -d ',' | tr -d '"' `


request_url="https://api.dooray.com/project/v1/projects/${project_id}/posts/${today_scrum_id}/logs"

echo `curl -d "${comments_info}" -X POST -H "${content_type}" -H 'Authorization: dooray-api '${user_token}'' ${request_url} `



# default 값으로 복구
# echo `cat ${absolute_path}/backup.txt > ${absolute_path}/todayScrum.md`

mac_create_weekly_meeting.sh
다음 주의 주간업무회의 태스크를 자동 생성 및 등록 셸
(매주 월요일에만 실행되도록 crontab 설정)

title_info=`date "+[20%y/%m/%d 데이터 운영팀 주간업무회의]" `
today_meeting_date_info=`date "+20%y/%m/%d"`
standard_meeting_date=`date -v '-7d' "+20%y%m%d"`
parentPost_id=[상위 업무의 id]
project_id=[태스크를 등록하고자 하는 프로젝트의 id]
user_token=[Dooray api를 통해 제공받은 사용자 인증 토큰]
tag_ids=[검색하고자 하는 태그의 id]
content_type="Content-Type: application/json"

meeting_create_url="https://api.dooray.com/project/v1/projects/${project_id}/posts"

current_meeting_date=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${scrum_create_url}\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | grep ''${today_scrum_date_info}'' | wc -l | tr -d ' '`

posts_info=$(cat <<EOF
[보낼 json 형식 데이터]
EOF
)

echo `curl -d "${posts_info}" -X POST -H "${content_type}" -H 'Authorization: dooray-api '${user_token}'' ${meeting_create_url}`
echo "이번주 주간 업무 회의을 제작합니다."

mac_checkCreate_meeting.sh
이번 주 주간업무회의 생성 확인 및 자동 등록 셸
(월요일이 공휴일일때 주간업무회의가 없으므로 생성)

title_info=`date "+[20%y/%m/%d 데이터 운영팀 주간업무회의]" `
today_meeting_date_info=`date "+20%y/%m/%d"`
standard_meeting_date=`date -v '-7d' "+20%y%m%d"`
parentPost_id=[상위 업무의 id]
project_id=[태스크를 등록하고자 하는 프로젝트의 id]
user_token=[Dooray api를 통해 제공받은 사용자 인증 토큰]
tag_ids=[검색하고자 하는 태그의 id]
content_type="Content-Type: application/json"

meeting_create_url="https://api.dooray.com/project/v1/projects/${project_id}/posts"

#가장 최근에 만들어진 미팅의 날짜 계산
current_meeting_date=`curl -G -H 'Authorization: dooray-api '${user_token}' ' ${meeting_create_url}\?tagIds\=${tag_ids}\&order\=-createdAt\&size\=10 | jq | grep '주간업무회의' | head -1| cut -d'[' -f2 | cut -d ' ' -f1 | tr -d '/'`

difference_date=$(($standard_meeting_date - $current_meeting_date))

posts_info=$(cat <<EOF
[보낼 json 형식 데이터]
EOF
)

if [ ${difference_date} -gt 0 ]; then
	echo `curl -d "${posts_info}" -X POST -H "${content_type}" -H 'Authorization: dooray-api '${user_token}'' ${meeting_create_url}`
	echo "일주일 이상 주간업무회의가 만들어지지 않았으므로 주간회의를 제작합니다."
else
	echo "이번주의 주간업무회의는 이미 만들어져 있습니다."
fi

sudo crontab -e명령어를 통해 crontab 등록


Error
{"header":{"resultMessage":"Failed to read HTTP message"}}
관련해서 전달하는 Json파일이 제대로 되어있는지 확인해 볼 필요가 있다.
(tagIDS같은경우 대괄호가 없으면 해당 에러가 발생함)

Error

nhn cloud인스턴스나 외부망의 local PC에서는 ACL 관련 에러가 발생할 수 있다.
회사 내부망(VPN)에 접속하여 인가된 IP만 정상적으로 작동한다.

세부적인 json 데이터 및 변수 값 관련 두레이 API 메뉴얼 참고


참고자료

profile
데이터를 탐구하는 개발자

0개의 댓글