top of page

Slack에서 흘러가던 알림을 Jira에서 추적 가능한 업무로 만들기

  • 2시간 전
  • 8분 분량


안녕하세요. 개발팀의 DevOps/SRE를 담당하고 있는 이창윤(CY Lee)입니다.

일전에 ClawHub 플러그인 이야기로 한 번 찾아뵀었는데, 이번엔 서비스 알림 때문에 생긴 고민과 그 해결 과정을 공유드리러 다시 돌아왔습니다.


여러분의 팀에는 하루에 알림이 몇 개나 쌓이나요?


유저 피드백, 결제 이벤트, 가입 이벤트, 그리고 SigNoz가 감지한 500 에러까지. 처음에는 이런 알림들이 각각 다른 Slack 채널로 들어오고 있었습니다. 채널이 유형별로 나뉘어 있으면 알림을 구분해서 보기에는 편했지만, 정작 지금 우리 서비스에 무슨 일이 일어나고 있는지 전체 상황을 한눈에 파악하기는 어려웠습니다. 그래서 흩어져 있던 알림을 하나의 Slack 채널로 모았습니다. 고객 이벤트와 시스템 알림을 한곳에서 볼 수 있게 되자 흐름을 파악하기는 한결 편해졌습니다. 그런데 정작 궁금한 건 따로 있었습니다. 급하게 대응해야 하는 알림이 정말 제대로 처리되고 있는지였습니다.

'급한 알림은 지금 누가, 어디까지 대응하고 있는 걸까?' 이 질문에 답하려면 알림을 한곳에서 보는 것만으로는 부족했습니다. 누가 맡았는지, 어디까지 진행됐는지 같은 담당자와 상태가 보여야 했고, 그건 Slack 알림이 아니라 Jira 같은 태스크 관리가 필요한 영역이었습니다. 결국 알림을 모으는 것과 그 알림이 처리되는지 아는 것은 서로 다른 문제였습니다. 그래서 Slack 알림을 feed와 alert로 나누고, 대응이 필요한 alert만 Activepieces를 통해 Jira 이슈로 전환하는 자동화를 구성했습니다. 이 글은 그 과정을 정리한 기록입니다.






1. 흩어져 있던 알림을 하나의 Slack 채널로 모으기까지


💁 처음에는 이벤트별로 채널이 나뉘어 있었다


처음에는 알림 종류마다 Slack 채널이 따로 있었습니다. 유저 피드백, 결제 이벤트, 가입 이벤트는 고객 쪽에서 발생하는 알림이었고, SigNoz 모니터링 알림이나 500 에러 같은 시스템 알림은 서비스 쪽에서 발생하는 알림이었습니다. 각각의 알림이 서로 다른 채널로 들어왔습니다.

Slack 채널

받던 알림

#일반-알림

사용자 피드백

회원가입, 결제

#alert-prod-critical

시스템 모니터링 (긴급)

#alert-prod-warning

시스템 모니터링

채널이 나뉘어 있으면 분명한 장점이 있습니다. 어떤 채널을 보느냐에 따라 알림의 종류를 바로 알 수 있고, 관심 있는 알림만 골라서 볼 수도 있습니다. 하지만 단점도 함께 따라왔습니다. 지금 우리 서비스에 무슨 일이 일어나고 있는지, 대응이 필요한 일이 어디서 발생했는지를 한눈에 보기가 어려웠던 것입니다. 결제 실패가 늘어나는 동안 다른 채널에서 가입 실패가 함께 발생하고 있어도, 채널을 옮겨 다니지 않으면 그 연결을 알아채기 어려웠습니다.



🤔 알림을 한곳으로 모았지만 처리 상태는 보이지 않았다


그래서 여러 알림을 하나의 Slack 채널로 모았습니다. 고객 이벤트와 시스템 알림을 한곳에서 확인할 수 있게 되자 전체 흐름을 보기는 한결 편해졌습니다.

그런데 한곳에 모은 뒤에 새로운 문제가 생겼습니다. 필요한 알림과 참고용 알림이 같은 흐름 안에 섞이기 시작한 것입니다. 하나의 채널에 다양한 알림이 쌓이다 보니 다음과 같은 점들을 알기 어려웠습니다.


  • 누가 어떤 알림을 확인했는지

  • 어떤 알림이 Jira로 추적되어야 하는지

  • 각 알림의 처리 상태가 어떤지

  • 대응이 필요한 알림이 참고용 알림 사이에 묻히지는 않았는지


