# API를 통한 알림 생성

**URL:** https://meta.discourse.org/t/creating-notifications-via-the-api/173769
**Category:** Development
**Tags:** notifications, rest-api
**Created:** [12월 17, 2020, 10:55오전 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769 "2020-12-17T10:55:49Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Mevo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mevo/32/187732_2.png) [@Mevo](https://meta.discourse.org/u/Mevo)
#### Post date: [12월 17, 2020, 10:55오전 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/1 "2020-12-17T10:55:49Z")

</div>

안녕하세요, 간단한 질문 하나만 드리고 싶습니다: API를 통해 사용자에게 알림을 보낼 수 있나요? (또는 다른 방법이 있는지요.)

문서에서는 사용자의 알림을 GET하는 방법과 읽음 처리하는 방법은 찾을 수 있었지만, 알림을 POST하는 방법은 찾지 못했습니다. 불가능하다면, 대신 개인 메시지를 사용하는 방법도 항상 가능할 것 같습니다.

이 부분에 대한 의견이나 조언을 주시면 감사하겠습니다. 감사합니다.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [12월 17, 2020, 2:02오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/2 "2020-12-17T14:02:45Z")

</div>

플러그인이 필요할 것 같아요. 어떤 종류의 알림을 원하시나요? 사용 사례를 설명해 주실 수 있나요?

---

<div class="post-metadata">

### Author: ![Mevo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mevo/32/187732_2.png) [@Mevo](https://meta.discourse.org/u/Mevo)
#### Post date: [12월 17, 2020, 2:15오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/3 "2020-12-17T14:15:37Z")

</div>

보통 외부 서비스의 이메일 알림을 Discourse 알림으로 대체하는 방식입니다. 이 서비스는 회원들에게 무료로 제공됩니다(\*). 이렇게 하면 모든 것을 Discourse로 통합할 수 있고, 포럼에 (정기적으로) 로그인할 유인도 생깁니다. 제가 염두에 둔 아이디어가 바로 이겁니다. 이 아이디어가 합리적인지, 아니면 추론에 결함이 있는지는 확신이 서지 않습니다. 어떤 제안이나 비판도 환영합니다.

[(\*): 회원 = 포럼 참여자. 최소한 포럼에 가입한 사람을 의미합니다. 최소 참여도나 신뢰 수준이 필요한지, 아니면 단순히 가입만으로도 충분한지는 아직 결정되지 않았습니다.]

플러그인이 정보를 받아서 Discourse에서 알림을 트리거하는 방식인가요? 플러그인을 통해 알림을 (더 쉽게) 구현할 수 있나요?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [12월 17, 2020, 3:10오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/4 "2020-12-17T15:10:25Z")

</div>

경로를 추가하고 사용자 ID(또는 이메일 주소), URL, 제목을 전달하면 알림이 생성되는 플러그인을 상상할 수 있습니다. 플러그인 없이는 불가능하다고 생각하지만, 코드를 자세히 살펴본 적은 없습니다.

어제 막 개발 중인 플러그인에 알림 기능을 추가하는 것을 고려하기 시작했기 때문에, 그 작동 방식에 대해 아주 익숙하지는 않습니다.

---

<div class="post-metadata">

### Author: ![renato](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/renato/32/383632_2.png) [@renato](https://meta.discourse.org/u/renato)
#### Post date: [12월 17, 2020, 3:23오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/5 "2020-12-17T15:23:24Z")

</div>

> [@Mevo](#):
>
> 플러그인이 정보를 받아서 Discourse에서 알림을 트리거하는 건가요? 알림은 플러그인에서 (더 쉽게) 처리할 수 있나요?

저도 비슷한 플러그인을 계획하고 있습니다. 제 웹사이트의 이메일이 아닌 알림을 Discourse 중심으로 구성하고, MessageBus를 통해 구독하여 중앙 집중식 푸시 알림 설정을 할 수 있도록 하려는 거죠.

이 스니펫들을 보고 나니 실현 가능하다고 생각합니다. 제 계획은 커스텀 알림을 생성하기 위한 커스텀 엔드포인트를 만드는 것입니다.

커스텀 알림 생성:

> <https://github.com/discourse/discourse-code-review/blob/main/lib/discourse_code_review/state/commit_approval.rb#L168-L173>

알림 목록에서 알림 항목이 어떻게 표시되는지 커스터마이징:  
[https://github.com/discourse/discourse-code-review/blob/master/assets/javascripts/discourse/widgets/code-review-commit-approved-notification-item.js.es6](https://github.com/discourse/discourse-code-review/blob/master/assets/javascripts/discourse/widgets/code-review-commit-approved-notification-item.js.es6)

알림을 생성하는 코어 API가 있었다면, 이 알림 항목 위젯은 테마 컴포넌트로 구현할 수 있을 텐데, 그렇게 하면 훨씬 더 간단할 것 같습니다.

---

<div class="post-metadata">

### Author: ![Mevo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mevo/32/187732_2.png) [@Mevo](https://meta.discourse.org/u/Mevo)
#### Post date: [12월 18, 2020, 2:34오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/6 "2020-12-18T14:34:51Z")

</div>

구현 난이도가 더 복잡해질 수 있는지는 모르겠지만, 알림 생성 기능을 API에 직접 추가하는 것이 합리적이지 않을까요? 팀이 이 제안을 받아들일 수도 있고, **PR을 환영** 할 수도 있습니다(누군가 이 일을 할 수 있고 의사가 있다면).

---

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [12월 18, 2020, 5:38오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/7 "2020-12-18T17:38:42Z")

</div>

아직 문서화가 되어 있지 않지만, [create notification API 엔드포인트](https://github.com/discourse/discourse/blob/d8e2b497f78e2a054406775b4bcde3bcfab8bad1/app/controllers/notifications_controller.rb#L75-L78)가 있습니다:

```plaintext
 POST /notifications(.:format) notifications#create {:format=>/(json|html|\*\/\*)/}

```

직접 만들 필요 없이 [`custom` 알림 유형](https://github.com/discourse/discourse/blob/master/app/models/notification.rb#L103)을 사용하는 것이 가능할 것입니다.

---

<div class="post-metadata">

### Author: ![renato](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/renato/32/383632_2.png) [@renato](https://meta.discourse.org/u/renato)
#### Post date: [12월 18, 2020, 7:04오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/8 "2020-12-18T19:04:55Z")

</div>

정말 좋습니다! 감사합니다.

제가 이해한 대로라면, 엔드포인트에서 `DefaultNotificationItem`를 오버라이드할 필요가 있을 경우, 커스텀 위젷에서 사용할 추가 알림 유형을 등록하기 위해 여전히 플러그인이 필요하다는 뜻인가요?

```ruby
Notification.types[:following] = 800

```

([discourse-follow/plugin.rb at main · discourse/discourse-follow · GitHub](https://github.com/paviliondev/discourse-follow/blob/master/plugin.rb#L23))

`custom` 유형을 사용하면 [https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/widgets/custom-notification-item.js를](https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/widgets/custom-notification-item.js%EB%A5%BC) 통해 렌더링되므로, 목적지 `url`을 오버라이드하려면 여전히 커스텀 위젯이 필요하다는 뜻인가요?

비슷한 시나리오에서 ["custom-notification-item"를 오버라이드하는](https://github.com/Borasification/clothing-deals/blob/master/assets/javascripts/discourse/app/widgets/custom-notification-item.js.es6#L7) 플러그인을 하나 봤는데, `data`에 특정 값이 있을 때만 `url`을 오버라이드하고, 그렇지 않으면 [`this._super.url`](https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/widgets/widget.js#L117)로 폴백하는 것이 안전한가요?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [12월 18, 2020, 10:26오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/9 "2020-12-18T22:26:57Z")

</div>

감사합니다, @renato!

현재 작성한 코드는 다음과 같습니다.

```ruby
Notification.create!(
  notification_type: Notification.types[:custom],
  user_id: 1,
  topic_id: nil,
  post_number: nil,
  high_priority: true,
  data: {
    message: 'pfaffmanager.title',
    display_username: 'pfaffman',
    topic_title: 'my title'
  }.to_json
)

```

알림은 확인되지만, 예상대로 (수정:) 클릭해도 **아무 반응이 없습니다**. 또한 (제가 직접 해보기 전까지는 명확하지 않았습니다) `message`는 임의의 문자열이 아니라 `I18n` 키입니다. … ). 저는 호출한 모델의 URL을 넣을 수 있도록 하고 싶습니다.

---

<div class="post-metadata">

### Author: ![Mevo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mevo/32/187732_2.png) [@Mevo](https://meta.discourse.org/u/Mevo)
#### Post date: [12월 18, 2020, 10:37오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/10 "2020-12-18T22:37:50Z")

</div>

> [@pfaffman](#):
>
> 알림은 보이지만, 예상대로 클릭하면 아무 일도 일어나지 않습니다

아마도 "아무 일도 일어나지 않는다"는 뜻이었을 것 같습니다.  
API를 통해 가입한 URL로 리디렉션되는 링크를 클릭할 수 있다면 정말 훌륭할 텐데요.

---

<div class="post-metadata">

### Author: ![renato](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/renato/32/383632_2.png) [@renato](https://meta.discourse.org/u/renato)
#### Post date: [12월 19, 2020, 2:32오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/11 "2020-12-19T14:32:50Z")

</div>

> [@pfaffman](#):
>
> 제가 원하는 것은 호출한 모델의 URL을 넣을 수 있도록 하는 것입니다.

`data.badge_id`, `topic_id` 또는 `data.group_id`를 채우면 [DefaultNotificationItem](https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/widgets/default-notification-item.js#L34)가 `url`을 자동으로 생성합니다.

> [@renato](#):
>
> `data`에 특정 값이 있는 경우 `url`을 단순히 오버라이드하는 것이 안전한가요?

이 접근 방식을 테스트해 보았고 작동합니다. `data.url`을 채우고 테마 컴포넌트에서 이렇게 사용하세요:

```js
  api.reopenWidget("custom-notification-item", {
      url(data) {
          return data.url || this._super(data);
      }
  })

```

---

<div class="post-metadata">

### Author: ![ootwch](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ootwch/32/141093_2.png) [@ootwch](https://meta.discourse.org/u/ootwch)
#### Post date: [2월 29, 2024, 3:34오전 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/12 "2024-02-29T03:34:53Z")

</div>

이게 어떻게 동작하는지 모르겠네요…

```plaintext
POST https://XXX/notifications
Api-Key:XXX
Api-Username:system
Content-Type:application/json
Accept:application/json

{
    "notification_type":9,
    "user_id": 123,
    "post_number": 1,
    "topic_id": 956,
    "data": {
        "topic_title": "Test",
        "original_post_id": 2222,
        "original_post_type": 1,
        "original_username": "User.Name",
        "revision_number": 1,
        "display_username": "Text"
            }

}

```

응답으로 다음을 받습니다:

```plaintext

{
  "errors": [
    "Data can't be blank"
  ],
  "error_type": "record_invalid"
}

```

포맷 오류인가요? 아니면 오해인가요? 아니면 `data`에서 뭔가 빠진 건가요?

웹에서 이걸 역추적하는 건 정말 어렵습니다 - 아니면 이 API가 어딘가에서 호출되고 있는 건가요?

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [2월 29, 2024, 6:38오후 UTC](https://meta.discourse.org/t/creating-notifications-via-the-api/173769/13 "2024-02-29T18:38:19Z")

</div>

`data` 값을 인코딩해야 합니다.

예:

```json
"data": "{\"topic_title\":\"Test\",\"original_post_id\":2222,\"original_post_type\":1,\"original_username\":\"User.Name\",\"revision_number\":1,\"display_username\":\"Text\"}"

```
