basant307/AI_Governance_Project
048
1/**2 * MIT License3 *4 * Copyright (c) 2022 Lark Technologies Pte. Ltd.5 *6 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:7 *8 * The above copyright notice and this permission notice, shall be included in all copies or substantial portions of the Software.9 *10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.11 */12 13import axios, { AxiosError } from 'axios';14import fs from 'fs';15import path from 'path';16import crypto from 'crypto';17import { stringify } from 'qs';18import identity from 'lodash.identity';19import pickBy from 'lodash.pickby';20import merge from 'lodash.merge';21import qs from 'querystring';22import WebSocket from 'ws';23import http from 'http';24import https from 'https';25import { promises } from 'dns';26import { isIP } from 'net';27 28/******************************************************************************
29Copyright (c) Microsoft Corporation.
30
31Permission to use, copy, modify, and/or distribute this software for any
32purpose with or without fee is hereby granted.
33
34THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
35REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
37INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
38LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
39OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
40PERFORMANCE OF THIS SOFTWARE.
41***************************************************************************** */
42
43function __rest(s, e) {
44 var t = {};
45 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
46 t[p] = s[p];
47 if (s != null && typeof Object.getOwnPropertySymbols === "function")
48 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
49 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
50 t[p[i]] = s[p[i]];
51 }
52 return t;
53}
54
55function __awaiter(thisArg, _arguments, P, generator) {
56 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
57 return new (P || (P = Promise))(function (resolve, reject) {
58 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
59 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
60 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
61 step((generator = generator.apply(thisArg, _arguments || [])).next());
62 });
63}
64
65function __values(o) {
66 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
67 if (m) return m.call(o);
68 if (o && typeof o.length === "number") return {
69 next: function () {
70 if (o && i >= o.length) o = void 0;
71 return { value: o && o[i++], done: !o };
72 }
73 };
74 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
75}
76
77function __await(v) {
78 return this instanceof __await ? (this.v = v, this) : new __await(v);
79}
80
81function __asyncGenerator(thisArg, _arguments, generator) {
82 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
83 var g = generator.apply(thisArg, _arguments || []), i, q = [];
84 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
85 function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
86 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
87 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
88 function fulfill(value) { resume("next", value); }
89 function reject(value) { resume("throw", value); }
90 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
91}
92
93function __asyncValues(o) {
94 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
95 var m = o[Symbol.asyncIterator], i;
96 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
97 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
98 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
99}
100
101typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
102 var e = new Error(message);
103 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
104};105 106/**107 * Resolve the SDK's own version from `package.json`. The source lives at108 * `utils/user-agent.ts`; the published bundle lives at `lib/index.js` or109 * `es/index.js`. In both shapes the package.json sits exactly one level110 * above the code, so `__dirname/..` is the primary candidate. A second111 * candidate (two levels up) covers downstream bundlers that re-emit this112 * module at a deeper path.113 *114 * We sanity-check `name === '@larksuiteoapi/node-sdk'` so we don't115 * accidentally read an unrelated package.json that happens to sit in a116 * parent directory during local development.117 */118let cachedVersion;119function getSdkVersion() {120 if (cachedVersion !== undefined)121 return cachedVersion;122 const candidates = [123 path.resolve(__dirname, '..', 'package.json'),124 path.resolve(__dirname, '..', '..', 'package.json'),125 ];126 for (const p of candidates) {127 try {128 const pkg = JSON.parse(fs.readFileSync(p, 'utf-8'));129 if (pkg.name === '@larksuiteoapi/node-sdk' && typeof pkg.version === 'string') {130 cachedVersion = pkg.version;131 return pkg.version;132 }133 }134 catch (_a) {135 // try next candidate136 }137 }138 cachedVersion = 'unknown';139 return 'unknown';140}141/**142 * Sanitize a caller-supplied `source` tag so it can be safely concatenated143 * into a User-Agent header. Non-token characters are replaced with '_'144 * and the result is clamped to 64 characters. Never throws.145 */146function sanitizeSource(raw) {147 return raw.replace(/[^a-zA-Z0-9._-]/g, '_').slice(0, 64);148}149function buildUserAgent(source, opts) {150 let ua = `oapi-node-sdk/${getSdkVersion()}`;151 if (source) {152 const clean = sanitizeSource(source);153 if (clean)154 ua += ` source/${clean}`;155 }156 if (opts === null || opts === void 0 ? void 0 : opts.extraTags) {157 for (const t of opts.extraTags) {158 const clean = sanitizeSource(t);159 if (clean)160 ua += ` ${clean}`;161 }162 }163 return ua;164}165 166const defaultHttpInstance = axios.create();167// Fallback UA for callers that bypass Client/WSClient and hit168// `defaultHttpInstance` directly. Client.formatPayload overrides this with169// a source-enriched UA when a `source` option is configured.170const FALLBACK_UA = buildUserAgent();171defaultHttpInstance.interceptors.request.use((req) => {172 if (req.headers && !req.headers['User-Agent']) {173 req.headers['User-Agent'] = FALLBACK_UA;174 }175 return req;176}, undefined, { synchronous: true });177defaultHttpInstance.interceptors.response.use((resp) => {178 if (resp.config['$return_headers']) {179 return {180 data: resp.data,181 headers: resp.headers182 };183 }184 return resp.data;185});186 187var AppType;188(function (AppType) {189 AppType[AppType["SelfBuild"] = 0] = "SelfBuild";190 AppType[AppType["ISV"] = 1] = "ISV";191})(AppType || (AppType = {}));192var Domain;193(function (Domain) {194 Domain[Domain["Feishu"] = 0] = "Feishu";195 Domain[Domain["Lark"] = 1] = "Lark";196})(Domain || (Domain = {}));197var LoggerLevel;198(function (LoggerLevel) {199 LoggerLevel[LoggerLevel["fatal"] = 0] = "fatal";200 LoggerLevel[LoggerLevel["error"] = 1] = "error";201 LoggerLevel[LoggerLevel["warn"] = 2] = "warn";202 LoggerLevel[LoggerLevel["info"] = 3] = "info";203 LoggerLevel[LoggerLevel["debug"] = 4] = "debug";204 LoggerLevel[LoggerLevel["trace"] = 5] = "trace";205})(LoggerLevel || (LoggerLevel = {}));206 207const CEventType = Symbol('event-type');208const CTenantKey = Symbol('tenant-key');209const CAppTicket = Symbol('app-ticket');210const CTenantAccessToken = Symbol('tenant-access-token');211const CWithHelpdeskAuthorization = Symbol('with-helpdesk-authorization');212const CWithUserAccessToken = Symbol('with-user-access-token');213const CUserAccessToken = Symbol('user-access-token');214const CAilySessionRecord = Symbol('aily-session-record');215 216const string2Base64 = (content) => Buffer.from(content).toString('base64');217 218class DefaultCache {219 constructor() {220 this.values = new Map();221 }222 // When there is a namespace, splice the namespace and key to form a new key223 getCacheKey(key, namespace) {224 if (namespace) {225 return `${namespace}/${key.toString()}`;226 }227 return key;228 }229 get(key, options) {230 return __awaiter(this, void 0, void 0, function* () {231 const cacheKey = this.getCacheKey(key, options === null || options === void 0 ? void 0 : options.namespace);232 const data = this.values.get(cacheKey);233 if (data) {234 const { value, expiredTime } = data;235 if (!expiredTime || expiredTime - new Date().getTime() > 0) {236 return value;237 }238 }239 return undefined;240 });241 }242 set(key, value, expiredTime, options) {243 return __awaiter(this, void 0, void 0, function* () {244 const cacheKey = this.getCacheKey(key, options === null || options === void 0 ? void 0 : options.namespace);245 this.values.set(cacheKey, {246 value,247 expiredTime,248 });249 return true;250 });251 }252}253const internalCache = new DefaultCache();254 255class AESCipher {256 constructor(key) {257 const hash = crypto.createHash('sha256');258 hash.update(key);259 this.key = hash.digest();260 }261 decrypt(encrypt) {262 const encryptBuffer = Buffer.from(encrypt, 'base64');263 const decipher = crypto.createDecipheriv('aes-256-cbc', this.key, encryptBuffer.slice(0, 16));264 let decrypted = decipher.update(encryptBuffer.slice(16).toString('hex'), 'hex', 'utf8');265 decrypted += decipher.final('utf8');266 return decrypted;267 }268}269 270const formatDomain = (domain) => {271 switch (domain) {272 case Domain.Feishu:273 return 'https://open.feishu.cn';274 case Domain.Lark:275 return 'https://open.larksuite.com';276 default:277 return domain;278 }279};280 281const fillApiPath = (apiPath, pathSupplement = {}) => apiPath.replace(/:([^/]+)/g, (_, $1) => {282 if (pathSupplement[$1] !== undefined) {283 return pathSupplement[$1];284 }285 throw new Error(`request miss ${$1} path argument`);286});287 288const assert = (predication, callback) => __awaiter(void 0, void 0, void 0, function* () {289 const isInvoke = typeof predication === 'function' ? predication() : predication;290 if (isInvoke) {291 yield callback();292 }293});294 295const formatUrl = (url) => (url ? url.replace(/^\//, '') : '');296 297const pick = (obj, keys = []) => {298 const result = {};299 if (!obj) {300 return result;301 }302 keys.forEach(key => {303 if (Object.prototype.hasOwnProperty.call(obj, key)) {304 result[key] = obj[key];305 }306 });307 return result;308};309 310const formatErrors = (e) => {311 var _a;312 if (e instanceof AxiosError) {313 const { message, response, request, config } = pick(e, [314 'message',315 'response',316 'request',317 'config',318 ]);319 const filteredErrorInfo = {320 message,321 config: pick(config, ['data', 'url', 'params', 'method']),322 request: pick(request, ['protocol', 'host', 'path', 'method']),323 response: pick(response, ['data', 'status', 'statusText']),324 };325 const errors = [filteredErrorInfo];326 const specificError = (_a = e === null || e === void 0 ? void 0 : e.response) === null || _a === void 0 ? void 0 : _a.data;327 if (specificError) {328 errors.push(Object.assign(Object.assign({}, specificError), (specificError.error ? specificError.error : {})));329 }330 return errors;331 }332 return [e];333};334 335// auto gen336class Client$16 {337 constructor() {338 /**339 * 智能门禁340 */341 this.acs = {342 /**343 * access_record.access_photo344 */345 accessRecordAccessPhoto: {346 /**347 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=access_record.access_photo&apiName=get&version=v1 click to debug }348 *349 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/access_record-access_photo/get document }350 *351 * 下载开门时的人脸识别图片352 *353 * 用户在门禁考勤机上成功开门或打卡后,智能门禁应用都会生成一条门禁记录,对于使用人脸识别方式进行开门的识别记录,还会有抓拍图。;;可以用该接口下载开门时的人脸识别照片。354 */355 get: (payload, options) => __awaiter(this, void 0, void 0, function* () {356 const { headers, params, data, path } = yield this.formatPayload(payload, options);357 const res = yield this.httpInstance358 .request({359 url: fillApiPath(`${this.domain}/open-apis/acs/v1/access_records/:access_record_id/access_photo`, path),360 method: "GET",361 headers,362 data,363 params,364 responseType: "stream",365 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),366 $return_headers: true,367 })368 .catch((e) => {369 this.logger.error(formatErrors(e));370 throw e;371 });372 const checkIsReadable = () => {373 const consumedError = "The stream has already been consumed";374 if (!res.data.readable) {375 this.logger.error(consumedError);376 throw new Error(consumedError);377 }378 };379 return {380 writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {381 checkIsReadable();382 return new Promise((resolve, reject) => {383 const writableStream = fs.createWriteStream(filePath);384 writableStream.on("finish", () => {385 resolve(filePath);386 });387 writableStream.on("error", (e) => {388 reject(e);389 });390 res.data.pipe(writableStream);391 });392 }),393 getReadableStream: () => {394 checkIsReadable();395 return res.data;396 },397 headers: res.headers,398 };399 }),400 },401 /**402 * 门禁记录403 */404 accessRecord: {405 listWithIterator: (payload, options) => __awaiter(this, void 0, void 0, function* () {406 const { headers, params, data, path } = yield this.formatPayload(payload, options);407 const sendRequest = (innerPayload) => __awaiter(this, void 0, void 0, function* () {408 const res = yield this.httpInstance409 .request({410 url: fillApiPath(`${this.domain}/open-apis/acs/v1/access_records`, path),411 method: "GET",412 headers: pickBy(innerPayload.headers, identity),413 params: pickBy(innerPayload.params, identity),414 data,415 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),416 })417 .catch((e) => {418 this.logger.error(formatErrors(e));419 });420 return res;421 });422 const Iterable = {423 [Symbol.asyncIterator]() {424 return __asyncGenerator(this, arguments, function* _a() {425 let hasMore = true;426 let pageToken;427 while (hasMore) {428 try {429 const res = yield __await(sendRequest({430 headers,431 params: Object.assign(Object.assign({}, params), { page_token: pageToken }),432 data,433 }));434 const _b = (res === null || res === void 0 ? void 0 : res.data) || {}, { 435 // @ts-ignore436 has_more, 437 // @ts-ignore438 page_token, 439 // @ts-ignore440 next_page_token } = _b, rest = __rest(_b, ["has_more", "page_token", "next_page_token"]);441 yield yield __await(rest);442 hasMore = Boolean(has_more);443 pageToken = page_token || next_page_token;444 }445 catch (e) {446 yield yield __await(null);447 break;448 }449 }450 });451 },452 };453 return Iterable;454 }),455 /**456 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=access_record&apiName=list&version=v1 click to debug }457 *458 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/access_record/list document }459 *460 * 获取门禁记录列表461 *462 * 用户在门禁考勤机上成功开门或打卡后,智能门禁应用都会生成一条门禁记录。;;该接口返回满足查询参数的识别记录。463 */464 list: (payload, options) => __awaiter(this, void 0, void 0, function* () {465 const { headers, params, data, path } = yield this.formatPayload(payload, options);466 return this.httpInstance467 .request({468 url: fillApiPath(`${this.domain}/open-apis/acs/v1/access_records`, path),469 method: "GET",470 data,471 params,472 headers,473 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),474 })475 .catch((e) => {476 this.logger.error(formatErrors(e));477 throw e;478 });479 }),480 },481 /**482 * 门禁设备483 */484 device: {485 /**486 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=device&apiName=list&version=v1 click to debug }487 *488 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/device/list document }489 *490 * 获取门禁设备列表491 *492 * 使用该接口获取租户内所有门禁设备。493 */494 list: (payload, options) => __awaiter(this, void 0, void 0, function* () {495 const { headers, params, data, path } = yield this.formatPayload(payload, options);496 return this.httpInstance497 .request({498 url: fillApiPath(`${this.domain}/open-apis/acs/v1/devices`, path),499 method: "GET",500 data,501 params,502 headers,503 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),504 })505 .catch((e) => {506 this.logger.error(formatErrors(e));507 throw e;508 });509 }),510 },511 /**512 * rule_external513 */514 ruleExternal: {515 /**516 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=rule_external&apiName=create&version=v1 click to debug }517 *518 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=create&project=acs&resource=rule_external&version=v1 document }519 */520 create: (payload, options) => __awaiter(this, void 0, void 0, function* () {521 const { headers, params, data, path } = yield this.formatPayload(payload, options);522 return this.httpInstance523 .request({524 url: fillApiPath(`${this.domain}/open-apis/acs/v1/rule_external`, path),525 method: "POST",526 data,527 params,528 headers,529 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),530 })531 .catch((e) => {532 this.logger.error(formatErrors(e));533 throw e;534 });535 }),536 /**537 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=rule_external&apiName=delete&version=v1 click to debug }538 *539 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=delete&project=acs&resource=rule_external&version=v1 document }540 */541 delete: (payload, options) => __awaiter(this, void 0, void 0, function* () {542 const { headers, params, data, path } = yield this.formatPayload(payload, options);543 return this.httpInstance544 .request({545 url: fillApiPath(`${this.domain}/open-apis/acs/v1/rule_external`, path),546 method: "DELETE",547 data,548 params,549 headers,550 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),551 })552 .catch((e) => {553 this.logger.error(formatErrors(e));554 throw e;555 });556 }),557 /**558 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=rule_external&apiName=device_bind&version=v1 click to debug }559 *560 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=device_bind&project=acs&resource=rule_external&version=v1 document }561 */562 deviceBind: (payload, options) => __awaiter(this, void 0, void 0, function* () {563 const { headers, params, data, path } = yield this.formatPayload(payload, options);564 return this.httpInstance565 .request({566 url: fillApiPath(`${this.domain}/open-apis/acs/v1/rule_external/device_bind`, path),567 method: "POST",568 data,569 params,570 headers,571 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),572 })573 .catch((e) => {574 this.logger.error(formatErrors(e));575 throw e;576 });577 }),578 /**579 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=rule_external&apiName=get&version=v1 click to debug }580 *581 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=get&project=acs&resource=rule_external&version=v1 document }582 */583 get: (payload, options) => __awaiter(this, void 0, void 0, function* () {584 const { headers, params, data, path } = yield this.formatPayload(payload, options);585 return this.httpInstance586 .request({587 url: fillApiPath(`${this.domain}/open-apis/acs/v1/rule_external`, path),588 method: "GET",589 data,590 params,591 headers,592 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),593 })594 .catch((e) => {595 this.logger.error(formatErrors(e));596 throw e;597 });598 }),599 },600 /**601 * user.face602 */603 userFace: {604 /**605 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=user.face&apiName=get&version=v1 click to debug }606 *607 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/user-face/get document }608 *609 * 下载人脸图片610 *611 * 对于已经录入人脸图片的用户,可以使用该接口下载用户人脸图片。612 */613 get: (payload, options) => __awaiter(this, void 0, void 0, function* () {614 const { headers, params, data, path } = yield this.formatPayload(payload, options);615 const res = yield this.httpInstance616 .request({617 url: fillApiPath(`${this.domain}/open-apis/acs/v1/users/:user_id/face`, path),618 method: "GET",619 headers,620 data,621 params,622 responseType: "stream",623 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),624 $return_headers: true,625 })626 .catch((e) => {627 this.logger.error(formatErrors(e));628 throw e;629 });630 const checkIsReadable = () => {631 const consumedError = "The stream has already been consumed";632 if (!res.data.readable) {633 this.logger.error(consumedError);634 throw new Error(consumedError);635 }636 };637 return {638 writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {639 checkIsReadable();640 return new Promise((resolve, reject) => {641 const writableStream = fs.createWriteStream(filePath);642 writableStream.on("finish", () => {643 resolve(filePath);644 });645 writableStream.on("error", (e) => {646 reject(e);647 });648 res.data.pipe(writableStream);649 });650 }),651 getReadableStream: () => {652 checkIsReadable();653 return res.data;654 },655 headers: res.headers,656 };657 }),658 /**659 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=user.face&apiName=update&version=v1 click to debug }660 *661 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/user-face/update document }662 *663 * 上传人脸图片664 *665 * 用户需要录入人脸图片才可以使用门禁考勤机。使用该 API 上传门禁用户的人脸图片。666 */667 update: (payload, options) => __awaiter(this, void 0, void 0, function* () {668 const { headers, params, data, path } = yield this.formatPayload(payload, options);669 const res = yield this.httpInstance670 .request({671 url: fillApiPath(`${this.domain}/open-apis/acs/v1/users/:user_id/face`, path),672 method: "PUT",673 data,674 params,675 headers: Object.assign(Object.assign({}, headers), { "Content-Type": "multipart/form-data" }),676 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),677 })678 .catch((e) => {679 this.logger.error(formatErrors(e));680 throw e;681 });682 return (res === null || res === void 0 ? void 0 : res.data) || null;683 }),684 },685 /**686 * 用户管理687 */688 user: {689 /**690 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=user&apiName=get&version=v1 click to debug }691 *692 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/user/get document }693 *694 * 获取单个用户信息695 *696 * 该接口用于获取智能门禁中单个用户的信息。697 *698 * 只能获取已加入智能门禁权限组的用户699 */700 get: (payload, options) => __awaiter(this, void 0, void 0, function* () {701 const { headers, params, data, path } = yield this.formatPayload(payload, options);702 return this.httpInstance703 .request({704 url: fillApiPath(`${this.domain}/open-apis/acs/v1/users/:user_id`, path),705 method: "GET",706 data,707 params,708 headers,709 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),710 })711 .catch((e) => {712 this.logger.error(formatErrors(e));713 throw e;714 });715 }),716 listWithIterator: (payload, options) => __awaiter(this, void 0, void 0, function* () {717 const { headers, params, data, path } = yield this.formatPayload(payload, options);718 const sendRequest = (innerPayload) => __awaiter(this, void 0, void 0, function* () {719 const res = yield this.httpInstance720 .request({721 url: fillApiPath(`${this.domain}/open-apis/acs/v1/users`, path),722 method: "GET",723 headers: pickBy(innerPayload.headers, identity),724 params: pickBy(innerPayload.params, identity),725 data,726 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),727 })728 .catch((e) => {729 this.logger.error(formatErrors(e));730 });731 return res;732 });733 const Iterable = {734 [Symbol.asyncIterator]() {735 return __asyncGenerator(this, arguments, function* _a() {736 let hasMore = true;737 let pageToken;738 while (hasMore) {739 try {740 const res = yield __await(sendRequest({741 headers,742 params: Object.assign(Object.assign({}, params), { page_token: pageToken }),743 data,744 }));745 const _b = (res === null || res === void 0 ? void 0 : res.data) || {}, { 746 // @ts-ignore747 has_more, 748 // @ts-ignore749 page_token, 750 // @ts-ignore751 next_page_token } = _b, rest = __rest(_b, ["has_more", "page_token", "next_page_token"]);752 yield yield __await(rest);753 hasMore = Boolean(has_more);754 pageToken = page_token || next_page_token;755 }756 catch (e) {757 yield yield __await(null);758 break;759 }760 }761 });762 },763 };764 return Iterable;765 }),766 /**767 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=user&apiName=list&version=v1 click to debug }768 *769 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/user/list document }770 *771 * 获取用户列表772 *773 * 使用该接口获取智能门禁中所有用户信息。774 *775 * 只能获取已加入智能门禁权限组的用户。776 */777 list: (payload, options) => __awaiter(this, void 0, void 0, function* () {778 const { headers, params, data, path } = yield this.formatPayload(payload, options);779 return this.httpInstance780 .request({781 url: fillApiPath(`${this.domain}/open-apis/acs/v1/users`, path),782 method: "GET",783 data,784 params,785 headers,786 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),787 })788 .catch((e) => {789 this.logger.error(formatErrors(e));790 throw e;791 });792 }),793 /**794 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=user&apiName=patch&version=v1 click to debug }795 *796 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/user/patch document }797 *798 * 修改用户部分信息799 *800 * 飞书智能门禁在人脸识别成功后会有韦根信号输出,输出用户的卡号。;对于使用韦根协议的门禁系统,企业可使用该接口录入用户卡号。801 */802 patch: (payload, options) => __awaiter(this, void 0, void 0, function* () {803 const { headers, params, data, path } = yield this.formatPayload(payload, options);804 return this.httpInstance805 .request({806 url: fillApiPath(`${this.domain}/open-apis/acs/v1/users/:user_id`, path),807 method: "PATCH",808 data,809 params,810 headers,811 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),812 })813 .catch((e) => {814 this.logger.error(formatErrors(e));815 throw e;816 });817 }),818 },819 /**820 * visitor821 */822 visitor: {823 /**824 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=visitor&apiName=create&version=v1 click to debug }825 *826 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=create&project=acs&resource=visitor&version=v1 document }827 */828 create: (payload, options) => __awaiter(this, void 0, void 0, function* () {829 const { headers, params, data, path } = yield this.formatPayload(payload, options);830 return this.httpInstance831 .request({832 url: fillApiPath(`${this.domain}/open-apis/acs/v1/visitors`, path),833 method: "POST",834 data,835 params,836 headers,837 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),838 })839 .catch((e) => {840 this.logger.error(formatErrors(e));841 throw e;842 });843 }),844 /**845 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=visitor&apiName=delete&version=v1 click to debug }846 *847 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=delete&project=acs&resource=visitor&version=v1 document }848 */849 delete: (payload, options) => __awaiter(this, void 0, void 0, function* () {850 const { headers, params, data, path } = yield this.formatPayload(payload, options);851 return this.httpInstance852 .request({853 url: fillApiPath(`${this.domain}/open-apis/acs/v1/visitors/:visitor_id`, path),854 method: "DELETE",855 data,856 params,857 headers,858 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),859 })860 .catch((e) => {861 this.logger.error(formatErrors(e));862 throw e;863 });864 }),865 },866 v1: {867 /**868 * access_record.access_photo869 */870 accessRecordAccessPhoto: {871 /**872 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=access_record.access_photo&apiName=get&version=v1 click to debug }873 *874 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/access_record-access_photo/get document }875 *876 * 下载开门时的人脸识别图片877 *878 * 用户在门禁考勤机上成功开门或打卡后,智能门禁应用都会生成一条门禁记录,对于使用人脸识别方式进行开门的识别记录,还会有抓拍图。;;可以用该接口下载开门时的人脸识别照片。879 */880 get: (payload, options) => __awaiter(this, void 0, void 0, function* () {881 const { headers, params, data, path } = yield this.formatPayload(payload, options);882 const res = yield this.httpInstance883 .request({884 url: fillApiPath(`${this.domain}/open-apis/acs/v1/access_records/:access_record_id/access_photo`, path),885 method: "GET",886 headers,887 data,888 params,889 responseType: "stream",890 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),891 $return_headers: true,892 })893 .catch((e) => {894 this.logger.error(formatErrors(e));895 throw e;896 });897 const checkIsReadable = () => {898 const consumedError = "The stream has already been consumed";899 if (!res.data.readable) {900 this.logger.error(consumedError);901 throw new Error(consumedError);902 }903 };904 return {905 writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {906 checkIsReadable();907 return new Promise((resolve, reject) => {908 const writableStream = fs.createWriteStream(filePath);909 writableStream.on("finish", () => {910 resolve(filePath);911 });912 writableStream.on("error", (e) => {913 reject(e);914 });915 res.data.pipe(writableStream);916 });917 }),918 getReadableStream: () => {919 checkIsReadable();920 return res.data;921 },922 headers: res.headers,923 };924 }),925 },926 /**927 * 门禁记录928 */929 accessRecord: {930 listWithIterator: (payload, options) => __awaiter(this, void 0, void 0, function* () {931 const { headers, params, data, path } = yield this.formatPayload(payload, options);932 const sendRequest = (innerPayload) => __awaiter(this, void 0, void 0, function* () {933 const res = yield this.httpInstance934 .request({935 url: fillApiPath(`${this.domain}/open-apis/acs/v1/access_records`, path),936 method: "GET",937 headers: pickBy(innerPayload.headers, identity),938 params: pickBy(innerPayload.params, identity),939 data,940 paramsSerializer: (params) => stringify(params, {941 arrayFormat: "repeat",942 }),943 })944 .catch((e) => {945 this.logger.error(formatErrors(e));946 });947 return res;948 });949 const Iterable = {950 [Symbol.asyncIterator]() {951 return __asyncGenerator(this, arguments, function* _a() {952 let hasMore = true;953 let pageToken;954 while (hasMore) {955 try {956 const res = yield __await(sendRequest({957 headers,958 params: Object.assign(Object.assign({}, params), { page_token: pageToken }),959 data,960 }));961 const _b = (res === null || res === void 0 ? void 0 : res.data) || {}, { 962 // @ts-ignore963 has_more, 964 // @ts-ignore965 page_token, 966 // @ts-ignore967 next_page_token } = _b, rest = __rest(_b, ["has_more", "page_token", "next_page_token"]);968 yield yield __await(rest);969 hasMore = Boolean(has_more);970 pageToken = page_token || next_page_token;971 }972 catch (e) {973 yield yield __await(null);974 break;975 }976 }977 });978 },979 };980 return Iterable;981 }),982 /**983 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=access_record&apiName=list&version=v1 click to debug }984 *985 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/access_record/list document }986 *987 * 获取门禁记录列表988 *989 * 用户在门禁考勤机上成功开门或打卡后,智能门禁应用都会生成一条门禁记录。;;该接口返回满足查询参数的识别记录。990 */991 list: (payload, options) => __awaiter(this, void 0, void 0, function* () {992 const { headers, params, data, path } = yield this.formatPayload(payload, options);993 return this.httpInstance994 .request({995 url: fillApiPath(`${this.domain}/open-apis/acs/v1/access_records`, path),996 method: "GET",997 data,998 params,999 headers,1000 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),1001 })1002 .catch((e) => {1003 this.logger.error(formatErrors(e));1004 throw e;1005 });1006 }),1007 },1008 /**1009 * 门禁设备1010 */1011 device: {1012 /**1013 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=device&apiName=list&version=v1 click to debug }1014 *1015 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/device/list document }1016 *1017 * 获取门禁设备列表1018 *1019 * 使用该接口获取租户内所有门禁设备。1020 */1021 list: (payload, options) => __awaiter(this, void 0, void 0, function* () {1022 const { headers, params, data, path } = yield this.formatPayload(payload, options);1023 return this.httpInstance1024 .request({1025 url: fillApiPath(`${this.domain}/open-apis/acs/v1/devices`, path),1026 method: "GET",1027 data,1028 params,1029 headers,1030 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),1031 })1032 .catch((e) => {1033 this.logger.error(formatErrors(e));1034 throw e;1035 });1036 }),1037 },1038 /**1039 * rule_external1040 */1041 ruleExternal: {1042 /**1043 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=rule_external&apiName=create&version=v1 click to debug }1044 *1045 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=create&project=acs&resource=rule_external&version=v1 document }1046 */1047 create: (payload, options) => __awaiter(this, void 0, void 0, function* () {1048 const { headers, params, data, path } = yield this.formatPayload(payload, options);1049 return this.httpInstance1050 .request({1051 url: fillApiPath(`${this.domain}/open-apis/acs/v1/rule_external`, path),1052 method: "POST",1053 data,1054 params,1055 headers,1056 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),1057 })1058 .catch((e) => {1059 this.logger.error(formatErrors(e));1060 throw e;1061 });1062 }),1063 /**1064 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=rule_external&apiName=delete&version=v1 click to debug }1065 *1066 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=delete&project=acs&resource=rule_external&version=v1 document }1067 */1068 delete: (payload, options) => __awaiter(this, void 0, void 0, function* () {1069 const { headers, params, data, path } = yield this.formatPayload(payload, options);1070 return this.httpInstance1071 .request({1072 url: fillApiPath(`${this.domain}/open-apis/acs/v1/rule_external`, path),1073 method: "DELETE",1074 data,1075 params,1076 headers,1077 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),1078 })1079 .catch((e) => {1080 this.logger.error(formatErrors(e));1081 throw e;1082 });1083 }),1084 /**1085 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=rule_external&apiName=device_bind&version=v1 click to debug }1086 *1087 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=device_bind&project=acs&resource=rule_external&version=v1 document }1088 */1089 deviceBind: (payload, options) => __awaiter(this, void 0, void 0, function* () {1090 const { headers, params, data, path } = yield this.formatPayload(payload, options);1091 return this.httpInstance1092 .request({1093 url: fillApiPath(`${this.domain}/open-apis/acs/v1/rule_external/device_bind`, path),1094 method: "POST",1095 data,1096 params,1097 headers,1098 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),1099 })1100 .catch((e) => {1101 this.logger.error(formatErrors(e));1102 throw e;1103 });1104 }),1105 /**1106 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=rule_external&apiName=get&version=v1 click to debug }1107 *1108 * {@link https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=get&project=acs&resource=rule_external&version=v1 document }1109 */1110 get: (payload, options) => __awaiter(this, void 0, void 0, function* () {1111 const { headers, params, data, path } = yield this.formatPayload(payload, options);1112 return this.httpInstance1113 .request({1114 url: fillApiPath(`${this.domain}/open-apis/acs/v1/rule_external`, path),1115 method: "GET",1116 data,1117 params,1118 headers,1119 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),1120 })1121 .catch((e) => {1122 this.logger.error(formatErrors(e));1123 throw e;1124 });1125 }),1126 },1127 /**1128 * user.face1129 */1130 userFace: {1131 /**1132 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=user.face&apiName=get&version=v1 click to debug }1133 *1134 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/user-face/get document }1135 *1136 * 下载人脸图片1137 *1138 * 对于已经录入人脸图片的用户,可以使用该接口下载用户人脸图片。1139 */1140 get: (payload, options) => __awaiter(this, void 0, void 0, function* () {1141 const { headers, params, data, path } = yield this.formatPayload(payload, options);1142 const res = yield this.httpInstance1143 .request({1144 url: fillApiPath(`${this.domain}/open-apis/acs/v1/users/:user_id/face`, path),1145 method: "GET",1146 headers,1147 data,1148 params,1149 responseType: "stream",1150 paramsSerializer: (params) => stringify(params, { arrayFormat: "repeat" }),1151 $return_headers: true,1152 })1153 .catch((e) => {1154 this.logger.error(formatErrors(e));1155 throw e;1156 });1157 const checkIsReadable = () => {1158 const consumedError = "The stream has already been consumed";1159 if (!res.data.readable) {1160 this.logger.error(consumedError);1161 throw new Error(consumedError);1162 }1163 };1164 return {1165 writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {1166 checkIsReadable();1167 return new Promise((resolve, reject) => {1168 const writableStream = fs.createWriteStream(filePath);1169 writableStream.on("finish", () => {1170 resolve(filePath);1171 });1172 writableStream.on("error", (e) => {1173 reject(e);1174 });1175 res.data.pipe(writableStream);1176 });1177 }),1178 getReadableStream: () => {1179 checkIsReadable();1180 return res.data;1181 },1182 headers: res.headers,1183 };1184 }),1185 /**1186 * {@link https://open.feishu.cn/api-explorer?project=acs&resource=user.face&apiName=update&version=v1 click to debug }1187 *1188 * {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/acs-v1/user-face/update document }1189 *1190 * 上传人脸图片1191 *1192 * 用户需要录入人脸图片才可以使用门禁考勤机。使用该 API 上传门禁用户的人脸图片。1193 */1194 update: (payload, options) => __awaiter(this, void 0, void 0, function* () {1195 const { headers, params, data, path } = yield this.formatPayload(payload, options);1196 const res = yield this.httpInstance1197 .request({1198 url: fillApiPath(`${this.domain}/open-apis/acs/v1/users/:user_id/face`, path),1199 method: "PUT",1200 data,