알림을 한곳에 모으는 것과 처리 상태를 관리하는 것은, 생각보다 다른 문제였습니다.



😞 이모지로 확인과 완료를 표시해보려 했지만 한계가 있었다


그렇다면 Slack 안에서 처리 상태를 표시할 방법은 없었을까요? 처음에는 이모지를 쓰는 방식을 고려했습니다. 예를 들어 👀 눈 모양 이모지는 "확인함", ✅ 체크 이모지는 "처리 완료"로 보는 식이었습니다.

이 방식은 알림을 가볍게 확인했다는 표시로는 충분했지만, 실제 업무 처리 상태를 관리하기에는 한계가 있었습니다. 이모지로 할 수 있는 일과 할 수 없는 일을 나눠 보면 그 차이가 분명해집니다.



이모지는 "봤다"를 표시할 수는 있어도 "어떻게 처리되고 있다"를 추적하기에는 부족했습니다. 결국 알림을 확인하는 공간과 업무를 추적하는 공간은 분리되어야 한다는 결론에 이르렀습니다. Slack에서는 알림을 확인하고, 대응이 필요한 항목은 Jira에서 추적하는 구조가 필요했습니다.




2. Feed와 Alert를 나누고 Jira 이관 기준 정하기


1️⃣ 모든 알림이 대응 대상은 아니다

그렇다고 모든 알림을 Jira 이슈로 만들 수는 없었습니다. 한 채널에 모인 알림을 그대로 전부 이슈로 만들면, 이번에는 Jira가 참고용 알림으로 가득 차기 때문입니다. 그러면 정작 처리해야 할 이슈를 찾는 일이 또 어려워집니다. Slack에서 겪던 문제를 Jira로 그대로 옮기는 셈이죠.

자동화를 만들기 전에 먼저 정해야 했던 것은 도구 설정이 아니라 기준이었습니다.

가입 성공 알림이나 단순 상태 변경처럼 참고만 하면 되는 알림도 많았기 때문에, 어떤 알림이 추적할 가치가 있는지부터 나눠야 했습니다.



2️⃣ Feed는 참고용, Alert는 대응 대상으로 나누기

그래서 Slack 알림을 크게 두 가지로 나누었습니다. feed는 참고용으로 흘러가도 되는 알림이고, alert는 누군가 대응해야 하는 알림입니다.

분류

의미

Jira 이관 여부

예시

feed

참고용 알림

제외

가입 성공, 단순 상태 변경, 참고용 로그

alert

대응해야 하는 알림

이관

결제 실패, 가입 실패, 유저 불편 피드백, SigNoz 500 에러

feed는 Slack에서 참고만 하면 충분했습니다. 반면 alert는 그냥 지나가게 두면 안 되는 알림이었습니다. 그리고 이 feed / alert 구분은 알림을 보내는 webhook 주체가 상황에 따라 채널을 나눠 보내면서 이미 정리되고 있었습니다. 그래서 자동화는 alert 채널만 바라보면 됐습니다.



3️⃣ Alert는 담당자 지정과 상태 트래킹이 필요하다

alert로 분류한 알림은 단순히 확인하는 것으로 끝나지 않았습니다. 누가 맡을지 정해야 하고, 지금 어디까지 진행됐는지 보여야 하고, 완료된 뒤에는 이력이 남아야 했습니다. 앞서 이모지로는 관리하기 어려웠던 바로 그 영역입니다. Slack은 알림을 빠르게 확인하는 데 적합했지만, 담당자와 상태를 추적하는 데는 Jira가 더 적합했습니다. 그래서 alert는 Jira 이슈로 전환해 추적 가능한 업무로 바꾸기로 했습니다.



4️⃣ Jira 이관 대상 기준 정리하기

feed와 alert를 나눈 다음에는 어떤 alert를 Jira로 이관할지 구체적인 기준을 정리했습니다.

구분

Jira 이관 여부

예시

유저 불편 피드백

이관

"결제가 안 돼요", "로그인이 안 돼요"

결제 실패

이관

카드 승인 실패, PG 오류

가입 실패

이관

인증 실패, 회원가입 오류

SigNoz 500 에러

이관

API 500, timeout, exception

단순 가입 성공 이벤트

제외

가입 완료 알림

참고용 로그

제외

단순 상태 알림

기준을 먼저 고정해 두니, 이후 자동화를 만들 때 "이 알림을 이슈로 만들어야 하나"를 매번 고민하지 않아도 되었습니다.




