이전에 사수님이 알려주신 슬랙 봇 만들기
미루고 미루다 이제야^^.. 기재해 본다.
내 업무의 목적은 FA관련 데이터를 이다.
* 짤막상식 : FA는 프리에이전트의 줄임말로 카쉐어링 업계에서 차량을 관리하는 매니저를 의미한다.
[ 챗봇 만들기 전반적 흐름 - 요약 ]
1. 외부에서 내 웹서버 확인
2. 슬랙 챗봇 연결
3. 슬랙 챗봇 연결을 위한 파이썬 코딩 작업 스켸줄러 수시 확인
[ 챗봇 만들기 순서 ]
1. 채널 생성
2. 슬랙 api페이지 접속 > 슬랙봇 생성 > From Scratch 선택 > Create App
3. APP의 SCOPE 산정하기
- 이 때, 회사 내 관리자가 BOT 접근에 대한 승인 절차가 필요함
- 정보를 받아오는 용도로 사용하는 경우 다음 세가지의 SCOPE을 설정하면 된다.
1) app_mentions:read
2) channels:history
3) chat:write
4. OAuth Tokens for Your Workspace 에서 install 눌러 OAuth Token 생성
- 해당 Token은 API 요청 시에 사용됨
5. Basic Information에서 Incoming Webhooks 선택 > ON
6. Add New Webhook to Workspace을 눌러 활용할 채널 선택
7. Basic Information > Display Information에서 bot 이름 인사말 등 설명
8. 코드 만들기
0) 전제사항
로컬pc와 연동하여 운영하면 중단없이 운영할 수 있다.
그렇기 위해서는 ngrok와 flask라는 app의 활용이 필요하다.
* 0번 기전 참고 블로그 : https://yunwoong.tistory.com/134
FLASK? 간단한 api 서버를 만드는 프레임워크
cmd 오픈 > pip install flask > 주피터 노트북 및 파이참 등등 IDE로 app.py 파일 만들어주기
설치 참고 사항 (출처 : https://flask-docs-kr.readthedocs.io/ko/latest/quickstart.html , https://growingsaja.tistory.com/246)
ngrok? 로컬pc를 외부사이트에서 접속 가능하게 하는 서비스. 반드시 로컬PC에 설치해야 함
https://ngrok.com/download > 로컬 ip접속(ngrok http 포트번호) > https://dashboard.ngrok.com/get-started/your-authtoken 가입하여 고정 token 발급받기
!팁! exe만 오억번 눌렀는데 아무것도 안떠요,,일때 해결법 EXE만 하염없이 누르던 과거가 생각남
(1) exe폴더 주소를 복사
(2) cd 복사한 주소 > 엔터
(3) ngrok http 내로컬 pc port(ex ngrok http 8000) > 엔터
* 웹서비스 포트 확인 법 :
1) Block Kit Builder 사용 + Pycharm 사용
- 목적 : 다양한 요구사항 수용 만능 BOT제작
* Block Kit Builder :슬랙 자체적으로 제공하는 UI프레임 워크 = 한마디로, 예쁘게 만드는 것을 돕는 tool
* Jupyter notebook : 파이썬 코드를 만들고 정상 작동하는지 확인 가능한 오픈소스 웹 플랫폼
~~ 해당 방법의 요약 ~~
- 해당 방식의 특징은 직접 상용 API를 활용하여 불러오는 방법
* 개발자가 아닌 이상.. 무에서 유를 창조하기는 어려움ㅠ 공유받은 코드조각을 유연하게 결함함
참고한 블로그 : https://cosmosproject.tistory.com/393
https://kitle.xyz/post/62/ https://wikidocs.net/81238 https://yunwoong.tistory.com/135
위 블로그대로 코딩 후
슬랙에 메세지가 잘 날라가는지 TEST
* 참고로 그냥 다른 IDE모르겠으면,, 주피터 노트북에서 냅다 코드 돌려도 잘 돌아간다
다양한 답답한 CASE 정리
CASE 1 : flask app 연동에 꽤 애를 먹었다..이거 일단 하려면 가상환경 세팅이 필수이다.
관련 내용은 해당 글에 자세히 서술했다.
https://chobotogosu.tistory.com/113
항상, flask run을 위해 가상환경에서 실행해야 한다는 점
CASE 2 : 방법 실행중 아래 코드가 뜰 때 해결법 https://github.com/INVESTAR/StockAnalysisInPython/issues/46
Error posting message: The request to the Slack API failed. (url: https://www.slack.com/api/chat.postMessage)
The server responded with: {'ok': False, 'error': 'not_authed'}
Slack API의 OAuth & Permissions > Scopes > Bot Token Scopes에 'chat:write.public' 반드시 추가
=> 이거 하면 웬만하면됨
그런데도 slacker 라이브러리로 안될 경우 다른 방법
- webhook url 방식으로 사용 (curl/postman 등 웹 클라이언트로 보내는 방식은 잘 작동했습니다. 봇 설정 시 webhook url 설정필요)
CASE 3: 슬랙 자체의 설정 오류 발생시 확인 법
- 슬랙 로그인 > https://api.slack.com/methods/chat.postMessage/test 페이지 접속
- "Tester" 탭에서 "Argument" 필요한 것만 설정
- Bot User OAuth Access Token을 "token" argument의 "Or, provide your own token:" 텍스트 박스에 입력
- "channel" argument에 보내시고자 하는 채널명을 입력
- "text" argument에 메시지 입력
- "Test Method" 버튼 누름
- 맨 아래 결과창 및 슬랙 채널에 메시지 도착 여부 확인
(1) 가상 환경을 세팅한다.
- cmd 오픈
- 코드 입력 : pipx install virtualenv / python -m pip insatll -user virtualenv
- 코드 입력 : virtualenv 가상환경명
- 코드 입력 : source 가상환경명/bin/activate
(2) app.py 제목을 입력하고 공유받은 슬랙봇 코드를 입력한다.
# -*- coding: utf-8 -*-
import json
from flask import Flask, request, make_response
from slacker import Slacker
token = "xoxb-슬랙에서 부여한 토큰" #여기를 변경 해주세요
slack = Slacker(token)
app = Flask(__name__)
@app.route('/', methods=['POST'])
def hello_there():
slack_event = json.loads(request.data)
if "challenge" in slack_event:
return make_response(slack_event["challenge"], 200, {"content_type": "application/json"})
return make_response("There are no slack request events", 404, {"X-Slack-No-Retry": 1})
if __name__ == '__main__':
app.run(debug=True, port=5004) #port는 미사용중인 것을 선택
(3) 코드 입력 : set FLASK_APP=app.py => flask run
(4) Running on 뒤 주소를 복사하여 open했을 때, 아래와 같은 모습이 보여야 함
(5) 코드 입력 : cd ngrok파일위치주소 => ngrok http 5004 (자신이 무슨 port를 쓰느냐에 따라 숫자다름)
(6) 주소 복사
(7) slack api 접속 => Event Subscriptions 메뉴의 Enable Events를 ON => 복사한 주소 넣기
(8) verified가 보여지면 성공!
(9) 하단의 Subscribe to bot events 아래삼각형 클릭 => Add Bot User Event에서 app_mention 권한 추
(10) 기존 app.py 파일 코드 수정
import json
from datetime import datetime
from flask import Flask, request, make_response
from slack_sdk import WebClient
import requests
import json
from bs4 import BeautifulSoup
#import openpyxl
# import datetime
import time
import math
import os
import openai
token = "xoxb-1195009919412-5191458519780-4iLoVtzuUr4o7c6hrMAi5nE4" #xoxb 뒤는 알맞게 수정 필요
app = Flask(__name__)
client = WebClient(token)
def get_day_of_week():
weekday_list = ['월요일', '화요일', '수요일', '목요일', '금요일', '토요일', '일요일']
weekday = weekday_list[datetime.today().weekday()]
date = datetime.today().strftime("%Y년 %m월 %d일")
result = '{}({})'.format(date, weekday)
return result
def get_time():
return datetime.today().strftime("%H시 %M분 %S초")
def askGPT(text):
print("질문 : " + text)
returnmessage = "```"
openai.api_key = "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"
response = openai.Completion.create(
model="text-davinci-003",
prompt=text,
temperature=0.6,
max_tokens=1000
)
returnmessage += response.choices[0].text + "```"
print("답변 : " + returnmessage)
return returnmessage
def srt_ticket_buy(strUser, strPsw, strDpt, strArr, strDt, strTm, strNum):
# python quickstart.py --user 1680201000 --psw rlarud1029! --dpt 동대구 --arr 수서 --dt 20230521 --tm 16 --num 8 --reserve True
strCMD = 'python quickstart.py --user ' + strUser + ' --psw ' + strPsw + ' --dpt ' + strDpt + ' --arr ' + strArr + ' --dt ' + strDt + ' --tm ' + strTm + ' --num ' + strNum + ' --reserve True'
print(strCMD)
os.chdir(r"c:\pythonProject\srt_reservation")
os.system(strCMD)
# time.sleep(10)
# return "OK"
def get_answer(text):
if text.find('GPT') != -1:
trim_text = text
else:
trim_text = text.replace(" ", "")
arrinput = trim_text.split(',')
ncount = len(arrinput)
answer_dict = {
'안녕': '안녕하세요. TEST-(1) 입니다.',
'요일': ':calendar: 오늘은 {}입니다'.format(get_day_of_week()),
'시간': ':clock9: 현재 시간은 {}입니다.'.format(get_time()),
}
if trim_text == '' or None:
return "알 수 없는 질의입니다. 답변을 드릴 수 없습니다."
elif ncount > 1 and arrinput[1].find('GPT') != -1:
return askGPT(arrinput[0])
elif ncount > 1 and arrinput[0] == "SRT":
# return srt_ticket_buy(arrinput[1],arrinput[2],arrinput[3],arrinput[4],arrinput[5],arrinput[6],arrinput[7])
srt_ticket_buy(arrinput[1], arrinput[2], arrinput[3], arrinput[4], arrinput[5], arrinput[6], arrinput[7])
return "ok"
elif trim_text in answer_dict.keys():
return answer_dict[trim_text]
else:
for key in answer_dict.keys():
if key.find(trim_text) != -1:
return "연관 단어 [" + key + "]에 대한 답변입니다.\n" + answer_dict[key]
for key in answer_dict.keys():
if answer_dict[key].find(text[1:]) != -1:
return "질문과 가장 유사한 질문 [" + key + "]에 대한 답변이에요.\n" + answer_dict[key]
return text + "은(는) 없는 질문입니다."
def event_handler(event_type, slack_event):
channel = slack_event["event"]["channel"]
string_slack_event = str(slack_event)
if string_slack_event.find("{'type': 'user', 'user_id': ") != -1:
try:
if event_type == 'app_mention':
user_query = slack_event['event']['blocks'][0]['elements'][0]['elements'][1]['text']
answer = get_answer(user_query)
result = client.chat_postMessage(channel=channel,
text=answer)
return make_response("ok", 200)
except IndexError:
pass
message = "[%s] cannot find event handler" % event_type
return make_response(message, 200, {"X-Slack-No-Retry": 1})
@app.route('/', methods=['POST'])
def hello_there():
slack_event = json.loads(request.data)
if "challenge" in slack_event:
return make_response(slack_event["challenge"], 200, {"content_type": "application/json"})
if "event" in slack_event:
event_type = slack_event["event"]["type"]
return event_handler(event_type, slack_event)
return make_response("There are no slack request events", 404, {"X-Slack-No-Retry": 1})
if __name__ == '__main__':
app.run(debug=True, port=5004)
* 내부 코드는 니즈에 맞게 수정하면 됨. 나는 OPENAPI 라이브러리 등 여러가지를 추가했다.
(11) 슬랙채널에서 호출 확인
2) 구글 시트 사용
- 부분 노코드로 봇 생성가능
- 목적 : 현황 파악
1 - 시트에서 확장 프로그램 선택 > Apps Script
2 - 필요한 코드 작성
* 해당 코드에는 대외비 내용이 들어있지 않아 그대로 노출한다.
function myFunction() {
var googlesheet = SpreadsheetApp.getActive(); //구글시트 변수 생성
var data = googlesheet.getRange("E:J").getValues(); //구글시트 불러올 범위
const webhook = "https://hooks.slack.com/services/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" //web hook url
let message = {
"text" : "FA 계정 현황 확인을 위한 알림입니다.\n" + //모든 숫자는 0부터 시작
"이번달 발생 데이터 : " + data[1][0] + "\n" + //2번 행 col0번 열
"외주 업체 계정 : " + data[1][1] + "\n" + // 2번 행 col1번 열
"정상 번호 변경 데이터 : " + data[1][4] + "\n" + // 2번 행 col4번 열
"수정 완료 데이터 / 전체 데이터 :" + data[1][5] + "\n" //2번 행 col5번 열
}
var option = {
"method" : "Post",
"contentType" : "application/json",
"multiHttpExceptions" : true,
"payload" : JSON.stringify(message) //메세지 설정
};
try {
UrlFetchApp.fetch(webhook, option);
}
catch(e) {
Logger.log(e);
}
}
* 코드 입력 쉽게 미리 시트 상단에 주석 글귀를 넣으면 편리함 : 코딩시 숫자는 0부터 시작이므로 1컬럼 = col0 처리하여 정리해두기
* 구글 시트 관련 함수 (출처 : https://dev.to/syan/google-apps-script-1-2j2m)(https://program1472.tistory.com/103)
- spreadsheetapp.getactivesheet() : 구글스프레드시트 활성화
- getrange() : 특정 셀 지정
- getvalue() : 값 가져옴
- console.log() : 가져온 값을 출력
- // : 주석
- \n : 줄바꿈
*슬랙으로 발송할 메세지 설정 코드(출처 : https://brunch.co.kr/@cocosociety/7)
3 - 실행 > 권한 승인
4- 필요 트리거 설정
- 시계모양 누름 > 필요한 시간대 및 함수 선택하여 설정
- 실행할 함수 : 함수 명명시 기재한 값 (function 바로 뒤 명칭)
5 - 실행 완료 이후 슬랙에 정상적으로 알람 오는지 확인
'slackbot, 크롤링 역량' 카테고리의 다른 글
[ngrok][인프라] Forwarding 주소 접속이 안될 때 TIP (0) | 2023.06.10 |
---|---|
[파이썬][FLASK] 끝없는 오류의 굴레...가상 환경 설정의 중요성 + 유용 정보 (0) | 2023.06.09 |
[파이썬] pip에 대한 이해 (0) | 2023.06.09 |
[ 실무 속 사소한 TIP ] 파이썬 코드 입력해서 돌리기 (0) | 2023.06.07 |
[ postman ] api호출해보기 (0) | 2023.03.09 |