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

# Manage Users

> Create, update, & manage user profiles and communication channels using NodeJS SDK methods.

## How SuprSend identifies a User

SuprSend identifies users with immutable `distinct_id`. It's best to map the same identifier in your DB with `distinct_id` in SuprSend. Do not use identifiers that can be changed like email or phone number. You can view synced users by searching `distinct_id` on [Users page](https://app.suprsend.com/en/production/users).

## Create User

To create a new user or to update an existing user, you’ll have to fetch user instance. Call `supr_client.user.get_instance` to instantiate user object.

<CodeGroup>
  ```javascript Request theme={"system"}
  const user = supr_client.user.get_instance("_distinct_id_"); // create user instance

  // user methods mentioned in this docs can be attached to user instance if needed

  const response = user.save() // IMP: trigger request
  response.then((res) => console.log("response", res));
  ```

  ```javascript Response theme={"system"}
  {
    "success": boolean,
    "status": "success"/"fail",
    "status_code": http_status_code,
    "message": "response_message"/"error_message",
  }
  ```
</CodeGroup>

## Edit User

To Edit user, you need to first fetch user instance, call all the update methods and save changes using `user.save()` method.

<CodeGroup>
  ```javascript Request theme={"system"}
  // Fetch user instance
  const user = supr_client.users.get_edit_instance("_distinct_id_");

  // Call user update methods
  user.set_timezone("America/Los_Angeles");
  user.set("name", "John Doe");

  // Save Changes
  const response = user.save(); // IMP: trigger request
  response.then((res) => console.log("response", res));
  ```

  ```javascript Response theme={"system"}
  {
    "success": true,
    "status": "success",
    "status_code": 200,
    "message": "User updated successfully"
  }
  ```
</CodeGroup>

Here's a list of all edit methods:

