> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 웹 SDK 참조

> 초기화, 사용자 관리, 푸시 알림, 슬라이드다운 프롬프트 및 디버깅 메서드를 포함한 OneSignal 웹 SDK v16의 완벽한 API 참조입니다. 웹 푸시 알림을 구현하고, 사용자 구독을 관리하고, 이메일/SMS 기능을 통합하는 방법을 알아보세요.

## 설정 및 디버깅

OneSignal 호출을 `OneSignalDeferred.push(async function() { ... })`로 래핑해야 할 수 있습니다.

`function()`에 원하는 만큼 많은 메서드를 추가할 수 있습니다.

OneSignal SDK는 페이지에서 `defer` 속성과 함께 로드됩니다. 예를 들어:

`<script src="https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js" defer></script>`

이것은 OneSignal 코드가 HTML 문서가 완전히 구문 분석된 후에 실행되어 OneSignal SDK에 의한 사이트 차단을 방지한다는 것을 의미합니다. 그러나 이것은 `OneSignalDeferred` 변수의 존재에 의존하는 페이지 스크립트에 문제를 제기합니다. 이를 해결하려면 사이트에 OneSignal을 추가할 때 다음으로 시작해야 합니다:

`window.OneSignalDeferred = window.OneSignalDeferred || [];`

이것은 `OneSignalDeferred` 변수를 생성하며, OneSignal이 이미 로드된 경우 로드된 인스턴스에 할당됩니다. 그렇지 않으면 OneSignal 변수는 빈 배열 `[]`과 같습니다.

