๋ชฉํ
slack ์ค์
์ค์ ์ด ์กฐ๊ธ ๋ณต์กํ๊ธฐ๋ ํฉ๋๋ค๋ง ์ธํฐ๋ท์ ๋ง์ด ๋์์์ผ๋ ํ๋ฒ ํ์ธํด๋ณด์๊ธฐ ๋ฐ๋๋๋ค.
๊ฒฐ๋ก ์ slack app์ ํ๋ ๋ง๋ค๊ณ ๋ค์ ํ ํฐ์ ๋ฐ์ผ๋ฉด ๋ฉ๋๋ค.
SLACK_BOT_TOKEN=xxx
SLACK_APP_TOKEN=xxx
SLACK_SIGNING_SECRET=xxx
๋ฌผ๋ก ํ์ํ ๊ถํ์ด ์์ด์ผํฉ๋๋ค.
์ฌ๋์ผ๋ก ๋ฉ์ธ์ง ๋ณด๋ด๊ธฐ
%pip install --user -Uq slackclient
.envํ์ผ์ ์ค์ ์ ์ ํ์
์ผ ํฉ๋๋ค.
slackbot
mode
web api mode : web server๊ฐ ์์ด์ผํจ.
socket mode : web server๊ฐ ํ์์์.
web api mode
https://api.slack.com/web
socket mode
https://api.slack.com/apis/socket-mode
์์ผ ๋ชจ๋๋ ์ฌ๋ ๋ด์ด ์ด๋ฒคํธ๋ ์ํธ์์ฉ์ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ ์ค ํ๋์ผ.
์๋๋ ์ฌ๋์ด ๋ด์๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ค๋ฉด ์ธํฐ๋ท ์ฃผ์๊ฐ ํ์ํ์ด. ํ์ง๋ง ์์ผ ๋ชจ๋๋ ์ธํฐ๋ท ์ฃผ์ ์์ด๋ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์์ด.
๊ทธ๋์ ๋ ์์ผ ๋ชจ๋๋ฅผ ์ฌ์ฉํ ๊ฑฐ์ผ.
bolt
์ฌ๋์์๋ ๊ฐ๋ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์คํํ์ด ์ด๊ฒ์ด bolt์
https://slack.dev/bolt-python/concepts
slack bot ๋ง๋ค๊ธฐ
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from slack_bolt.adapter.socket_mode import SocketModeHandler
from slack_bolt import App
import slack
import os
from dotenv import load_dotenv
load_dotenv()
app = App(
token=os.environ.get("SLACK_BOT_TOKEN"),
signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)
prompt = ChatPromptTemplate.from_messages(
[
("system", "๋น์ ์ ์ธ๊ฐ๊ณผ ๋ํํ๋ ์ ์ฉํ AI์
๋๋ค, ๋ต์ ๋ชจ๋ฅธ๋ค๋ฉด ๊ทธ๋ฅ ๋ชจ๋ฅธ๋ค๊ณ ๋งํ๊ณ ์ง์ด๋ด์ง ๋ง์ธ์"),
("human", "{question}"),
]
)
llm = ChatOpenAI(
temperature=0
)
chain = prompt | llm | StrOutputParser()
@app.message(".*")
def message_handler(message, say):
print(message)
output = chain.invoke({"question": message['text']})
say(output)
# Start your app
if __name__ == "__main__":
SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()
slackbot๊ณผ jira issue์ฐ๋
import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from jira import JIRA
from dotenv import load_dotenv
load_dotenv()
app = App(
token=os.environ.get("SLACK_BOT_TOKEN"),
signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)
# Langchain implementation
llm = ChatOpenAI(
temperature=0.1, # ์ฐฝ์์ฑ (0.0 ~ 2.0)
)
jira = JIRA(server=os.environ['JIRA_URL'],
basic_auth=(
os.environ['JIRA_EMAIL'],
os.environ['JIRA_TOKEN'])
)
def getJiraIssue(issue_key):
# ํน์ ์ด์๋ฅผ ๊ฐ์ ธ์ด
# issue = jira.issue('NETOP-14473')
issue = jira.issue(issue_key)
# ํ๋๋ฅผ ์ ์ฅํ ์๋ก์ด ์ฌ์ ์ ์์ฑ
issue_fields = {}
# ์ด์์ ๋ชจ๋ ํ๋๋ฅผ ํ์ธ
for field_name, field_value in vars(issue.fields).items():
# ํ๋ ์ด๋ฆ์ด 'customfield'๋ก ์์ํ๊ณ ๊ฐ์ด None์ธ ํ๋๋ ์ ์ธ
if not (field_name.startswith('customfield') and field_value is None):
issue_fields[field_name] = field_value
return issue_fields
template = """
JIRA ์ด์ ๋ฐ์ดํฐ๋ `key: value` ํํ๋ก ๋์ด์๊ณ value๋ ์ค๋ฐ๊ฟ ๋ฌธ์๊ฐ ์๋๊ณณ๊น์ง ํฌํจํฉ๋๋ค.
์ฃผ์ด์ง JIRA ์ด์ ๋ฐ์ดํฐ์์ ์๋ฒ ์ด๋ฆ, VCPU, ๋ฉ๋ชจ๋ฆฌ, OS ์ด๋ฆ์ ์ถ์ถํ์ฌ Ansible ํ๋ ์ด๋ถ ์ปค๋งจ๋๋ฅผ ์์ฑํด ์ฃผ์ธ์.
์๋ฒ ์ด๋ฆ์ด ์ฌ๋ฌ ์ธ์คํด์ค๋ฅผ ํฌํจํ๋ ๊ฒฝ์ฐ ๊ฐ ์ธ์คํด์ค์ ๋ํด ๋ณ๋์ Ansible ํ๋ ์ด๋ถ ์ปค๋งจ๋๋ฅผ ์์ฑํด ์ฃผ์ธ์.
vcpu๊ฐฏ์๋ customfield_10148 ์ ๊ฐ์ ์ฌ์ฉํด์ผํ๋๋ฐ ๋ฌธ์ฅ ๋๊น์ง ์ธ์ํด์ฃผ์ธ์ ๊ฑฐ๊ธฐ์์ ์ซ์๋ง ์ถ์ถํ๋ฉด ๋ฉ๋๋ค.
vcpu๊ฐ ์์ผ๊ณ cpu๊ฐ ์๋ ๊ฒฝ์ฐ cpu๋ vcpu์ ์ ๋ฐ์ผ๋ก ์ค์ ํด ์ฃผ์ธ์.
cpu๊ฐ ์๊ณ vcpu๊ฐ ์์ผ๋ฉด vcpu๋ cpu์ 2๋ฐฐ๋ก ์ค์ ํด ์ฃผ์ธ์.
๋๋ค ์์ผ๋ฉด cpu=1, vcpu=2๋ก ์ค์ ํด ์ฃผ์ธ์.
os_name์ customfield_10165 ์์ ๊ณต๋ฐฑ์ ์ ๊ฑฐํ ๋ฌธ์์ด๋ก ์ค์ ํด ์ฃผ์ธ์.
os_version์ customfield_10166 ์์ ๊ณต๋ฐฑ์ ์ ๊ฑฐํ ๋ฌธ์์ด๋ก ์ค์ ํด ์ฃผ์ธ์.
os_version์ด ์๋๊ฒฝ์ฐ๋ oraclelinux๋ 9.3 , centos๋ 7.8๋ก ์ค์ ํด์ฃผ์ธ์
JIRA ์ด์ ๋ฐ์ดํฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
{ISSUE_DATA}
SAMPLE) here is Ansible Playbook Command SAMPLE
ansible-playbook create-vm.yaml \
-e "server_name=**server_name**" \
-e "cpu=**cpu**" \
-e "vcpu=**vcpu**" \
-e "memory=**memory**" \
-e "image_name=**os_name**-**os_version**" \
-e "network_name=Private"
Please Make Correct Ansible Playbook Command use above sample
๋ต๋ณ์ ์๋์ฒ๋ผ ๋ณด์ฌ์ค. ๊ฒฐ๊ณผ๋ง ๋ณด์ฌ์ค
ANSWER) Ansible Playbook Command
ansible-playbook create-vm.yaml \
-e "server_name=**server_name**" \
-e "cpu=**cpu**" \
-e "vcpu=**vcpu**" \
-e "memory=**memory**" \
-e "image_name=**os_name**-**os_version**" \
-e "network_name=Private"
๋ต๋ณ์ ํ๊ธ๋ก ํด์ฃผ์ธ์
"""
prompt = PromptTemplate.from_template(template=template)
chain = prompt | llm | StrOutputParser()
# @app.message(".*")
# def message_handler(message, say):
# print(message)
# say(output)
@app.message("build")
def message_build(message, say):
print(message)
ticket_number = message['text'].replace('build', '').strip()
jira = getJiraIssue(ticket_number)
print(jira)
output = chain.invoke({"ISSUE_DATA": jira})
say(output)
# @app.event("message")
# def handle_message_events(body, logger):
# logger.info(body)
# Start your app
if __name__ == "__main__":
SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()