# 알림 문제 해결

**Notifications > Activity**에서 시작하세요. 소스에서 Mocco가 받은 모든 이벤트와, 채널로 보낸 모든 Mocco 이벤트가 최신순으로 30일 동안 이곳에 나열됩니다. **Source**, **Channel**, **Outcome** 필터로 범위를 좁힐 수 있습니다. 필터는 페이지 주소에 포함되므로, 필터를 적용한 화면을 팀원과 공유할 수 있습니다.

![행 하나가 펼쳐진 Activity 탭](https://fi-workers-mocco-storage.s3.ap-northeast-2.amazonaws.com/pub/w/93e11fe8-0494-4e3d-b1cb-fe4dffd3ee7e/p/d64785b8-9a23-4fa1-a81d-550af30e203a/helpcenter/a66c1b8f-ce9b-4ebc-80bc-9537238da28d/activity.png)

각 행은 두 부분으로 이루어집니다.

1. **outcome**: Mocco가 받은 전달을 어떻게 처리했는지(아래 참고).
2. **Details**: 클릭하면 채널마다 메시지가 전송되었는지, 그 이유가 무엇인지 볼 수 있습니다.

## Activity에 아무것도 나타나지 않을 때

외부 서비스가 웹훅을 보냈다고 하는데 Activity에 해당 행이 없다면, Mocco가 아무것도 기록하기 전에 전달을 거부한 것입니다. 외부 서비스의 전달 로그에서 HTTP 응답을 확인하세요(GitHub에서는 웹훅의 **Recent deliveries**).

| 응답 | 의미 | 대처 |
|---|---|---|
| `404 not found` | URL이 활성 소스를 가리키지 않습니다. URL을 잘못 입력했거나, 소스가 삭제되었거나, **Paused** 상태입니다. | Sources 탭에서 **Ingest URL**을 다시 복사하세요. 소스가 일시 중지되었다면 **Resume**을 클릭하세요. |
| `401 invalid signature` | 서명이 소스의 시크릿과 일치하지 않습니다. | 올바른 시크릿을 붙여 넣으세요. Sentry의 Client Secret, Vercel 웹훅의 시크릿, 또는 Mocco가 GitHub용으로 생성한 시크릿입니다. 확신이 없으면 **Rotate secret**을 클릭하고 외부 서비스 쪽을 갱신하세요. |
| `400 missing delivery id` | 요청에 외부 서비스의 전달 ID가 없습니다. 그 서비스의 웹훅 시스템에서 온 요청이 아니라는 뜻입니다. | 직접 보내지 말고 외부 서비스의 웹훅 설정에서 보내세요. |
| `413` | 본문이 1 MB보다 큽니다. | Mocco에서 고칠 것은 없습니다. 매우 큰 페이로드는 받지 않습니다. |
| `429 too many deliveries` | 워크스페이스가 24시간 동안 20,000건이 넘는 전달을 받았습니다. | 전달이 몰리는 소스를 찾아(외부 서비스가 재시도를 반복하는 경우가 많습니다) 일시 중지하거나 이벤트를 좁히세요. 24시간 구간이 지나가면 새 전달을 다시 받습니다. |
| `503` | 이 Mocco 배포에 웹훅이 설정되어 있지 않습니다. | Mocco 배포를 운영하는 사람에게 문의하세요. |

Sources 탭에서 소스의 **Last received** 시각도 확인하세요. **Never**는 유효한 전달이 한 번도 도착하지 않았다는 뜻입니다.

## 수신 결과(Receipt outcomes)

| Outcome | 의미 | 대처 |
|---|---|---|
| `published` | Mocco가 전달을 기록하고 이벤트로 변환했습니다. | **Details**를 열어 각 채널이 어떻게 처리했는지 확인하세요. |
| `pending` | 기록되었고 이벤트를 만드는 중입니다. 보통 몇 초 걸립니다. | 1분 기다리세요. Mocco가 스스로 재시도하며, 계속 실패하는 전달은 `publishing failed 5 times`라는 사유와 함께 `ignored`로 끝납니다. |
| `ignored` | Mocco가 이런 종류의 전달은 전달(forward)하지 않습니다. 사유에 이유가 나옵니다. | 아래 표를 참고하세요. |
| `over_quota` | 워크스페이스가 최근 24시간 동안 5,000건이 넘는 이벤트를 전달해서, 이 이벤트는 기록만 되었습니다. | 외부 서비스가 보내는 이벤트(이벤트 종류나 프로젝트)를 줄이거나, 잡음이 되는 부분을 분리하세요. 24시간 구간이 지나가면 전달이 재개됩니다. 버려진 전달은 나중에 전송되지 않습니다. |

자주 보이는 `ignored` 사유:

| 사유 | 대처 |
|---|---|
| `ping` | 할 일은 없습니다. GitHub가 웹훅을 만들 때 보내는 이벤트이며, URL과 시크릿이 동작한다는 뜻입니다. |
| `github event "…" is not mapped`, `vercel event "…" is not mapped`, `sentry resource "…" is not mapped` | 해당 이벤트 종류는 전달되지 않습니다. 잡음을 줄이려면 외부 서비스의 웹훅 설정에서 선택을 해제하세요. |
| `github pull_request action "edited" is not mapped`, `sentry action "resolved" is not mapped`, … | 일부 action만 전달됩니다. [GitHub](https://www.mocco.club/docs/ko/articles/cnzvv7-github), [Sentry](https://www.mocco.club/docs/ko/articles/wbbawp-sentry), [Vercel](https://www.mocco.club/docs/ko/articles/55gt7w-vercel)을 참고하세요. |
| `github workflow_run conclusion "cancelled" is not mapped` | 실패한 실행과 성공한 실행만 전달됩니다. |
| `malformed JSON body` | GitHub에서는 웹훅의 content type을 **application/json**으로 설정하세요. |
| `body is not valid UTF-8` | Mocco가 읽을 수 있는 텍스트가 아닙니다. 계속 발생하면 지원팀에 문의하세요. |
| `missing Sentry-Hook-Resource header` | Sentry 통합 웹훅에서 온 요청이 아닙니다. |

## Details: 채널별

`published` 이벤트(와 Mocco 이벤트)의 **Details**에는 워크스페이스의 모든 채널이 다음 중 하나와 함께 나열됩니다.

### 메시지가 없을 때와 그 이유

| 표시 | 의미 | 대처 |
|---|---|---|
| No rule matched: `the channel has no rules` | 채널에 아직 규칙이 없습니다. | Channels 탭에서 규칙을 추가하거나 프리셋을 적용하세요. |
| No rule matched: ``no rule for `github.push` `` | 채널의 규칙 중 이 이벤트 타입에 대한 것이 없습니다. | 해당 타입이나 그 계열(`github.*`)에 대한 규칙을 추가하세요. |
| No rule matched: ``rule `vercel.deployment.succeeded` needs target = "production" (the event has "preview")`` | 이 타입에 대한 규칙이 있지만, 필터가 다른 값을 요구합니다. | 프로덕션만 받으려는 것이라면 의도한 동작입니다. 그렇지 않으면 필터를 바꾸거나 규칙을 하나 더 추가하세요. |
| No rule matched: ``rule `…` is limited to another source`` | 규칙이 다른 소스의 이벤트만 받습니다. | 소스 제한을 없애거나, 이 소스에 대한 규칙을 추가하세요. |
| No rule matched: ``rule `…` matches`` | 채널의 규칙이 지금은 일치하지만, 이벤트가 도착했을 때는 일치하지 않았습니다(규칙이 나중에 추가되었습니다). | 할 일은 없습니다. 다음 이벤트는 전송됩니다. |
| Channel disabled | 이벤트가 도착했을 때 채널이 비활성화되어 있었습니다. | [비활성화된 채널](#disabled-channels)을 참고하세요. |
| Channel added after this event | 그 시점에는 채널이 없었습니다. | 할 일은 없습니다. |

이 설명은 채널의 현재 규칙을 기준으로 계산하며, 무엇을 보낼지 결정할 때 쓰는 것과 같은 일치 로직을 사용합니다.

### 메시지가 있을 때: 전송 상태

| 상태 | 의미 |
|---|---|
| `queued` | 전송을 기다리는 중입니다. **next retry** 시각은 Mocco가 다시 시도할 때를, 마지막 오류는 기다리는 이유를 알려 줍니다. |
| `sending` | Mocco가 지금 Discord에 게시하는 중입니다. |
| `sent` | Discord가 메시지를 받아들였습니다. |
| `failed` | Mocco가 포기했습니다. 마지막 오류에 이유가 나옵니다. |
| `suppressed` | 메시지가 전송되기 전에 채널이 삭제되었습니다. |

**Attempts**는 Mocco가 실제로 Discord를 호출한 횟수입니다. 처리 여유가 생기기를 기다리는 시간은 세지 않습니다.

### 볼 수 있는 오류

| 오류 | 의미 | 대처 |
|---|---|---|
| `discord rate limit` (queued) | Discord가 봇에 속도를 늦추라고 요청했습니다. | 할 일은 없습니다. Mocco가 Discord가 알려 준 시간만큼 기다렸다가 전송합니다. |
| `workspace send limit (per minute) reached` (queued) | 워크스페이스가 1분에 메시지를 120개보다 많이 보냈습니다. Mocco가 나머지를 이후 몇 분에 걸쳐 나눠 보냅니다. | 자주 발생하는 경우가 아니면 할 일은 없습니다. 자주 발생하면 규칙을 줄이거나 필터를 더 좁게 거세요. |
| `Discord did not answer within … ms` 같은 Discord 서버 오류 또는 시간 초과 (queued) | Discord에 일시적인 문제가 있었습니다. | 할 일은 없습니다. Mocco가 간격을 늘려 가며 약 두 시간 동안 재시도하고, 그래도 안 되면 `failed`로 표시합니다. |
| `Discord 403 (code 50001): Missing Access` (failed) | 봇이 채널을 볼 수 없습니다. 채널은 이제 비활성화됩니다. | 봇에 접근 권한을 준([비공개 채널](https://www.mocco.club/docs/ko/articles/9kwifm-connect-discord#give-the-bot-access-to-a-private-channel)) 다음 **Re-enable**을 클릭하세요. |
| `Discord 403 (code 50013): …` (failed) | 봇이 채널을 볼 수는 있지만 권한이 부족합니다. 대개 **Send Messages**나 **Embed Links**입니다. 채널은 이제 비활성화됩니다. | 채널에서 봇에게 **View Channel**, **Send Messages**, **Embed Links**, **Read Message History**를 허용한 다음 **Re-enable**을 클릭하세요. |
| `Discord 404 (code 10003): Unknown Channel` (failed) | Discord에서 채널이 삭제되었습니다. 채널은 이제 비활성화됩니다. | Mocco에서 채널을 삭제하고 다른 채널을 추가하세요. |
| `channel disabled: …` (failed) | 메시지를 보낼 차례가 되었을 때 채널이 이미 비활성화되어 있었습니다. 뒤의 내용은 채널의 비활성화 이유입니다. | 이유를 해결하고 **Re-enable**을 클릭하세요. 이렇게 실패한 메시지는 다시 전송되지 않습니다. |
| `channel deleted` (suppressed) | Mocco에서 채널이 삭제되었습니다. | 할 일은 없습니다. |
| `discord not configured` (queued) | 이 Mocco 배포에는 지금 Discord 봇이 설정되어 있지 않습니다. | Mocco 배포를 운영하는 사람에게 문의하세요. 메시지는 최대 24시간 동안 대기합니다. |
| `discord sender paused (bot token or egress rejected): …` (queued) | Discord가 채널이 아니라 Mocco 봇 자체를 거부했습니다. Mocco가 한 시간 동안 전송을 멈춥니다. | 사용자 쪽에서 할 일은 없습니다. Mocco 팀에 알림이 갑니다. |
| `expired waiting for capacity (…)` (failed) | 메시지가 24시간이 넘게 대기했습니다(속도 제한, Discord 미설정 등). | 대기한 이유(괄호 안의 내용)를 확인하세요. 메시지는 다시 전송되지 않습니다. |
| `the delivery job ended before the delivery settled` (failed) | 이 메시지를 처리하는 Mocco의 백그라운드 작업이 끝나기 전에 중단되었습니다. | 드문 경우입니다. 반복되면 이벤트 시각과 함께 지원팀에 문의하세요. |

## 비활성화된 채널

봇이 채널에 접근할 수 없다고 Discord가 Mocco에 알려 주면 채널은 **Disabled** 상태가 됩니다. 이유는 채널 카드에 표시됩니다. 비활성화된 동안에는 아무것도 전송되지 않습니다.

1. Discord에서 원인을 해결합니다(봇에 접근 권한을 주거나 채널을 복원합니다).
2. Channels 탭에서 **Re-enable**을 클릭합니다. Mocco가 채널을 확인하고 테스트 메시지를 게시합니다.
3. 봇이 여전히 게시하지 못하면 채널은 새 이유와 함께 비활성화된 상태로 남습니다.

Mocco가 Discord를 다시 연결하라고 안내하면, 봇이 서버에서 제거되었거나 제거되었다가 다시 추가된 것입니다. **Connect Discord**를 클릭한 다음 채널을 다시 추가하세요. [Discord 연결하기](https://www.mocco.club/docs/ko/articles/9kwifm-connect-discord)을 참고하세요.

## 소스가 조용해졌을 때

Sources 탭의 **Last received**는 소스가 마지막으로 유효한 전달을 받은 시각을 보여 줍니다. 예상보다 오래되었다면 다음을 확인하세요.

- 소스가 **Paused** 상태일 수 있습니다(이 경우 `404`로 응답합니다).
- 외부 서비스가 반복된 실패 뒤에 웹훅을 비활성화했을 수 있습니다. 그 서비스의 웹훅 설정을 확인하세요.
- Vercel이라면 웹훅이 여전히 해당 프로젝트를 다루는지, 그리고 팀이 웹훅을 지원하는 플랜(Pro 또는 Enterprise)인지 확인하세요.