3. Activepieces로 Slack Alert를 Jira 이슈로 전환하기


기준을 정했으니 이제 그 기준을 실제로 동작하게 만들 차례입니다. alert를 Jira 이슈로 옮기는 일은 Activepieces로 자동화했습니다. Activepieces를 고른 이유는, Slack·Jira 커넥터로 Flow를 빠르게 구성할 수 있는 데다 Zapier와 달리 실행 횟수에 제한이 없어(Flow 개수만 제한됩니다) 알림이 많아도 비용 부담이 없었기 때문입니다.


초기 간단한 구조

Slack에 새 메시지가 들어오면 Jira 이슈를 만드는 Flow입니다. Slack과 Jira를 각각 연동하기만 하면 어렵지 않게 만들 수 있습니다. 다만 이 구조만으로는 슬랙 메시지에서 원하는 정보를 뽑아 이슈를 다듬을 수가 없었습니다. 들어온 텍스트가 그대로 이슈가 될 뿐이었죠.




Code 스텝으로 원문·링크·날짜 정리하기

그래서 Slack과 Jira 사이에 Code 스텝을 넣어, 이슈에 필요한 정보를 직접 가공했습니다. 슬랙 메시지의 원문과 작성 시각으로부터 Jira 이슈에 쓸 permalink(원본 메시지 링크), 시작일(start_date), 그리고 원문을 담은 설명(description)을 만들어 두는 코드입니다.


export const code = async (inputs) => {
  const ts = String(inputs.ts ?? '');
  const channel = String(inputs.channel ?? '');
  const raw = inputs.text ?? '';

  // Slack permalink (used for both the dedup key and the "메시지 열기" link)
  const link = `https://<workspace>.slack.com/archives/${channel}/p${ts.replace('.', '')}`;

  // start date in Asia/Seoul (YYYY-MM-DD)
  const start_date = new Date(parseFloat(ts) * 1000)
    .toLocaleDateString('en-CA', { timeZone: 'Asia/Seoul' });

  // Build ADF: newlines -> hardBreak, text properly escaped by JSON serialization
  const nodes = [{ type: 'text', text: '슬랙 원문: ' }];
  raw.split('\n').forEach((line, i) => {
    if (i > 0) nodes.push({ type: 'hardBreak' });
    if (line.length) nodes.push({ type: 'text', text: line });
  });
  nodes.push({ type: 'hardBreak' });
  nodes.push({
    type: 'text',
    text: '메시지 열기',
    marks: [{ type: 'link', attrs: { href: link } }],
  });

  const description = {
    type: 'doc',
    version: 1,
    content: [{ type: 'paragraph', content: nodes }],
  };

  return { link, start_date, description };
};

여기서 반환한 link , start_date , description 은 다음 Jira 스텝에서 입력값으로 바로 매핑할 수 있습니다. 이슈에 원본 메시지와 "메시지 열기" 링크를 함께 남겨 두면, 담당자가 이슈만 보고도 원래 맥락으로 돌아갈 수 있습니다.





4. LLM으로 Jira 제목과 설명 만들기


슬랙 원문을 그대로 옮기면 제목이 지저분했다

Code 스텝으로 원문과 링크는 깔끔하게 담았지만, 한 가지가 남았습니다. 바로 이슈 제목입니다. 슬랙 메시지에는 봇 태그, 이모지, 줄바꿈이 섞여 있어서 그대로 제목에 넣으면 길고 지저분했습니다. 그렇다고 사람이 매번 제목을 다듬는 건 자동화를 무색하게 만드는 일이었습니다. 그래서 슬랙 메시지에서 사람이 읽기 좋은 제목과 설명을 LLM으로 생성하기로 했습니다. LLM에게 분류나 판단을 맡기는 게 아니라, 같은 내용을 보기 좋게 가공하는 역할만 준 셈입니다.


Slack 메시지
→ LLM (OpenRouter Chat)
→ title / description (JSON)
→ Jira Issue 생성



OpenRouter로 호출하기

OpenRouter의 chat completions 엔드포인트로 호출했습니다. 앞 스텝에서 받은 슬랙 메시지 텍스트를 넣고, 결과를 title description  두 키를 가진 JSON으로 받도록 했습니다.

URL: POST <https://openrouter.ai/api/v1/chat/completions>