모든 배열에는 [`.push() 함수`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push)가 있으므로 이 시점에서 `OneSignalDeferred` 변수는 단순히 우리가 푸시하는 함수의 배열입니다. SDK가 최종적으로 로드되면 SDK는 [지금까지 푸시된 모든 함수를 처리하고 .push()를 재정의합니다](https://github.com/OneSignal/OneSignal-Website-SDK/blob/03cd16cacb79ff6d37156878d4f59ebf31ad8044/src/OneSignal.js#L2050).

### `init()`

OneSignal SDK를 초기화합니다. 사이트의 각 페이지에서 `<head>` 태그에 한 번 호출되어야 합니다. `ONESIGNAL_APP_ID`는 [키 및 ID](./keys-and-ids)에서 찾을 수 있습니다.

<Note>
  OneSignal SDK의 초기화를 지연하려면 [개인 정보 보호 메서드](#privacy)를 사용하는 것이 좋습니다.
</Note>

<CodeGroup>
  ```javascript JavaScript theme={null}
  window.OneSignalDeferred = window.OneSignalDeferred || [];
  OneSignalDeferred.push(async function(OneSignal) {
    await OneSignal.init({
      appId: "ONESIGNAL_APP_ID",
    });
  });
  ```
</CodeGroup>

<Warning>
  Init 옵션은 [사용자 지정 코드 설정](./web-push-custom-code-setup)에서만 작동합니다. 그렇지 않으면 OneSignal 대시보드에서 구성됩니다.
</Warning>

|               매개변수               |    타입   | 설명                                                                                                                    |
| :------------------------------: | :-----: | --------------------------------------------------------------------------------------------------------------------- |
|              `appId`             |  String | **필수:** [키 및 ID](./keys-and-ids)에서 찾을 수 있는 OneSignal 앱 ID입니다.                                                         |
|   `requiresUserPrivacyConsent`   | Boolean | 사용자가 개인 정보 동의를 제공할 때까지 SDK 초기화를 지연합니다. 설정을 완료하려면 [`setConsentGiven()`](#setconsentgiven)을 호출해야 합니다.                   |
|          `safari_web_id`         |  String | 업로드된 Safari `.p12` 인증서의 Safari 웹 ID입니다. [웹 빠른 시작](./web-push-setup).                                                  |
|          `promptOptions`         |  Object | 권한 프롬프트를 사용자 지정합니다. [아래 세부 정보](#promptoptions-parameters).                                                            |
|          `notifyButton`          |  Object | 구독 벨을 활성화하고 구성합니다. [아래 세부 정보](#notifybutton-parameters).                                                              |
|       `welcomeNotification`      |  Object | 환영 알림을 사용자 지정하거나 비활성화합니다. [아래 세부 정보](#welcomenotification-parameters).                                                |
|       `persistNotification`      | Boolean | Chrome(데스크톱 전용) - `true`: 클릭할 때까지 알림이 지속됨, `false`: 짧은 시간 후 사라짐. Firefox/Safari는 이 설정을 무시합니다.                         |
|            `webhooks`            |  Object | 이벤트 콜백을 구성합니다. [웹훅 참조](./webhooks).                                                                                   |
|         `autoResubscribe`        | Boolean | **권장:** 브라우저 캐시를 지우거나 OneSignal로 마이그레이션하는 사용자를 자동으로 재구독합니다. 코드에서 사용하면 대시보드 설정을 재정의합니다.                                |
|  `notificationClickHandlerMatch` |  String | `"exact"`(기본값): 정확한 URL 일치가 있는 탭에 포커스를 맞춥니다. `"origin"`: 동일한 도메인의 모든 탭에 포커스를 맞춥니다.                                    |
| `notificationClickHandlerAction` |  String | `"navigate"`(기본값): `launchURL`로 이동합니다. `"focus"`: 기존 탭에 포커스를 맞춥니다(`"origin"` 일치에서만 사용됨).                              |
|       `serviceWorkerParam`       |  Object | Service Worker의 `scope`를 설정합니다. 해당하는 경우 다른 Service Worker의 범위와 달라야 합니다. 예:<br />`{ scope: "/myPath/myCustomScope/" }` |
|        `serviceWorkerPath`       |  String | OneSignal Service Worker 파일의 위치를 설정합니다. 예:<br />`"myPath/OneSignalSDKWorker.js"`                                      |

***

#### `promptOptions` 매개변수

`promptOptions`를 사용하여 사용자 권한 프롬프트를 현지화하거나 사용자 지정합니다. 모든 필드는 선택 사항입니다.

|     매개변수     |        타입        | 설명                                                                                                                                                                                                                                                                               |
| :----------: | :--------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|  `slidedown` |      Object      | 구성 옵션이 있는 `prompts` 배열을 포함합니다.                                                                                                                                                                                                                                                   |
|   `prompts`  | Array of Objects | 프롬프트 구성의 배열입니다. 예:<br />`"slidedown": { "prompts": [{...}, {...}] }`                                                                                                                                                                                                             |
|    `type`    |      String      | 프롬프트 유형:<br /><ul><li>`push` – 슬라이드 프롬프트(카테고리 없음)</li><li>`category` – 최대 10개 카테고리가 있는 슬라이드 프롬프트</li><li>`email` – 이메일만 수집</li><li>`sms` – 전화번호만 수집</li><li>`smsAndEmail` – 둘 다 수집</li></ul>[웹 권한 프롬프트](./permission-requests) 참조.                                               |
| `autoPrompt` |      Boolean     | <ul><li>`true`: `delay`에 따라 표시합니다.</li><li>`false`: 슬라이드다운 API를 통해 수동으로만 프롬프트가 표시됩니다.</li></ul>                                                                                                                                                                                  |
|    `delay`   |      Object      | 자동 프롬프트가 표시되는 시기를 제어합니다:<br />`{ pageViews: 3, timeDelay: 20 }` = 3번째 페이지뷰 및 20초 대기 후 표시합니다.                                                                                                                                                                                     |
|    `text`    |      Object      | 사용자 지정 텍스트 옵션:<br /><ul><li>`actionMessage`(최대 90자)</li><li>`acceptButton`(최대 15자)</li><li>`cancelButton`(최대 15자)</li><li>`emailLabel`, `smsLabel`, `confirmMessage`</li><li>`updateMessage`, `positiveUpdateButton`, `negativeUpdateButton`(카테고리 또는 연락처 정보 업데이트에 사용됨)</li></ul> |
| `categories` | Array of Objects | `type: category`에만 해당합니다. 각 객체에는 다음이 포함됩니다:<br />`tag`: 내부 키<br />`label`: 사용자에게 표시되는 이름<br />예: `[ {tag: "local_news", label: "Local News"} ]`. [데이터 태그](./add-user-data-tags) 참조.                                                                                              |

***

#### `notifyButton` 매개변수

페이지에 표시되는 구독 벨(알림 버튼)을 구성합니다.

|        매개변수        |    타입    | 설명                                                                              |
| :----------------: | :------: | ------------------------------------------------------------------------------- |
|      `enable`      |  Boolean | 구독 벨을 활성화합니다. 기본적으로 비활성화되어 있습니다.                                                |
| `displayPredicate` | Function | 벨을 표시/숨기기 위해 `true` 또는 `false`를 반환하는 사용자 지정 함수(또는 Promise)입니다. 표시될 때 한 번 평가됩니다. |
|       `size`       |  String  | `'small'`, `'medium'` 또는 `'large'`. 구독 후 `'small'`로 축소됩니다.                      |
|     `position`     |  String  | `'bottom-left'` 또는 `'bottom-right'`.                                            |
|      `offset`      |  Object  | CSS 픽셀 오프셋: `{ bottom: '50px', left: '10px' }`                                  |
|     `prenotify`    |  Boolean | `true`인 경우 "읽지 않은 항목 1개" 아이콘과 사용자 지정 호버 텍스트를 표시합니다.                             |
|    `showCredit`    |  Boolean | 팝업에서 "Powered by OneSignal"을 숨기려면 `false`로 설정합니다.                               |
|       `text`       |  Object  | 벨 UI의 사용자 지정 텍스트입니다.                                                            |

***

#### `welcomeNotification` 매개변수

최초 구독 후 전송되는 환영 알림을 사용자 지정합니다.

|    매개변수   |    타입   | 설명                                                             |
| :-------: | :-----: | -------------------------------------------------------------- |
| `disable` | Boolean | 환영 알림을 비활성화합니다.                                                |
| `message` |  String | **필수:** 알림 메시지입니다. 비어 있으면 `'Thanks for subscribing!'`이 기본값입니다. |
|  `title`  |  String | 알림 제목입니다. 사이트 제목이 기본값입니다. 제거하려면 `' '`(공백)를 사용하세요(권장하지 않음).     |
|   `url`   |   URL   | 사용자가 알림을 클릭할 때 열 선택적 URL입니다. 일반적으로 필요하지 않습니다.                  |

***

**예시:**

<CodeGroup>
  ```javascript 사용자 지정 코드 설정을 위한 init 예시 theme={null}
  <script src="https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js" defer></script>
  <script>
  window.OneSignalDeferred = window.OneSignalDeferred || [];
  OneSignalDeferred.push(async function(OneSignal) {
    await OneSignal.init({
      appId: "YOUR_APP_ID",
      safari_web_id: "YOUR_SAFARI_WEB_ID",
      notifyButton: {
        enable: true,
      },
      promptOptions: {
        slidedown: {
          prompts: [{
              type: "smsAndEmail",
              autoPrompt: false,
              text: {
                emailLabel: "Insert Email Address",
                smsLabel: "Insert Phone Number",
                acceptButton: "Submit",
                cancelButton: "No Thanks",
                actionMessage: "Receive the latest news, updates and offers as they happen.",
                updateMessage: "Update your push notification subscription preferences.",
                confirmMessage: "Thank You!",
                positiveUpdateButton: "Save Preferences",
                negativeUpdateButton: "Cancel",
              },
              delay: {
                pageViews: 1,
                timeDelay: 20
              },
            },
            {
              type: "category",
              autoPrompt: true,
              text: {
                actionMessage: "We'd like to show you notifications for the latest news and updates.",
                acceptButton: "Allow",
                cancelButton: "Cancel",

                /* CATEGORY SLIDEDOWN SPECIFIC TEXT */
                negativeUpdateButton: "Cancel",
                positiveUpdateButton: "Save Preferences",
                updateMessage: "Update your push notification subscription preferences.",
              },
              delay: {
                pageViews: 3,
                timeDelay: 20
              },
              categories: [{
                  tag: "politics",
                  label: "Politics"
                },
                {
                  tag: "local_news",
                  label: "Local News"
                },
                {
                  tag: "world_news",
                  label: "World News",
                },
                {
                  tag: "culture",
                  label: "Culture"
                },
              ]
            }
          ]
        }
      }
    });
  });
  </script>
  ```
</CodeGroup>

### `setLogLevel()`

콘솔에 추가 로그를 출력하도록 로깅을 설정합니다. 자세한 내용은 [브라우저 DevTools로 디버깅](./troubleshooting-web-push#debugging-using-browser-developer-tools)을 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Debug.setLogLevel('trace');
```

**로그 레벨:**

* `'trace'`
* `'debug'`
* `'info'`
* `'warn'`
* `'error'`

***

## 사용자 신원 및 속성

사용자가 웹사이트에서 푸시 알림에 구독하면 OneSignal은 자동으로 OneSignal ID(사용자 수준) 및 구독 ID(기기 수준)를 생성합니다. 고유한 사용자 식별자로 `login()`을 호출하여 여러 구독(예: 기기, 이메일, 전화번호)을 단일 사용자와 연결할 수 있습니다.

<Note>
  자세한 내용은 [사용자](./users) 및 [별칭](./aliases)을 참조하세요.
</Note>

### `login(external_id)`

제공된 `external_id`로 사용자 컨텍스트를 설정합니다. 이 `external_id`와 연결된 모든 구독 및 속성이 단일 `onesignal_id` 아래에 통합되도록 합니다. 자세한 내용은 [사용자](./users)를 참조하세요.

**주요 동작:**

* `external_id`가 이미 존재하는 경우 SDK는 해당 사용자로 전환합니다. 로그인 전에 수집된 익명 데이터는 병합되지 않으며 삭제됩니다.
* `external_id`가 존재하지 않는 경우 로컬 상태가 현재 `onesignal_id` 아래에 저장됩니다. 사용자가 익명이었을 때 수집된 모든 데이터가 유지됩니다.
* SDK는 네트워크 장애 또는 서버 오류 시 자동으로 재시도합니다.

<Note> 사용자가 사이트를 열 때마다 또는 [구독 변경 리스너](#addeventlistener-push-subscription-changes) 내에서 이 메서드를 호출하여 [외부 ID](./users#external-id)가 설정되고 구독이 사용자에게 연결되도록 하세요. </Note>

<CodeGroup>
  ```javascript JavaScript theme={null}
  OneSignalDeferred.push(async function(OneSignal) {
     await OneSignal.login("external_id");
  });
  ```

  ```javascript 구독 변경과 함께 로그인 theme={null}
  //푸시 구독 변경 이벤트와 결합하는 예시
  function pushSubscriptionChangeListener(event) {
    if (event.current.token) {
      console.log(`The push subscription has received a token!`);
      //OneSignal.login을 호출하고 사용자 ID를 전달하기에 좋은 곳입니다
      OneSignal.login("external_id");
    }
  }
  OneSignalDeferred.push(function(OneSignal) {
    OneSignal.User.PushSubscription.addEventListener("change", pushSubscriptionChangeListener);
  });
  ```
</CodeGroup>

### `logout()`

현재 사용자를 구독에서 연결 해제합니다.

* 현재 푸시 구독에서 `external_id`를 제거합니다.
* OneSignal ID를 새 익명 사용자로 재설정합니다.
* 새 데이터(예: 태그, 구독, 세션 데이터 등)는 이제 `login` 메서드로 식별될 때까지 새 익명 사용자에게 설정됩니다.

<Note>사용자가 앱에서 로그아웃할 때 구독을 새 익명 사용자로 설정하려면 이것을 사용하세요. </Note>

```javascript JavaScript theme={null}
  OneSignalDeferred.push(async function(OneSignal) {
     await OneSignal.logout();
  });
```

### `OneSignal.User.onesignalId`

브라우저에 로컬로 저장된 현재 사용자의 OneSignal ID를 검색합니다. 사용자 상태가 초기화되기 전에 호출되면 `null`일 수 있습니다. 대신 [사용자 상태 `addObserver()`](#addeventlistener-user-state)를 사용하여 사용자 상태 변경을 수신하세요.

```javascript JavaScript theme={null}
  OneSignal.User.onesignalId
```

### `OneSignal.User.externalId`

브라우저에 로컬로 저장된 현재 사용자의 외부 ID를 검색합니다. `login` 메서드를 통해 설정되지 않았거나 사용자 상태가 초기화되기 전에 호출되면 `null`일 수 있습니다. 대신 [사용자 상태 `addObserver()`](#addeventlistener-user-state)를 사용하여 사용자 상태 변경을 수신하세요.

```javascript JavaScript theme={null}
  OneSignal.User.externalId
```

### `addEventListener()` *사용자 상태*

사용자 컨텍스트의 변경(예: 로그인, 로그아웃, ID 할당)을 수신합니다.

```javascript JavaScript theme={null}
  OneSignalDeferred.push(function() {
    OneSignal.User.addEventListener('change', function (event) {
      console.log('change', { event });
    });
  });
```

### `addAlias()`, `addAliases()`, `removeAlias()`, `removeAliases()`

별칭은 대체 식별자입니다(사용자 이름 또는 CRM ID 등).

* 별칭을 추가하기 전에 `login()`으로 `external_id`를 설정하세요. `external_id` 없이 구독에 추가된 별칭은 여러 구독에서 동기화되지 않습니다.
* 자세한 내용은 [별칭](./aliases)을 참조하세요.

```javascript JavaScript theme={null}
  // Add a single alias
  OneSignal.User.addAlias("ALIAS_LABEL", "ALIAS_ID");

  // Add multiple aliases
  OneSignal.User.addAliases({
    ALIAS_LABEL_01: "ALIAS_ID_01",
    ALIAS_LABEL_02: "ALIAS_ID_02",
    ALIAS_LABEL_03: "ALIAS_ID_03",
  });

  // Remove a single alias
  OneSignal.User.removeAlias("ALIAS_LABEL");

  // Remove multiple aliases
  OneSignal.User.removeAliases(["ALIAS_LABEL_01", "ALIAS_LABEL_02", "ALIAS_LABEL_03"]);
```

### `getLanguage()`, `setLanguage()`

사용자의 자동 감지된 언어를 가져오거나 재정의합니다. 사용 가능한 언어 코드 목록은 [다국어 메시징](./multi-language-messaging)을 참조하세요.

```javascript JavaScript theme={null}
  // 현재 로그인한 사용자의 언어 가져오기
  OneSignal.User.getLanguage()

  // 현재 로그인한 사용자의 언어 설정
  OneSignal.User.setLanguage('en')
```

***

## 사용자 지정 이벤트

[사용자 지정 이벤트](./custom-events)를 통해 [여정 트리거](./journeys-settings#custom-events) 및 [대기 단계 활성화](./journeys-actions#wait-until)를 수행합니다.

<Note>
  사용자 지정 이벤트에는 웹 SDK `160500`+ 이상이 필요합니다

  사용자 지정 이벤트를 추적하려면 사용자가 로그인되어 있어야 합니다.
</Note>

현재 사용자가 수행한 사용자 지정 이벤트를 추적하고 전송합니다.

* `name` - **필수.** 문자열로 된 이벤트 이름입니다.
* `properties` - **선택 사항.** 이벤트에 추가할 키-값 쌍입니다. 속성 사전 또는 맵은 유효한 JSON 객체로 직렬화할 수 있어야 합니다. 중첩된 값을 지원합니다.

SDK는 예약된 키 `os_sdk` 아래의 속성 페이로드에 앱별 데이터를 자동으로 포함하며 이를 사용할 수 있습니다. 예를 들어 구독 유형별로 이벤트를 타겟팅하려면 `os_sdk.type`에 액세스합니다.

```json json theme={null}
{
  "os_sdk": {
    "device_os": "138",
    "type": "ChromePush",
    "device_model": "MacIntel",
    "sdk": "160500"
  }
}
```

### `trackEvent()`

```javascript JavaScript theme={null}
const properties = {
  "promo_code": "NEW50",
  "membership_details": {
     "vip": true,
     "products_viewed_count": 15,
  }
}
window.OneSignal.User.trackEvent('started_free_trial', properties);

// 추가 속성 없이 이름으로만 이벤트를 추적할 수도 있습니다
window.OneSignal.User.trackEvent('my_event_name');
```

***

## 데이터 태그

태그는 이벤트 또는 사용자 속성을 기반으로 사용자에게 설정하는 사용자 지정 `key : value` 쌍의 문자열 데이터입니다. 자세한 내용은 [데이터 태그](./add-user-data-tags)를 참조하세요.

### `addTag()`, `addTags()`

현재 사용자에게 단일 또는 여러 태그를 설정합니다.

* 키가 이미 존재하는 경우 값이 교체됩니다.
* 플랜의 태그 제한을 초과하면 작업이 자동으로 실패합니다.

```javascript JavaScript theme={null}
  // 단일 태그 추가
  OneSignal.User.addTag('tag_key', 'tag_value');

  // 여러 태그 추가
  OneSignal.User.addTags({
   KEY_01: "VALUE_01",
   KEY_02: "VALUE_02",
   KEY_03: "VALUE_03"
  });
```

### `removeTag()`, `removeTags()`

현재 사용자에서 단일 또는 여러 태그를 삭제합니다.

```javascript JavaScript theme={null}
  // 단일 태그 삭제
  OneSignal.User.removeTag("KEY");

  OneSignal.User.removeTags(['KEY_01', 'KEY_02', 'KEY_03']);
```

### `getTags()`

사용자 태그의 로컬 복사본을 반환합니다. 태그는 `login()` 또는 새 앱 세션 중에 서버에서 업데이트됩니다.

```javascript JavaScript theme={null}
  const tags = OneSignal.User.getTags()
```

***

## 개인 정보 보호

### `setConsentRequired()`

데이터 수집이 시작되기 전에 사용자 동의를 시행합니다. **SDK를 초기화하기 전에** 호출해야 합니다.

이 메서드는 `init` 메서드에 `requiresUserPrivacyConsent: true`를 추가하는 것과 동일합니다.

```javascript JavaScript theme={null}
  OneSignal.setConsentRequired(true);
```

### `setConsentGiven()`

데이터 수집에 대한 사용자 동의를 부여하거나 취소합니다. 동의 없이는 OneSignal로 데이터가 전송되지 않으며 구독이 생성되지 않습니다.

* [`setConsentRequired()`](#setconsentrequired) 또는 `requiresUserPrivacyConsent`가 `true`로 설정된 경우 `setConsentGiven`이 `true`로 호출될 때까지 SDK가 완전히 활성화되지 않습니다.
* `setConsentGiven`이 `true`로 설정되고 구독이 생성된 후 나중에 `false`로 설정되면 해당 구독은 더 이상 업데이트를 받지 않습니다. 해당 구독의 현재 데이터는 `setConsentGiven`이 다시 `true`로 설정될 때까지 변경되지 않습니다.
* 사용자 및/또는 구독 데이터를 삭제하려면 [사용자 삭제](/reference/delete-user) 또는 [구독 삭제](/reference/delete-subscription) API를 사용하세요.

```javascript JavaScript theme={null}
  OneSignal.setConsentGiven(true);
```

***

## 구독

자세한 내용은 [구독](./subscriptions)을 참조하세요.

### `User.PushSubscription.id`

브라우저에 로컬로 저장된 현재 사용자의 푸시 구독 ID를 검색합니다. 너무 일찍 호출되면 `null`을 반환할 수 있습니다. 변경 사항에 반응하려면 [구독 관찰자](#addeventlistener-push-subscription-changes) 내에서 이 데이터를 가져오는 것이 좋습니다.

```javascript JavaScript theme={null}
  OneSignal.User.PushSubscription.id;
```

### `User.PushSubscription.token`

현재 푸시 구독 토큰을 반환합니다. 너무 일찍 호출되면 `null`을 반환할 수 있습니다. 변경 사항에 반응하려면 [구독 관찰자](#addeventlistener-push-subscription-changes) 내에서 이 데이터를 가져오는 것이 좋습니다.

```javascript JavaScript theme={null}
  OneSignal.User.PushSubscription.token;
```

### `addEventListener()` *푸시 구독 변경*

다음과 같은 푸시 구독 변경에 응답하려면 이 메서드를 사용하세요:

* 기기가 Google(FCM) 또는 Apple(APNs)에서 새 푸시 토큰을 받습니다
* OneSignal이 구독 ID를 할당합니다
* `optedIn` 값이 변경됩니다(예: `optIn()` 또는 `optOut()` 호출)
* 사용자가 시스템 설정에서 푸시 권한을 토글한 다음 앱을 엽니다

이런 일이 발생하면 SDK가 `onPushSubscriptionChange` 이벤트를 트리거합니다. 리스너는 `previous` 및 `current` 값이 있는 상태 객체를 수신하므로 정확히 무엇이 변경되었는지 감지할 수 있습니다.

업데이트 수신을 중지하려면 연결된 `removeObserver()` 또는 `removeEventListener()` 메서드를 호출하세요.

```javascript JavaScript theme={null}
  function pushSubscriptionChangeListener(event) {
    console.log("event.previous.id", event.previous.id);
    console.log("event.current.id", event.current.id);
    console.log("event.previous.token", event.previous.token);
    console.log("event.current.token", event.current.token);
    console.log("event.previous.optedIn", event.previous.optedIn);
    console.log("event.current.optedIn", event.current.optedIn);
  }

  OneSignalDeferred.push(function(OneSignal) {
    OneSignal.User.PushSubscription.addEventListener("change", pushSubscriptionChangeListener);
  });
```

### `optOut()`, `optIn()`, `optedIn`

현재 푸시 구독의 구독 상태(`subscribed` 또는 `unsubscribed`)를 제어합니다. 이러한 메서드를 사용하여 사이트에서 푸시 구독 상태를 제어하세요. 일반적인 사용 사례: 1) 로그아웃하는 사용자에게 푸시가 전송되지 않도록 방지. 2) 사이트 내에서 알림 기본 설정 센터 구현.

* `optOut()`: 현재 푸시 구독 상태를 구독 취소로 설정합니다(사용자에게 유효한 푸시 토큰이 있더라도).
* `optIn()`: 다음 세 가지 작업 중 하나를 수행합니다:
  1. 구독에 유효한 푸시 토큰이 있는 경우 현재 푸시 구독 상태를 `subscribed`로 설정합니다.
  2. 구독에 유효한 푸시 토큰이 없는 경우 푸시 권한 프롬프트를 표시하려고 시도합니다.
* `optedIn`: 현재 푸시 구독 상태가 구독된 경우 `true`를 반환하고 그렇지 않으면 `false`를 반환합니다. 푸시 토큰이 유효하지만 `optOut()`이 호출된 경우 `false`를 반환합니다.

```javascript JavaScript theme={null}
  OneSignal.User.PushSubscription.optOut();

  OneSignal.User.PushSubscription.optIn();

  var optedIn = OneSignal.User.PushSubscription.optedIn;
```

### `addEmail()`, `removeEmail()`

현재 사용자에게 이메일 구독(이메일 주소)을 추가하거나 제거합니다. 올바른 사용자 컨텍스트를 설정하려면 `login()` 후에 `addEmail`을 호출하세요. [ID 확인](./identity-verification)과 호환됩니다.

```javascript JavaScript theme={null}
  OneSignal.User.addEmail("example@email.com");

  OneSignal.User.removeEmail("example@email.com");
```

### `addSms()`, `removeSms()`

현재 사용자에게 SMS 구독(전화번호)을 추가하거나 제거합니다. [E.164 형식](https://www.twilio.com/docs/glossary/what-e164)이 필요합니다. 올바른 사용자 컨텍스트를 설정하려면 `login()` 후에 `addSms`를 호출하세요. [ID 확인](./identity-verification)과 호환됩니다.

```javascript JavaScript theme={null}
  OneSignal.User.addSms("+15558675309");

  OneSignal.User.removeSms("+15558675309");
```

***

## 슬라이드다운 프롬프트

사이트에 다양한 슬라이드다운 프롬프트를 표시합니다. 자세한 내용은 [웹 권한 프롬프트](./permission-requests)를 참조하세요.

* 해제되면 향후 호출은 최소 3일 동안 무시됩니다. 추가 거부는 사용자에게 다시 프롬프트를 표시하기 전에 경과해야 하는 시간을 늘립니다.
* 백오프 동작을 재정의하려면 메서드에 `{force: true}`를 전달하세요. 그러나 좋은 사용자 경험을 제공하려면 버튼 클릭과 같은 UI 시작 이벤트에 작업을 바인딩하세요.

<Warning>
  구독에 필요한 기본 브라우저 프롬프트를 대체하지 않습니다. 기본 브라우저 프롬프트를 사용하여 권한을 얻어야 합니다.
</Warning>

### `promptPush()`

푸시 알림에 대한 일반 슬라이드다운 프롬프트를 표시합니다.

* 카테고리를 사용하는 경우 대신 [`promptPushCategories()`](#promptpushcategories)를 호출하세요.
* OneSignal에서 설정한 백오프 로직의 적용을 받습니다. 자세한 내용은 [웹 권한 프롬프트](./permission-requests#auto-prompt-%26-display-settings)를 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Slidedown.promptPush();
  // 테스트하는 동안 백오프 로직을 우회하려면 {force: true}를 전달하세요
  //OneSignal.Slidedown.promptPush({force: true});
```

### `promptPushCategories()`

카테고리 슬라이드다운 프롬프트를 표시하여 사용자가 태그를 업데이트할 수 있도록 합니다. 또한 사용자가 아직 권한을 부여하지 않은 경우 기본 알림 권한 프롬프트를 트리거합니다.

* 카테고리를 사용하지 않는 경우 대신 [`promptPush()`](#promptpush)를 호출하세요.
* OneSignal에서 설정한 백오프 로직의 적용을 받습니다. 자세한 내용은 [웹 권한 프롬프트](./permission-requests#auto-prompt-%26-display-settings)를 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Slidedown.promptPushCategories();
  // 테스트하는 동안 백오프 로직을 우회하려면 {force: true}를 전달하세요
  //OneSignal.Slidedown.promptPushCategories({force: true});
```

### `promptSms()`

SMS 구독 프롬프트를 표시합니다.

* OneSignal에서 설정한 백오프 로직의 적용을 받습니다. 자세한 내용은 [웹 권한 프롬프트](./permission-requests#auto-prompt-%26-display-settings)를 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Slidedown.promptSms();
  // 테스트하는 동안 백오프 로직을 우회하려면 {force: true}를 전달하세요
  //OneSignal.Slidedown.promptSms({force: true});
```

### `promptEmail()`

이메일 구독 프롬프트를 표시합니다.

* OneSignal에서 설정한 백오프 로직의 적용을 받습니다. 자세한 내용은 [웹 권한 프롬프트](./permission-requests#auto-prompt-%26-display-settings)를 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Slidedown.promptEmail();
  // 테스트하는 동안 백오프 로직을 우회하려면 {force: true}를 전달하세요
  //OneSignal.Slidedown.promptEmail({force: true});
```

### `promptSmsAndEmail()`

SMS 및 이메일 구독 프롬프트를 동시에 표시합니다.

* OneSignal에서 설정한 백오프 로직의 적용을 받습니다. 자세한 내용은 [웹 권한 프롬프트](./permission-requests#auto-prompt-%26-display-settings)를 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Slidedown.promptSmsAndEmail();
  // 테스트하는 동안 백오프 로직을 우회하려면 {force: true}를 전달하세요
  //OneSignal.Slidedown.promptSmsAndEmail({force: true});
```

### `addEventListener()` *슬라이드다운*

슬라이드다운 프롬프트 표시 이벤트를 감지하기 위한 콜백을 추가합니다.

```javascript JavaScript theme={null}
  OneSignalDeferred.push(function(OneSignal) {

    OneSignal.Slidedown.addEventListener('slidedownShown', function (event) {
      console.log('slidedownShown', { event });
    });

  });
```

***

## 푸시 알림

### `requestPermission()`

기본 브라우저 프롬프트를 통해 푸시 알림 권한을 요청합니다. 브라우저에서 설정한 백오프 로직의 적용을 받습니다. 자세한 내용은 [웹 권한 프롬프트](./permission-requests#native-permission-prompt)를 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Notifications.requestPermission();
```

### `isPushSupported()`

현재 브라우저가 웹 푸시를 지원하는 경우 `true`를 반환합니다.

```javascript JavaScript theme={null}
  const isSupported = OneSignal.Notifications.isPushSupported();
```

### `OneSignal.Notifications.permission`

알림을 표시할 사이트의 현재 권한을 나타내는 부울을 반환합니다.

* `true`: 사용자가 알림을 표시할 권한을 부여했습니다.
* `false`: 사용자가 알림을 표시할 권한을 거부했거나 아직 부여하지 않았습니다.

이것은 사이트의 권한일 뿐이며 OneSignal의 `optOut` 상태나 구독 ID 및 푸시 토큰의 존재를 고려하지 않습니다. 이에 대해서는 `OneSignal.User.PushSubscription`을 참조하세요.

권한 변경을 수신하려면 [`permissionChange`](#permissionchange) 이벤트를 사용하세요.

```javascript JavaScript theme={null}
  let permission = OneSignal.Notifications.permission;
```

### `addEventListener()` *알림*

알림 이벤트에 이벤트 핸들러를 연결하여 알림 수명 주기에 연결할 수 있습니다. `addEventListener`를 호출하면 알림 이벤트에 대해 임의의 수의 이벤트 핸들러를 추가할 수 있습니다.

이벤트 수신을 중지하려면 연결된 `removeEventListener()` 메서드를 호출하세요.

```javascript JavaScript theme={null}
  function eventListener(event) {
    console.log(`${event}`);
  }

  OneSignal.Notifications.addEventListener("event", eventListener);

  OneSignal.Notifications.removeEventListener("event", eventListener);
```

#### `permissionChange`

이 이벤트는 사용자가 허용 또는 차단을 클릭하거나 브라우저의 기본 권한 요청을 해제할 때 발생합니다.

```javascript JavaScript theme={null}
  function permissionChangeListener(permission) {
    if (permission) {
      console.log(`permission accepted!`);
    }
  }

  OneSignal.Notifications.addEventListener("permissionChange", permissionChangeListener);
```

#### `permissionPromptDisplay`

이 이벤트는 브라우저의 기본 권한 요청이 방금 표시되었을 때 발생합니다.

```javascript JavaScript theme={null}
  function promptListener() {
    console.log(`permission prompt dispslayed event: ${event}`);
  }

  OneSignal.Notifications.addEventListener("permissionPromptDisplay", promptListener);
```

#### `click`

이 이벤트는 알림의 본문/제목 또는 작업 버튼이 클릭될 때 발생합니다.

```javascript JavaScript theme={null}
  function clickEventListener(event) {
    console.log(`click event: ${event}`);
  }

  OneSignal.Notifications.addEventListener("click", clickEventListener);
```

#### `foregroundWillDisplay`

이 이벤트는 알림이 표시되기 전에 발생합니다. 이 이벤트는 페이지에서 발생합니다. 사이트에서 여러 브라우저 탭이 열려 있는 경우 이 이벤트는 OneSignal이 활성화된 *모든* 페이지에서 발생합니다.

```javascript JavaScript theme={null}
  function foregroundWillDisplayListener(event) {
    console.log(`notification will display: ${notification}`);
  }

  OneSignal.Notifications.addEventListener("foregroundWillDisplay", foregroundWillDisplayListener);
```

#### `dismiss`

이 이벤트는 다음과 같은 경우에 발생합니다:

* 사용자가 알림 본문 또는 작업 버튼을 클릭하지 않고 의도적으로 알림을 해제합니다
* Android의 Chrome에서 사용자가 모든 웹 푸시 알림을 해제합니다(이 이벤트는 표시하는 각 웹 푸시 알림에 대해 발생합니다)
* 알림이 자체적으로 만료되어 사라집니다

<Info>
  이 이벤트는 사용자가 알림 본문이나 작업 버튼 중 하나를 클릭하면 *발생하지 않습니다*. 그것은 알림 `click` 이벤트로 간주됩니다.
</Info>

```javascript JavaScript theme={null}
  function notificationDismissedListener(event) {
    console.log(`dismiss event: ${event}`);
  }

  OneSignal.Notifications.addEventListener("dismiss", notificationDismissedListener);
```

### `setDefaultUrl()`

알림의 기본 URL을 설정합니다.

기본 URL을 설정하지 않은 경우 알림은 기본적으로 사이트의 루트로 열립니다.

```javascript JavaScript theme={null}
  OneSignal.Notifications.setDefaultUrl("https://onesignal.com");
```

알림의 기본 URL을 설정하려면 알림을 클릭할 때 실행할 유효한 URL을 제공하세요. 이 기본 URL은 알림을 생성할 때 다른 URL이 지정되지 않은 경우 사용됩니다. 알림을 생성할 때 URL을 지정하면 기본 URL이 재정의됩니다.

Safari의 경우 이 함수를 사용할 수 없으므로 기본 알림 아이콘 URL은 Safari 설정에서 지정한 사이트 URL로 설정됩니다.

### `setDefaultTitle()`

알림에 표시할 기본 제목을 설정합니다.

```javascript JavaScript theme={null}
  OneSignal.Notifications.setDefaultTitle("Powered by OneSignal!");
```

제목이 있는 알림이 생성되면 지정된 제목이 항상 이 기본 제목을 재정의합니다.

알림의 제목은 기본적으로 사용자가 마지막으로 방문한 페이지의 제목으로 설정됩니다. 페이지 제목이 페이지마다 다른 경우 이러한 불일치는 바람직하지 않을 수 있습니다. 알림 제목이 지정되지 않은 한 알림 전체에서 페이지 제목을 표준화하려면 이것을 호출하세요.

***

## 성과

### `sendOutcome()`

OneSignal 대시보드에서 볼 수 있는 성과를 트리거합니다. 성과 이름(`string`, 필수) 및 값(`number`, 선택 사항)을 허용합니다. 동일한 성과 이름으로 `sendOutcome` 메서드가 호출될 때마다 성과 수가 증가하고 성과 값은 전달된 양만큼 증가합니다(포함된 경우). 자세한 내용은 [사용자 지정 성과](./custom-outcomes)를 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Session.sendOutcome('outcome name', 19.84);
```

### `sendUniqueOutcome()`

OneSignal 대시보드에서 볼 수 있는 성과를 트리거합니다. 성과 이름(`string`, 필수)만 허용합니다. `sendUniqueOutcome`은 사용자당 한 번만 해당 성과에 대한 수를 증가시킵니다. 자세한 내용은 [사용자 지정 성과](./custom-outcomes)를 참조하세요.

```javascript JavaScript theme={null}
  OneSignal.Session.sendUniqueOutcome('outcome name');
```

***