<AccordionGroup>
  <Accordion title="Add User Channels">
    Use `user.add_*` method to add user channels.

    <CodeGroup>
      ```javascript Request theme={"system"}

      // add Email
      user.add_email("user@example.com")

      // add SMS
      user.add_sms("+15555555555")

      // add Whatsapp
      user.add_whatsapp("+15555555555")

      // add fcm push token
      user.add_androidpush("__android_push_fcm_token__")

      // add apns push token
      user.add_iospush("__iospush_token__")

      // add Slack using email
      user.add_slack({
        email: "user@example.com",
        access_token: "xoxb-XXXXXXXX"
      });

      // add Slack if slack member_id is known
      user.add_slack({
        user_id: "U03XXXXXXXX",
        access_token: "xoxb-XXXXXXXX"
      });

      // add Slack channel
      user.add_slack({
        channel_id: "CXXXXXXXX",
        access_token: "xoxb-XXXXXXXX"
      });

      // add Slack incoming webhook
      user.add_slack({
        incoming_webhook: {
          url: "https://hooks.slack.com/services/TXXXX/BXXXX/XXXXXXX"
        }
      });

      // add MS teams user or channel using conversation_id
      user.add_ms_teams({
        tenant_id: "c19xxxx2-9aaf-xxxx-xxxx",
        service_url: "https://smba.trafficmanager.net/amer",
        conversation_id: "19:c1524d7c-a06f-456f-8abe-xxxx"
      });

      // add MS teams user using user_id
      user.add_ms_teams({
        tenant_id: "c19xxxx2-9aaf-xxxx-xxxx",
        service_url: "https://smba.trafficmanager.net/amer",
        user_id: "29:1nsLcmJ2RKtYH6Cxxxx-xxxx"
      });

      // add MS teams using incoming webhook
      user.add_ms_teams({
        incoming_webhook: {
          url: "https://wnk1z.webhook.office.com/webhookb2/XXXXXXXXX"
        }
      });
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Remove User Channels">
    Use `user.remove_*` method(s) to remove user channels. These methods will detach provided value from the user profile in specified channel.

    <CodeGroup>
      ```javascript Request theme={"system"}

      // remove Email
      user.remove_email("user@example.com")

      // remove SMS
      user.remove_sms("+15555555555")

      // remove Whatsapp
      user.remove_whatsapp("+15555555555")

      // remove fcm push token
      user.remove_androidpush("__android_push_fcm_token__")

      // remove apns push token
      user.remove_iospush("__iospush_token__")

      // remove Slack email
      user.remove_slack({
        email: "user@example.com",
        access_token: "xoxb-XXXXXXXX"
      });

      // remove Slack if slack member_id is known
      user.remove_slack({
        user_id: "U03XXXXXXXX",
        access_token: "xoxb-XXXXXXXX"
      });

      // remove Slack channel
      user.remove_slack({
        channel_id: "CXXXXXXXX",
        access_token: "xoxb-XXXXXXXX"
      });

      // remove Slack incoming webhook
      user.remove_slack({
        incoming_webhook: {
          url: "https://hooks.slack.com/services/TXXXX/BXXXX/XXXXXXX"
        }
      });

      // remove MS teams user or channel using conversation_id
      user.remove_ms_teams({
        tenant_id: "c19xxxx2-9aaf-xxxx-xxxx",
        service_url: "https://smba.trafficmanager.net/amer",
        conversation_id: "19:c1524d7c-a06f-456f-8abe-xxxx"
      });

      // remove MS teams user using user_id
      user.remove_ms_teams({
        tenant_id: "c19xxxx2-9aaf-xxxx-xxxx",
        service_url: "https://smba.trafficmanager.net/amer",
        user_id: "29:1nsLcmJ2RKtYH6Cxxxx-xxxx"
      });

      // remove MS teams using incoming webhook
      user.remove_ms_teams({
        incoming_webhook: {
          url: "https://wnk1z.webhook.office.com/webhookb2/XXXXXXXXX"
        }
      });
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Remove User Channels in bulk">
    This method will delete/unset all values in specified channel for user (ex: remove all emails attached to user).

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.unset("$email")
      user.unset(["$email", "$sms", "$whatsapp"])

      // what value to pass to unset channels
      // for email:                $email
      // for whatsapp:             $whatsapp
      // for SMS:                  $sms
      // for androidpush tokens:   $androidpush
      // for iospush tokens:       $iospush
      // for webpush tokens:       $webpush
      // for slack:                $slack
      // for ms_teams:             $ms_teams
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Set Preferred Language">
    If you want to send notification in user's preferred language, you can set it by passing [language code](https://github.com/suprsend/suprsend-py-sdk/blob/v0.12.0/src/suprsend/language_codes.py) in this method. This is useful especially for the applications which offer vernacular or multi-lingual support.

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.set_preferred_language("en")
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Set Preferred Timezone">
    You can set timezone of user using this method. Value for timezone must be from amongst the [IANA timezones](https://data.iana.org/time-zones/tzdb-2024a/zonenow.tab).

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.set_timezone("America/Los_Angeles")
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Set">
    Set is used to set the custom user property or properties. The given key and value will be assigned to the user, overwriting an existing property with the same key if present.

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.set(key, value)
      user.set("name","John Doe")

      user.set({ key1: value1, key2: value2 })
      user.set({"name": "John Doe","city": "San Francisco"})
      ```
    </CodeGroup>

    | Parameters | type   |
    | ---------- | ------ |
    | key        | string |
    | value      | any    |
  </Accordion>

  <Accordion title="Set Once">
    Works just like `user.set`, except it will not override already existing property values. This is useful for properties like first\_login\_date.

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.set_once(key, value)
      user.set_once("first_login","2021-11-02")

      user.set_once({ key1: value1, key2: value2 })
      user.set_once({"first_login": "2021-11-02","signup_date": "2021-11-02"})
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Append">
    This method will append a value to the list for a given property.

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.append(key, value)
      user.append("played_games", "game_1")

      user.append({ key1: value1, key2: value2 })
      user.append({"played_games": "game_1", "liked_games": "game_2"})
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Remove">
    This method will remove a value from the list for a given property.

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.remove(key, value)
      user.remove("played_games", "game_1")

      user.remove({ key1: value1, key2: value2 })
      user.remove({"played_games": "game_1", "liked_games": "game_2"})
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Increment">
    Add the given number to an existing property on the user. If the user does not already have the associated property, the amount will be added to zero. To reduce a property, provide a negative number for the value.

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.increment(key, value)
      user.increment("login_count", 1)

      user.increment({ key1: value1, key2: value2 })
      user.increment({"login_count" : 1, "order_count" : 1})
      ```
    </CodeGroup>

    | Parameters | type            |
    | ---------- | --------------- |
    | key        | string          |
    | value      | number (+ or -) |
  </Accordion>

  <Accordion title="Unset">
    This will remove a property permanently from user properties.

    <CodeGroup>
      ```javascript Request theme={"system"}
      user.unset(key)
      user.unset("wishlist")

      user.unset([key1, key2])
      user.unset(["wishlist", "cart"])
      ```
    </CodeGroup>

    | Parameters | type   |
    | ---------- | ------ |
    | keys       | string |
  </Accordion>
</AccordionGroup>

<Warning>
  After calling `add*/remove*/unset` methods, don't forget to call the `user.save()` request. the changes will be sent to SuprSend only after calling this method.
</Warning>

## Bulk Update Users

Bulk operations use **UPSERT** to create or update users.
There isn't any limit on number-of-records that can be added to `bulk_users` instance. Use `.append()` on bulk\_users instance to add however-many-records to call in bulk.

<Tip>
  **Rate limit:** 1000 requests per second. The SDK automatically chunks requests based on the size of the payload. So, you don't need to worry about these rate limits while using bulk operations.
</Tip>

<CodeGroup>
  ```javascript Request theme={"system"}
  const { Suprsend } = require("@suprsend/node-sdk");

  const supr_client = new Suprsend("workspace_key", "workspace_secret");

  const bulk_ins = supr_client.bulk_users.new_instance()

  // user1 instance
  const user1 = supr_client.user.get_instance("_distinct_id_1")
  user1.add_email("u1@example.com")
  user1.set_preferred_language("en")

  // user2 instance
  const user2 = supr_client.user.get_instance("_distinct_id_2")
  user2.remove_email("u2@example.com")

  //append users instance to bulk instance
  bulk_ins.append(user1)
  bulk_ins.append(user2)
  // OR
  bulk_ins.append(user1, user2)

   // trigger request
  const response = bulk_ins.save()
  response.then((res) => console.log("response", res));
  ```

  ```javascript Bulk Response theme={"system"}
  {
    status: "success/fail/partial",
    total: 10,
    success: 10,
    failure: 0,
    failed_records: [{"record": {...}, "error": "error_str", "code": "<status_code>"}],
    warnings: []
  }
  ```
</CodeGroup>

## Get user details

<CodeGroup>
  ```javascript Request theme={"system"}
  const response = await supr_client.users.get(_distinct_id_);
  ```
</CodeGroup>

## Delete user

<CodeGroup>
  ```javascript Request theme={"system"}
  const response = await supr_client.users.delete(_distinct_id_);
  ```
</CodeGroup>

## Get list of objects subscribed by user

<CodeGroup>
  ```javascript Request theme={"system"}
  const response = await supr_client.users.get_objects_subscribed_to(_distinct_id_, {limit:20});
  ```
</CodeGroup>

You can pass optional query parameters - `limit`,`before`,`after`.

## Get lists subscribed by user

<CodeGroup>
  ```javascript Request theme={"system"}
  const response = await supr_client.users.get_lists_subscribed_to(_distinct_id_, {limit:20});
  ```
</CodeGroup>

You can pass optional query parameters - `limit`,`before`,`after`.

***