{
  "model": "qwen/qwen3.6-flash",
  "messages": [
    {
      "role": "system",
      "content": "You create a Jira issue from a Slack message. Respond with a single JSON object with exactly two keys: \"title\" (short summary) and \"description\" (details with context). Output JSON only, no extra text."
    },
    {
      "role": "user",
      "content": "Slack message:\n\n{{trigger['output']['text']}}"
    }
  ],
  "reasoning": { "enabled": false },
  "response_format": { "type": "json_object" }
}

여기서 한 가지 주의할 점이 있습니다. 이 모델은 엄격한 스키마 지정( json_schema )을 지원하지 않아서, response_format json_object 로 두었습니다. 그리고 json_object  모드는 메시지 안에 "json"이라는 단어가 들어 있어야 동작하기 때문에, system 프롬프트에서 "Output JSON only"라고 명시했습니다.





JSON 문자열을 파싱해 제목과 설명으로 나누기


응답에서 결과는 choices[0].message.content 에 JSON "문자열"로 들어옵니다. 이걸 그대로 Jira에 넣을 수는 없으니, Code 스텝을 하나 더 두어 파싱했습니다. 모델이 가끔 ````json` 으로 감싸거나 이미 객체로 들어오는 경우까지 막아 둔 버전입니다.


export const code = async (inputs) => {
  const value = inputs.ai_response;

  // 이미 객체로 들어오면 그대로 사용
  let parsed = value;

  if (typeof value === 'string') {
    let raw = value.trim();

    // 모델이 ```json ... ``` 으로 감싼 경우 제거
    if (raw.startsWith('```')) {
      raw = raw.replace(/^```(?:json)?\s*/i, '').replace(/\s*```$/, '').trim();
    }

    parsed = JSON.parse(raw);
  }

  return {
    title: parsed.title,
    description: parsed.description,
  };
};

이 스텝의 출력으로 나온 title 은 Jira 이슈의 Summary에, description 은 Description에 매핑합니다. 3장에서 만든 원문·링크와 함께 두면, 제목은 LLM이 다듬어 깔끔하고 본문에는 원래 맥락이 그대로 남는 이슈가 만들어집니다.





5. 자동화 이후 달라진 대응 방식


(Before) 필요한 알림과 불필요한 알림이 함께 흘러가던 방식

자동화 전으로 잠시 돌아가 보겠습니다. 그때는 Slack 채널에 대응이 필요한 알림과 참고용 알림이 함께 쌓였습니다. 결제 실패나 500 에러처럼 바로 확인해야 하는 alert도 있었지만, 가입 성공 이벤트나 단순 상태 알림처럼 참고만 하면 되는 feed도 같은 흐름 안에 있었습니다.

이 상태에서는 알림을 많이 받을수록 오히려 대응 대상이 흐려졌습니다. 누군가 확인해야 하는 메시지인지, 그냥 지나가도 되는 메시지인지 매번 사람이 판단해야 했고, 실제 대응이 필요한 알림도 다른 메시지 사이에 묻히기 쉬웠습니다. Jira 이슈를 만들고 제목을 다듬고 원문을 옮기는 일도 전부 수동이었습니다.


(After) Alert만 Jira 이슈로 이어지는 방식

자동화 이후에는 feed와 alert가 나뉘었습니다. alert만 Slack Alert 채널로 모이고, Activepieces Flow는 그 Alert 채널을 기준으로 실행됩니다. alert가 들어오면 Code 스텝이 원문과 링크를 정리하고, LLM이 제목과 설명을 만들어, Jira 이슈가 자동으로 생성됩니다. 담당자 지정과 상태 관리는 그 이슈를 받아 Jira에서 이어갑니다.



Slack과 Jira의 역할이 분리되었다

자동화 전과 후를 나란히 놓고 보면 달라진 점이 한눈에 들어옵니다.

구분

Before

After

알림 흐름

feed와 alert가 한 채널에 섞임

✅ feed / alert 채널 분리

대응 대상 판단

매번 사람이 판단

Alert 채널 = 대응 대상

Jira 이슈 생성

수동

Activepieces가 자동 생성

제목·설명 작성

사람이 매번 다듬음

LLM이 생성, 원문은 그대로 보존

담당자·상태 관리

Slack 이모지로는 한계

Jira에서 추적

결과적으로 Slack과 Jira의 역할이 분리되었습니다. Slack은 알림을 빠르게 확인하는 공간으로, Jira는 담당자와 처리 상태를 추적하는 공간으로 나뉘었습니다. 그 사이에서 Activepieces가 alert를 추적 가능한 이슈로 옮기는 역할을 맡았습니다.





