How to escape ( when I query the MS AD LDAP

Here is my code:

import ldap from 'ldapjs';
import fs from "fs";
import dotenvFlow from 'dotenv-flow';
dotenvFlow.config();
let config = {
    baseDN: ..........,
    groupDN: ........,
    url: process.env["AD_LDAP_URL"]
}
let client;
try {
    client = ldap.createClient(config);
    let opts = {
        attributes: ['distinguishedName'],
        filter: "distinguishedName=CN=(R)," + config.groupDN,
        "scope": "sub"
    }        
    await bind(process.env["AD_USER_NAME"], process.env["AD_PASSWORD"]);

    let searchResult = await search(config.baseDN, opts);
    console.log(searchResult);    
} catch (error) {
    throw error
} finally{
    await unbind();
}

async function bind(userName, password) {
    return new Promise((resolve, reject) => {
        client.bind(userName, password, async err => {
            if (err) {
                reject(err)
            }
            resolve();
        });
    });
}
async function search(dn, opts) {
    const entries = [];
    let referrals = [];
    return new Promise((resolve, reject) => {
        client.search(dn, opts, function (err, response) {
            response.on('searchEntry', function (entry) {
                entries.push(entry);
            });
            response.on('searchReference', referral => {
                referrals = referrals.concat(referral.uris);
            });
            response.on('error', error => {
                return reject(error);
            })
            response.on('end', result => {
                if (result.status !== 0) {
                    return reject(result.status);
                }

                return resolve({
                    entries: entries,
                    referrals: referrals
                });
            });
        });
    });
}
async function unbind() {
    return new Promise((resolve, reject) => {
        client.unbind(err => {
            if (err) {
                return reject(err);
            }
            resolve();
        });
    });
}

It prompts the “Error: unbalanced parentheses”.

When I change the following:

filter: "distinguishedName=CN=(R)," + config.groupDN,

to

filter: "distinguishedName=CN=(R," + config.groupDN,

The error message is gone.

However when I change the above to

filter: "distinguishedName=CN=(R)," + config.groupDN,

The error message came back.

So, how can I escape the right parentheses?

My environment is node 22 and “ldapjs”: “^3.0.7”.