# CRM 속성

CRM 속성은 핵클 서버에만 안전하게 저장되며 SDK를 통해 값을 직접 조회할 수는 없습니다.

{% hint style="danger" %}
CRM 속성은 별도로 관리되며, `resetUser()`를 호출하거나 `updateUserProperties`에서 `clearAll`을 호출해도 삭제되거나 초기화되지 않습니다.

사용자가 회원 탈퇴 등을 한 경우, 반드시 별도로 제공되는 함수를 호출하여 정보를 삭제해야 합니다.
{% endhint %}

## 전화번호 수집

{% hint style="danger" %}
Node.js SDK에서는 전화번호 수집 기능을 제공하지 않습니다.

HTTP API를 이용해서 [전화번호 수집 및 삭제](/development-guide/http-api/api-properties.md)를 할 수 있습니다.
{% endhint %}

## CRM 마케팅 메시지 수신 동의

{% hint style="info" %}
수신 동의 상태에 대한 자세한 내용은 [CRM 메시지 수신 동의 관리 문서](/development-guide/sdk/user-identifier/crm-subscription.md)를 참고해주세요.
{% endhint %}

### 수신 동의 속성

메시지 목적 별로 수신 동의/거부를 할 수 있습니다.

`HackleSubscriptionOperationsBuilder`를 사용해 원하는 속성의 동의 상태를 설정한 후, `updatePushSubscriptions()` 같은 메서드로 최종 업데이트를 진행합니다.

메시지 채널 별로 동의 상태를 업데이트할 수 있습니다.

```javascript
import { HackleSubscriptionOperationsBuilder } from "@hackler/javascript-sdk";

const user = {
  userId: "143",
  deviceId: "ae2182e0",
};

const operations = new HackleSubscriptionOperationsBuilder()
  .marketing(HackleSubscriptionStatus.SUBSCRIBED)
  .information(HackleSubscriptionStatus.SUBSCRIBED)
  .build();

hackleClient.updatePushSubscriptions(operations, user);
```

#### 광고성 메시지

광고성 메시지 수신 동의 속성을 설정합니다.

```javascript
import { HackleSubscriptionOperationsBuilder } from "@hackler/javascript-sdk";

const user = {
  userId: "143",
  deviceId: "ae2182e0",
};

const operations = new HackleSubscriptionOperationsBuilder()
  .marketing(HackleSubscriptionStatus.SUBSCRIBED)
  .build();

hackleClient.updatePushSubscriptions(operations, user);
```

#### 정보성 메시지

정보성 메시지 수신 동의 속성을 설정합니다.

```javascript
import { HackleSubscriptionOperationsBuilder } from "@hackler/javascript-sdk";

const user = {
  userId: "143",
  deviceId: "ae2182e0",
};

const operations = new HackleSubscriptionOperationsBuilder()
  .information(HackleSubscriptionStatus.SUBSCRIBED)
  .build();

hackleClient.updatePushSubscriptions(operations, user);
```

<table><thead><tr><th width="224.09765625">HackleSubscriptionStatus</th><th>설명</th></tr></thead><tbody><tr><td><code>UNKNOWN</code></td><td>수신 동의/거부를 하지 않음 (<code>default</code>)</td></tr><tr><td><code>SUBSCRIPTION</code></td><td>명시적으로 수신 동의</td></tr><tr><td><code>UNSUBSCRIPTION</code></td><td>명시적으로 수신 거부</td></tr></tbody></table>

### 푸시 수신 동의 상태 업데이트

사용자의 푸시 메시지 수신 동의 상태를 업데이트 합니다.

```javascript
import { HackleSubscriptionOperationsBuilder } from "@hackler/javascript-sdk";

const user = {
  userId: "143",
  deviceId: "ae2182e0",
};

const operations = new HackleSubscriptionOperationsBuilder()
  .marketing(HackleSubscriptionStatus.SUBSCRIBED)
  .information(HackleSubscriptionStatus.SUBSCRIBED)
  .build();

hackleClient.updatePushSubscriptions(operations, user);
```

### 카카오 메시지 수신 동의 상태 업데이트

사용자의 카카오 메시지 수신 동의 상태를 업데이트 합니다.

```javascript
import { HackleSubscriptionOperationsBuilder } from "@hackler/javascript-sdk";

const user = {
  userId: "143",
  deviceId: "ae2182e0",
};

const operations = new HackleSubscriptionOperationsBuilder()
  .marketing(HackleSubscriptionStatus.SUBSCRIBED)
  .information(HackleSubscriptionStatus.SUBSCRIBED)
  .build();

hackleClient.updateKakaoSubscriptions(operations, user);
```

### 문자 메시지 수신 동의 상태 업데이트

사용자의 문자 메시지 수신 동의 상태를 업데이트 합니다.

```javascript
import { HackleSubscriptionOperationsBuilder } from "@hackler/javascript-sdk";

const user = {
  userId: "143",
  deviceId: "ae2182e0",
};

const operations = new HackleSubscriptionOperationsBuilder()
  .marketing(HackleSubscriptionStatus.SUBSCRIBED)
  .information(HackleSubscriptionStatus.SUBSCRIBED)
  .build();

hackleClient.updateSmsSubscriptions(operations, user);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hackle.io/development-guide/nodejs/user-identifier/node-user-info-crm.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