6. 이번 작업을 통해 배운 점


알림을 모으는 것과 처리하는 것은 다르다

알림을 한곳에 모으면 "많이 본다"는 느낌은 들지만, 그게 곧 "잘 처리된다"는 뜻은 아니었습니다. 오히려 알림이 늘수록 무엇을 먼저 처리해야 하는지가 더 흐려졌습니다. 처음에는 확인하는 공간과 추적하는 공간을 한 도구 안에서 해결하려 했는데, 그게 시행착오였습니다. 두 가지를 떼어 놓고 나서야 비로소 정리가 됐습니다.


자동화 전에 기준을 먼저 정해야 한다

정작 시간이 많이 든 건 Activepieces 설정이 아니라, feed와 alert를 가르는 기준을 합의하는 일이었습니다. 어디까지를 "대응이 필요한 알림"으로 볼지는 사람마다 생각이 달라서, 표로 정리하기 전까지 의견이 쉽게 모이지 않았습니다. 이 합의를 건너뛰고 자동화부터 만들었다면 Jira는 또 다른 잡동사니 채널이 됐을 겁니다.


LLM은 일단 '가공'에만 맡겼다

이번에는 LLM을 슬랙 메시지에서 제목과 설명을 만드는 데에만 썼습니다. 알림 분류나 담당자 지정까지 LLM에게 맡기는 것도 떠올렸지만, 아직 검증해보지 않은 영역이라 이번 범위에서는 뺐습니다. 분류와 우선순위는 알림을 보내는 채널(critical/warning 등)에서 이미 갈리고 있어서, 굳이 LLM으로 다시 판단할 이유도 없었고요. 판단까지 자동화하는 건 충분히 검증한 뒤 천천히 넓혀가도 늦지 않다고 봤습니다. 일단은 결과가 틀려도 부담이 적은 "가공"(제목·설명 다듬기)부터 적용하고, 분류·담당자 할당 같은 "판단"은 다음 과제로 남겨 두었습니다.


자동화는 사람이 이어받기 좋은 형태로 끝나야 한다

이번 자동화의 목표는 알림을 끝까지 자동으로 처리하는 것이 아니었습니다. 대응이 필요한 알림을 놓치지 않도록 Jira 이슈로 만들고, 사람이 이어서 확인할 수 있는 상태로 넘기는 것이 목표였습니다. 그래서 Jira 이슈에는 LLM이 다듬은 제목과 설명뿐 아니라 원본 슬랙 메시지와 링크를 함께 남기도록 했습니다. 자동화가 만든 이슈를 보고도 다시 Slack을 뒤져야 한다면 자동화의 효과가 줄어들기 때문입니다. 결국 중요한 것은 자동화가 어디까지 처리할지보다, 사람이 어디서부터 자연스럽게 이어받을 수 있는지였습니다.


자동화는 대응의 끝이 아니라, 대응을 시작하기 좋은 형태를 만드는 역할에 가까웠습니다.



7. 마치며


처음의 질문으로 돌아가 보겠습니다. 급한 알림은 정말 제대로 대응되고 있었을까요? 모으기만 해서는 알 수 없었습니다. 누가 맡았는지, 어디까지 처리됐는지가 보이지 않았기 때문입니다.

그래서 (보내는 쪽에서 이미 나뉜) alert만 Activepieces를 통해 Jira 이슈로 생성되도록 구성했습니다. Code 스텝으로 원문과 링크를 보존하고, LLM으로 사람이 읽기 좋은 제목과 설명을 만들었습니다. Slack은 알림을 확인하는 공간으로, Jira는 담당자와 처리 상태를 추적하는 공간으로 역할을 나누었습니다.

이번 작업으로 alert는 추적 가능한 Jira 이슈가 됐습니다. 다만 처음에 궁금했던 "누가 맡아 대응하고 있는가"까지 자동으로 채워지는 건 아직입니다. 담당자 할당은 다음 과제로 남겨 두고, 그 지점부터는 사람이 자연스럽게 이어받도록 두었습니다. 이번 작업은 단순히 Slack 메시지를 Jira로 옮기는 자동화가 아니라, 흘러가던 알림을 추적 가능한 업무 단위로 바꾸는 과정이었습니다. 앞으로도 범위를 무작정 넓히기보다, 검증된 만큼 한 걸음씩 넓혀가려고 합니다.








| Dev Team

| Author: CY Lee

| Site: Linkedin

Blog
bottom of page