내 관심사/정보보안

[2] Slack을 연동한 재택근무 모니터링

궁데렐라 2023. 2. 15. 09:50
728x90

우리 회사는 사내 시스템에 재택근무를 신청하고 있다. 그 중 우리 부서는 재택근무를 Slack 채널에 공유하며 재택근무 완료 후 재택근무 결과 보고서를 제출해야한다.

오늘 날짜를 쓰레드에 적고 댓글에 각 재택근무자가 댓글로 재택근무 시작 시간~종료시간을 작성한다

문제는 부서원이 너무 많고, 재택근무를 몇 일 하다가 몰아서 제출하는 사람들이 있다. 직원들 편의를 위해 크게 간섭하고 있지는 않지만 재택근무 결과 보고서가 누락되었는지 일일이 Slack 채널 히스토리를 비교하며 점검하기도 불편하고, 

일별 재택근무자를 수동으로 어딘가 기록하기에도 은근히 부하가 걸린다.

 

나는 이를 해결하기 위해 Slack bot을 만들어 API 연동하여 일별 재택근무자를 자동으로 엑셀에 작성하여 주는 스크립트를 제작하였다.

 

 

import os
import openpyxl
from datetime import datetime
from time import sleep
import schedule from slack_sdk
import WebClient from slack_sdk.errors
import SlackApiError

먼저 필요한 모듈을 import 해준다. 

 

output = './재택근무일지.xlsx'
if os.path.isfile(output):
    wb = openpyxl.load_workbook(output)
    sheet = wb.active

else:
    wb = openpyxl.Workbook()
    sheet = wb.active
    sheet.cell(1,1).value = "멤버ID"
    sheet.cell(1,2).value = "이름"

재택근무일지.xlsx 파일이 동일 경로에 있는지 확인하고 있으면 해당 엑셀을 열고 제어, 없으면 생성하고 제어한다.

 

def main_function():
    x=3
    y=2
    now = datetime.now().strftime('%Y.%m.%d %H:%M:%S')
    print(now)
    output = '/Users/HIT-Admin/Desktop/재택근무모니터링/재택근무일지.xlsx'
    if os.path.isfile(output):
        wb = openpyxl.load_workbook('/Users/HIT-Admin/Desktop/재택근무모니터링/재택근무일지.xlsx')
        sheet = wb.active

    else:
        wb = openpyxl.Workbook()
        sheet = wb.active

        sheet.cell(1,1).value = "멤버ID"
        sheet.cell(1,2).value = "이름"


        
    # Slack API 클라이언트 초기화
    client = WebClient(token=os.environ['SLACK_API_TOKEN'])

    # 읽어올 채널의 ID 입력
    channel_id = "XXXXXX"


    # 채널의 쓰레드 목록 가져오기
    response = client.conversations_history(channel=channel_id)
    threads = ''
    i=0
    try:
        threads = response.get('messages')[i]

        # 멤버 join / 채널 가입 이벤트인지 확인 및 처리
        try:
            if threads['subtype'] == 'group_join':
                i+=1
                threads = response.get('messages')[i]
            else:
                pass
        except:
            pass
        
        if threads:
            # 각 쓰레드에 대해 댓글 가져오기
            response = client.conversations_replies(channel=channel_id, ts=threads['ts'])
            comments = response.get('messages')
            
            # comments 가 None이 아닌 경우에만 처리
            if comments:
                # 각 댓글의 텍스트 출력
                flag=1

                for comment in comments:
                    if flag==1:
                        print("thread : "+comment['text'])  # 최초 쓰레드 내용 
                        flag=2

                        # 엑셀 1행에 확인된 날짜 작성
                        while True:
                            if sheet.cell(1,x).value == comment['text']:
                                flag=3
                                break
                            elif sheet.cell(1,x).value != None:
                                x+=1
                            else:
                                sheet.cell(1,x).value = comment['text']
                                break
                          
                    elif flag==2 and flag!=3:
                        print("reply : ("+comment['user']+") "+comment['text']) # 멤버ID + 댓글내용
                        while True:
                            if sheet.cell(y,1).value == comment['user']:
                                sheet.cell(y,x).value = 'O'
                                break
                            elif sheet.cell(y,1).value == None:
                                sheet.cell(y,1).value = comment['user']
                                sheet.cell(y,2).value = id_mapping(comment['user'])
                                sheet.cell(y,x).value = 'O'
                                break
                            else:
                                y+=1
                    elif flag==3:
                        print("No new thread")                   
            else:
                print("No comment")
        else:
            print("No thread")

    except SlackApiError as e:
        print("Error : {}".format(e))


    wb.save(output)

 

id_mapping : 'user'는 Slack ID를 가져오지만 이게 누구인지 가독성이 떨어진다. 그래서 Slack ID는 어떤 사용자인지 이름을 매핑해주는 함수를 만들었다.

728x90
# 멤버ID 별 이름 매핑
def id_mapping(member_id):
    f = open('./멤버ID.txt','r')
    while True:
        line = f.readline()
        if member_id in line:
            result = line
            break
        else:
            pass
    
    name = line.split('=')[1].split('\n')[0]
    return name

멤버ID.txt 파일로 Slack ID, 사용자 이름을 매핑해놓은 파일을 만들어 확인하게 만들었다. 이를 통해 위 comment['user'] 로 가져온 Slack ID가 누구인지 가독성을 증가시켰다.

 

# 함수 실행
schedule.every().day.at("16:00").do(main_function)
while True:
    schedule.run_pending()
    sleep(1)

이제 스케줄을 이용하여 매일 16시에 함수가 실행되게 만들었다. 윈도우 작업스케줄러에 등록하면 정상적으로 동작하지 못하므로 schedule을 활용한다.

 

실행결과

실행 시 위와 같이 멤버ID, 이름 요일과 재택근무 여부'O'를 자동으로 기록하여준다.

새로운 멤버가 재택근무를 하면 A,B 에 계속 추가가 되며 재택근무 일자는 1열에 계속 자동으로 생성된다. (재택근무 한 날짜에만..)

 

나는 이제 재택근무 결과 보고서가 오면 해당 엑셀 파일을 열어 해당 멤버의 'O' 표시와 비교만 하면 되어 업무가 훨씬 간편해지고 더 체계가 잡힌 듯 하다.

 

나는 개발자가 아니기 때문에 위 코드가 잘 짜여진건지는 잘 모른다. 하지만 원하는 결과물이 나오고 있기 때문에 사용한다. 코드가 이상하다고 욕하지는 말자.

 

앞으로도 업무를 좀더 자동화하고 간소화하는 방안을 모색해보겠다.

728x90