diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 86224dd6..cb910d7d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -41,7 +41,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [14, 16, 18] + node-version: [16, 18, 20] steps: - name: Check out diff --git a/README.md b/README.md index a1a94068..a2c0a0f6 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,11 @@ - [x] Telegram - [x] OneBot (v11) - [x] QQ Guild - - [x] KOOK (Kaiheila) - - [x] Lark (Feishu) + - [x] KOOK (开黑啦) + - [x] Lark (飞书) + - [x] Line + - [ ] Whatsapp + - [ ] Slack - [ ] Dingding - [ ] Wecom diff --git a/adapters/dingtalk/.npmignore b/adapters/dingtalk/.npmignore new file mode 100644 index 00000000..7e5fcbc1 --- /dev/null +++ b/adapters/dingtalk/.npmignore @@ -0,0 +1,2 @@ +.DS_Store +tsconfig.tsbuildinfo diff --git a/adapters/dingtalk/package.json b/adapters/dingtalk/package.json new file mode 100644 index 00000000..9f8ed0fb --- /dev/null +++ b/adapters/dingtalk/package.json @@ -0,0 +1,31 @@ +{ + "name": "@satorijs/adapter-dingtalk", + "description": "Dingtalk Adapter for Satorijs", + "version": "1.0.1", + "main": "lib/index.js", + "typings": "lib/index.d.ts", + "files": [ + "lib" + ], + "author": "LittleC ", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/satorijs/satori.git", + "directory": "adapters/dingtalk" + }, + "bugs": { + "url": "https://github.com/satorijs/satori/issues" + }, + "homepage": "https://koishi.chat/plugins/adapter/dingtalk.html", + "keywords": [ + "bot", + "dingtalk", + "adapter", + "chatbot", + "satori" + ], + "peerDependencies": { + "@satorijs/satori": "^2.6.1" + } +} diff --git a/adapters/dingtalk/src/api/alitrip.ts b/adapters/dingtalk/src/api/alitrip.ts new file mode 100644 index 00000000..a944b9f2 --- /dev/null +++ b/adapters/dingtalk/src/api/alitrip.ts @@ -0,0 +1,466 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface BillSettementBtripTrainQuery { + /** 企业id。 */ + corpId?: string + /** 类目:机酒火车: */ + category?: number + /** 每页数据量,默认100,最高100。 */ + pageSize?: number + /** 记账更新开始日期。 */ + periodStart?: string + /** 页数,从1开始。 */ + pageNumber?: number + /** 记账更新结束日期。 */ + periodEnd?: string +} + +export interface BillSettementBtripTrainResponse { + resultMsg?: string + module?: { + category?: number + corpId?: string + dataList?: number + periodEnd?: string + periodStart?: string + totalNum?: number + } + success?: unknown + resultCode?: number +} + +export interface BillSettementHotelQuery { + /** 第三方企业。 */ + corpId?: string + /** 类目:机酒火车: */ + category?: number + /** 每页数据量,默认100,最高500。 */ + pageSize?: number + /** 记账更新开始日期。 */ + periodStart?: string + /** 页数,从1开始。 */ + pageNumber?: number + /** 记账更新结束日期。 */ + periodEnd?: string +} + +export interface BillSettementHotelResponse { + resultMsg?: string + module?: { + category?: number + corpId?: string + dataList?: number + periodEnd?: string + periodStart?: string + totalNum?: number + } + success?: unknown + resultCode?: number +} + +export interface BillSettementCarQuery { + /** 企业id。 */ + corpId?: string + /** 类目:机酒火车: */ + category?: number + /** 每页数据量,默认100,最高100。 */ + pageSize?: number + /** 记账更新开始日期。 */ + periodStart?: string + /** 记账更新结束日期。 */ + periodEnd?: string + /** 页数,从1开始。 */ + pageNumber?: number +} + +export interface BillSettementCarResponse { + resultMsg?: string + module?: { + category?: number + corpId?: string + dataList?: number + periodEnd?: string + periodStart?: string + totalNum?: number + } + success?: unknown + resultCode?: number +} + +export interface BillSettementFlightQuery { + /** 第三方企业的CorpId。 */ + corpId?: string + /** 类目,取值: */ + category?: number + /** 分页参数,每页数据量。默认值100,最大值500。 */ + pageSize?: number + /** 记账更新开始日期。 */ + periodStart?: string + /** 分页参数,页码,从1开始。 */ + pageNumber?: number + /** 记账更新结束日期。 */ + periodEnd?: string +} + +export interface BillSettementFlightResponse { + resultMsg?: string + module?: { + category?: number + corpId?: string + dataList?: number + periodEnd?: string + periodStart?: string + totalNum?: number + } + success?: unknown + resultCode?: number +} + +export interface GetFlightExceedApplyQuery { + /** 第三方企业的corpId。 */ + corpId: string + /** 商旅超标审批单ID。 */ + applyId: string +} + +export interface GetFlightExceedApplyResponse { + corpId: string + applyId: number + status: number + btripCause: string + exceedType: number + exceedReason: string + originStandard: string + submitTime: string + userId: string + applyIntentionInfoDO: { + arrCity: string + arrCityName: string + arrTime: string + cabin: string + cabinClass: number + cabinClassStr: string + depCity: string + depCityName: string + depTime: string + discount: number + flightNo: string + price: number + type: number + } + thirdpartApplyId: string +} + +export interface QueryUnionOrderQuery { + /** 第三方企业corpId。 */ + corpId: string + /** 第三方申请单ID。 */ + thirdPartApplyId?: string + /** 关联单号ID。 */ + unionNo?: string +} + +export interface QueryUnionOrderResponse { + flightList?: { + flightOrderId?: number + flightOrderStatus?: number + }[] + corpId?: string + trainList?: { + trainOrderId?: number + trainOrderstatus?: number + }[] + hotelList?: { + hotelOrderId?: number + hotelOrderStatus?: number + }[] + vehicleList?: { + vehicleOrderId?: number + vehicleOrderStatus?: number + }[] +} + +export interface GetTrainExceedApplyQuery { + /** 第三方企业的corpId。 */ + corpId: string + /** 商旅审批单ID。 */ + applyId: string +} + +export interface GetTrainExceedApplyResponse { + corpId: string + applyId: number + status: number + btripCause: string + exceedType: number + exceedReason: string + originStandard: string + submitTime: string + userId: string + applyIntentionInfoDO: { + price: number + depCityName: string + arrCityName: string + depCity: string + arrCity: string + depTime: string + arrTime: string + arrStation: string + depStation: string + trainNo: string + trainTypeDesc: string + seatName: string + } + thirdpartApplyId: string +} + +export interface GetHotelExceedApplyQuery { + /** 第三方企业的corpId。 */ + corpId: string + /** 商旅审批单ID。 */ + applyId: string +} + +export interface GetHotelExceedApplyResponse { + corpId: string + applyId: number + status: number + btripCause: string + exceedType: number + exceedReason: string + originStandard: string + submitTime: string + userId: string + applyIntentionInfoDO: { + checkIn: string + checkOut: string + cityCode: string + cityName: string + price: number + together: number + type: number + } + thirdpartApplyId: string +} + +export interface SyncExceedApplyQuery { + /** 审批意见。 */ + remark: string + /** 商旅超标审批单号。 */ + applyId: string + /** 企业的corpId。 */ + corpId: string + /** 第三方流程实例ID。 */ + thirdpartyFlowId: string + /** 员工的userid。 */ + userId: string + /** 审批单状态,取值: */ + status: number +} + +export interface SyncExceedApplyResponse { + module: unknown +} + +export interface QueryCityCarApplyQuery { + /** 企业的CorpId。 */ + corpId: string + /** 审批单创建时间小于值,例如2021-03-18 20:26:50。 */ + createdEndAt?: string + /** 审批单创建时间大于或等于的时间,例如2021-03-18 20:26:56。 */ + createdStartAt?: string + /** 页码,要求大于等于1,默认1。 */ + pageNumber?: number + /** 每页数据量,要求大于等于1,默认20。 */ + pageSize?: number + /** 三方审批单ID。 */ + thirdPartApplyId?: string + /** 第三方员工ID。 */ + userId?: string +} + +export interface QueryCityCarApplyResponse { + applyList?: { + approverList?: number + departId?: string + departName?: string + gmtCreate?: string + gmtModified?: string + itineraryList?: number + status?: number + statusDesc?: string + thirdPartApplyId?: string + tripCause?: string + tripTitle?: string + userId?: string + userName?: string + }[] + total?: number +} + +export interface ApproveCityCarApplyParams { + /** 第三方企业的corpid。 */ + corpId: string + /** 审批时间,例如2021-03-18 20:26:56。 */ + operateTime?: string + /** 审批备注。 */ + remark?: string + /** 审批结果: */ + status: number + /** 第三方审批单ID。 */ + thirdPartApplyId: string + /** 审批的第三方员工ID。 */ + userId: string +} + +export interface ApproveCityCarApplyResponse { + approveResult?: unknown +} + +export interface AddCityCarApplyParams { + /** 出差事由。 */ + cause: string + /** 用车城市。 */ + city: string + /** 第三方企业的corpid。 */ + corpId: string + /** 用车时间,按天管控,比如传值2021-03-18 20:26:56表示2021-03-18当天可用车,跨天情况配合finishedDate参数使用 */ + date: string + /** 审批单关联的项目code。 */ + projectCode?: string + /** 审批单关联的项目名。 */ + projectName?: string + /** 审批单状态: */ + status: number + /** 三方审批单ID。 */ + thirdPartApplyId: string + /** 审批单关联的三方成本中心ID。 */ + thirdPartCostCenterId: string + /** 审批单关联的三方发票抬头ID。 */ + thirdPartInvoiceId: string + /** 审批单可用总次数。 */ + timesTotal: number + /** 审批单可用次数类型: */ + timesType: number + /** 审批单已用次数。 */ + timesUsed: number + /** 审批单标题。 */ + title: string + /** 发起审批的第三方员工ID。 */ + userId: string + /** 用车截止时间,按天管控,比如date传值2021-03-18 20:26:56、finishedDate传值2021-03-30 20:26:56表示2021-03-18(含)到2021-03-30(含)之间可用车,该参数不传值情况使用date作为用车截止时间; */ + finishedDate?: string +} + +export interface AddCityCarApplyResponse { + applyId?: number +} + +// funcName: isOldApi +Internal.define({ + '/alitrip/billSettlements/btripTrains': { + GET: { billSettementBtripTrain: false }, + }, + '/alitrip/billSettlements/hotels': { GET: { billSettementHotel: false } }, + '/alitrip/billSettlements/cars': { GET: { billSettementCar: false } }, + '/alitrip/billSettlements/flights': { GET: { billSettementFlight: false } }, + '/alitrip/exceedapply/getFlight': { GET: { getFlightExceedApply: false } }, + '/alitrip/unionOrders': { GET: { queryUnionOrder: false } }, + '/alitrip/exceedapply/getTrain': { GET: { getTrainExceedApply: false } }, + '/alitrip/exceedapply/getHotel': { GET: { getHotelExceedApply: false } }, + '/alitrip/exceedapply/sync': { POST: { syncExceedApply: false } }, + '/alitrip/cityCarApprovals': { + GET: { queryCityCarApply: false }, + PUT: { approveCityCarApply: false }, + POST: { addCityCarApply: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 查询商旅火车票结算记账数据 + * @see https://developers.dingtalk.com/document/isvapp/business-travel-train-ticket-settlement-bookkeeping-query-interface + */ + billSettementBtripTrain( + query: BillSettementBtripTrainQuery, + ): Promise + /** + * 查询酒店结算记账数据 + * @see https://developers.dingtalk.com/document/isvapp/hotel-settlement-bookkeeping-query-interface + */ + billSettementHotel( + query: BillSettementHotelQuery, + ): Promise + /** + * 查询用车结算记账记录 + * @see https://developers.dingtalk.com/document/isvapp/query-interface-for-vehicle-settlement-and-bookkeeping + */ + billSettementCar( + query: BillSettementCarQuery, + ): Promise + /** + * 查询机票结算记账数据 + * @see https://developers.dingtalk.com/document/isvapp/ticket-settlement-bookkeeping-query-interface + */ + billSettementFlight( + query: BillSettementFlightQuery, + ): Promise + /** + * 搜索第三方机票超标审批单 + * @see https://developers.dingtalk.com/document/isvapp/dingtalk-oapi-alitrip-btrip-exceedapply-flight-get + */ + getFlightExceedApply( + query: GetFlightExceedApplyQuery, + ): Promise + /** + * 关联单号查询相关订单信息列表 + * @see https://developers.dingtalk.com/document/isvapp/link-no-to-query-the-list-of-related-order-information + */ + queryUnionOrder( + query: QueryUnionOrderQuery, + ): Promise + /** + * 搜索第三方火车票超标审批单 + * @see https://developers.dingtalk.com/document/isvapp/dingtalk-oapi-alitrip-btrip-exceedapply-train-get + */ + getTrainExceedApply( + query: GetTrainExceedApplyQuery, + ): Promise + /** + * 搜索第三方酒店超标审批单 + * @see https://developers.dingtalk.com/document/isvapp/dingtalk-oapi-alitrip-btrip-exceedapply-hotel-get + */ + getHotelExceedApply( + query: GetHotelExceedApplyQuery, + ): Promise + /** + * 同步超标审批结果 + * @see https://developers.dingtalk.com/document/isvapp/dingtalk-oapi-alitrip-btrip-exceedapply-sync + */ + syncExceedApply( + query: SyncExceedApplyQuery, + ): Promise + /** + * 查询市内用车申请单 + * @see https://developers.dingtalk.com/document/isvapp/query-the-application-form-for-third-party-vehicles-in-the-city + */ + queryCityCarApply( + query: QueryCityCarApplyQuery, + ): Promise + /** + * 审批市内用车申请单 + * @see https://developers.dingtalk.com/document/isvapp/approval-of-third-party-city-car-application-form + */ + approveCityCarApply( + params: ApproveCityCarApplyParams, + ): Promise + /** + * 同步市内用车申请单 + * @see https://developers.dingtalk.com/document/isvapp/synchronize-third-party-city-vehicle-approval-form + */ + addCityCarApply( + params: AddCityCarApplyParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/attendance.ts b/adapters/dingtalk/src/api/attendance.ts new file mode 100644 index 00000000..1582ad65 --- /dev/null +++ b/adapters/dingtalk/src/api/attendance.ts @@ -0,0 +1,81 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetAdjustmentsQuery { + /** 分页起始页。 */ + pageNumber: number + /** 分页大小。 */ + pageSize: number +} + +export interface GetAdjustmentsResponse { + result?: { + pageNumber?: number + totalPage?: number + items?: number + } +} + +export interface GetSimpleOvertimeSettingQuery { + /** 分页起始页。 */ + pageNumber: number + /** 分页大小。 */ + pageSize: number +} + +export interface GetSimpleOvertimeSettingResponse { + result?: { + pageNumber?: number + totalPage?: number + items?: number + } +} + +export interface GetOvertimeSettingParams { + overtimeSettingIds?: number[] +} + +export interface GetOvertimeSettingResponse { + result: { + settingId?: number + name?: string + default?: number + durationSettings?: number + warningSettings?: number + stepType?: number + stepValue?: number + workMinutesPerDay?: number + overtimeDivisions?: number + id: number + }[] +} + +// funcName: isOldApi +Internal.define({ + '/attendance/adjustments': { GET: { getAdjustments: false } }, + '/attendance/overtimeSettings': { GET: { getSimpleOvertimeSetting: false } }, + '/attendance/overtimeSettings/query': { POST: { getOvertimeSetting: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取补卡规则列表 + * @see https://developers.dingtalk.com/document/isvapp/retrieve-a-list-of-replenishment-rules-by-page + */ + getAdjustments(query: GetAdjustmentsQuery): Promise + /** + * 加班规则列表 + * @see https://developers.dingtalk.com/document/isvapp/retrieve-a-list-of-overtime-rules-by-page + */ + getSimpleOvertimeSetting( + query: GetSimpleOvertimeSettingQuery, + ): Promise + /** + * 批量获取加班规则设置 + * @see https://developers.dingtalk.com/document/isvapp/batch-retrieve-overtime-rules + */ + getOvertimeSetting( + params: GetOvertimeSettingParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/badge.ts b/adapters/dingtalk/src/api/badge.ts new file mode 100644 index 00000000..594662ee --- /dev/null +++ b/adapters/dingtalk/src/api/badge.ts @@ -0,0 +1,284 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface CreateBadgeNotifyParams { + /** 用户userid。 */ + userId: string + /** 消息传入,调用方传入,唯一标识消息。 */ + msgId: string + /** 消息类型,取值: */ + msgType: string + /** 通知内容 */ + content: string +} + +export interface CreateBadgeNotifyResponse { + result: unknown +} + +export interface NotifyBadgeCodeVerifyResultParams { + /** 码值,接入方硬件设备扫描钉工牌二维码获取的码值。 */ + payCode: string + /** 企业corpId。 */ + corpId: string + /** 用户和企业的关系类型,用于区分内部员工,外部联系人,无关系普通用户。 */ + userCorpRelationType: string + /** 用户身份标识。 */ + userIdentity: string + /** 验证时间。 */ + verifyTime: string + /** 验证结果。 */ + verifyResult: unknown + /** 验证地点。 */ + verifyLocation?: string + /** 验证流水号,可随机生成,确保用户下唯一 */ + verifyNo?: string + /** 验证事件。8个汉字以内,如门禁验证、班车登记、餐盘绑定等。 */ + verifyEvent?: string + /** 备注信息。 */ + remark?: string +} + +export interface NotifyBadgeCodeVerifyResultResponse { + result: string +} + +export interface SaveBadgeCodeCorpInstanceParams { + /** 码标识,取值: */ + codeIdentity: string + /** 开通的企业corpId。 */ + corpId: string + /** 状态,传入关闭状态需要用户手动开启后才会渲染二维码。 */ + status: string + /** 扩展参数,是否关联支付宝。 */ + extInfo?: unknown +} + +export interface SaveBadgeCodeCorpInstanceResponse { + codeIdentity?: string + corpId?: string + status?: string + extInfo?: unknown +} + +export interface NotifyBadgeCodePayResultParams { + /** 码值,接入方硬件设备扫描钉工牌二维码获取的码值。 */ + payCode: string + /** 企业corpId。 */ + corpId: string + /** 用户userid,需要与生成码时传入的**userid**保持一致。 */ + userId: string + /** 交易开始时间。 */ + gmtTradeCreate: string + /** 交易结束时间。 */ + gmtTradeFinish: string + /** 交易号,接入方自身系统针对交易生成的唯一订单号。 */ + tradeNo: string + /** 交易状态,取值: */ + tradeStatus: string + /** 订单标题。 */ + title: string + /** 备注。 */ + remark: string + /** 订单金额。 */ + amount: string + /** 订单优惠金额。 */ + promotionAmount: string + /** 收费金额。 */ + chargeAmount: string + /** 支付渠道明细信息。 */ + payChannelDetailList: object[] + /** 支付失败错误码,当**tradeStatus**为**FAIL**时必须传入。 */ + tradeErrorCode?: string + /** 支付失败信息,当**tradeStatus**为**FAIL**时必须传入。 */ + tradeErrorMsg?: string + /** 扩展信息。 */ + extInfo?: string + /** 商户名称。 */ + merchantName: string +} + +export interface NotifyBadgeCodePayResultResponse { + result: string +} + +export interface CreateBadgeCodeUserInstanceParams { + /** 业务幂等ID,由调用方随机生成。 */ + requestId: string + /** 码标识,取值: */ + codeIdentity: string + /** 码值,由调用方生成。 */ + codeValue?: string + /** 码值类型,可不传,默认为DING_STATIC */ + codeValueType?: string + /** 状态,传入关闭状态需要用户手动开启后才会渲染二维码。 */ + status: string + /** 企业corpId。 */ + corpId: string + /** 用户和企业的关系类型,用于区分内部员工,外部联系人,无关系普通用户。 */ + userCorpRelationType: string + /** 用户身份标识。 */ + userIdentity: string + /** 临时码过期时间,格式:yyyy-MM-dd HH:mm:ss。 */ + gmtExpired: string + /** 有效时间列表,对于连续时间段,只需传入一个对象即可。 */ + availableTimes: object[] + /** 扩展参数。 */ + extInfo: unknown +} + +export interface CreateBadgeCodeUserInstanceResponse { + codeId: string + codeDetailUrl?: string +} + +export interface NotifyBadgeCodeRefundResultParams { + /** 企业的corpId。 */ + corpId: string + /** 用户userid,需要与生成码时使用的**userid**保持一致。 */ + userId: string + /** 交易订单号,自定义,接入方针对交易生成的唯一订单号。 */ + tradeNo: string + /** 本次退款订单号,自定义,接入方针对交易生成的唯一退款订单号。 */ + refundOrderNo: string + /** 备注。 */ + remark: string + /** 退款金额。 */ + refundAmount: string + /** 退款的优惠金额。 */ + refundPromotionAmount: string + /** 退款时间。 */ + gmtRefund: string + /** 支付渠道明细信息。 */ + payChannelDetailList: object[] + /** 支付时使用的付款码。 */ + payCode: string +} + +export interface NotifyBadgeCodeRefundResultResponse { + result: string +} + +export interface UpdateBadgeCodeUserInstanceParams { + /** 用户码ID。 */ + codeId: string + /** 码标识,取值: */ + codeIdentity: string + /** 码值,由调用方生成。 */ + codeValue?: string + /** 状态,传入关闭状态需要用户手动开启后才会渲染二维码。 */ + status?: string + /** 企业corpId。 */ + corpId: string + /** 用户和企业的关系类型,用于区分内部员工,外部联系人,无关系普通用户。 */ + userCorpRelationType: string + /** 用户身份标识。 */ + userIdentity: string + /** 临时码过期时间,格式:yyyy-MM-dd HH:mm:ss。 */ + gmtExpired: string + /** 有效时间列表,对于连续时间段,只需传入一个对象即可。 */ + availableTimes: object[] + /** 扩展参数。 */ + extInfo: unknown +} + +export interface UpdateBadgeCodeUserInstanceResponse { + codeId?: string +} + +export interface DecodeBadgeCodeParams { + /** 码值,解码接口仅支持钉钉侧生成的码值。 */ + payCode: string + /** 请求ID,由调用方随机生成幂等字符串。 */ + requestId: string +} + +export interface DecodeBadgeCodeResponse { + corpId: string + userId?: string + codeType: string + alipayCode: string + userCorpRelationType: string + codeIdentity?: string + codeId?: string + outBizId?: string + extInfo?: string +} + +// funcName: isOldApi +Internal.define({ + '/badge/notices': { POST: { createBadgeNotify: false } }, + '/badge/codes/verifyResults': { + POST: { notifyBadgeCodeVerifyResult: false }, + }, + '/badge/codes/corpInstances': { POST: { saveBadgeCodeCorpInstance: false } }, + '/badge/codes/payResults': { POST: { notifyBadgeCodePayResult: false } }, + '/badge/codes/userInstances': { + POST: { createBadgeCodeUserInstance: false }, + PUT: { updateBadgeCodeUserInstance: false }, + }, + '/badge/codes/refundResults': { + POST: { notifyBadgeCodeRefundResult: false }, + }, + '/badge/codes/decode': { POST: { decodeBadgeCode: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 钉工牌通知消息 + * @see https://developers.dingtalk.com/document/isvapp/dingtalk-badge-notification-message + */ + createBadgeNotify( + params: CreateBadgeNotifyParams, + ): Promise + /** + * 通知钉工牌码验证结果 + * @see https://developers.dingtalk.com/document/isvapp/notification-dingtalk-badge-verification-result + */ + notifyBadgeCodeVerifyResult( + params: NotifyBadgeCodeVerifyResultParams, + ): Promise + /** + * 配置企业钉工牌 + * @see https://developers.dingtalk.com/document/isvapp/save-dingtalk-enterprise-instance + */ + saveBadgeCodeCorpInstance( + params: SaveBadgeCodeCorpInstanceParams, + ): Promise + /** + * 通知支付结果 + * @see https://developers.dingtalk.com/document/isvapp/sync-dingtalk-badge-code-payment-result + */ + notifyBadgeCodePayResult( + params: NotifyBadgeCodePayResultParams, + ): Promise + /** + * 创建钉工牌电子码 + * @see https://developers.dingtalk.com/document/isvapp/create-a-badge-user-instance + */ + createBadgeCodeUserInstance( + params: CreateBadgeCodeUserInstanceParams, + ): Promise + /** + * 通知退款结果 + * @see https://developers.dingtalk.com/document/isvapp/notification-dingtalk-badge-code-refund-result + */ + notifyBadgeCodeRefundResult( + params: NotifyBadgeCodeRefundResultParams, + ): Promise + /** + * 更新钉工牌电子码 + * @see https://developers.dingtalk.com/document/isvapp/update-dingtalk-user-instance + */ + updateBadgeCodeUserInstance( + params: UpdateBadgeCodeUserInstanceParams, + ): Promise + /** + * 解码钉工牌电子码 + * @see https://developers.dingtalk.com/document/isvapp/stack-dingtalk-badge + */ + decodeBadgeCode( + params: DecodeBadgeCodeParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/blackboard.ts b/adapters/dingtalk/src/api/blackboard.ts new file mode 100644 index 00000000..60d9c1f8 --- /dev/null +++ b/adapters/dingtalk/src/api/blackboard.ts @@ -0,0 +1,27 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface QueryBlackboardSpaceQuery { + /** 操作人userId。 */ + operationUserId: string +} + +export interface QueryBlackboardSpaceResponse { + spaceId?: string +} + +// funcName: isOldApi +Internal.define({ + '/blackboard/spaces': { GET: { queryBlackboardSpace: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取公告钉盘空间信息 + * @see https://developers.dingtalk.com/document/app/obtain-bulletin-nail-disk-space-information + */ + queryBlackboardSpace( + query: QueryBlackboardSpaceQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/calendar.ts b/adapters/dingtalk/src/api/calendar.ts new file mode 100644 index 00000000..cc7ef491 --- /dev/null +++ b/adapters/dingtalk/src/api/calendar.ts @@ -0,0 +1,816 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetMeetingRoomsScheduleParams { + /** 待查询的会议室roomId列表,建议不超过5个。 */ + roomIds: string[] + /** 查询开始时间,iso8601格式,例如:2022-07-29T14:55Z。 */ + startTime: string + /** 查询结束时间,iso8601格式,例如:2022-07-29T14:55Z。 */ + endTime: string +} + +export interface GetMeetingRoomsScheduleResponse { + scheduleInformation?: { + roomId?: string + error?: string + scheduleItems?: number + }[] +} + +export interface AddMeetingRoomsParams { + /** 需要预定的会议室roomId列表,一个日程最多添加5个会议室。 */ + meetingRoomsToAdd: object[] +} + +export interface AddMeetingRoomsResponse { + result?: unknown +} + +export interface RemoveMeetingRoomsParams { + /** 需要取消预定的会议室信息。 */ + meetingRoomsToRemove?: object[] +} + +export interface RemoveMeetingRoomsResponse { + result?: unknown +} + +export interface UnsubscribeCalendarResponse { + result?: unknown +} + +export interface DeleteSubscribedCalendarResponse { + result?: unknown +} + +export interface GetSubscribedCalendarResponse { + calendarId?: string + name?: string + description?: string + author?: string + managers?: string[] + subscribeScope?: { + unionIds?: number + openConversationIds?: number + corpIds?: number + } +} + +export interface CreateSubscribedCalendarParams { + /** 订阅日历的名称。 */ + name: string + /** 订阅日历的描述,最大长度1024字符。 */ + description?: string + /** 订阅日历共同编辑人的unionId。 */ + managers?: string[] + /** 可订阅该日历的对象。 */ + subscribeScope: unknown +} + +export interface CreateSubscribedCalendarResponse { + calendarId?: string +} + +export interface SignOutResponse { + checkOutTime?: number +} + +export interface GetSignOutListQuery { + /** 查询返回结果数,最大值500。 */ + maxResults: number + /** 分页游标。 */ + nextToken?: string + /** 签退信息类型。 */ + type: string +} + +export interface GetSignOutListResponse { + nextToken?: string + users?: { + userId?: string + displayName?: string + checkOutTime?: number + }[] +} + +export interface ListAttendeesQuery { + /** 最大返回记录数,默认值100,最大值500。 */ + maxResults?: number + /** 分页游标。 */ + nextToken?: string +} + +export interface ListAttendeesResponse { + nextToken?: string + attendees?: { + id?: string + displayName?: string + responseStatus?: string + self?: number + isOptional?: number + }[] +} + +export interface SignInResponse { + checkInTime?: number +} + +export interface ListAclsResponse { + acls?: { + privilege?: string + aclId?: string + scope?: number + }[] +} + +export interface CreateAclsParams { + /** 权限信息,取值: */ + privilege: string + /** 是否向授权人发消息。 */ + sendMsg: unknown + /** 权限范围。 */ + scope: unknown +} + +export interface CreateAclsResponse { + privilege?: string + aclId?: string + scope?: { + scopeType?: string + userId?: string + } +} + +export interface GetSignInListQuery { + /** 查询返回结果数,最大值500。 */ + maxResults: number + /** 分页游标。 */ + nextToken?: string + /** 签到信息类型,取值: */ + type: string +} + +export interface GetSignInListResponse { + nextToken?: string + users?: { + userId?: string + displayName?: string + checkInTime?: number + }[] +} + +export interface ListCalendarsResponse { + response?: { + calendars: number + } +} + +export interface GetScheduleParams { + /** 查询目标用户的unionId,可通过[根据userid获取用户详情](https://developers.dingtalk.com/document/app/query-user-details)接口获取。 */ + userIds: string[] + /** 查询的开始时间。 */ + startTime: string + /** 查询的结束时间。 */ + endTime: string +} + +export interface GetScheduleResponse { + scheduleInformation?: { + userId?: string + error?: string + scheduleItems?: number + }[] +} + +export interface ListEventsQuery { + /** 日程开始时间的最小值,格式为ISO-8601的date-time格式,可不填。 */ + timeMin?: string + /** 日程开始时间的最大值,格式为ISO-8601的date-time格式,可不填。 */ + timeMax?: string + /** 是否返回已取消/删除的日程。 */ + showDeleted?: unknown + /** 最大返回记录数,最大值100,默认值100。 */ + maxResults?: number + /** 每个日程的参与者查询个数,默认100,最大100。 */ + maxAttendees?: number + /** 分页游标。 */ + nextToken?: string + /** 同步token,用于增量数据同步场景,一个查询条件已经返回全部数据后(如果数据比较多会分页返回,调用方需要连续使用nextToken查询,直到所有分页都查完nextToken返回null之后),会返回一个syncToken,下次带着该token来查询会返回两次查询之间发生变更的增量数据。 */ + syncToken?: string +} + +export interface ListEventsResponse { + nextToken?: string + events?: { + id?: string + summary?: string + description?: string + start?: number + originStart?: number + end?: number + isAllDay?: number + recurrence?: number + attendees?: number + organizer?: number + location?: number + seriesMasterId?: string + createTime?: string + updateTime?: string + status?: string + onlineMeetingInfo?: number + reminders?: number + extendedProperties?: number + meetingRooms?: number + categories?: number + richTextDescription?: number + }[] + syncToken?: string +} + +export interface GetEventQuery { + /** 最大参与人数,默认值100,最大值500。 */ + maxAttendees?: number +} + +export interface GetEventResponse { + id?: string + summary?: string + description?: string + status: string + start?: { + date?: string + dateTime?: string + timeZone?: string + } + originStart?: { + dateTime?: string + } + end?: { + date?: string + dateTime?: string + timeZone?: string + } + isAllDay?: unknown + recurrence?: { + pattern?: number + range?: number + } + attendees?: { + id?: string + displayName?: string + responseStatus?: string + self?: number + isOptional?: number + }[] + organizer?: { + id?: string + displayName?: string + responseStatus?: string + self?: number + } + location?: { + displayName?: string + meetingRooms?: number + } + seriesMasterId?: string + createTime?: string + updateTime?: string + reminders?: { + method?: string + minutes?: string + }[] + onlineMeetingInfo?: { + type?: string + conferenceId?: string + url?: string + extraInfo?: number + } + extendedProperties?: { + sharedProperties?: number + } + meetingRooms?: { + roomId?: string + responseStatus?: string + displayName?: string + }[] + categories?: { + displayName?: string + }[] + richTextDescription?: { + text?: string + } +} + +export interface AddAttendeeParams { + /** 参与人信息。 */ + attendeesToAdd: object[] +} + +export interface RemoveAttendeeParams { + /** 日程参与人列表。 */ + attendeesToRemove?: object[] +} + +export interface CreateEventParams { + /** 日程标题,最大不超过2048个字符。 */ + summary: string + /** 日程描述,最大不超过5000个字符。 */ + description?: string + /** 日程开始时间。 */ + start: unknown + /** 日程结束时间。 */ + end?: unknown + /** 是否全天日程。 */ + isAllDay?: unknown + /** 日程循环规则。 */ + recurrence?: unknown + /** 日程参与人列表,最多支持500个参与人。 */ + attendees?: object[] + /** 日程地点。 */ + location?: unknown + /** 日程提醒,可以添加多个,如果不传默认提醒时间为: */ + reminders?: object[] + /** 创建日程同时创建线上会议。 */ + onlineMeetingInfo?: unknown + /** JSON格式的扩展能力开关,选填,具体属性定义如下: */ + extra?: unknown +} + +export interface CreateEventResponse { + id?: string + summary?: string + description?: string + start: { + date?: string + dateTime?: string + timeZone?: string + } + end?: { + date?: string + dateTime?: string + timeZone?: string + } + isAllDay?: unknown + recurrence?: { + pattern?: number + range?: number + } + attendees?: { + id?: string + displayName?: string + responseStatus?: string + self?: number + isOptional?: number + }[] + organizer?: { + id?: string + displayName?: string + responseStatus?: string + self?: number + } + location?: { + displayName?: string + } + reminders?: { + method?: string + minutes?: string + }[] + createTime?: string + updateTime?: string + onlineMeetingInfo?: { + type?: string + conferenceId?: string + url?: string + extraInfo?: number + } + uiConfigs?: { + uiName?: string + uiStatus?: string + }[] + richTextDescription?: { + text?: string + } +} + +export interface ListEventsViewQuery { + /** 查询开始时间,格式为ISO-8601的date-time格式。 */ + timeMin?: string + /** 查询截止时间,格式为ISO-8601的date-time格式。 */ + timeMax?: string + /** 最大返回记录数,最大值100,默认值100。 */ + maxResults?: number + /** 每个日程的参与者查询个数,默认100,最大100。如果参会人数超过100人,需要拉取全部参会人请使用 */ + maxAttendees?: number + /** 分页游标。 */ + nextToken?: string +} + +export interface ListEventsViewResponse { + nextToken?: string + events?: { + id?: string + summary?: string + description?: string + start?: number + originStart?: number + end?: number + isAllDay?: number + recurrence?: number + attendees?: number + organizer?: number + location?: number + seriesMasterId?: string + createTime?: string + updateTime?: string + status?: string + extendedProperties?: number + onlineMeetingInfo?: number + categories?: number + richTextDescription?: number + meetingRooms?: number + }[] +} + +export interface RespondEventParams { + /** 响应状态: */ + responseStatus: string +} + +export interface PatchEventParams { + /** 日程标题。 */ + summary?: string + /** 日程ID。 */ + id: string + /** 日程描述。 */ + description?: string + /** 日程开始时间。 */ + start?: unknown + /** 日程结束时间。 */ + end?: unknown + /** 是否全天日程。 */ + isAllDay?: unknown + /** 日程循环规则。 */ + recurrence?: unknown + /** 参会人。 */ + attendees?: object[] + /** 日程地点。 */ + location?: unknown + /** JSON格式的扩展能力开关,选填,具体属性定义如下。 */ + extra?: unknown + /** 单个日程提醒记录。 */ + reminders?: object[] + /** 视频会议。 */ + onlineMeetingInfo?: unknown +} + +export interface PatchEventResponse { + id?: string + summary?: string + description?: string + start: { + date?: string + dateTime?: string + timeZone?: string + } + end?: { + date?: string + dateTime?: string + timeZone?: string + } + isAllDay?: unknown + recurrence?: { + pattern?: number + range?: number + } + attendees?: { + id?: string + displayName?: string + responseStatus?: string + self?: number + isOptional?: number + }[] + organizer?: { + id?: string + displayName?: string + responseStatus?: string + self?: number + } + location?: { + displayName?: string + meetingRooms?: number + } + reminders?: { + method?: string + minutes?: string + }[] + createTime?: string + updateTime?: string + onlineMeetingInfo?: { + type?: string + conferenceId?: string + url?: string + } + richTextDescription?: { + text?: string + } + uiConfigs?: { + uiName: string + uiStatus: string + }[] +} + +// funcName: isOldApi +Internal.define({ + '/calendar/users/{userId}/meetingRooms/schedules/query': { + POST: { getMeetingRoomsSchedule: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/events/{eventId}/meetingRooms': + { POST: { addMeetingRooms: false } }, + '/calendar/users/{userId}/calendars/{calendarId}/events/{eventId}/meetingRooms/batchRemove': + { POST: { removeMeetingRooms: false } }, + '/calendar/users/{userId}/calendars/{calendarId}/unsubscribe': { + POST: { unsubscribeCalendar: false }, + }, + '/calendar/users/{userId}/subscribedCalendars/{calendarId}': { + DELETE: { deleteSubscribedCalendar: false }, + GET: { getSubscribedCalendar: false }, + }, + '/calendar/users/{userId}/subscribedCalendars': { + POST: { createSubscribedCalendar: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/events/{eventId}/signOut': { + POST: { signOut: false }, + GET: { getSignOutList: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/subscribe': { + POST: { subscribeCalendar: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/events/{eventId}/attendees': + { GET: { listAttendees: false }, POST: { addAttendee: false } }, + '/calendar/users/{userId}/calendars/{calendarId}/events/{eventId}/signin': { + POST: { signIn: false }, + GET: { getSignInList: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/acls': { + GET: { listAcls: false }, + POST: { createAcls: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/acls/{aclId}': { + DELETE: { deleteAcl: false }, + }, + '/calendar/users/{userId}/calendars': { GET: { listCalendars: false } }, + '/calendar/users/{userId}/querySchedule': { POST: { getSchedule: false } }, + '/calendar/users/{userId}/calendars/{calendarId}/events': { + GET: { listEvents: false }, + POST: { createEvent: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/events/{eventId}': { + GET: { getEvent: false }, + DELETE: { deleteEvent: false }, + PUT: { patchEvent: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/events/{eventId}/attendees/batchRemove': + { POST: { removeAttendee: false } }, + '/calendar/users/{userId}/calendars/{calendarId}/eventsview': { + GET: { listEventsView: false }, + }, + '/calendar/users/{userId}/calendars/{calendarId}/events/{eventId}/respond': { + POST: { respondEvent: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 查询会议室忙闲 + * @see https://developers.dingtalk.com/document/isvapp/queries-free-and-busy-meeting-room-information + */ + getMeetingRoomsSchedule( + userId: string, + params: GetMeetingRoomsScheduleParams, + ): Promise + /** + * 添加会议室 + * @see https://developers.dingtalk.com/document/app/add-a-meeting-room + */ + addMeetingRooms( + userId: string, + calendarId: string, + eventId: string, + params: AddMeetingRoomsParams, + ): Promise + /** + * 删除会议室 + * @see https://developers.dingtalk.com/document/isvapp/cancel-a-meeting-room-reservation + */ + removeMeetingRooms( + userId: string, + calendarId: string, + eventId: string, + params: RemoveMeetingRoomsParams, + ): Promise + /** + * 取消订阅公共日历 + * @see https://developers.dingtalk.com/document/orgapp/unsubscribe-from-a-public-calendar + */ + unsubscribeCalendar( + userId: string, + calendarId: string, + ): Promise + /** + * 删除订阅日历 + * @see https://developers.dingtalk.com/document/isvapp/delete-subscription-calendar + */ + deleteSubscribedCalendar( + userId: string, + calendarId: string, + ): Promise + /** + * 查询单个订阅日历详情 + * @see https://developers.dingtalk.com/document/isvapp/query-a-single-subscription-calendar + */ + getSubscribedCalendar( + userId: string, + calendarId: string, + ): Promise + /** + * 创建订阅日历 + * @see https://developers.dingtalk.com/document/isvapp/create-subscription-calendar + */ + createSubscribedCalendar( + userId: string, + params: CreateSubscribedCalendarParams, + ): Promise + /** + * 针对单个日程进行签退 + * @see https://developers.dingtalk.com/document/isvapp/sign-off-for-a-single-schedule + */ + signOut( + userId: string, + calendarId: string, + eventId: string, + ): Promise + /** + * 查看单个日程的签退详情 + * @see https://developers.dingtalk.com/document/isvapp/view-the-billing-details-of-a-single-schedule + */ + getSignOutList( + userId: string, + calendarId: string, + eventId: string, + query: GetSignOutListQuery, + ): Promise + /** + * 订阅公共日历 + * @see https://developers.dingtalk.com/document/orgapp/subscribe-to-a-public-calendar + */ + subscribeCalendar(userId: string, calendarId: string): Promise + /** + * 获取日程参与者 + * @see https://developers.dingtalk.com/document/isvapp/query-schedule-participants + */ + listAttendees( + userId: string, + calendarId: string, + eventId: string, + query: ListAttendeesQuery, + ): Promise + /** + * 针对单个日程进行签到 + * @see https://developers.dingtalk.com/document/orgapp-server/sign-in-for-a-single-schedule + */ + signIn( + userId: string, + calendarId: string, + eventId: string, + ): Promise + /** + * 获取访问控制列表 + * @see https://developers.dingtalk.com/document/personalapp/get-access-control-list + */ + listAcls(userId: string, calendarId: string): Promise + /** + * 删除访问控制 + * @see https://developers.dingtalk.com/document/personalapp/delete-access-control + */ + deleteAcl(userId: string, calendarId: string, aclId: string): Promise + /** + * 创建访问控制 + * @see https://developers.dingtalk.com/document/personalapp/create-access-control + */ + createAcls( + userId: string, + calendarId: string, + params: CreateAclsParams, + ): Promise + /** + * 查看单个日程的签到详情 + * @see https://developers.dingtalk.com/document/isvapp/view-the-check-in-details-of-a-single-schedule + */ + getSignInList( + userId: string, + calendarId: string, + eventId: string, + query: GetSignInListQuery, + ): Promise + /** + * 查询日历 + * @see https://developers.dingtalk.com/document/isvapp/query-the-calendar + */ + listCalendars(userId: string): Promise + /** + * 获取用户忙闲信息 + * @see https://developers.dingtalk.com/document/isvapp/free-schedule + */ + getSchedule( + userId: string, + params: GetScheduleParams, + ): Promise + /** + * 查询日程列表 + * @see https://developers.dingtalk.com/document/personalapp/query-an-event-list-1 + */ + listEvents( + userId: string, + calendarId: string, + query: ListEventsQuery, + ): Promise + /** + * 查询日程列表 + * @see https://developers.dingtalk.com/document/personalapp/query-a-single-schedule + */ + getEvent( + userId: string, + calendarId: string, + eventId: string, + query: GetEventQuery, + ): Promise + /** + * 新增日程参与人 + * @see https://developers.dingtalk.com/document/isvapp/add-schedule-participant + */ + addAttendee( + userId: string, + calendarId: string, + eventId: string, + params: AddAttendeeParams, + ): Promise + /** + * 删除日程参与人 + * @see https://developers.dingtalk.com/document/isvapp/delete-schedule-participant + */ + removeAttendee( + userId: string, + calendarId: string, + eventId: string, + params: RemoveAttendeeParams, + ): Promise + /** + * 删除指定日程 + * @see https://developers.dingtalk.com/document/isvapp/delete-schedule + */ + deleteEvent( + userId: string, + calendarId: string, + eventId: string, + ): Promise + /** + * 创建日程 + * @see https://developers.dingtalk.com/document/personalapp/create-schedule + */ + createEvent( + userId: string, + calendarId: string, + params: CreateEventParams, + ): Promise + /** + * 查询日程视图列表以查看闲忙,展开循环日程 + * @see https://developers.dingtalk.com/document/personalapp/query-schedule-view-1 + */ + listEventsView( + userId: string, + calendarId: string, + query: ListEventsViewQuery, + ): Promise + /** + * 回复日程邀请 + * @see https://developers.dingtalk.com/document/isvapp/participants-respond-to-schedule-invitations + */ + respondEvent( + userId: string, + calendarId: string, + eventId: string, + params: RespondEventParams, + ): Promise + /** + * 修改日程 + * @see https://developers.dingtalk.com/document/personalapp/modify-schedule + */ + patchEvent( + userId: string, + calendarId: string, + eventId: string, + params: PatchEventParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/card.ts b/adapters/dingtalk/src/api/card.ts new file mode 100644 index 00000000..933e3573 --- /dev/null +++ b/adapters/dingtalk/src/api/card.ts @@ -0,0 +1,214 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface UpdateCardParams { + /** 外部卡片实例Id。 */ + outTrackId: string + /** 卡片数据 */ + cardData?: unknown + /** 用户的私有数据。 */ + privateData?: unknown + /** 卡片更新选项 */ + cardUpdateOptions?: unknown +} + +export interface UpdateCardResponse { + success?: unknown + result?: unknown +} + +export interface CreateCardParams { + /** 卡片创建者的userId。 */ + userId?: string + /** 卡片内容模板ID,可通过登录[开发者后台 > 卡片平台](https://open-dev.dingtalk.com/fe/card)获取。 */ + cardTemplateId: string + /** 外部卡片实例Id。 */ + outTrackId: string + /** 卡片回调的类型: */ + callbackType?: string + /** 卡片回调HTTP模式时的路由 Key,用于查询注册的 callbackUrl。 */ + callbackRouteKey?: string + /** 卡片数据,示例: */ + cardData: unknown + /** 用户的私有数据: */ + privateData?: unknown + /** 动态数据源配置。 */ + openDynamicDataConfig?: unknown + /** IM 群聊场域信息。 */ + imGroupOpenSpaceModel?: unknown + /** IM 单聊场域信息。 */ + imRobotOpenSpaceModel?: unknown + /** 协作场域信息。 */ + coFeedOpenSpaceModel?: unknown + /** 吊顶场域信息。 */ + topOpenSpaceModel?: unknown + /** 用户id类型: */ + userIdType?: number +} + +export interface CreateCardResponse { + success?: unknown + result?: string +} + +export interface CreateAndDeliverParams { + /** 卡片创建者的userId。 */ + userId?: string + /** 卡片内容模板ID,可通过登录[开发者后台 > 卡片平台](https://open-dev.dingtalk.com/fe/card)获取。 */ + cardTemplateId: string + /** 外部卡片实例Id。 */ + outTrackId: string + /** 卡片回调的类型: */ + callbackType?: string + /** 卡片回调HTTP模式时的路由 Key,用于查询注册的 callbackUrl。 */ + callbackRouteKey?: string + /** 卡片数据,示例: */ + cardData: unknown + /** 用户的私有数据: */ + privateData?: unknown + /** 动态数据源配置。 */ + openDynamicDataConfig?: unknown + /** IM群聊场域信息。 */ + imGroupOpenSpaceModel?: unknown + /** IM机器人单聊场域信息。 */ + imRobotOpenSpaceModel?: unknown + /** 协作场域信息。 */ + coFeedOpenSpaceModel?: unknown + /** 吊顶场域信息。 */ + topOpenSpaceModel?: unknown + /** 表示场域及其场域id,其格式为`dtv1.card//spaceType1.spaceId1;spaceType2.spaceId2_1;spaceType2.spaceId2_2;spaceType3.spaceId3`。 */ + openSpaceId: string + /** 群聊投放参数。 */ + imGroupOpenDeliverModel?: unknown + /** IM机器人单聊投放参数。 */ + imRobotOpenDeliverModel?: unknown + /** 吊顶投放参数。 */ + topOpenDeliverModel?: unknown + /** 协作投放参数。 */ + coFeedOpenDeliverModel?: unknown + /** 文档投放参数 */ + docOpenDeliverModel?: unknown + /** 用户userId类型: */ + userIdType?: number +} + +export interface CreateAndDeliverResponse { + success?: unknown + result?: { + outTrackId?: string + deliverResults?: number + } +} + +export interface RegisterCallbackParams { + /** 回调地址的路由 Key,一个 callbackRouteKey 仅可映射一个 callbackUrl */ + callbackRouteKey: string + /** 接受动态卡片回调的 URL 地址 */ + callbackUrl: string + /** 加密密钥用于校验来源 */ + apiSecret?: string + /** 是否强制覆盖更新,默认 false。 */ + forceUpdate?: unknown +} + +export interface RegisterCallbackResponse { + success?: unknown + result?: { + callbackUrl?: string + apiSecret?: string + } +} + +export interface AppendSpaceParams { + /** 外部卡片实例Id。 */ + outTrackId: string + /** IM群聊场域信息 */ + imGroupOpenSpaceModel?: unknown + /** 机器人单聊场域参数 */ + imRobotOpenSpaceModel?: unknown + /** 吊顶场域信息 */ + topOpenSpaceModel?: unknown + /** 协作场域信息 */ + coFeedOpenSpaceModel?: unknown +} + +export interface AppendSpaceResponse { + success?: unknown + result?: unknown +} + +export interface DeliverCardParams { + /** 外部卡片实例Id。 */ + outTrackId: string + /** 表示场域及其场域id,其格式为dtv1.card//spaceType1.spaceId1;spaceType2,spaceId2;spaceType3,spaceId3 */ + openSpaceId: string + /** 单聊场域投放参数 */ + imSingleOpenDeliverModel?: unknown + /** 群聊投放参数 */ + imGroupOpenDeliverModel?: unknown + /** 吊顶投放参数 */ + topOpenDeliverModel?: unknown + /** 协作投放参数 */ + coFeedOpenDeliverModel?: unknown + /** 工作台投放参数 */ + workBenchOpenDeliverModel?: unknown +} + +export interface DeliverCardResponse { + success?: unknown + result?: { + spaceType?: string + spaceId?: string + success?: number + }[] +} + +// funcName: isOldApi +Internal.define({ + '/card/instances': { + PUT: { updateCard: false }, + POST: { createCard: false }, + }, + '/card/instances/createAndDeliver': { POST: { createAndDeliver: false } }, + '/card/callbacks/register': { POST: { registerCallback: false } }, + '/card/instances/spaces': { PUT: { appendSpace: false } }, + '/card/instances/deliver': { POST: { deliverCard: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 更新卡片 + * @see https://developers.dingtalk.com/document/orgapp/interactive-card-update-interface + */ + updateCard(params: UpdateCardParams): Promise + /** + * 创建卡片 + * @see https://developers.dingtalk.com/document/orgapp/interface-for-creating-a-card-instance + */ + createCard(params: CreateCardParams): Promise + /** + * 创建并投放卡片 + * @see https://developers.dingtalk.com/document/orgapp/create-and-deliver-cards + */ + createAndDeliver( + params: CreateAndDeliverParams, + ): Promise + /** + * 注册卡片回调地址 + * @see https://developers.dingtalk.com/document/orgapp/register-card-callback-address + */ + registerCallback( + params: RegisterCallbackParams, + ): Promise + /** + * 新增或更新卡片的场域信息 + * @see https://developers.dingtalk.com/document/orgapp/add-field-interface + */ + appendSpace(params: AppendSpaceParams): Promise + /** + * 投放卡片 + * @see https://developers.dingtalk.com/document/isvapp/delivery-card-interface + */ + deliverCard(params: DeliverCardParams): Promise + } +} diff --git a/adapters/dingtalk/src/api/conference.ts b/adapters/dingtalk/src/api/conference.ts new file mode 100644 index 00000000..cf56470c --- /dev/null +++ b/adapters/dingtalk/src/api/conference.ts @@ -0,0 +1,560 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface InviteUsersParams { + /** 操作用户unionId。 */ + unionId?: string + /** 被邀请人对象。 */ + inviteeList?: object[] +} + +export interface InviteUsersResponse { + success?: unknown +} + +export interface FocusParams { + /** 行为动作: */ + action: string + /** 被操作用户unionId。 */ + unionId: string +} + +export interface FocusResponse { + success?: unknown +} + +export interface CohostsParams { + /** 行为动作: */ + action: string + /** 被操作用户对象。 */ + userList: object[] +} + +export interface CohostsResponse { + success?: unknown +} + +export interface MuteMembersParams { + /** 操作类型: */ + action: string + /** 被操作用户对象。 */ + userList: object[] +} + +export interface MuteMembersResponse { + success?: unknown +} + +export interface QueryScheduleConferenceInfoQuery { + /** 标记当前开始读取的位置,置空表示从头开始 */ + nextToken?: string + /** 本次读取的最大数据记录数量 */ + maxResults?: number +} + +export interface QueryScheduleConferenceInfoResponse { + totalCount?: number + nextToken: string + conferenceList?: { + conferenceId?: string + title?: string + roomCode?: string + status?: number + startTime?: number + endTime?: number + }[] +} + +export interface QueryCloudRecordVideoQuery { + /** 用户unionId。 */ + unionId: string +} + +export interface QueryCloudRecordVideoResponse { + videoList?: { + recordId?: string + unionId?: string + startTime?: number + recordType?: number + duration?: number + fileSize?: number + endTime?: number + mediaId?: string + regionId?: string + }[] +} + +export interface QueryCloudRecordTextQuery { + /** 用户unionId。 */ + unionId?: string + /** 开始时间的千分之一秒,单位毫秒。 */ + startTime?: number + /** 查询方式: */ + direction?: string + /** 单词查询条数,最大2000。 */ + maxResults?: number + /** 分页游标。 */ + nextToken?: number +} + +export interface QueryCloudRecordTextResponse { + hasMore?: unknown + paragraphList?: { + nextTtoken?: number + status?: number + unionId?: string + nickName?: string + recordId?: number + startTime?: number + endTime?: number + paragraph?: string + sentenceList?: number + }[] +} + +export interface QueryCloudRecordVideoPlayInfoQuery { + /** 用户unionId。 */ + unionId: string + /** 媒体文件ID。 */ + mediaId: string + /** 地域ID。 */ + regionId: string +} + +export interface QueryCloudRecordVideoPlayInfoResponse { + playUrl?: string + mp4FileUrl?: string + fileSize?: number + duration?: number + status?: number +} + +export interface StopCloudRecordParams { + /** 用户unionId。 */ + unionId: string +} + +export interface StopCloudRecordResponse { + code?: string +} + +export interface StopStreamOutParams { + /** 推流ID,开启视频会议直播推流后生成。 */ + streamId: string + /** 是否停止所有流,为true时**streamId**参数无效。 */ + stopAllStream: unknown + /** 用户unionId,可以调用[通过免登码获取用户信息(v2)](https://developers.dingtalk.com/document/app/obtain-the-userid-of-a-user-by-using-the-log-free)接口获取。 */ + unionId: string +} + +export interface StopStreamOutResponse { + code: string +} + +export interface StartStreamOutParams { + /** 用户unionId,可以调用[通过免登码获取用户信息(v2)](https://developers.dingtalk.com/document/app/obtain-the-userid-of-a-user-by-using-the-log-free)接口获取。 */ + unionId: string + /** 是否需要主持人加入后才允许推流。 */ + needHostJoin: unknown + /** 推流地址列表,最多10个,需要以rtmp开头。 */ + streamUrlList: string[] + /** 推流名称。 */ + streamName: string + /** 布局,取值: */ + mode: string + /** 小窗位置,取值: */ + smallWindowPosition: string +} + +export interface StartStreamOutResponse { + successStreamMap?: unknown + failStreamMap?: unknown +} + +export interface StartCloudRecordParams { + /** 用户unionId。 */ + unionId: string + /** 小窗位置,取值: */ + smallWindowPosition?: string + /** 布局,取值: */ + mode?: string +} + +export interface StartCloudRecordResponse { + code?: string +} + +export interface QueryConferenceInfoBatchParams { + /** 会议ID列表。 */ + conferenceIdList: string[] +} + +export interface QueryConferenceInfoBatchResponse { + infos?: { + conferenceId?: string + title?: string + startTime?: number + status?: number + mediaStatus?: number + userList?: number + }[] +} + +export interface CloseVideoConferenceQuery { + /** 员工在当前开发者企业账号范围内的唯一标识。 */ + unionId: string +} + +export interface CloseVideoConferenceResponse { + code: number + cause?: string +} + +export interface CreateVideoConferenceParams { + /** 会议发起人的unionId。 */ + userId: string + /** 会议主题,最多不能超20个中文。 */ + confTitle: string + /** 邀请参会人员unionId列表。 */ + inviteUserIds?: string[] + /** 是否邀请主叫。 */ + inviteCaller?: unknown +} + +export interface CreateVideoConferenceResponse { + conferenceId: string + conferencePassword?: string + hostPassword?: string + externalLinkUrl?: string + phoneNumbers?: string[] + roomCode?: string +} + +export interface QueryConferenceMembersQuery { + /** 分页游标。 */ + nextToken?: string + /** 每页最大条目数,默认值300,无最大值限制。 */ + maxResults?: number +} + +export interface QueryConferenceMembersResponse { + memberModels?: { + unionId?: string + conferenceId?: string + userNick?: string + joinTime?: number + leaveTime?: number + duration?: number + host?: number + attendStatus?: number + outerOrgMember?: number + pstnJoin?: number + coHost?: number + }[] + nextToken?: string + totalCount?: number +} + +export interface QueryConferenceInfoResponse { + confInfo?: { + activeNum?: number + attendNum?: number + confDuration?: number + conferenceId?: string + creatorId?: string + creatorNick?: string + externalLinkUrl?: string + invitedNum?: number + startTime?: number + status?: number + title?: string + roomCode?: string + endTime?: number + } +} + +export interface CancelScheduleConferenceParams { + /** 预约会议id: */ + scheduleConferenceId: string + /** 预约会议创建者unionId。 */ + creatorUnionId: string +} + +export interface CancelScheduleConferenceResponse { + success?: unknown +} + +export interface QueryScheduleConferenceQuery { + /** 请求者unionId。 */ + requestUnionId: string +} + +export interface QueryScheduleConferenceResponse { + requestId?: string + scheduleConferenceId?: string + title?: string + startTime?: number + endTime?: number + roomCode?: string + url?: string + phones?: string[] +} + +export interface UpdateScheduleConferenceParams { + /** 预约会议创建者unionId。 */ + creatorUnionId: string + /** 预约会议id: */ + scheduleConferenceId: string + /** 预约会议标题。 */ + title: string + /** 预约会议开始时间,毫秒级UTC时间戳。 */ + startTime: number + /** 预约会议结束时间,毫秒级UTC时间戳。 */ + endTime: number +} + +export interface UpdateScheduleConferenceResponse { + success?: unknown +} + +export interface CreateScheduleConferenceParams { + /** 创建者unionId。 */ + creatorUnionId: string + /** 预约会议标题。 */ + title: string + /** 预约会议开始时间,毫秒级UTC时间戳。 */ + startTime: number + /** 预约会议结束时间,毫秒级UTC时间戳。 */ + endTime: number +} + +export interface CreateScheduleConferenceResponse { + requestId?: string + scheduleConferenceId?: string + roomCode?: string + url?: string + phones?: string[] +} + +// funcName: isOldApi +Internal.define({ + '/conference/videoConferences/{conferenceId}/users/invite': { + POST: { inviteUsers: false }, + }, + '/conference/videoConferences/{conferenceId}/focus': { + POST: { focus: false }, + }, + '/conference/videoConferences/{conferenceId}/coHosts/set': { + POST: { cohosts: false }, + }, + '/conference/videoConferences/{conferenceId}/members/mute': { + POST: { muteMembers: false }, + }, + '/conference/videoConferences/scheduleConferences/{scheduleConferenceId}': { + GET: { queryScheduleConferenceInfo: false }, + }, + '/conference/videoConferences/{conferenceId}/cloudRecords/getVideos': { + GET: { queryCloudRecordVideo: false }, + }, + '/conference/videoConferences/{conferenceId}/cloudRecords/getTexts': { + GET: { queryCloudRecordText: false }, + }, + '/conference/videoConferences/{conferenceId}/cloudRecords/videos/getPlayInfos': + { GET: { queryCloudRecordVideoPlayInfo: false } }, + '/conference/videoConferences/{conferenceId}/cloudRecords/stop': { + POST: { stopCloudRecord: false }, + }, + '/conference/videoConferences/{conferenceId}/streamOuts/stop': { + POST: { stopStreamOut: false }, + }, + '/conference/videoConferences/{conferenceId}/streamOuts/start': { + POST: { startStreamOut: false }, + }, + '/conference/videoConferences/{conferenceId}/cloudRecords/start': { + POST: { startCloudRecord: false }, + }, + '/conference/videoConferences/query': { + POST: { queryConferenceInfoBatch: false }, + }, + '/conference/videoConferences/{conferenceId}': { + DELETE: { closeVideoConference: false }, + GET: { queryConferenceInfo: false }, + }, + '/conference/videoConferences': { POST: { createVideoConference: false } }, + '/conference/videoConferences/{conferenceId}/members': { + GET: { queryConferenceMembers: false }, + }, + '/conference/scheduleConferences/cancel': { + POST: { cancelScheduleConference: false }, + }, + '/conference/scheduleConferences/{scheduleConferenceId}/infos': { + GET: { queryScheduleConference: false }, + }, + '/conference/scheduleConferences': { + PUT: { updateScheduleConference: false }, + POST: { createScheduleConference: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 邀请其他人员 + * @see https://developers.dingtalk.com/document/orgapp/invite-users-to-join + */ + inviteUsers( + conferenceId: string, + params: InviteUsersParams, + ): Promise + /** + * 设置全员看他 + * @see https://developers.dingtalk.com/document/orgapp/set-the-whole-staff-to-see-him + */ + focus(conferenceId: string, params: FocusParams): Promise + /** + * 设置联席主持人 + * @see https://developers.dingtalk.com/document/orgapp/set-up-co-hosts + */ + cohosts( + conferenceId: string, + params: CohostsParams, + ): Promise + /** + * 指定人员静音或取消静音 + * @see https://developers.dingtalk.com/document/orgapp/specify-person-to-mute-or-unmute + */ + muteMembers( + conferenceId: string, + params: MuteMembersParams, + ): Promise + /** + * 分页获取预约会议历史会议信息,当前仅返回最后一次的会议信息 + * @see https://developers.dingtalk.com/document/orgapp/query-appointment-meeting-history-meeting-information + */ + queryScheduleConferenceInfo( + scheduleConferenceId: string, + query: QueryScheduleConferenceInfoQuery, + ): Promise + /** + * 查询会议录制的详情信息 + * @see https://developers.dingtalk.com/document/isvapp/query-recording-information + */ + queryCloudRecordVideo( + conferenceId: string, + query: QueryCloudRecordVideoQuery, + ): Promise + /** + * 查询会议录制中的文本信息 + * @see https://developers.dingtalk.com/document/isvapp/queries-the-text-information-about-cloud-recording + */ + queryCloudRecordText( + conferenceId: string, + query: QueryCloudRecordTextQuery, + ): Promise + /** + * 查询会议录制中的视频信息 + * @see https://developers.dingtalk.com/document/isvapp/queries-the-playback-information-about-a-recorded-cloud-video + */ + queryCloudRecordVideoPlayInfo( + conferenceId: string, + query: QueryCloudRecordVideoPlayInfoQuery, + ): Promise + /** + * 停止视频会议云录制 + * @see https://developers.dingtalk.com/document/isvapp/video-conferencing-stops-cloud-recording + */ + stopCloudRecord( + conferenceId: string, + params: StopCloudRecordParams, + ): Promise + /** + * 会议停止直播推流 + * @see https://developers.dingtalk.com/document/orgapp/videoconferencing-stops-live-stream-ingest + */ + stopStreamOut( + conferenceId: string, + params: StopStreamOutParams, + ): Promise + /** + * 会议开始直播推流 + * @see https://developers.dingtalk.com/document/orgapp/video-conference-enables-live-stream-ingest + */ + startStreamOut( + conferenceId: string, + params: StartStreamOutParams, + ): Promise + /** + * 开启视频会议云录制 + * @see https://developers.dingtalk.com/document/isvapp/video-conference-open-cloud-recording + */ + startCloudRecord( + conferenceId: string, + params: StartCloudRecordParams, + ): Promise + /** + * 批量查询视频会议信息 + * @see https://developers.dingtalk.com/document/isvapp/batch-query-of-video-conference-information + */ + queryConferenceInfoBatch( + params: QueryConferenceInfoBatchParams, + ): Promise + /** + * 关闭视频会议 + * @see https://developers.dingtalk.com/document/isvapp/close-audio-video-conferencing + */ + closeVideoConference( + conferenceId: string, + query: CloseVideoConferenceQuery, + ): Promise + /** + * 创建视频会议 + * @see https://developers.dingtalk.com/document/isvapp/create-a-video-conference + */ + createVideoConference( + params: CreateVideoConferenceParams, + ): Promise + /** + * 查询视频会议成员 + * @see https://developers.dingtalk.com/document/app/query-video-meeting-member-information + */ + queryConferenceMembers( + conferenceId: string, + query: QueryConferenceMembersQuery, + ): Promise + /** + * 查询视频会议信息 + * @see https://developers.dingtalk.com/document/app/querying-video-conference-information + */ + queryConferenceInfo( + conferenceId: string, + ): Promise + /** + * 取消预约会议 + * @see https://developers.dingtalk.com/document/app/cancel-appointment-meeting + */ + cancelScheduleConference( + params: CancelScheduleConferenceParams, + ): Promise + /** + * 查询预约会议信息 + * @see https://developers.dingtalk.com/document/app/query-meeting-reservation + */ + queryScheduleConference( + scheduleConferenceId: string, + query: QueryScheduleConferenceQuery, + ): Promise + /** + * 更新预约会议 + * @see https://developers.dingtalk.com/document/app/update-appointment-meeting + */ + updateScheduleConference( + params: UpdateScheduleConferenceParams, + ): Promise + /** + * 创建预约会议 + * @see https://developers.dingtalk.com/document/app/create-appointment-meeting + */ + createScheduleConference( + params: CreateScheduleConferenceParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/connector.ts b/adapters/dingtalk/src/api/connector.ts new file mode 100644 index 00000000..9f977545 --- /dev/null +++ b/adapters/dingtalk/src/api/connector.ts @@ -0,0 +1,96 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface PullDataByPkQuery { + /** 数据的主键字段值。 */ + primaryKey: string + /** 同步数据的应用ID,第三方企业应用传应用的appId,企业自建应用传agentId。 */ + appId?: string +} + +export interface PullDataByPkResponse { + dataGmtCreate: number + dataGmtModified: number + dataCreateAppType: string + dataCreateAppId: string + dataModifiedAppType: string + dataModifiedAppId: string + jsonData: string +} + +export interface PullDataByPageQuery { + /** 要拉取的主数据模型id。 */ + dataModelId: string + /** 用于过滤时间范围的字段,包含数据创建时间(dataGmtCreate)和数据修改时间(dataGmtModified),如不传则不过滤。 */ + datetimeFilterField?: string + /** 当配置了datetimeFilterField字段后,数据的时间起点,如果不传则将最早一条数据作为起点。 */ + minDatetime?: number + /** 当配置了datetimeFilterField字段后,数据的时间终点,如果不传则按最新一条数据作为终点。 */ + maxDatetime?: number + /** 用于翻页的游标,如果为空则从第一条数据开始查询。 */ + nextToken?: string + /** 单次获取的最大记录条数,最大限制100条。 */ + maxResults?: number + /** 同步数据的应用ID,第三方企业应用传应用的appId,企业自建应用传agentId。 */ + appId?: string +} + +export interface PullDataByPageResponse { + list: { + dataGmtCreate: number + dataGmtModified: number + dataCreateAppType: string + dataCreateAppId: string + dataModifiedAppType: string + dataModifiedAppId: string + jsonData: string + }[] + nextToken?: string + maxResults?: number +} + +export interface SyncDataParams { + /** 支持批量同步数据。 */ + triggerDataList: object[] + /** 同步数据的应用ID: */ + appId?: string +} + +export interface SyncDataResponse { + list: { + triggerId: string + bizPrimaryKey: string + success: number + subErrCode: string + subErrMsg: string + }[] +} + +// funcName: isOldApi +Internal.define({ + '/connector/data/{dataModelId}': { GET: { pullDataByPk: false } }, + '/connector/data': { GET: { pullDataByPage: false } }, + '/connector/triggers/data/sync': { POST: { syncData: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 通过业务主键拉取单条连接器主数据 + * @see https://developers.dingtalk.com/document/connector/pull-a-single-primary-record-based-on-the-business-primary + */ + pullDataByPk( + dataModelId: string, + query: PullDataByPkQuery, + ): Promise + /** + * 分页拉取连接器主数据 + * @see https://developers.dingtalk.com/document/connector/bulk-pull-dingtalk-connector-master-data + */ + pullDataByPage(query: PullDataByPageQuery): Promise + /** + * 同步连接器数据 + * @see https://developers.dingtalk.com/document/connector/dingtalk-connector-data-synchronization-interface + */ + syncData(params: SyncDataParams): Promise + } +} diff --git a/adapters/dingtalk/src/api/contact.ts b/adapters/dingtalk/src/api/contact.ts new file mode 100644 index 00000000..73205ca1 --- /dev/null +++ b/adapters/dingtalk/src/api/contact.ts @@ -0,0 +1,55 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetOrgAuthInfoQuery { + /** 需要获取的企业认证信息的企业corpId。详情参见[基础概念-CorpId](https://open.dingtalk.com/document/org/basic-concepts)。 */ + targetCorpId?: string +} + +export interface GetOrgAuthInfoResponse { + orgName: string + licenseOrgName: string + registrationNum?: string + unifiedSocialCredit?: string + organizationCode?: string + legalPerson?: string + licenseUrl?: string + authLevel: number +} + +export interface BatchApproveUnionApplyParams { + /** 申请的合作伙伴组织CorpId,参考[基础概念-CorpId](https://open.dingtalk.com/document/org/basic-concepts)。 */ + branchCorpId?: string + /** 合作伙伴组织在上下游组织内的名称。 */ + unionRootName?: string + /** 合作伙伴组织在上下游组织内的位置。 */ + linkDeptId?: number +} + +export interface BatchApproveUnionApplyResponse { + result?: unknown +} + +// funcName: isOldApi +Internal.define({ + '/contact/organizations/authInfos': { GET: { getOrgAuthInfo: false } }, + '/contact/cooperateCorps/unionApplications/approve': { + POST: { batchApproveUnionApply: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 查询企业认证信息 + * @see https://developers.dingtalk.com/document/isvapp/obtain-enterprise-authentication-information + */ + getOrgAuthInfo(query: GetOrgAuthInfoQuery): Promise + /** + * 批量通过分支组织的关联申请 + * @see https://developers.dingtalk.com/document/isvapp/apply-for-association-with-multiple-branches-in-batch-batch-through-the-application-of-partner-organizations-to-join-contact + */ + batchApproveUnionApply( + params: BatchApproveUnionApplyParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/convFile.ts b/adapters/dingtalk/src/api/convFile.ts new file mode 100644 index 00000000..b38367ee --- /dev/null +++ b/adapters/dingtalk/src/api/convFile.ts @@ -0,0 +1,165 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface SendLinkParams { + /** 文件所在空间ID,调用[添加空间](https://open.dingtalk.com/document/orgapp-server/add-space)接口获取id参数值。 */ + spaceId: string + /** 文件ID,调用[获取文件或文件夹列表](https://open.dingtalk.com/document/orgapp-server/obtain-the-file-list-storage)接口获取id参数值。 */ + dentryId: string + /** 目标会话的openConversationId,调用[创建群会话](https://open.dingtalk.com/document/orgapp-server/create-group-session)接口获取openConversationId参数值。 */ + openConversationId: string +} + +export interface SendLinkQuery { + /** 操作人的unionId,调用[查询用户详情](https://open.dingtalk.com/document/orgapp-server/query-user-details)接口获取unionid参数值。 */ + unionId: string +} + +export interface SendLinkResponse { + file?: { + id?: string + conversationId?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + uuid?: string + } +} + +export interface SendParams { + /** 空间ID,调用[添加空间](https://open.dingtalk.com/document/orgapp-server/add-space)接口获取id参数值。 */ + spaceId: string + /** 文件ID,调用[获取文件或文件夹列表](https://open.dingtalk.com/document/orgapp-server/obtain-the-file-list-storage)接口获取id参数值。 */ + dentryId: string + /** 目标会话的openConversationId,调用[创建群会话](https://open.dingtalk.com/document/orgapp-server/create-group-session)接口获取openConversationId参数值。 */ + openConversationId: string +} + +export interface SendQuery { + /** 操作人的unionId,调用[查询用户详情](https://open.dingtalk.com/document/orgapp-server/query-user-details)接口获取unionid参数值。 */ + unionId: string +} + +export interface SendResponse { + file?: { + id?: string + conversationId?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + uuid?: string + } +} + +export interface ConvFileGetSpaceParams { + /** 会话openConversationId。 */ + openConversationId: string +} + +export interface ConvFileGetSpaceQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface ConvFileGetSpaceResponse { + space?: { + spaceId?: string + corpId?: string + createTime?: string + modifiedTime?: string + } +} + +export interface SendByAppParams { + /** 文件所在空间ID。 */ + spaceId: string + /** 文件ID。 */ + dentryId: string +} + +export interface SendByAppQuery { + /** 接收文件的用户unionId。 */ + unionId: string +} + +export interface SendByAppResponse { + file?: { + id?: string + conversationId?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + uuid?: string + } +} + +// funcName: isOldApi +Internal.define({ + '/convFile/conversations/files/links/send': { POST: { sendLink: false } }, + '/convFile/conversations/files/send': { POST: { send: false } }, + '/convFile/conversations/spaces/query': { POST: { convFileGetSpace: false } }, + '/convFile/apps/conversations/files/send': { POST: { sendByApp: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 发送文件链接到指定会话 + * @see https://developers.dingtalk.com/document/orgapp/send-a-file-link-to-the-specified-session + */ + sendLink( + query: SendLinkQuery, + params: SendLinkParams, + ): Promise + /** + * 发送文件到指定会话 + * @see https://developers.dingtalk.com/document/orgapp/send-file-to-specified-session + */ + send(query: SendQuery, params: SendParams): Promise + /** + * 获取IM会话存储空间信息 + * @see https://developers.dingtalk.com/document/orgapp/obtain-group-storage-space-information + */ + convFileGetSpace( + query: ConvFileGetSpaceQuery, + params: ConvFileGetSpaceParams, + ): Promise + /** + * 以应用身份发送文件给自己 + * @see https://developers.dingtalk.com/document/isvapp/sends-a-storage-file-to-a-specified-user + */ + sendByApp( + query: SendByAppQuery, + params: SendByAppParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/crm.ts b/adapters/dingtalk/src/api/crm.ts new file mode 100644 index 00000000..b2377139 --- /dev/null +++ b/adapters/dingtalk/src/api/crm.ts @@ -0,0 +1,829 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface QueryGlobalInfoQuery { + /** 用户 userId */ + userId: string +} + +export interface QueryGlobalInfoResponse { + result?: { + oemEnable?: number + } +} + +export interface BatchUpdateFollowRecordsParams { + /** 操作人userId。 */ + operatorUserId: string + /** 更新的跟进记录数据信息。 */ + instanceList: object[] +} + +export interface BatchUpdateFollowRecordsResponse { + results?: { + success?: number + errorCode?: string + errorMsg?: string + instanceId?: string + }[] +} + +export interface BatchAddFollowRecordsParams { + /** 操作人userId。 */ + operatorUserId: string + /** 跟进记录数据字段列表,最大值40。 */ + instanceList: object[] +} + +export interface BatchAddFollowRecordsResponse { + results?: { + success?: number + errorCode?: string + errorMsg?: string + instanceId?: string + }[] +} + +export interface BatchRemoveFollowRecordsParams { + /** 操作人userId。 */ + operatorUserId: string + /** 跟进记录ID。 */ + instanceIds: string[] +} + +export interface BatchRemoveFollowRecordsResponse { + results?: { + success?: number + errorCode?: string + errorMsg?: string + instanceId?: string + }[] +} + +export interface DeleteCrmCustomObjectDataQuery { + /** 自定义对象表单code。 */ + formCode: string +} + +export interface DeleteCrmCustomObjectDataResponse { + instanceId: string +} + +export interface BatchUpdateContactsParams { + /** 操作人userId。 */ + operatorUserId: string + /** 联系人数据列表,最大值10。 */ + relationList: object[] +} + +export interface BatchUpdateContactsResponse { + results?: { + success?: number + errorCode?: string + errorMsg?: string + relationId?: string + }[] +} + +export interface BatchAddContactsParams { + /** 操作人userId。 */ + operatorUserId: string + /** 联系人数据列表,最大值10。 */ + relationList: object[] +} + +export interface BatchAddContactsResponse { + results?: { + success?: number + errorCode?: string + errorMsg?: string + relationId?: string + }[] +} + +export interface BatchAddRelationDatasParams { + /** 客户类型。 */ + relationType: string + /** 操作人userId。 */ + operatorUserId: string + /** 是否跳过查重,默认不跳过。 */ + skipDuplicateCheck?: unknown + /** 新增客户关系列表,最大值10。 */ + relationList: object[] +} + +export interface BatchAddRelationDatasResponse { + results?: { + success?: number + errorCode?: string + errorMsg?: string + relationId?: string + duplicatedRelationIds?: number + }[] +} + +export interface BatchUpdateRelationDatasParams { + /** 客户类型。 */ + relationType: string + /** 操作人userId。 */ + operatorUserId: string + /** 是否跳过查重,默认不跳过。 */ + skipDuplicateCheck?: unknown + /** 更新的客户数据列表,最大值10。 */ + relationList: object[] +} + +export interface BatchUpdateRelationDatasResponse { + results?: { + success?: number + errorCode?: string + errorMsg?: string + relationId?: string + duplicatedRelationIds?: number + }[] +} + +export interface GetRelationUkSettingQuery { + /** 客户类型。 */ + relationType: string +} + +export interface GetRelationUkSettingResponse { + result?: { + fieldId: string + bizAlias?: string + }[] +} + +export interface CrmCreateGroupParams { + /** 群名称。 */ + groupName: string + /** 群主userId。 */ + ownerUserId: string + /** 群成员userId。 */ + memberUserIds?: string + /** 关系类型。 */ + relationType: string +} + +export interface CrmCreateGroupResponse { + openConversationId: string +} + +export interface GetCrmGroupChatMultiParams { + /** 客户群openConversationId。 */ + openConversationIds?: string[] +} + +export interface GetCrmGroupChatMultiResponse { + result?: { + openConversationId?: string + openGroupSetId?: string + ownerUserId?: string + ownerUserName?: string + name?: string + memberCount?: number + gmtCreate?: number + iconUrl?: string + }[] +} + +export interface GetCrmGroupChatSingleQuery { + /** 客户群openConversationId。 */ + openConversationId: string +} + +export interface GetCrmGroupChatSingleResponse { + openConversationId?: string + openGroupSetId?: string + ownerUserId?: string + ownerUserName?: string + name?: string + memberCount?: number + gmtCreate?: number + iconUrl?: string +} + +export interface QueryRelationDatasByTargetIdQuery { + /** 关系类型。 */ + relationType: string +} + +export interface QueryRelationDatasByTargetIdResponse { + relations: { + relationId: string + relationType: string + bizDataList: number + openConversationIds: number + }[] +} + +export interface QueryCrmGroupChatsQuery { + /** 关系类型。 */ + relationType: string + /** 分页游标。 */ + nextToken?: string + /** 每页最大条目数,最大值100。 */ + maxResults: number + /** 查询DSL语法。 */ + queryDsl?: string +} + +export interface QueryCrmGroupChatsResponse { + resultList?: { + openConversationId: string + openGroupSetId?: string + ownerUserId: string + ownerUserName: string + name: string + memberCount: number + gmtCreate: number + }[] + hasMore: unknown + nextToken?: string + totalCount?: number +} + +export interface CrmUpdateGroupSetParams { + /** 群组openGroupSetId,调用[查询客户群组列表](https://open.dingtalk.com/document/orgapp-server/query-groups)接口获取。 */ + openGroupSetId: string + /** 群组名。 */ + name?: string + /** 单个群的人数上限。 */ + memberQuota?: number + /** 群主userId。 */ + ownerUserId?: string + /** 群管理员userId列表,多个用逗号隔开,裂变出的新群会自动设置这些userId为群管理员。 */ + managerUserIds?: string + /** 群公告文本。 */ + notice?: string + /** 群公告是否置顶。 */ + noticeToped?: number + /** 群模板Id。 */ + templateId?: string + /** 新成员入群后收到的欢迎语。 */ + welcome?: string +} + +export interface ListGroupSetQuery { + /** 分页游标。 */ + nextToken?: string + /** 每页条目数,最大值10。 */ + maxResults?: number + /** 查询DSL。 */ + queryDsl?: string + /** 关系类型。 */ + relationType: string +} + +export interface ListGroupSetResponse { + hasMore?: unknown + nextToken?: string + resultList: { + name?: string + openGroupSetId?: string + relationType?: string + memberQuota?: number + memberCount?: number + templateId?: string + ownerUserId?: string + managerUserIds?: string + notice?: string + noticeToped?: number + owner: number + manager: number + lastOpenConversationId: string + gmtCreate?: string + gmtModified?: string + groupChatCount?: number + }[] + totalCount?: number +} + +export interface CreateGroupSetParams { + /** 群组名。 */ + name: string + /** 群主userId。 */ + ownerUserId: string + /** 创建人userId。 */ + creatorUserId: string + /** 群模板Id。 */ + templateId?: string + /** 单个群的人数上限,最大值900。 */ + memberQuota?: number + /** 群管理员userId列表,多个用逗号隔开。 */ + managerUserIds?: string + /** 群公告文本。 */ + notice?: string + /** 群公告是否置顶。 */ + noticeToped?: number + /** 关系类型。 */ + relationType: string + /** 新成员入群后收到的欢迎语。 */ + welcome?: string +} + +export interface CreateGroupSetResponse { + name?: string + openGroupSetId?: string + relationType?: string + memberQuota?: number + memberCount?: number + templateId?: string + ownerUserId?: string + managerUserIds?: string + notice?: string + noticeToped?: number + owner: { + name?: string + userId?: string + } + manager: { + name?: string + userId?: string + }[] + lastOpenConversationId: string + gmtCreate?: string + gmtModified?: string + inviteLink?: string +} + +export interface GetGroupSetQuery { + /** 群组openGroupSetId。 */ + openGroupSetId: string +} + +export interface GetGroupSetResponse { + name?: string + openGroupSetId?: string + relationType?: string + memberQuota?: number + memberCount?: number + templateId?: string + ownerUserId?: string + managerUserIds?: string + notice?: string + noticeToped?: number + owner: { + name?: string + userId?: string + } + manager: { + name?: string + userId?: string + }[] + lastOpenConversationId?: string + gmtCreate?: string + gmtModified?: string + groupChatCount?: number + inviteLink?: string +} + +export interface UpdateCrmPersonalCustomerParams { + /** 客户数据ID。 */ + instanceId: string + /** 操作人的用户userId。 */ + modifierUserId: string + /** 操作人的用户昵称。 */ + modifierNick?: string + /** 客户数据内容,JSON格式字符串。 */ + data: unknown + /** 扩展数据。 */ + extendData?: unknown + /** 权限。 */ + permission?: unknown + /** 关系类型。 */ + relationType?: string + /** 是否跳过查重字段。 */ + skipDuplicateCheck?: unknown + /** 取值。 */ + action?: string +} + +export interface UpdateCrmPersonalCustomerResponse { + instanceId: string +} + +export interface AddCrmPersonalCustomerParams { + /** 记录创建人的用户userId。 */ + creatorUserId: string + /** 记录创建人的昵称。 */ + creatorNick?: string + /** 客户数据内容,JSON格式字符串。 */ + data: unknown + /** 扩展数据内容。 */ + extendData?: unknown + /** 权限。 */ + permission?: unknown + /** 关系类型。 */ + relationType?: string + /** 是否跳过查重字段,取值: */ + skipDuplicateCheck?: unknown + /** 取值: */ + action?: string +} + +export interface AddCrmPersonalCustomerResponse { + instanceId: string +} + +export interface DeleteCrmPersonalCustomerQuery { + /** 关系类型。 */ + relationType?: string + /** 操作人用户userId。 */ + currentOperatorUserId: string +} + +export interface DeleteCrmPersonalCustomerResponse { + instanceId: string +} + +export interface DescribeCrmPersonalCustomerObjectMetaQuery { + /** 关系类型。 */ + relationType?: string +} + +export interface DescribeCrmPersonalCustomerObjectMetaResponse { + name?: string + customized?: unknown + fields?: { + name?: string + customized?: number + label?: string + type?: string + nillable?: number + format?: string + unit?: string + selectOptions?: number + quote?: number + referenceTo?: string + referenceFields?: number + rollUpSummaryFields?: number + }[] + status?: string + code?: string +} + +export interface ListCrmPersonalCustomersQuery { + /** 操作人的用户userId。 */ + currentOperatorUserId?: string + /** 关系类型。 */ + relationType?: string +} + +export interface ListCrmPersonalCustomersResponse { + result: { + instanceId: string + objectType: string + creatorUserId: string + creatorNick: string + data: number + extendData: number + permission: number + appUuid: string + formCode: string + procOutResult: string + procInstStatus: string + gmtCreate: string + gmtModified: string + }[] +} + +export interface QueryCrmPersonalCustomerQuery { + /** 用户userid。 */ + currentOperatorUserId?: string + /** 关系类型。 */ + relationType?: string + /** 分页游标,获取下一页时传入上一页返回的nextToken。 */ + nextToken?: string + /** 每页条数,最大值100。 */ + maxResults: number + /** 查询条件。 */ + queryDsl?: string +} + +export interface QueryCrmPersonalCustomerResponse { + values?: { + instanceId: string + objectType: string + creatorUserId: string + creatorNick: string + data: number + extendData: number + permission: number + procOutResult: string + procInstStatus: string + gmtCreate: string + gmtModified: string + }[] + hasMore?: unknown + nextToken?: string + maxResults?: number + totalCount?: number +} + +export interface QueryAllCustomerParams { + /** 操作人员的userId。 */ + operatorUserId?: string + /** 每页条目数,取值范围1~100。 */ + maxResults?: number + /** 分页游标。 */ + nextToken?: string + /** 数据类型,不传或者传null时,默认值为**crm_customer**,具体参数如下。 */ + objectType?: string +} + +export interface QueryAllCustomerResponse { + result?: { + nextToken?: string + values?: number + maxResults?: number + } +} + +export interface SendOfficialAccountOTOMessageParams { + /** 消息详情。 */ + detail: unknown + /** 可选参数,API调用方标识,仅用于定制调用方场景。 */ + bizId?: string + /** 服务窗账号id,默认不需要传此参数。 */ + accountId?: string +} + +export interface SendOfficialAccountOTOMessageResponse { + requestId?: string + result: { + openPushId: string + } +} + +export interface BatchSendOfficialAccountOTOMessageParams { + /** 消息详情。 */ + detail: unknown + /** 服务窗授权的调用方标识,可以为空。 */ + bizId?: string + /** 账单id。 */ + accountId?: string +} + +export interface BatchSendOfficialAccountOTOMessageResponse { + result?: { + openPushId: string + } + requestId?: string +} + +// funcName: isOldApi +Internal.define({ + '/crm/globalInfos': { GET: { queryGlobalInfo: false } }, + '/crm/followRecords/batch': { + PUT: { batchUpdateFollowRecords: false }, + POST: { batchAddFollowRecords: false }, + }, + '/crm/followRecords/batchRemove': { + POST: { batchRemoveFollowRecords: false }, + }, + '/crm/customObjectDatas/instances/{instanceId}': { + DELETE: { deleteCrmCustomObjectData: false }, + }, + '/crm/contacts/batch': { + PUT: { batchUpdateContacts: false }, + POST: { batchAddContacts: false }, + }, + '/crm/relationDatas/batch': { + POST: { batchAddRelationDatas: false }, + PUT: { batchUpdateRelationDatas: false }, + }, + '/crm/relationUkSettings': { GET: { getRelationUkSetting: false } }, + '/crm/groups': { POST: { crmCreateGroup: false } }, + '/crm/crmGroupChats/batchQuery': { POST: { getCrmGroupChatMulti: false } }, + '/crm/crmGroupChats/query': { POST: { getCrmGroupChatSingle: false } }, + '/crm/relations/datas/targets/{targetId}': { + GET: { queryRelationDatasByTargetId: false }, + }, + '/crm/crmGroupChats': { GET: { queryCrmGroupChats: false } }, + '/crm/groupSets/set': { PUT: { crmUpdateGroupSet: false } }, + '/crm/groupSets/lists': { GET: { listGroupSet: false } }, + '/crm/groupSets': { + POST: { createGroupSet: false }, + GET: { getGroupSet: false }, + }, + '/crm/personalCustomers': { + PUT: { updateCrmPersonalCustomer: false }, + POST: { addCrmPersonalCustomer: false }, + GET: { queryCrmPersonalCustomer: false }, + }, + '/crm/personalCustomers/{dataId}': { + DELETE: { deleteCrmPersonalCustomer: false }, + }, + '/crm/personalCustomers/objectMeta': { + GET: { describeCrmPersonalCustomerObjectMeta: false }, + }, + '/crm/personalCustomers/batchQuery': { + POST: { listCrmPersonalCustomers: false }, + }, + '/crm/customerInstances': { POST: { queryAllCustomer: false } }, + '/crm/officialAccounts/oToMessages/send': { + POST: { sendOfficialAccountOTOMessage: false }, + }, + '/crm/officialAccounts/oToMessages/batchSend': { + POST: { batchSendOfficialAccountOTOMessage: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 营销服融合三方全局信息 + * @see https://developers.dingtalk.com/document/isvapp/get-customer-management-global-information + */ + queryGlobalInfo( + query: QueryGlobalInfoQuery, + ): Promise + /** + * 批量修改跟进记录 + * @see https://developers.dingtalk.com/document/orgapp/batch-update-follow-up-record-data + */ + batchUpdateFollowRecords( + params: BatchUpdateFollowRecordsParams, + ): Promise + /** + * 批量新增跟进记录 + * @see https://developers.dingtalk.com/document/orgapp/batch-add-follow-up-record-data + */ + batchAddFollowRecords( + params: BatchAddFollowRecordsParams, + ): Promise + /** + * 批量删除跟进记录 + * @see https://developers.dingtalk.com/document/orgapp/batch-delete-follow-up-record-data + */ + batchRemoveFollowRecords( + params: BatchRemoveFollowRecordsParams, + ): Promise + /** + * 删除CRM自定义对象数据 + * @see https://developers.dingtalk.com/document/orgapp/delete-crm-custom-object-data + */ + deleteCrmCustomObjectData( + instanceId: string, + query: DeleteCrmCustomObjectDataQuery, + ): Promise + /** + * 批量修改联系人 + * @see https://developers.dingtalk.com/document/orgapp/modify-contact-data-in-batches + */ + batchUpdateContacts( + params: BatchUpdateContactsParams, + ): Promise + /** + * 批量新增联系人 + * @see https://developers.dingtalk.com/document/orgapp/add-contact-data-in-batches + */ + batchAddContacts( + params: BatchAddContactsParams, + ): Promise + /** + * 批量新增关系数据 + * @see https://developers.dingtalk.com/document/orgapp/add-multiple-relationship-data-in-batches + */ + batchAddRelationDatas( + params: BatchAddRelationDatasParams, + ): Promise + /** + * 批量修改关系数据 + * @see https://developers.dingtalk.com/document/orgapp/update-multiple-relational-data-tables-at-a-time + */ + batchUpdateRelationDatas( + params: BatchUpdateRelationDatasParams, + ): Promise + /** + * 获取个人客户或企业客户查重字段 + * @see https://developers.dingtalk.com/document/isvapp/obtain-duplicate-check-fields + */ + getRelationUkSetting( + query: GetRelationUkSettingQuery, + ): Promise + /** + * 创建客户群 + * @see https://developers.dingtalk.com/document/isvapp/create-a-customer-group + */ + crmCreateGroup( + params: CrmCreateGroupParams, + ): Promise + /** + * 批量查询客户群 + * @see https://developers.dingtalk.com/document/isvapp/query-customer-groups-in-batches + */ + getCrmGroupChatMulti( + params: GetCrmGroupChatMultiParams, + ): Promise + /** + * 获取单个客户群详情 + * @see https://developers.dingtalk.com/document/isvapp/obtain-a-single-customer-group + */ + getCrmGroupChatSingle( + query: GetCrmGroupChatSingleQuery, + ): Promise + /** + * 查询客户数据 + * @see https://developers.dingtalk.com/document/isvapp/querying-customer-data + */ + queryRelationDatasByTargetId( + targetId: string, + query: QueryRelationDatasByTargetIdQuery, + ): Promise + /** + * 查询客户群列表 + * @see https://developers.dingtalk.com/document/isvapp/query-a-list-of-customer-groups + */ + queryCrmGroupChats( + query: QueryCrmGroupChatsQuery, + ): Promise + /** + * 更新客户群组 + * @see https://developers.dingtalk.com/document/orgapp/crm-update-group + */ + crmUpdateGroupSet(params: CrmUpdateGroupSetParams): Promise + /** + * 查询客户群组列表 + * @see https://developers.dingtalk.com/document/isvapp/query-the-list-of-customer-groups-set + */ + listGroupSet(query: ListGroupSetQuery): Promise + /** + * 创建群组 + * @see https://developers.dingtalk.com/document/isvapp/create-a-customer-group-set + */ + createGroupSet( + params: CreateGroupSetParams, + ): Promise + /** + * 获取单个客户群组详情 + * @see https://developers.dingtalk.com/document/isvapp/queries-the-details-of-a-single-customer-group + */ + getGroupSet(query: GetGroupSetQuery): Promise + /** + * 更新crm个人客户(或企业客户) + * @see https://developers.dingtalk.com/document/isvapp/update-crm-personal-customers + */ + updateCrmPersonalCustomer( + params: UpdateCrmPersonalCustomerParams, + ): Promise + /** + * 添加crm个人客户(或企业客户) + * @see https://developers.dingtalk.com/document/orgapp/add-crm-personal-customers + */ + addCrmPersonalCustomer( + params: AddCrmPersonalCustomerParams, + ): Promise + /** + * 删除crm个人客户(或企业客户) + * @see https://developers.dingtalk.com/document/orgapp/delete-crm-personal-customer + */ + deleteCrmPersonalCustomer( + dataId: string, + query: DeleteCrmPersonalCustomerQuery, + ): Promise + /** + * 获取CRM客户对象的元数据描述 + * @see https://developers.dingtalk.com/document/isvapp/get-metadata-description-of-crm-customer-object-1 + */ + describeCrmPersonalCustomerObjectMeta( + query: DescribeCrmPersonalCustomerObjectMetaQuery, + ): Promise + /** + * 批量获取crm个人客户 + * @see https://developers.dingtalk.com/document/isvapp/acquire-crm-individual-customers-in-batches + */ + listCrmPersonalCustomers( + query: ListCrmPersonalCustomersQuery, + ): Promise + /** + * 根据指定查询条件批量获取客户数据 + * @see https://developers.dingtalk.com/document/isvapp/obtains-crm-individual-customers-in-batches-based-on-specified-query + */ + queryCrmPersonalCustomer( + query: QueryCrmPersonalCustomerQuery, + ): Promise + /** + * 获取全量个人或企业客户数据 + * @see https://developers.dingtalk.com/document/orgapp/crm-obtains-all-private-sea-customer-data + */ + queryAllCustomer( + params: QueryAllCustomerParams, + ): Promise + /** + * 服务窗单发接口,指定消息接收人发送 + * @see https://developers.dingtalk.com/document/isvapp/sends-a-single-message-from-the-service-window + */ + sendOfficialAccountOTOMessage( + params: SendOfficialAccountOTOMessageParams, + ): Promise + /** + * 服务窗消息群发 + * @see https://developers.dingtalk.com/document/isvapp/batch-sending-of-service-window-messages + */ + batchSendOfficialAccountOTOMessage( + params: BatchSendOfficialAccountOTOMessageParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/customerService.ts b/adapters/dingtalk/src/api/customerService.ts new file mode 100644 index 00000000..e8013d5a --- /dev/null +++ b/adapters/dingtalk/src/api/customerService.ts @@ -0,0 +1,155 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface ExecuteActivityParams { + /** 会员来源,取diamond配置的值。 */ + sourceId: string + /** 会员ID。 */ + foreignId: string + /** 会员名称。 */ + foreignName: string + /** 动作编码。 */ + activityCode: string + /** 实例ID。 */ + openInstanceId?: string + /** 智能客服产品类型: */ + productionType?: number + /** 工单表单。 */ + properties?: object[] +} + +export interface ExecuteActivityResponse { + taskId?: string +} + +export interface PageListActionQuery { + /** 实例ID。 */ + openInstanceId?: string + /** 智能客服产品类型: */ + productionType?: number + /** 查询数据的起始位置,0表示从头开始。 */ + nextToken: string + /** 查询单页查询的最大条目数,最大值为100。 */ + maxResults: number +} + +export interface PageListActionResponse { + nextCursor?: number + total?: number + list?: { + operatorId?: string + operator?: string + operatorRole?: string + actionCode?: string + actionContent?: number + }[] +} + +export interface PageListTicketQuery { + /** 实例ID。 */ + openInstanceId?: string + /** 智能客服产品类型: */ + productionType?: number + /** 工单模板ID。 */ + templateId: string + /** 工单ID。 */ + ticketId?: string + /** 会员来源,取diamond配置的值。 */ + sourceId?: string + /** 第三方用户userid。 */ + foreignId?: string + /** 工单状态。 */ + ticketStatus?: string + /** 开始时间,时间戳,单位毫秒。 */ + startTime?: number + /** 结束时间,时间戳,单位毫秒。 */ + endTime?: number + /** 查询数据的起始位置,0表示从头开始。 */ + nextToken: string + /** 查询单页查询的最大条目数,最大值为100。 */ + maxResults: number +} + +export interface PageListTicketResponse { + nextCursor?: number + total?: number + list?: { + foreignId?: string + sourceId?: string + foreignName?: string + templateId?: string + title?: string + ticketId?: string + ticketStatus?: string + openInstanceId?: string + productionType?: number + gmtCreate?: string + gmtModified?: string + bizDataMap?: number + }[] +} + +export interface CreateTicketParams { + /** 会员来源,取diamond配置的值。 */ + sourceId: string + /** 第三方会员ID。 */ + foreignId: string + /** 第三方会员名称。 */ + foreignName: string + /** 实例ID。 */ + openInstanceId?: string + /** 智能客服产品类型: */ + productionType?: number + /** 自助单ID,钉钉智能客服自助单配置里的值。 */ + templateId: string + /** 工单标题。 */ + title: string + /** 表单信息。 */ + properties?: object[] +} + +export interface CreateTicketResponse { + ticketId?: string +} + +// funcName: isOldApi +Internal.define({ + '/customerService/tickets/{ticketId}': { PUT: { executeActivity: false } }, + '/customerService/tickets/{ticketId}/actions': { + GET: { pageListAction: false }, + }, + '/customerService/tickets': { + GET: { pageListTicket: false }, + POST: { createTicket: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 执行工单活动 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-customer-service-execute-work-order-activities + */ + executeActivity( + ticketId: string, + params: ExecuteActivityParams, + ): Promise + /** + * 查询动作记录 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-customer-service-query-action-records + */ + pageListAction( + ticketId: string, + query: PageListActionQuery, + ): Promise + /** + * 分页查询工单 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-customer-service-paging-query-work-order + */ + pageListTicket(query: PageListTicketQuery): Promise + /** + * 创建自助单 + * @see https://developers.dingtalk.com/document/isvapp/smart-customer-service-create-a-self-service-order + */ + createTicket(params: CreateTicketParams): Promise + } +} diff --git a/adapters/dingtalk/src/api/datacenter.ts b/adapters/dingtalk/src/api/datacenter.ts new file mode 100644 index 00000000..5d17d9c7 --- /dev/null +++ b/adapters/dingtalk/src/api/datacenter.ts @@ -0,0 +1,671 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface QueryGeneralDataServiceQuery { + /** 开始日期,例如:20220901。 */ + startDate: string + /** 服务编码,在创建数据服务后获取。 */ + serviceId: string + /** 结束日期,例如:20220901。 */ + endDate: string + /** 部门ID,非部门维度接口不需要传。 */ + deptId?: string + /** 员工userId。 */ + userId: string + /** 每页大小,不填默认为10,最大为50。 */ + pageSize?: number + /** 分页页码,从1开始,不填默认为1。 */ + pageNumber?: number +} + +export interface QueryGeneralDataServiceResponse { + dataList?: object[] + metaList?: { + fieldName: string + fieldDesc: string + fieldType: string + fieldId: string + }[] +} + +export interface QueryOnlineUserStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryOnlineUserStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryActiveUserStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryActiveUserStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryEmployeeTypeStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryEmployeeTypeStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryCircleStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryCircleStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QuerySingleMessageStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QuerySingleMessageStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryGroupMessageStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryGroupMessageStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryDingSendStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryDingSendStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryDingReciveStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryDingReciveStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryVedioMeetingStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryVedioMeetingStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryTelMeetingStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryTelMeetingStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryGroupLiveStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryGroupLiveStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryRedEnvelopeSendStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryRedEnvelopeSendStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryRedEnvelopeReciveStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryRedEnvelopeReciveStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryBlackboardStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryBlackboardStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryTodoStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryTodoStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryHealthStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryHealthStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryDocumentStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryDocumentStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryCheckinStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryCheckinStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryApprovalStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryApprovalStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryReportStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryReportStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryAttendanceStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryAttendanceStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryDriveStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryDriveStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryMailStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryMailStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryCalendarStatisticalDataQuery { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDate: string +} + +export interface QueryCalendarStatisticalDataResponse { + dataList?: object[] + metaList?: { + kpiId: string + kpiName: string + unit: string + kpiCaliber: string + period: string + }[] +} + +export interface QueryDigitalDistrictOrgInfoParams { + /** 查询时间,日期格式为yyyyMMdd。 */ + statDates: string[] + /** 数字区县组织corpId列表。 */ + corpIds: string[] +} + +export interface QueryDigitalDistrictOrgInfoResponse { + arguments?: string[] + result?: string +} + +// funcName: isOldApi +Internal.define({ + '/datacenter/generalDataServices': { + GET: { queryGeneralDataService: false }, + }, + '/datacenter/onlineUserData': { + GET: { queryOnlineUserStatisticalData: false }, + }, + '/datacenter/activeUserData': { + GET: { queryActiveUserStatisticalData: false }, + }, + '/datacenter/employeeTypeData': { + GET: { queryEmployeeTypeStatisticalData: false }, + }, + '/datacenter/circleData': { GET: { queryCircleStatisticalData: false } }, + '/datacenter/singleMessagerData': { + GET: { querySingleMessageStatisticalData: false }, + }, + '/datacenter/groupMessageData': { + GET: { queryGroupMessageStatisticalData: false }, + }, + '/datacenter/dingSendData': { GET: { queryDingSendStatisticalData: false } }, + '/datacenter/dingReciveData': { + GET: { queryDingReciveStatisticalData: false }, + }, + '/datacenter/vedioMeetingData': { + GET: { queryVedioMeetingStatisticalData: false }, + }, + '/datacenter/telMeetingData': { + GET: { queryTelMeetingStatisticalData: false }, + }, + '/datacenter/groupLiveData': { + GET: { queryGroupLiveStatisticalData: false }, + }, + '/datacenter/redEnvelopeSendData': { + GET: { queryRedEnvelopeSendStatisticalData: false }, + }, + '/datacenter/redEnvelopeReciveData': { + GET: { queryRedEnvelopeReciveStatisticalData: false }, + }, + '/datacenter/blackboardData': { + GET: { queryBlackboardStatisticalData: false }, + }, + '/datacenter/todoUserData': { GET: { queryTodoStatisticalData: false } }, + '/datacenter/healtheUserData': { GET: { queryHealthStatisticalData: false } }, + '/datacenter/documentData': { GET: { queryDocumentStatisticalData: false } }, + '/datacenter/checkinData': { GET: { queryCheckinStatisticalData: false } }, + '/datacenter/approvalData': { GET: { queryApprovalStatisticalData: false } }, + '/datacenter/reportData': { GET: { queryReportStatisticalData: false } }, + '/datacenter/attendanceData': { + GET: { queryAttendanceStatisticalData: false }, + }, + '/datacenter/driveData': { GET: { queryDriveStatisticalData: false } }, + '/datacenter/mailData': { GET: { queryMailStatisticalData: false } }, + '/datacenter/calendarData': { GET: { queryCalendarStatisticalData: false } }, + '/datacenter/digitalCounty/orgInfos/query': { + POST: { queryDigitalDistrictOrgInfo: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 数据资产平台数据服务接口 + * @see https://developers.dingtalk.com/document/orgapp-server/data-assets-platform-data-services-apis + */ + queryGeneralDataService( + query: QueryGeneralDataServiceQuery, + ): Promise + /** + * 获取企业用户在线统计数据 + * @see https://developers.dingtalk.com/document/orgapp/retrieve-online-statistics-of-enterprise-users + */ + queryOnlineUserStatisticalData( + query: QueryOnlineUserStatisticalDataQuery, + ): Promise + /** + * 获取企业用户激活状态统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtains-statistics-on-user-activation-status + */ + queryActiveUserStatisticalData( + query: QueryActiveUserStatisticalDataQuery, + ): Promise + /** + * 获取企业员工类型统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtains-statistics-on-employee-types + */ + queryEmployeeTypeStatisticalData( + query: QueryEmployeeTypeStatisticalDataQuery, + ): Promise + /** + * 获取企业全员圈统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-statistical-data-of-all-employees-of-an-enterprise + */ + queryCircleStatisticalData( + query: QueryCircleStatisticalDataQuery, + ): Promise + /** + * 获取企业单聊统计数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-the-statistics-on-one-time-enterprise-chats + */ + querySingleMessageStatisticalData( + query: QuerySingleMessageStatisticalDataQuery, + ): Promise + /** + * 获取企业群聊统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtain-enterprise-group-chat-statistics + */ + queryGroupMessageStatisticalData( + query: QueryGroupMessageStatisticalDataQuery, + ): Promise + /** + * 获取企业DING发送统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtain-sending-statistics-of-an-enterprise-ding + */ + queryDingSendStatisticalData( + query: QueryDingSendStatisticalDataQuery, + ): Promise + /** + * 获取企业DING接收及评论统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtain-statistics-on-receiving-and-comments-of-enterprise-ding + */ + queryDingReciveStatisticalData( + query: QueryDingReciveStatisticalDataQuery, + ): Promise + /** + * 获取企业视频会议统计数据 + * @see https://developers.dingtalk.com/document/orgapp/get-enterprise-video-conference-statistics + */ + queryVedioMeetingStatisticalData( + query: QueryVedioMeetingStatisticalDataQuery, + ): Promise + /** + * 获取企业电话会议统计数据 + * @see https://developers.dingtalk.com/document/orgapp/get-enterprise-teleconference-statistics + */ + queryTelMeetingStatisticalData( + query: QueryTelMeetingStatisticalDataQuery, + ): Promise + /** + * 获取企业群直播统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-live-stream-statistics-for-an-enterprise-group + */ + queryGroupLiveStatisticalData( + query: QueryGroupLiveStatisticalDataQuery, + ): Promise + /** + * 获取企业发送红包统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-statistics-on-red-packets-issued-by-enterprises + */ + queryRedEnvelopeSendStatisticalData( + query: QueryRedEnvelopeSendStatisticalDataQuery, + ): Promise + /** + * 获取企业接收红包统计数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-the-red-envelope-receiving-statistics-of-an-enterprise + */ + queryRedEnvelopeReciveStatisticalData( + query: QueryRedEnvelopeReciveStatisticalDataQuery, + ): Promise + /** + * 获取企业公告统计数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-corporate-announcement-statistics + */ + queryBlackboardStatisticalData( + query: QueryBlackboardStatisticalDataQuery, + ): Promise + /** + * 获取企业待办统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-to-do-statistics-of-an-enterprise + */ + queryTodoStatisticalData( + query: QueryTodoStatisticalDataQuery, + ): Promise + /** + * 获取企业钉钉运动统计数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-dingtalk-movement-statistics + */ + queryHealthStatisticalData( + query: QueryHealthStatisticalDataQuery, + ): Promise + /** + * 获取企业文档统计数据 + * @see https://developers.dingtalk.com/document/orgapp/get-enterprise-document-statistics + */ + queryDocumentStatisticalData( + query: QueryDocumentStatisticalDataQuery, + ): Promise + /** + * 获取企业签到统计数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-enterprise-check-in-statistics + */ + queryCheckinStatisticalData( + query: QueryCheckinStatisticalDataQuery, + ): Promise + /** + * 获取企业审批统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtains-enterprise-approval-statistics + */ + queryApprovalStatisticalData( + query: QueryApprovalStatisticalDataQuery, + ): Promise + /** + * 获取企业日志统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtain-enterprise-log-statistics + */ + queryReportStatisticalData( + query: QueryReportStatisticalDataQuery, + ): Promise + /** + * 获取企业考勤统计数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-enterprise-attendance-statistics + */ + queryAttendanceStatisticalData( + query: QueryAttendanceStatisticalDataQuery, + ): Promise + /** + * 获取企业钉盘统计数据 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-statistics-on-enterprise-dingtalk-trays + */ + queryDriveStatisticalData( + query: QueryDriveStatisticalDataQuery, + ): Promise + /** + * 获取企业邮箱统计数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-enterprise-email-statistics + */ + queryMailStatisticalData( + query: QueryMailStatisticalDataQuery, + ): Promise + /** + * 获取企业日程统计数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-enterprise-schedule-statistics + */ + queryCalendarStatisticalData( + query: QueryCalendarStatisticalDataQuery, + ): Promise + /** + * 获取数字区县组织信息 + * @see https://developers.dingtalk.com/document/orgapp/querydigitaldistrictorginfo-api-reference + */ + queryDigitalDistrictOrgInfo( + params: QueryDigitalDistrictOrgInfoParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/devicemng.ts b/adapters/dingtalk/src/api/devicemng.ts new file mode 100644 index 00000000..b250ea03 --- /dev/null +++ b/adapters/dingtalk/src/api/devicemng.ts @@ -0,0 +1,201 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface ListMaintainInfoParams { + /** 页码,从1开始。 */ + pageNumber?: number + /** 页面大小,最大值20。 */ + pageSize?: number + /** 设备uuIi列表,最大值10。 */ + deviceUuid?: string[] +} + +export interface ListMaintainInfoResponse { + totalCount?: number + success?: unknown + result?: { + gmtCreate?: string + deviceCode?: string + deviceName?: string + remark?: string + maintenanceStaff?: number + processState?: number + handleTime?: string + }[] +} + +export interface ListInspectInfoParams { + /** 当前页码,从1开始。 */ + pageNumber?: number + /** 当页大小,最大值20。 */ + pageSize?: number + /** 设备uuIi列表,最大值10。 */ + deviceUuid?: string[] + /** 类型。 */ + type?: string +} + +export interface ListInspectInfoResponse { + totalCount?: number + success?: unknown + result?: { + deviceName?: string + deviceCode?: string + type?: string + status?: number + repairStatus?: number + maintenanceStaff?: number + handleTime?: string + remark?: string + name?: string + gmtCreate?: string + }[] +} + +export interface ListActivateDevicesQuery { + /** 设备型号。 */ + deviceTypeId?: string + /** 当前页码,从1开始。 */ + pageNumber?: number + /** 分组标识。 */ + groupId?: string + /** 每页大小,最大值50。 */ + pageSize?: number + /** 设备编号。 */ + deviceCode?: string + /** 设备分类。 */ + deviceCategory?: number +} + +export interface ListActivateDevicesResponse { + totalCount?: number + success?: unknown + result?: { + bizExt?: string + deviceCallbackUrl?: string + deviceCode?: string + deviceDetailUrl?: string + deviceName?: string + groupUuid?: string + icon?: string + introduction?: string + typeUuid?: string + uuid?: string + deviceCategory?: number + }[] +} + +export interface RegisterAndActivateDeviceBatchParams { + /** 设备信息。 */ + registerAndActivateVOS?: object[] +} + +export interface RegisterAndActivateDeviceBatchResponse { + successItems?: { + errorCode?: string + errorMsg?: string + result?: number + success?: number + }[] + success?: unknown + failItems?: { + errorCode?: string + errorMsg?: string + result?: number + success?: number + }[] +} + +export interface RegisterAndActivateDeviceParams { + /** 设备号。 */ + deviceCode: string + /** 设备名称。 */ + deviceName: string + /** 设备的简介。 */ + introduction?: string + /** 设备型号。 */ + typeUuid?: string + /** 设备管理员的userId列表。 */ + userIds?: string[] + /** 角色标识。 */ + roleUuid?: string + /** 设备详情链接,最大长度2048字符。 */ + deviceDetailUrl?: string + /** 设备回调链接,最大长度2048字符。 */ + deviceCallbackUrl?: string + /** 设备分类。 */ + deviceCategory?: number +} + +export interface RegisterAndActivateDeviceResponse { + success?: unknown + result: { + deviceCode: string + deviceUuid: string + deviceName: string + introduction: string + typeUuid: string + roleUuid: string + deviceDetailUrl: string + userIds: number + deviceCategory?: number + } +} + +// funcName: isOldApi +Internal.define({ + '/devicemng/customers/devices/maintainInfos/query': { + POST: { listMaintainInfo: false }, + }, + '/devicemng/customers/devices/inspectInfos/query': { + POST: { listInspectInfo: false }, + }, + '/devicemng/customers/devices/activations/infos': { + GET: { listActivateDevices: false }, + }, + '/devicemng/customers/devices/registrationActivations/batch': { + POST: { registerAndActivateDeviceBatch: false }, + }, + '/devicemng/customers/devices/registerAndActivate': { + POST: { registerAndActivateDevice: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取报修信息 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-repair-report-record + */ + listMaintainInfo( + params: ListMaintainInfoParams, + ): Promise + /** + * 获取巡检、保养记录 + * @see https://developers.dingtalk.com/document/isvapp/obtain-inspection-and-maintenance-records + */ + listInspectInfo( + params: ListInspectInfoParams, + ): Promise + /** + * 查询激活的设备信息 + * @see https://developers.dingtalk.com/document/isvapp/query-information-about-a-registered-device + */ + listActivateDevices( + query: ListActivateDevicesQuery, + ): Promise + /** + * 批量注册与激活设备 + * @see https://developers.dingtalk.com/document/isvapp/register-and-activate-devices-in-batches + */ + registerAndActivateDeviceBatch( + params: RegisterAndActivateDeviceBatchParams, + ): Promise + /** + * 注册与激活设备 + * @see https://developers.dingtalk.com/document/isvapp/register-the-device-to-the-dingtalk + */ + registerAndActivateDevice( + params: RegisterAndActivateDeviceParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/diot.ts b/adapters/dingtalk/src/api/diot.ts new file mode 100644 index 00000000..06a75be7 --- /dev/null +++ b/adapters/dingtalk/src/api/diot.ts @@ -0,0 +1,18 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface UpgradeDeviceResponse { + requestId?: string +} + +// funcName: isOldApi +Internal.define({ '/diot/upgrade/device': { POST: { upgradeDevice: false } } }) +declare module '../internal' { + interface Internal { + /** + * 升级设备 + * @see https://developers.dingtalk.com/document/app/upgrade-equipment + */ + upgradeDevice(): Promise + } +} diff --git a/adapters/dingtalk/src/api/doc.ts b/adapters/dingtalk/src/api/doc.ts new file mode 100644 index 00000000..bcb8e176 --- /dev/null +++ b/adapters/dingtalk/src/api/doc.ts @@ -0,0 +1,231 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface SetRowsVisibilityParams { + /** 可见性。 */ + visibility: string + /** 要显示或者隐藏的第一行的游标,从0开始。 */ + row: number + /** 要显示或隐藏的行的数量。 */ + rowCount: number +} + +export interface SetRowsVisibilityQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface SetRowsVisibilityResponse { + id?: string +} + +export interface SetColumnsVisibilityParams { + /** 要显示或隐藏的第一列的游标,从0开始。 */ + column: number + /** 要显示或隐藏的列的数量。 */ + columnCount: number + /** 可见性。 */ + visibility: string +} + +export interface SetColumnsVisibilityQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface SetColumnsVisibilityResponse { + id?: string +} + +export interface DeleteRowsParams { + /** 要删除的第一行的游标,从0开始。 */ + row: number + /** 要删除的行的数量。 */ + rowCount: number +} + +export interface DeleteRowsQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface DeleteRowsResponse { + id?: string +} + +export interface DeleteColumnsParams { + /** 要删除的第一列的游标,从0开始。 */ + column: number + /** 要删除的列的数量。 */ + columnCount: number +} + +export interface DeleteColumnsQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface DeleteColumnsResponse { + id?: string +} + +export interface InsertRowsBeforeParams { + /** 指定行的游标,从0开始。 */ + row: number + /** 插入行的数量。 */ + rowCount: number +} + +export interface InsertRowsBeforeQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface InsertRowsBeforeResponse { + id?: string +} + +export interface InsertColumnsBeforeParams { + /** 指定列的游标,从0开始。 */ + column: number + /** 插入列的数量。 */ + columnCount: number +} + +export interface InsertColumnsBeforeQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface InsertColumnsBeforeResponse { + id?: string +} + +export interface ClearQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface ClearResponse { + a1Notation?: string +} + +export interface ClearDataQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface ClearDataResponse { + a1Notation?: string +} + +// funcName: isOldApi +Internal.define({ + '/doc/workbooks/{workbookId}/sheets/{sheetId}/setRowsVisibility': { + POST: { setRowsVisibility: false }, + }, + '/doc/workbooks/{workbookId}/sheets/{sheetId}/setColumnsVisibility': { + POST: { setColumnsVisibility: false }, + }, + '/doc/workbooks/{workbookId}/sheets/{sheetId}/deleteRows': { + POST: { deleteRows: false }, + }, + '/doc/workbooks/{workbookId}/sheets/{sheetId}/deleteColumns': { + POST: { deleteColumns: false }, + }, + '/doc/workbooks/{workbookId}/sheets/{sheetId}/insertRowsBefore': { + POST: { insertRowsBefore: false }, + }, + '/doc/workbooks/{workbookId}/sheets/{sheetId}/insertColumnsBefore': { + POST: { insertColumnsBefore: false }, + }, + '/doc/workbooks/{workbookId}/sheets/{sheetId}/ranges/{rangeAddress}/clear': { + POST: { clear: false }, + }, + '/doc/workbooks/{workbookId}/sheets/{sheetId}/ranges/{rangeAddress}/clearData': + { POST: { clearData: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 设置行隐藏或显示 + * @see https://developers.dingtalk.com/document/app/set-row-visibility + */ + setRowsVisibility( + workbookId: string, + sheetId: string, + query: SetRowsVisibilityQuery, + params: SetRowsVisibilityParams, + ): Promise + /** + * 设置列隐藏或显示 + * @see https://developers.dingtalk.com/document/app/set-column-visibility + */ + setColumnsVisibility( + workbookId: string, + sheetId: string, + query: SetColumnsVisibilityQuery, + params: SetColumnsVisibilityParams, + ): Promise + /** + * 删除行 + * @see https://developers.dingtalk.com/document/app/delete-row + */ + deleteRows( + workbookId: string, + sheetId: string, + query: DeleteRowsQuery, + params: DeleteRowsParams, + ): Promise + /** + * 删除列 + * @see https://developers.dingtalk.com/document/app/delete-column + */ + deleteColumns( + workbookId: string, + sheetId: string, + query: DeleteColumnsQuery, + params: DeleteColumnsParams, + ): Promise + /** + * 指定行上方插入若干行 + * @see https://developers.dingtalk.com/document/app/insert-rows-before-rows + */ + insertRowsBefore( + workbookId: string, + sheetId: string, + query: InsertRowsBeforeQuery, + params: InsertRowsBeforeParams, + ): Promise + /** + * 指定列左侧插入若干列 + * @see https://developers.dingtalk.com/document/app/insert-column-before-column + */ + insertColumnsBefore( + workbookId: string, + sheetId: string, + query: InsertColumnsBeforeQuery, + params: InsertColumnsBeforeParams, + ): Promise + /** + * 清除单元格区域内所有内容 + * @see https://developers.dingtalk.com/document/app/clear-all + */ + clear( + workbookId: string, + sheetId: string, + rangeAddress: string, + query: ClearQuery, + ): Promise + /** + * 清除单元格区域内数据 + * @see https://developers.dingtalk.com/document/app/clear-cell-data + */ + clearData( + workbookId: string, + sheetId: string, + rangeAddress: string, + query: ClearDataQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/drive.ts b/adapters/dingtalk/src/api/drive.ts new file mode 100644 index 00000000..3f1e02f4 --- /dev/null +++ b/adapters/dingtalk/src/api/drive.ts @@ -0,0 +1,108 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface AddCustomSpaceParams { + /** 自定义空间标识。任意小于10位的字符串即可。 */ + identifier: string + /** 业务类型。任意小于8位的字符串即可。 */ + bizType: string + /** 授权模式,取值: */ + permissionMode: string + /** 用户unionId,可通过以下两种方式获取: */ + unionId: string +} + +export interface AddCustomSpaceResponse { + spaceId: string + spaceName?: string + spaceType: string + quota?: number + usedQuota: number + permissionMode?: string + createTime?: string + modifyTime?: string +} + +export interface DeleteSpaceQuery { + /** 用户unionId,可通过以下两种方式获取: */ + unionId: string +} + +export interface DriveAddSpaceParams { + /** 空间名称(不能为空)。 */ + name: string + /** 用户unionId,可通过以下两种方式获取: */ + unionId: string +} + +export interface DriveAddSpaceResponse { + spaceId: string + spaceName?: string + spaceType: string + quota?: number + usedQuota: number + permissionMode?: string + createTime?: string + modifyTime?: string +} + +export interface ListSpacesQuery { + /** 用户unionId,可通过以下两种方式获取: */ + unionId: string + /** 空间类型。 */ + spaceType: string + /** 分页游标。 */ + nextToken?: string + /** 分页大小。 */ + maxResults: number +} + +export interface ListSpacesResponse { + spaces: { + spaceId: string + spaceName?: string + spaceType: string + quota?: number + usedQuota: number + permissionMode?: string + createTime?: string + modifyTime?: string + }[] + nextToken?: string +} + +// funcName: isOldApi +Internal.define({ + '/drive/spaces/customSpaces': { POST: { addCustomSpace: false } }, + '/drive/spaces/{spaceId}': { DELETE: { deleteSpace: false } }, + '/drive/spaces': { + POST: { driveAddSpace: false }, + GET: { listSpaces: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 新建自定义空间 + * @see https://developers.dingtalk.com/document/isvapp/new-custom-space + */ + addCustomSpace( + params: AddCustomSpaceParams, + ): Promise + /** + * 删除空间 + * @see https://developers.dingtalk.com/document/isvapp/delete-a-space + */ + deleteSpace(spaceId: string, query: DeleteSpaceQuery): Promise + /** + * 新建空间 + * @see https://developers.dingtalk.com/document/isvapp/new-space + */ + driveAddSpace(params: DriveAddSpaceParams): Promise + /** + * 获取空间列表 + * @see https://developers.dingtalk.com/document/isvapp/queries-a-space-list + */ + listSpaces(query: ListSpacesQuery): Promise + } +} diff --git a/adapters/dingtalk/src/api/edu.ts b/adapters/dingtalk/src/api/edu.ts new file mode 100644 index 00000000..904d91b4 --- /dev/null +++ b/adapters/dingtalk/src/api/edu.ts @@ -0,0 +1,29 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface MoveStudentParams { + /** 操作者的userid,可调用[通过免登码获取用户信息](https://developers.dingtalk.com/document/app/obtain-the-userid-of-a-user-by-using-the-log-free)接口获取。 */ + operator: string + /** 学生的userid,可调用[获取人员列表](https://developers.dingtalk.com/document/app/obtains-a-list-of-home-school-user-identities)接口获取。 */ + userId: string + /** 原班级ID,可调用[获取部门列表](https://developers.dingtalk.com/document/app/obtains-the-department-node-list)接口获取。 */ + originClassId: number + /** 目标班级ID,可调用[获取部门列表](https://developers.dingtalk.com/document/app/obtains-the-department-node-list)接口获取。 */ + targetClassId: number +} + +export interface MoveStudentResponse { + success?: unknown +} + +// funcName: isOldApi +Internal.define({ '/edu/students/move': { POST: { moveStudent: false } } }) +declare module '../internal' { + interface Internal { + /** + * 学生调班 + * @see https://developers.dingtalk.com/document/isvapp/shift-students + */ + moveStudent(params: MoveStudentParams): Promise + } +} diff --git a/adapters/dingtalk/src/api/esign.ts b/adapters/dingtalk/src/api/esign.ts new file mode 100644 index 00000000..fb303ef6 --- /dev/null +++ b/adapters/dingtalk/src/api/esign.ts @@ -0,0 +1,43 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetFlowDocsResponse { + data?: { + fileId?: string + fileName?: string + fileUrl?: string + }[] +} + +export interface ApprovalListResponse { + data?: { + approvalName?: string + status?: string + refuseReason?: string + sponsorAccountName?: string + startTime?: number + endTime?: number + sealIdImg?: string + approvalNodes?: number + }[] +} + +// funcName: isOldApi +Internal.define({ + '/esign/flowTasks/{taskId}/docs': { GET: { getFlowDocs: false } }, + '/esign/approvals/{taskId}': { GET: { approvalList: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取流程任务的所有合同列表 + * @see https://developers.dingtalk.com/document/isvapp/get-a-list-of-all-contracts-for-the-process-task + */ + getFlowDocs(taskId: string): Promise + /** + * 获取流程任务用印审批列表 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-print-approval-list-for-process-tasks + */ + approvalList(taskId: string): Promise + } +} diff --git a/adapters/dingtalk/src/api/exclusive.ts b/adapters/dingtalk/src/api/exclusive.ts new file mode 100644 index 00000000..a72f05f8 --- /dev/null +++ b/adapters/dingtalk/src/api/exclusive.ts @@ -0,0 +1,371 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface QueryUserBehaviorParams { + /** 用户行为: */ + type: number + /** 端类型: */ + platform: number + /** 开始时间,时间戳,单位毫秒。 */ + startTime?: number + /** 结束时间,时间戳,单位毫秒。 */ + endTime?: number + /** 分页大小。 */ + pageSize: number + /** 起始页。 */ + pageNumber: number + /** 用户userId信息,可调用[获取部门用户userId列表](https://open.dingtalk.com/document/orgapp/query-the-list-of-department-userids)接口获取userId。 */ + userId?: string +} + +export interface QueryUserBehaviorResponse { + data?: { + userName?: string + time?: number + type?: number + pictureUrl?: string + platform?: number + scene?: string + userId?: string + }[] + totalCnt?: number + dataCnt?: number +} + +export interface GetPublicDevicesQuery { + /** 系统: */ + platform?: string + /** 注册或申请的开始时间,单位毫秒。 */ + startTime?: number + /** 注册或申请截止时间,单位毫秒。 */ + endTime?: number + /** 单页返回的数据条数。 */ + pageSize?: number + /** 页码。 */ + pageNumber?: number + /** 设备标题。 */ + title?: string + /** 设备mac地址。 */ + macAddress?: string +} + +export interface GetPublicDevicesResponse { + totalCnt?: number + dataCnt?: number + data?: { + gmtCreate?: number + gmtModified?: number + title?: string + macAddress?: string + platform?: string + deviceScopeType?: number + deviceStaffs?: number + deviceDepts?: number + deviceRoles?: number + }[] +} + +export interface SendPhoneDingParams { + /** 接收DING消息的用户userId列表,最大值20。 */ + userids: string[] + /** 消息内容。 */ + content: string +} + +export interface SendPhoneDingResponse { + success?: unknown +} + +export interface QueryPartnerInfoResponse { + partnerDeptList?: { + title: string + value: string + memberCount: number + partnerNum?: string + partnerLabelModelLevel1?: number + }[] + partnerLabelList?: { + id?: number + name?: string + }[] + userId?: string +} + +export interface GetConfBaseInfoByLogicalIdQuery { + /** 会议逻辑ID。 */ + logicalConferenceId: string +} + +export interface GetConfBaseInfoByLogicalIdResponse { + conferenceId?: string + title?: string + startTime?: number + logicalConferenceId?: string + unionId?: string + nickname?: string +} + +export interface CreateTrustedDeviceBatchParams { + /** 员工userid,为0时表示这个设备为公共设备 */ + userId: string + /** 操作端。 */ + platform: string + /** 设备的Mac地址。 */ + macAddressList: string[] +} + +export interface CreateTrustedDeviceBatchResponse { + result?: unknown +} + +export interface ListAuditLogQuery { + /** 操作日志起始时间,UNIX时间戳,单位毫秒。 */ + startDate: number + /** 操作日志截止时间,UNIX时间戳,单位毫秒。 */ + endDate: number + /** 每页最大条目数,最大值500。 */ + pageSize: number + /** 操作记录生成时间,UNIX时间戳,单位毫秒,作为分页偏移量。 */ + nextGmtCreate?: number + /** 操作记录文件id,作为分页偏移量。 */ + nextBizId?: number +} + +export interface ListAuditLogResponse { + list?: { + operatorName?: string + platform?: number + platformView?: string + status?: number + action?: number + actionView?: string + resource?: string + gmtCreate?: number + userId?: string + ipAddress?: string + orgName?: string + receiverName?: string + receiverTypeView?: string + receiverType?: number + resourceExtension?: string + resourceSize?: number + targetSpaceId?: number + realName?: string + bizId?: string + operateModuleView?: string + operateModule?: number + gmtModified?: number + docMemberList?: number + docReceiverList?: number + workSpaceName?: string + workSpacePcUrl?: string + workSpaceMobileUrl?: string + docPcUrl?: string + docMobileUrl?: string + workSpaceId?: number + }[] +} + +export interface BanOrOpenGroupWordsParams { + /** 群ID,获取方式如下 */ + openConverationId: string + /** 操作类型。 */ + banWordsType: number +} + +export interface BanOrOpenGroupWordsResponse { + code?: string + cause?: string +} + +export interface GetSignedDetailByPageQuery { + /** 页码,首次传1。 */ + pageNumber: number + /** 签署状态。 */ + signStatus: number + /** 每页数量,最大值2000。 */ + pageSize: number +} + +export interface GetSignedDetailByPageResponse { + auditSignedDetailDTOList?: { + name?: string + staffId?: string + title?: string + phone?: string + email?: string + deptName?: string + roles?: string + }[] + currentPage?: number + pageSize?: number + total?: number +} + +export interface PublishFileChangeNoticeParams { + /** 钉盘文件ID。可以调用[查询文件列表](https://open.dingtalk.com/document/orgapp-server/obtain-the-file-list)接口获取。 */ + fileId: string + /** 钉盘空间ID,可调用[获取空间列表](https://open.dingtalk.com/document/orgapp-server/queries-a-space-list)接口获取。 */ + spaceId: string + /** 操作人的unionId,可通过以下两种方式获取: */ + operatorUnionId: string + /** 操作类型,取值: */ + operateType?: string +} + +export interface SendAppDingParams { + /** 接收DING消息的用户userid列表。 */ + userids: string[] + /** 消息内容。 */ + content: string +} + +export interface GetPartnerTypeByParentIdResponse { + data: { + typeId: number + typeName: string + labelId: string + }[] +} + +export interface SetDeptPartnerTypeAndNumParams { + /** 部门ID。 */ + deptId: string + /** 伙伴编码。 */ + partnerNum?: string + /** 伙伴类型ID。 */ + labelIds?: string[] +} + +export interface GetAllLabelableDeptsResponse { + data: { + deptId: string + superDeptId: string + deptName: string + memberCount: number + partnerNum: string + partnerLabelVOLevel1: number + partnerLabelVOLevel2: number + partnerLabelVOLevel3: number + partnerLabelVOLevel4: number + partnerLabelVOLevel5: number + }[] +} + +// funcName: isOldApi +Internal.define({ + '/exclusive/enterpriseSecurities/userBehaviors/screenshots/query': { + POST: { queryUserBehavior: false }, + }, + '/exclusive/trusts/publicDevices': { GET: { getPublicDevices: false } }, + '/exclusive/phoneDings/send': { POST: { sendPhoneDing: false } }, + '/exclusive/partners/users/{userId}': { GET: { queryPartnerInfo: false } }, + '/exclusive/data/conferences': { GET: { getConfBaseInfoByLogicalId: false } }, + '/exclusive/trusts/devices': { POST: { createTrustedDeviceBatch: false } }, + '/exclusive/fileAuditLogs': { GET: { listAuditLog: false } }, + '/exclusive/enterpriseSecurities/banOrOpenGroupWords': { + PUT: { banOrOpenGroupWords: false }, + }, + '/exclusive/audits/users': { GET: { getSignedDetailByPage: false } }, + '/exclusive/comments/send': { POST: { publishFileChangeNotice: false } }, + '/exclusive/appDings/send': { POST: { sendAppDing: false } }, + '/exclusive/partnerLabels/{parentId}': { + GET: { getPartnerTypeByParentId: false }, + }, + '/exclusive/partnerDepartments': { + POST: { setDeptPartnerTypeAndNum: false }, + GET: { getAllLabelableDepts: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取用户截屏操作记录 + * @see https://developers.dingtalk.com/document/app/obtain-anti-screen-capture-operation-records + */ + queryUserBehavior( + params: QueryUserBehaviorParams, + ): Promise + /** + * 获取公共设备列表。 + * @see https://developers.dingtalk.com/document/orgapp/query-public-equipment + */ + getPublicDevices( + query: GetPublicDevicesQuery, + ): Promise + /** + * 通过接口发送电话DING + * @see https://developers.dingtalk.com/document/orgapp/outgoing-phone-ding + */ + sendPhoneDing(params: SendPhoneDingParams): Promise + /** + * 根据userId查询人员的标签信息 + * @see https://developers.dingtalk.com/document/isvapp/you-can-call-this-operation-to-retrieve-the-user-tag + */ + queryPartnerInfo(userId: string): Promise + /** + * 根据会议逻辑ID查询会议基本信息 + * @see https://developers.dingtalk.com/document/isvapp/you-can-call-this-operation-to-query-the-basic-information + */ + getConfBaseInfoByLogicalId( + query: GetConfBaseInfoByLogicalIdQuery, + ): Promise + /** + * 批量新增可信设备 + * @see https://developers.dingtalk.com/document/isvapp/add-trusted-devices-in-batches + */ + createTrustedDeviceBatch( + params: CreateTrustedDeviceBatchParams, + ): Promise + /** + * 获取企业文件审计日志 + * @see https://developers.dingtalk.com/document/app/queries-file-audit-logs + */ + listAuditLog(query: ListAuditLogQuery): Promise + /** + * 群禁言或解禁 + * @see https://developers.dingtalk.com/document/isvapp/exclusive-dingtalk-group-ban + */ + banOrOpenGroupWords( + params: BanOrOpenGroupWordsParams, + ): Promise + /** + * 获取审计协议签署人员信息 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-information-about-the-persons-who-sign-the-audit + */ + getSignedDetailByPage( + query: GetSignedDetailByPageQuery, + ): Promise + /** + * 发送文件更改的评论 + * @see https://developers.dingtalk.com/document/isvapp/send-comments-on-file-changes + */ + publishFileChangeNotice( + params: PublishFileChangeNoticeParams, + ): Promise + /** + * 通过接口发送应用内DING + * @see https://developers.dingtalk.com/document/orgapp/send-in-application-ding + */ + sendAppDing(params: SendAppDingParams): Promise + /** + * 伙伴钉根据父标签查询子标签 + * @see https://developers.dingtalk.com/document/isvapp/obtain-child-tags-from-a-parent-tag + */ + getPartnerTypeByParentId( + parentId: string, + ): Promise + /** + * 设置部门伙伴类型和伙伴编码 + * @see https://developers.dingtalk.com/document/isvapp/set-department-partner-type-and-partner-code + */ + setDeptPartnerTypeAndNum( + params: SetDeptPartnerTypeAndNumParams, + ): Promise + /** + * 获取可打标部门列表 + * @see https://developers.dingtalk.com/document/isvapp/obtains-a-list-of-departments-that-can-be-marked + */ + getAllLabelableDepts(): Promise + } +} diff --git a/adapters/dingtalk/src/api/h3yun.ts b/adapters/dingtalk/src/api/h3yun.ts new file mode 100644 index 00000000..e1343ad0 --- /dev/null +++ b/adapters/dingtalk/src/api/h3yun.ts @@ -0,0 +1,536 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetUploadUrlQuery { + /** 表单编码。 */ + schemaCode: string + /** 业务数据实例ID。 */ + bizObjectId: string + /** 文件上传至目标控件的字段名。 */ + fieldName: string + /** 是否覆盖,取值: */ + isOverwrite: unknown +} + +export interface GetUploadUrlResponse { + code: string + message: string + data?: { + uploadUrl?: string + } +} + +export interface QueryAppFunctionNodesQuery { + /** 应用编码。 */ + appCode: string +} + +export interface QueryAppFunctionNodesResponse { + code: string + message: string + data?: { + schemaCode?: string + appCode?: string + parentCode?: string + displayName?: string + nodeVisibleType?: string + nodeType?: string + state?: string + sortKey?: number + isSystem?: number + }[] +} + +export interface CreateProcessesInstanceParams { + /** 流程表单编码。 */ + schemaCode: string + /** 业务数据实例ID。 */ + bizObjectId: string + /** 操作者的ID。 */ + opUserId: string +} + +export interface CreateProcessesInstanceResponse { + code: string + message: string + data?: { + processInstanceId?: string + } +} + +export interface DeleteProcessesInstanceQuery { + /** 流程实例ID。可以调用[查询流程实例](https://open.dingtalk.com/document/orgapp-server/query-flow-instances)接口获取。 */ + processInstanceId: string + /** 删除成功后,是否需要更新业务表单关联的流程实例ID。 */ + isAutoUpdateBizObject: unknown +} + +export interface DeleteProcessesInstanceResponse { + code: string + message: string +} + +export interface LoadBizFieldsQuery { + /** 表单编码。 */ + schemaCode: string +} + +export interface LoadBizFieldsResponse { + code: string + message: string + data?: { + schemaCode?: string + formName?: string + fields?: number + childForms?: number + } +} + +export interface QueryProcessesWorkItemsQuery { + /** 流程实例ID。 */ + processInstanceId: string +} + +export interface QueryProcessesWorkItemsResponse { + code: string + message: string + data?: { + workItemId?: string + workItemType?: string + processInstanceId?: string + appCode?: string + schemaCode?: string + bizObjectId?: string + processVersion?: string + activityCode?: string + activityName?: string + displayName?: string + state?: string + isFinish?: number + receiveTimeGMT?: string + startTimeGMT?: string + finishTimeGMT?: string + comment?: string + isApproval?: number + participant?: number + finisher?: number + receiptor?: number + }[] +} + +export interface BatchInsertBizObjectParams { + /** 表单编码。 */ + schemaCode: string + /** 操作用户ID。 */ + opUserId: string + /** 待新增的业对象json数组。JSON数组的key只可以调用[获取表单对象结构](https://open.dingtalk.com/document/orgapp-server/gets-the-form-object-structure)接口获取。 */ + bizObjectJsonArray: string[] + /** 是否是草稿,取值: */ + isDraft: unknown +} + +export interface BatchInsertBizObjectResponse { + code: string + message: string + data?: { + bizObjectIds?: number + processIds?: number + failedDatas?: number + failedMessages?: number + } +} + +export interface DeleteBizObjectQuery { + /** 表单编码。 */ + schemaCode: string + /** 业务数据ID。 */ + bizObjectId: string +} + +export interface DeleteBizObjectResponse { + code: string + message: string +} + +export interface CancelProcessInstanceParams { + /** 流程实例ID。可以调用[查询流程实例](https://open.dingtalk.com/document/orgapp-server/query-flow-instances)接口获取。 */ + processInstanceId: string +} + +export interface CancelProcessInstanceResponse { + code: string + message: string +} + +export interface CreateBizObjectParams { + /** 表单编码。 */ + schemaCode: string + /** 操作用户ID。 */ + opUserId: string + /** json格式的业务数据。JSON数组的key只可以调用[获取表单对象结构](https://open.dingtalk.com/document/orgapp-server/gets-the-form-object-structure)接口获取。 */ + bizObjectJson: string + /** 是否是草稿,取值: */ + isDraft: unknown +} + +export interface CreateBizObjectResponse { + code: string + message: string + data?: { + schemaCode?: string + formUsageType?: string + bizObjectId?: string + processInstanceId?: string + } +} + +export interface QueryProcessesInstanceQuery { + /** 流程表单编码。 */ + schemaCode: string + /** 业务数据ID。 */ + bizObjectId: string +} + +export interface QueryProcessesInstanceResponse { + code: string + message: string + data?: { + processInstanceId?: string + dingTalkProcessId?: string + processDisplayName?: string + processVersion?: number + schemaCode?: string + bizObjectId?: string + appCode?: string + state?: string + originator?: number + createdTimeGMT?: string + startTimeGMT?: string + finishTimeGMT?: string + }[] +} + +export interface UpdateBizObjectParams { + /** 表单编码。 */ + schemaCode: string + /** 业务数据ID。 */ + bizObjectId: string + /** 待修改的json格式业务数据。 */ + bizObjectJson: string +} + +export interface UpdateBizObjectResponse { + code: string + message: string +} + +export interface LoadBizObjectQuery { + /** 表单编码或流程表单编码。 */ + schemaCode: string + /** 业务对象实例ID。 */ + bizObjectId: string +} + +export interface LoadBizObjectResponse { + code: string + message: string + data?: unknown +} + +export interface LoadBizObjectsParams { + /** 表单编码。 */ + schemaCode: string + /** 分页页码。 */ + pageNumber: number + /** 分页页大小,最大值500。 */ + pageSize: number + /** 需要返回的字段名,仅支持传入主表的字段。 */ + returnFields?: string[] + /** 排序字段结构列表。 */ + sortByFields?: object[] + /** json格式的动态条件过滤器。 */ + matcherJson?: string +} + +export interface LoadBizObjectsResponse { + code: string + message: string + data?: { + pageNumber?: number + pageSize?: number + totalCount?: number + bizObjects?: number + } +} + +export interface GetAttachmentTemporaryUrlQuery { + /** 附件ID。 */ + attachmentId: string +} + +export interface GetAttachmentTemporaryUrlResponse { + code: string + message: string + data?: { + attachmentUrl?: string + } +} + +export interface GetRoleUsersQuery { + /** 角色ID。 */ + roleId: string +} + +export interface GetRoleUsersResponse { + code: string + message: string + data?: { + userId?: string + name?: string + code?: string + sex?: string + description?: string + mobile?: string + email?: string + departmentId?: string + departmentName?: string + domainType?: string + partDepartmentIds?: number + sortKey?: number + }[] +} + +export interface GetRolesResponse { + code: string + message: string + data?: { + roleGroups?: number + roles?: number + } +} + +export interface GetUsersQuery { + /** 部门ID。 */ + departmentId: string + /** 是否递归获取子级部门下的用户。 */ + isRecursive?: unknown +} + +export interface GetUsersResponse { + code: string + message: string + data?: { + id?: string + name?: string + code?: string + sex?: string + description?: string + mobile?: string + email?: string + departmentId?: string + departmentName?: string + domainType?: string + partDepartmentIds?: number + sortKey?: number + }[] +} + +export interface GetAppsParams { + /** 查询类型,取值: */ + queryType: string + /** 待查询条件数组。 */ + values?: string[] +} + +export interface GetAppsResponse { + code: string + message: string + data?: { + appCode?: string + displayName?: string + appSource?: string + appState?: string + solution?: string + }[] +} + +export interface GetOrganizationsQuery { + /** 部门ID。 */ + departmentId?: string +} + +export interface GetOrganizationsResponse { + code: string + message: string + data?: { + id?: string + parentId?: string + name?: string + code?: string + unitType?: string + sortKey?: number + description?: string + }[] +} + +// funcName: isOldApi +Internal.define({ + '/h3yun/attachments/uploadUrls': { GET: { getUploadUrl: false } }, + '/h3yun/apps/functionNodes': { GET: { queryAppFunctionNodes: false } }, + '/h3yun/processes/instances': { + POST: { createProcessesInstance: false }, + DELETE: { deleteProcessesInstance: false }, + GET: { queryProcessesInstance: false }, + }, + '/h3yun/forms/loadBizFields': { GET: { loadBizFields: false } }, + '/h3yun/processes/workItems': { GET: { queryProcessesWorkItems: false } }, + '/h3yun/forms/instances/batch': { POST: { batchInsertBizObject: false } }, + '/h3yun/forms/instances': { + DELETE: { deleteBizObject: false }, + POST: { createBizObject: false }, + PUT: { updateBizObject: false }, + }, + '/h3yun/processes/instances/cancel': { + POST: { cancelProcessInstance: false }, + }, + '/h3yun/forms/instances/loadInstances': { GET: { loadBizObject: false } }, + '/h3yun/forms/instances/search': { POST: { loadBizObjects: false } }, + '/h3yun/attachments/temporaryUrls': { + GET: { getAttachmentTemporaryUrl: false }, + }, + '/h3yun/roles/roleUsers': { GET: { getRoleUsers: false } }, + '/h3yun/roles': { GET: { getRoles: false } }, + '/h3yun/users': { GET: { getUsers: false } }, + '/h3yun/apps/search': { POST: { getApps: false } }, + '/h3yun/departments': { GET: { getOrganizations: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取文件上传地址 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-upload-url-of-a-file-2 + */ + getUploadUrl(query: GetUploadUrlQuery): Promise + /** + * 获取应用功能节点 + * @see https://developers.dingtalk.com/document/isvapp/queries-the-application-feature-nodes + */ + queryAppFunctionNodes( + query: QueryAppFunctionNodesQuery, + ): Promise + /** + * 创建流程实例 + * @see https://developers.dingtalk.com/document/isvapp/create-a-process-instance + */ + createProcessesInstance( + params: CreateProcessesInstanceParams, + ): Promise + /** + * 删除流程实例数据 + * @see https://developers.dingtalk.com/document/isvapp/delete-process-instance-data + */ + deleteProcessesInstance( + query: DeleteProcessesInstanceQuery, + ): Promise + /** + * 获取表单对象结构 + * @see https://developers.dingtalk.com/document/isvapp/gets-the-form-object-structure + */ + loadBizFields(query: LoadBizFieldsQuery): Promise + /** + * 获取流程实例节点工作项 + * @see https://developers.dingtalk.com/document/isvapp/query-flow-instance-node-work-items + */ + queryProcessesWorkItems( + query: QueryProcessesWorkItemsQuery, + ): Promise + /** + * 批量新增表单业务数据 + * @see https://developers.dingtalk.com/document/isvapp/batch-add-form-business-data + */ + batchInsertBizObject( + params: BatchInsertBizObjectParams, + ): Promise + /** + * 删除业务对象 + * @see https://developers.dingtalk.com/document/isvapp/delete-a-business-object + */ + deleteBizObject( + query: DeleteBizObjectQuery, + ): Promise + /** + * 取消流程实例 + * @see https://developers.dingtalk.com/document/isvapp/cancel-a-process-instance + */ + cancelProcessInstance( + params: CancelProcessInstanceParams, + ): Promise + /** + * 创建表单业务数据 + * @see https://developers.dingtalk.com/document/isvapp/create-form-business-data + */ + createBizObject( + params: CreateBizObjectParams, + ): Promise + /** + * 查询流程实例 + * @see https://developers.dingtalk.com/document/isvapp/query-flow-instances + */ + queryProcessesInstance( + query: QueryProcessesInstanceQuery, + ): Promise + /** + * 修改表单业务对象数据 + * @see https://developers.dingtalk.com/document/isvapp/modify-form-business-object-data + */ + updateBizObject( + params: UpdateBizObjectParams, + ): Promise + /** + * 获取业务实例信息 + * @see https://developers.dingtalk.com/document/isvapp/queries-business-instance-information + */ + loadBizObject(query: LoadBizObjectQuery): Promise + /** + * 查询表单业务数据列表 + * @see https://developers.dingtalk.com/document/isvapp/querying-form-business-data + */ + loadBizObjects( + params: LoadBizObjectsParams, + ): Promise + /** + * 获取附件临时免登地址 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-temporary-attachment-free-address + */ + getAttachmentTemporaryUrl( + query: GetAttachmentTemporaryUrlQuery, + ): Promise + /** + * 获取角色用户数据 + * @see https://developers.dingtalk.com/document/isvapp/obtain-role-data-1 + */ + getRoleUsers(query: GetRoleUsersQuery): Promise + /** + * 获取角色数据 + * @see https://developers.dingtalk.com/document/isvapp/obtain-role-data + */ + getRoles(): Promise + /** + * 获取用户数据 + * @see https://developers.dingtalk.com/document/isvapp/obtain-user-data + */ + getUsers(query: GetUsersQuery): Promise + /** + * 获取应用列表 + * @see https://developers.dingtalk.com/document/isvapp/queries-applications + */ + getApps(params: GetAppsParams): Promise + /** + * 获取组织数据 + * @see https://developers.dingtalk.com/document/isvapp/queries-organization-data + */ + getOrganizations( + query: GetOrganizationsQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/hrm.ts b/adapters/dingtalk/src/api/hrm.ts new file mode 100644 index 00000000..57856ba4 --- /dev/null +++ b/adapters/dingtalk/src/api/hrm.ts @@ -0,0 +1,271 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface HrmProcessUpdateTerminationInfoParams { + /** 已离职员工的userId,可调用[获取离职员工列表](https://open.dingtalk.com/document/orgapp/obtain-the-list-of-employees-who-have-left)接口获取离职员工userId。 */ + userId: string + /** 最后工作日,即离职日期,格式为毫秒值时间戳。 */ + lastWorkDate: number + /** 离职备注信息。 */ + dismissionMemo: string +} + +export interface HrmProcessUpdateTerminationInfoResponse { + result: unknown +} + +export interface HrmProcessRegularParams { + /** 待转正用户userId。 */ + userId: string + /** 转正时间,unix时间戳,单位毫秒。 */ + regularDate: number + /** 备注信息。 */ + remark?: string + /** 操作用户userId。 */ + operationId: string +} + +export interface HrmProcessRegularResponse { + result: unknown +} + +export interface QueryDismissionStaffIdListQuery { + /** 分页查询的游标。 */ + nextToken?: number + /** 每页条目数,默认值30,最大值50。 */ + maxResults?: number +} + +export interface QueryDismissionStaffIdListResponse { + nextToken?: number + hasMore?: unknown + userIdList?: string[] +} + +export interface RosterMetaFieldOptionsUpdateParams { + /** 花名册分组ID。 */ + groupId: string + /** 花名册字段标识。 */ + fieldCode: string + /** 需要修改的选项值列表,最大值20。 */ + labels: string[] + /** 修改类型。 */ + modifyType: string +} + +export interface RosterMetaFieldOptionsUpdateQuery { + /** 对应应用的agentId值。 */ + appAgentId?: number +} + +export interface RosterMetaFieldOptionsUpdateResponse { + result?: unknown +} + +export interface HrmProcessTransferParams { + /** 被调岗员工userId。 */ + userId: string + /** 部门ID。 */ + deptIdsAfterTransfer?: number[] + /** 员工调岗后的人事主部门ID。 */ + mainDeptIdAfterTransfer?: number + /** 员工调岗后的职位名称,长度最大124字符。 */ + positionNameAfterTransfer?: string + /** 员工调岗后的职级名称,长度不超过64字符。 */ + positionLevelAfterTransfer?: string + /** 员工调岗后的职务ID,调用[获取企业职务信息](https://open.dingtalk.com/document/orgapp-server/obtain-enterprise-title-information)接口获取jobId参数值。 */ + jobIdAfterTransfer?: string + /** 员工调岗后的职位ID。 */ + positionIdAfterTransfer?: string + /** 员工调岗后的职级ID。 */ + rankIdAfterTransfer?: string + /** 操作人userId。 */ + operateUserId?: string +} + +export interface HrmProcessTransferResponse { + result?: unknown +} + +export interface QueryHrmEmployeeDismissionInfoQuery { + /** 员工userId列表, 最大长度50。 */ + userIdList: string +} + +export interface QueryHrmEmployeeDismissionInfoResponse { + result?: { + userId?: string + lastWorkDay?: number + deptList?: number + reasonMemo?: string + preStatus?: number + handoverUserId?: string + status?: number + mainDeptName?: string + mainDeptId?: number + voluntaryReason?: number + passiveReason?: number + }[] +} + +export interface QueryJobsQuery { + /** 职务名称。 */ + jobName?: string + /** 分页游标。 */ + nextToken: number + /** 每页最大条目数,最大值100。 */ + maxResults: number +} + +export interface QueryJobsResponse { + nextToken?: number + hasMore?: unknown + list?: { + jobId?: string + jobName?: string + jobDescription?: string + }[] +} + +export interface QueryJobRanksQuery { + /** 职级序列ID。 */ + rankCategoryId?: string + /** 职级编码。 */ + rankCode?: string + /** 职级名称。 */ + rankName?: string + /** 分页游标。 */ + nextToken: number + /** 每页最大条目数,最大值200。 */ + maxResults: number +} + +export interface QueryJobRanksResponse { + nextToken?: number + hasMore?: unknown + list?: { + rankId?: string + rankCategoryId?: string + rankCode?: string + rankName?: string + minJobGrade?: number + maxJobGrade?: number + rankDescription?: string + }[] +} + +export interface QueryPositionsParams { + /** 职位名称。 */ + positionName?: string + /** 职位类别ID列表。 */ + inCategoryIds?: string[] + /** 职位ID列表。 */ + inPositionIds?: string[] + /** 部门ID。 */ + deptId?: number +} + +export interface QueryPositionsQuery { + /** 分页游标。 */ + nextToken: number + /** 每页最大条目数,最大值200。 */ + maxResults: number +} + +export interface QueryPositionsResponse { + nextToken?: number + hasMore?: unknown + list?: { + positionId?: string + positionName?: string + positionCategoryId?: string + jobId?: string + positionDes?: string + rankIdList?: number + status?: number + }[] +} + +// funcName: isOldApi +Internal.define({ + '/hrm/processes/employees/terminations': { + PUT: { hrmProcessUpdateTerminationInfo: false }, + }, + '/hrm/processes/regulars/become': { POST: { hrmProcessRegular: false } }, + '/hrm/employees/dismissions': { GET: { queryDismissionStaffIdList: false } }, + '/hrm/rosters/meta/fields/options': { + PUT: { rosterMetaFieldOptionsUpdate: false }, + }, + '/hrm/processes/transfer': { POST: { hrmProcessTransfer: false } }, + '/hrm/employees/dimissionInfos': { + GET: { queryHrmEmployeeDismissionInfo: false }, + }, + '/hrm/jobs': { GET: { queryJobs: false } }, + '/hrm/jobRanks': { GET: { queryJobRanks: false } }, + '/hrm/positions/query': { POST: { queryPositions: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 修改员工最后一次离职信息 + * @see https://developers.dingtalk.com/document/app/modify-resigned-employee-information + */ + hrmProcessUpdateTerminationInfo( + params: HrmProcessUpdateTerminationInfoParams, + ): Promise + /** + * 智能人事转正接口 + * @see https://developers.dingtalk.com/document/orgapp/intelligent-personnel-staff-to-become-regular + */ + hrmProcessRegular( + params: HrmProcessRegularParams, + ): Promise + /** + * 获取离职员工列表 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-list-of-employees-who-have-left + */ + queryDismissionStaffIdList( + query: QueryDismissionStaffIdListQuery, + ): Promise + /** + * 新增或删除花名册选项类型字段的选项 + * @see https://developers.dingtalk.com/document/orgapp/intelligent-personnel-roster-field-option-modification + */ + rosterMetaFieldOptionsUpdate( + query: RosterMetaFieldOptionsUpdateQuery, + params: RosterMetaFieldOptionsUpdateParams, + ): Promise + /** + * 智能人事员工调岗 + * @see https://developers.dingtalk.com/document/orgapp/intelligent-personnel-staff-transfer + */ + hrmProcessTransfer( + params: HrmProcessTransferParams, + ): Promise + /** + * 批量获取员工离职信息 + * @see https://developers.dingtalk.com/document/isvapp/obtain-multiple-employee-demission-information-1 + */ + queryHrmEmployeeDismissionInfo( + query: QueryHrmEmployeeDismissionInfoQuery, + ): Promise + /** + * 获取企业职务列表 + * @see https://developers.dingtalk.com/document/isvapp/obtains-a-list-of-enterprise-jobs + */ + queryJobs(query: QueryJobsQuery): Promise + /** + * 获取企业职级列表 + * @see https://developers.dingtalk.com/document/isvapp/obtain-a-list-of-enterprise-ranks + */ + queryJobRanks(query: QueryJobRanksQuery): Promise + /** + * 获取企业职位列表 + * @see https://developers.dingtalk.com/document/isvapp/obtain-a-list-of-enterprise-positions + */ + queryPositions( + query: QueryPositionsQuery, + params: QueryPositionsParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/im.ts b/adapters/dingtalk/src/api/im.ts new file mode 100644 index 00000000..90ffe53b --- /dev/null +++ b/adapters/dingtalk/src/api/im.ts @@ -0,0 +1,977 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface QuerySceneGroupTemplateRobotQuery { + /** 机器人的编码。 */ + robotCode?: string + /** 群会话ID。 */ + openConversationId?: string +} + +export interface QuerySceneGroupTemplateRobotResponse { + success?: unknown + result?: { + userId?: string + unionId?: string + } +} + +export interface BatchQueryGroupMemberParams { + /** 开放群ID。 */ + openConversationId: string + /** 群应用编码。 */ + coolAppCode?: string + /** 本次读取的最大数据记录数量(该入参传入值小于钉钉阈值时返回全部)。 */ + maxResults: number + /** 标记当前开始读取的位置,置空表示从头开始。 */ + nextToken?: string +} + +export interface BatchQueryGroupMemberResponse { + success?: unknown + memberUserIds?: string[] + hasMore?: unknown + nextToken?: string +} + +export interface QueryGroupMuteStatusQuery { + /** 群成员userId。 */ + userId: string + /** 开放的会话ID,可通过[创建场景群](https://open.dingtalk.com/document/group/create-a-scene-group-v2)接口获取。 */ + openConversationId: string +} + +export interface QueryGroupMuteStatusResponse { + groupMuteMode: unknown + userMuteResult: { + userMuteMode: number + muteStartTime: number + muteEndTime: number + } +} + +export interface UpdateMemberBanWordsParams { + /** 群成员id列表。 */ + userIdList: string[] + /** 开放群id,可通过[创建场景群](https://open.dingtalk.com/document/group/create-a-scene-group-v2)接口获取。 */ + openConversationId: string + /** 禁言状态: */ + muteStatus: number + /** 禁言持续时长,单位:毫秒。 */ + muteDuration: number +} + +export interface GetSceneGroupInfoParams { + /** 群ID: */ + openConversationId: string + /** 群聊酷应用编码: */ + coolAppCode?: string +} + +export interface GetSceneGroupInfoResponse { + success?: unknown + openConversationId?: string + templateId?: string + title?: string + ownerUserId?: string + icon?: string + groupUrl?: string + status?: number +} + +export interface UpdateGroupSubAdminParams { + /** 场景群群ID。 */ + openConversationId: string + /** 用户userid列表。 */ + userIds: string[] + /** 群成员类型: */ + role: number +} + +export interface UpdateGroupSubAdminResponse { + success: unknown +} + +export interface UpdateMemberGroupNickParams { + /** 场景群群ID,可以调用[创建场景群](https://developers.dingtalk.com/document/chatgroup/create-a-scene-group-v2)接口获取。 */ + openConversationId: string + /** 用户的userid。 */ + userId: string + /** 用户群昵称。 */ + groupNick: string +} + +export interface UpdateMemberGroupNickResponse { + success?: unknown +} + +export interface SendTemplateInteractiveCardParams { + /** 卡片内容模板ID,响应模板目前有: */ + cardTemplateId: string + /** 接收卡片的加密群ID,特指多人群会话(非单聊)。 */ + openConversationId?: string + /** 单聊会话接收者json字符串。 */ + singleChatReceiver?: string + /** 唯一标识一张卡片的外部ID。 */ + outTrackId: string + /** 机器人代码。 */ + robotCode: string + /** 可控制卡片回调的URL。 */ + callbackUrl?: string + /** 卡片模板,文本内容参数、 */ + cardData: string + /** 互动卡片发送选项。 */ + sendOptions?: unknown +} + +export interface SendTemplateInteractiveCardResponse { + processQueryKey?: string +} + +export interface UpdateInteractiveCardParams { + /** 唯一标示卡片的外部编码 */ + outTrackId?: string + /** 卡片数据 */ + cardData?: unknown + /** 卡片用户私有差异部分数据(如卡片不同人显示不同按钮;key:用户userId;value:用户数据变量) */ + privateData?: unknown + userIdType?: number + cardOptions?: unknown +} + +export interface UpdateInteractiveCardResponse { + success?: string +} + +export interface SendInteractiveCardParams { + /** 互动卡片的消息模板ID: */ + cardTemplateId: string + /** 群ID: */ + openConversationId?: string + /** 接收人userId列表。 */ + receiverUserIdList?: string[] + /** 唯一标示卡片的外部编码。 */ + outTrackId: string + /** 机器人的编码。 */ + robotCode?: string + /** 发送的会话类型: */ + conversationType: number + /** 卡片回调时的路由Key,用于查询注册的**callbackUrl**。 */ + callbackRouteKey?: string + /** 卡片公有数据。 */ + cardData: unknown + /** 卡片私有数据。 */ + privateData?: unknown + /** 企业机器人ID,填写企业内部开发-机器人的AppKey。 */ + chatBotId?: string + /** 用户ID类型: */ + userIdType?: number + /** 消息@人。格式:`{"key":"value"}`。 */ + atOpenIds?: unknown + /** 卡片操作。 */ + cardOptions?: unknown + /** 是否开启卡片纯拉模式。 */ + pullStrategy?: unknown +} + +export interface SendInteractiveCardResponse { + success?: unknown + result?: { + processQueryKey: string + } +} + +export interface UpdateRobotInteractiveCardParams { + /** 唯一标识一张卡片的外部ID(卡片幂等ID,可用于更新或重复发送同一卡片到多个群会话)【备注:同一个outTrackId重复创建,卡片数据不覆盖更新】 */ + cardBizId: string + /** 卡片模板-文本内容参数(卡片json结构体) */ + cardData?: string + /** 卡片模板-userId差异用户参数(json结构体) */ + userIdPrivateDataMap?: string + /** 卡片模板-userId差异用户参数(json结构体) */ + unionIdPrivateDataMap?: string + /** 互动卡片更新选项 */ + updateOptions?: unknown +} + +export interface UpdateRobotInteractiveCardResponse { + processQueryKey?: string +} + +export interface SendRobotInteractiveCardParams { + /** 卡片搭建平台模板ID,固定值填写为StandardCard。 */ + cardTemplateId: string + /** 接收卡片的加密群ID,特指多人群会话(非单聊)。 */ + openConversationId?: string + /** 单聊会话接收者json串。 */ + singleChatReceiver?: string + /** 唯一标识一张卡片的外部ID,卡片幂等ID,可用于更新或重复发送同一卡片到多个群会话。 */ + cardBizId: string + /** 机器人代码ID。 */ + robotCode: string + /** 可控制卡片回调的URL,不填则无需回调。 */ + callbackUrl?: string + /** 卡片模板文本内容参数,卡片json结构体。 */ + cardData: string + /** 卡片模板userId差异用户参数,json结构体。 */ + userIdPrivateDataMap?: string + /** 卡片模板unionId差异用户参数,json结构体。 */ + unionIdPrivateDataMap?: string + /** 互动卡片发送选项。 */ + sendOptions?: unknown + /** 是否开启卡片纯拉模式。 */ + pullStrategy?: unknown +} + +export interface SendRobotInteractiveCardResponse { + processQueryKey?: string +} + +export interface ChatIdToOpenConversationIdResponse { + openConversationId: string +} + +export interface ChatSubAdminUpdateParams { + /** 开放群ID。可以调用[创建群会话](https://open.dingtalk.com/document/orgapp-server/create-group-session)接口获取openConversationId参数值。 */ + openConversationId: string + /** 企业员工userid列表。可以调用[获取用户userid列表](https://open.dingtalk.com/document/orgapp-server/query-the-list-of-department-userids)接口获取userid_list参数值。 */ + userIds: string[] + /** 设置类型,取值: */ + role: number +} + +export interface ChatSubAdminUpdateResponse { + success: string +} + +export interface ImCreateGroupParams { + /** 群名称,长度限制为1~64个字符。例如:客户群。 */ + groupName: string + /** 群头像地址,长度限制为1~1024个字符。例如:http://***.png。 */ + groupAvatar?: string + /** 群模板Id,来源自钉钉客联工作台,通过群模板可以为群配置群机器人、群工具栏、常用语、欢迎语。长度限制为1~32个字符。例如:8d42****nkld。 */ + groupTemplateId: string + /** 群成员信息。 */ + users: object[] + /** 操作者在业务系统内的唯一标识。 */ + operatorId?: string +} + +export interface ImCreateGroupResponse { + openConversationId?: string + conversationId?: string + appUserIds?: string[] + userIds?: string[] +} + +export interface CreateCoupleGroupParams { + /** 群模板Id,来源自钉钉客联工作台,通过群模板可以为群配置群机器人、群工具栏、常用语、欢迎语。长度限制为1~32个字符。例如:8d42****nkld。 */ + groupTemplateId: string + /** 群成员信息。 */ + users?: object[] + /** 操作者在业务系统内的唯一标识。 */ + operatorId?: string +} + +export interface CreateCoupleGroupResponse { + openConversationId?: string + conversationId?: string + appUserIds?: string[] + userIds?: string[] +} + +export interface ChangeGroupOwnerParams { + /** 群会话openConversationId。 */ + openConversationId: string + /** 群主Id。 */ + groupOwnerId: string + /** 群主类型,取值: */ + groupOwnerType: number +} + +export interface ChangeGroupOwnerResponse { + newGroupOwnerId?: string + newGroupOwnerType?: number +} + +export interface DismissGroupConversationParams { + /** 需要被解散的群会话openConversationId。 */ + openConversationId: string +} + +export interface DismissGroupConversationResponse { + openConversationId?: string +} + +export interface SendRobotMessageParams { + /** 群会话openConversationId,长度限制为1~32个字符。 */ + openConversationIds: string[] + /** 机器人robotId(robotCode),指定哪个机器人发送消息,获取来源:在客联应用的机器人管理中获取robotCode。 */ + robotCode?: string + /** 消息类型,取值: */ + msgType: string + /** 消息体内容,请参考本文消息格式说明。 */ + msgContent: string + /** 钉内账号userId,长度限制为1~64个字符,例如:1745****8777。 */ + atDingUserId?: string + /** 钉外账号在业务系统内的唯一标志,长度限制为1~64个字符,例如:1107****2120。 */ + atAppUserId?: string + /** 是否@群所有人: */ + atAll?: unknown +} + +export interface SendRobotMessageResponse { + success?: unknown +} + +export interface CreateStoreGroupConversationParams { + /** 群名称。 */ + groupName: string + /** 群头像。 */ + groupAvatar?: string + /** 群模板Id。 */ + groupTemplateId: string + /** 钉外用户在业务系统内的标识。 */ + appUserId: string + /** 外部业务唯一标识(店铺唯一标识)。 */ + businessUniqueKey: string + /** 钉内用户userId。 */ + userIds?: string[] + /** 操作者在业务系统内的唯一标识。 */ + operatorId: string +} + +export interface CreateStoreGroupConversationResponse { + openConversationId: string + conversationId: string +} + +export interface CreateCoupleGroupConversationParams { + /** 群名称。 */ + groupName: string + /** 群头像链接地址。 */ + groupAvatar?: string + /** 群模板Id。 */ + groupTemplateId: string + /** 群主在业务系统内的标识。 */ + groupOwnerId: string + /** 钉外用户在业务系统内的标识。 */ + appUserId: string + /** 操作者在业务系统内的唯一标识。 */ + operatorId: string +} + +export interface CreateCoupleGroupConversationResponse { + openConversationId: string + conversationId: string +} + +export interface UpdateGroupNameParams { + /** 需要修改名称的群会话openConversationId。 */ + openConversationId: string + /** 新的群名称。 */ + groupName: string +} + +export interface UpdateGroupNameResponse { + newGroupName?: string +} + +export interface UpdateGroupAvatarParams { + /** 需要更新群头像的群会话openConversationId。 */ + openConversationId: string + /** 新的群头像地址。 */ + groupAvatar: string +} + +export interface UpdateGroupAvatarResponse { + newGroupAvatar: string +} + +export interface QuerySingleGroupParams { + /** 群模版Id。 */ + groupTemplateId: string + /** 群成员列表,最大值20。 */ + groupMembers: object[] +} + +export interface QuerySingleGroupResponse { + openConversations: { + openConversationId?: string + appUserId: string + userId: string + }[] +} + +export interface QueryGroupMemberQuery { + /** 群会话openConversationId。 */ + openConversationId: string +} + +export interface QueryGroupMemberResponse { + openConversationId: string + groupMembers: { + groupMemberId?: string + groupMemberName: string + groupMemberType: number + groupMemberAvatar?: string + groupMemberDynamics?: string + }[] +} + +export interface QueryUnReadMessageParams { + /** 钉外用户在业务系统内的标识。 */ + appUserId: string + /** 群会话openConversationIds列表,最大值100。 */ + openConversationIds?: string[] +} + +export interface QueryUnReadMessageResponse { + unReadCount: number + unReadItems?: { + openConversationId?: string + unReadCount?: number + }[] +} + +export interface SendMessageParams { + /** 钉外用户在业务系统内的标识,长度限制为1~64个字符。 */ + senderId: string + /** 钉内用户userId。 */ + receiverId?: string + /** 群会话openConversationId。 */ + openConversationId?: string + /** 消息类型,取值: */ + messageType: string + /** 消息内容。 */ + message: string + /** 渠道信息。 */ + sourceInfos?: unknown +} + +export interface SendMessageResponse { + requestId: string +} + +export interface RemoveGroupMemberParams { + /** 群会话openConversationId。 */ + openConversationId: string + /** 需要被移除的钉外用户在业务系统内的标识列表。 */ + appUserIds?: string[] + /** 需要被移除的钉内用户的userId列表。 */ + userIds?: string[] + /** 操作者在业务系统内的唯一标识。 */ + operatorId: string +} + +export interface RemoveGroupMemberResponse { + message: string +} + +export interface AddGroupMemberParams { + /** 群会话openConversationId。 */ + openConversationId: string + /** 钉外用户在业务系统内的标识列表。 */ + appUserIds?: string[] + /** 钉内用户userId。 */ + userIds?: string[] + /** 操作者在业务系统内的唯一标识。 */ + operatorId: string +} + +export interface AddGroupMemberResponse { + appUserIds: string[] + userIds: string[] +} + +export interface CreateGroupConversationParams { + /** 群名称。 */ + groupName: string + /** 群头像。 */ + groupAvatar?: string + /** 群模板Id。 */ + groupTemplateId: string + /** 群主在业务系统内的唯一标识。 */ + groupOwnerId: string + /** 群主类型,取值: */ + groupOwnerType?: number + /** 钉外用户ID列表。 */ + appUserIds?: string[] + /** 钉内用户userId列表。 */ + userIds?: string[] + /** 操作者在业务系统内的唯一标识。 */ + operatorId: string +} + +export interface CreateGroupConversationResponse { + openConversationId: string + conversationId: string + appUserIds: string[] + userIds: string[] +} + +export interface SendDingMessageParams { + /** 消息发送者userId,即钉内用户userId。 */ + senderId: string + /** 钉外用户在业务系统内的唯一标识。 */ + receiverId?: string + /** 群会话openConversationId。 */ + openConversationId?: string + /** 消息类型,取值: */ + messageType: string + /** 消息内容。 */ + message: string + /** 发送者在钉钉客联应用内的个人授权码。 */ + code: string +} + +export interface SendDingMessageResponse { + requestId: string +} + +export interface GetConversationUrlParams { + /** 钉外用户在业务系统内的标识,长度限制为1~64个字符。 */ + appUserId: string + /** 钉内用户userId。 */ + userId?: string + /** 群会话openConversationId。 */ + openConversationId?: string + /** 渠道code。 */ + channelCode: string + /** 钉外用户设备信息,用于安全性校验,自定义参数。 */ + sourceCode: string +} + +export interface GetConversationUrlResponse { + url: string +} + +export interface CreateInterconnectionParams { + /** 钉内用户与钉外用户关系。 */ + interconnections: object[] +} + +export interface CreateInterconnectionResponse { + results?: { + appUserId?: string + userId?: string + message?: string + }[] +} + +export interface SendOTOInteractiveCardParams { + /** 卡片模板ID,可通过[卡片平台](https://open-dev.dingtalk.com/fe/card)创建消息卡片,参见[创建消息模板](https://open.dingtalk.com/document/orgapp/create-message-template)。 */ + cardTemplateId: string + /** 会话ID。 */ + openConversationId?: string + /** 用户ID列表。 */ + receiverUserIdList?: string[] + /** 唯一标示卡片的外部编码。 */ + outTrackId: string + /** 机器人编码。 */ + robotCode?: string + /** 卡片回调时的路由Key,用于查询注册的callbackUrl。 */ + callbackRouteKey?: string + /** 卡片模板内容。 */ + cardData: unknown + /** 指定用户可见的按钮列表: */ + privateData?: unknown + /** 用户ID类型: */ + userIdType?: number + /** 消息@人。格式:`{"key":"value"}`。 */ + atOpenIds?: unknown + /** 卡片属性。 */ + cardOptions?: unknown + /** 是否开启卡片纯拉模式: */ + pullStrategy?: unknown +} + +export interface SendOTOInteractiveCardResponse { + success?: unknown + result?: { + processQueryKey: string + } +} + +export interface CloseTopboxParams { + /** 唯一标识一张卡片的外部ID,最大长度64。 */ + outTrackId: string + /** 会话类型: */ + conversationType: number + /** 会话id: */ + openConversationId?: string + /** 用户userId: */ + userId?: string + /** 用户unionId: */ + unoinId?: string + /** 机器人编码: */ + robotCode?: string + /** 酷应用编码: */ + coolAppCode?: string + /** 群模板id: */ + groupTemplateId?: string +} + +export interface CloseTopboxResponse { + success?: unknown +} + +export interface CreateTopboxParams { + /** 互动卡片的消息模板ID,详情参见[创建消息模板](https://open.dingtalk.com/document/group/create-message-template)后可获取模板ID。 */ + cardTemplateId: string + /** 唯一标识一张卡片的外部ID,最大长度64。 */ + outTrackId: string + /** 可控制卡片回调时的路由Key,用于指定特定的callbackUrl,调用[注册互动卡片回调地址](https://open.dingtalk.com/document/group/registration-card-interaction-callback-address-1)接口,获取参数callbackRouteKey。 */ + callbackRouteKey?: string + /** 卡片数据。 */ + cardData: unknown + /** 卡片模板userId差异用户参数。 */ + userIdPrivateDataMap?: unknown + /** 卡片模板unionId差异用户参数。 */ + unionIdPrivateDataMap?: unknown + /** 卡片设置项。 */ + cardSettings?: unknown + /** 会话类型: */ + conversationType: number + /** 会话id: */ + openConversationId?: string + /** 用户userId: */ + userId?: string + /** 用户unionId: */ + unoinId?: string + /** 机器人编码: */ + robotCode?: string + /** 酷应用编码: */ + coolAppCode?: string + /** 群模板id: */ + groupTemplateId?: string + /** 吊顶可见者userId,最多可传100个userId: */ + receiverUserIdList?: string[] + /** 吊顶可见者unionId,最多可传100个unionId: */ + receiverUnionIdList?: string[] + /** 吊顶的过期时间,毫秒级时间戳。 */ + expiredTime?: number + /** 期望吊顶的端,如果有多个用“|”分隔。 例如:ios|mac|android|win表示iOS、MAC、安卓和windows端。 */ + platforms?: string +} + +export interface CreateTopboxResponse { + success?: unknown +} + +// funcName: isOldApi +Internal.define({ + '/im/sceneGroups/templates/robots': { + GET: { querySceneGroupTemplateRobot: false }, + }, + '/im/sceneGroups/members/batchQuery': { + POST: { batchQueryGroupMember: false }, + }, + '/im/sceneGroups/muteSettings': { GET: { queryGroupMuteStatus: false } }, + '/im/sceneGroups/muteMembers/set': { POST: { updateMemberBanWords: false } }, + '/im/sceneGroups/query': { POST: { getSceneGroupInfo: false } }, + '/im/sceneGroups/subAdmins': { PUT: { updateGroupSubAdmin: false } }, + '/im/sceneGroups/members/groupNicks': { + PUT: { updateMemberGroupNick: false }, + }, + '/im/interactiveCards/templates/send': { + POST: { sendTemplateInteractiveCard: false }, + }, + '/im/interactiveCards': { PUT: { updateInteractiveCard: false } }, + '/im/interactiveCards/send': { POST: { sendInteractiveCard: false } }, + '/im/robots/interactiveCards': { PUT: { updateRobotInteractiveCard: false } }, + '/im/v1.0/robot/interactiveCards/send': { + POST: { sendRobotInteractiveCard: false }, + }, + '/im/chat/{chatId}/convertToOpenConversationId': { + POST: { chatIdToOpenConversationId: false }, + }, + '/im/subAdministrators': { POST: { chatSubAdminUpdate: false } }, + '/im/interconnections/groups': { POST: { createGroupConversation: false } }, + '/im/interconnections/couples/groups': { POST: { createCoupleGroup: false } }, + '/im/interconnections/groups/owners': { PUT: { changeGroupOwner: false } }, + '/im/interconnections/groups/dismiss': { + POST: { dismissGroupConversation: false }, + }, + '/im/interconnections/robotMessages/send': { + POST: { sendRobotMessage: false }, + }, + '/im/interconnections/storeGroups': { + POST: { createStoreGroupConversation: false }, + }, + '/im/interconnections/coupleGroups': { + POST: { createCoupleGroupConversation: false }, + }, + '/im/interconnections/groups/names': { PUT: { updateGroupName: false } }, + '/im/interconnections/groups/avatars': { PUT: { updateGroupAvatar: false } }, + '/im/interconnections/doubleGroups/query': { + POST: { querySingleGroup: false }, + }, + '/im/interconnections/conversations/members': { + GET: { queryGroupMember: false }, + }, + '/im/interconnections/unReadMsgs/query': { + POST: { queryUnReadMessage: false }, + }, + '/im/interconnections/messages/send': { POST: { sendMessage: false } }, + '/im/interconnections/groups/members/remove': { + POST: { removeGroupMember: false }, + }, + '/im/interconnections/groups/members': { POST: { addGroupMember: false } }, + '/im/interconnections/dingMessages/send': { + POST: { sendDingMessage: false }, + }, + '/im/conversations/urls': { POST: { getConversationUrl: false } }, + '/im/interconnections': { POST: { createInterconnection: false } }, + '/im/privateChat/interactiveCards/send': { + POST: { sendOTOInteractiveCard: false }, + }, + '/im/topBoxes/close': { POST: { closeTopbox: false } }, + '/im/topBoxes': { POST: { createTopbox: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 查询群内群模板机器人 + * @see https://developers.dingtalk.com/document/isvapp/query-intra-group-template-robot + */ + querySceneGroupTemplateRobot( + query: QuerySceneGroupTemplateRobotQuery, + ): Promise + /** + * 查询群成员 + * @see https://developers.dingtalk.com/document/orgapp/query-group-members + */ + batchQueryGroupMember( + params: BatchQueryGroupMemberParams, + ): Promise + /** + * 查询群禁言状态 + * @see https://developers.dingtalk.com/document/orgapp/query-group-silence-status + */ + queryGroupMuteStatus( + query: QueryGroupMuteStatusQuery, + ): Promise + /** + * 设置群成员禁言状态 + * @see https://developers.dingtalk.com/document/orgapp/set-group-members-access-control + */ + updateMemberBanWords(params: UpdateMemberBanWordsParams): Promise + /** + * 查询群简要信息 + * @see https://developers.dingtalk.com/document/isvapp/query-group-brief-information + */ + getSceneGroupInfo( + params: GetSceneGroupInfoParams, + ): Promise + /** + * 更新群管理员 + * @see https://developers.dingtalk.com/document/isvapp/update-group-administrator + */ + updateGroupSubAdmin( + params: UpdateGroupSubAdminParams, + ): Promise + /** + * 更新群成员的群昵称 + * @see https://developers.dingtalk.com/document/isvapp/update-group-nicknames-for-group-members + */ + updateMemberGroupNick( + params: UpdateMemberGroupNickParams, + ): Promise + /** + * 发送模板响应式可交互式卡片 + * @see https://developers.dingtalk.com/document/orgapp/send-lightweight-interactive-cards + */ + sendTemplateInteractiveCard( + params: SendTemplateInteractiveCardParams, + ): Promise + /** + * 更新钉钉互动卡片 + * @see https://developers.dingtalk.com/document/orgapp/update-dingtalk-interactive-cards-1 + */ + updateInteractiveCard( + params: UpdateInteractiveCardParams, + ): Promise + /** + * 发送可交互式动态卡片 + * @see https://developers.dingtalk.com/document/orgapp/send-interactive-dynamic-cards-1 + */ + sendInteractiveCard( + params: SendInteractiveCardParams, + ): Promise + /** + * 更新机器人发送互动卡片 + * @see https://developers.dingtalk.com/document/orgapp/update-the-robot-to-send-interactive-cards + */ + updateRobotInteractiveCard( + params: UpdateRobotInteractiveCardParams, + ): Promise + /** + * 机器人发送互动卡片(普通版) + * @see https://developers.dingtalk.com/document/orgapp/robots-send-interactive-cards + */ + sendRobotInteractiveCard( + params: SendRobotInteractiveCardParams, + ): Promise + /** + * 获取群会话的OpenConversationId + * @see https://developers.dingtalk.com/document/orgapp/obtain-group-openconversationid + */ + chatIdToOpenConversationId( + chatId: string, + ): Promise + /** + * 设置群管理员 + * @see https://developers.dingtalk.com/document/orgapp/batch-setup-group-administrator + */ + chatSubAdminUpdate( + params: ChatSubAdminUpdateParams, + ): Promise + /** + * 创建普通群 + * @see https://developers.dingtalk.com/document/app/create-common-group-new-version + */ + imCreateGroup(params: ImCreateGroupParams): Promise + /** + * 创建两人群 + * @see https://developers.dingtalk.com/document/app/creating-two-groups-of-people + */ + createCoupleGroup( + params: CreateCoupleGroupParams, + ): Promise + /** + * 更换群主 + * @see https://developers.dingtalk.com/document/isvapp/change-group-owner + */ + changeGroupOwner( + params: ChangeGroupOwnerParams, + ): Promise + /** + * 解散互通群 + * @see https://developers.dingtalk.com/document/isvapp/disband-bc-interconnection-group + */ + dismissGroupConversation( + params: DismissGroupConversationParams, + ): Promise + /** + * 机器人发送消息 + * @see https://developers.dingtalk.com/document/app/group-robots-send-messages + */ + sendRobotMessage( + params: SendRobotMessageParams, + ): Promise + /** + * 创建店铺群 + * @see https://developers.dingtalk.com/document/isvapp/create-a-store-group + */ + createStoreGroupConversation( + params: CreateStoreGroupConversationParams, + ): Promise + /** + * 创建钉外两人群 + * @see https://developers.dingtalk.com/document/isvapp/create-two-people-outside-the-nail + */ + createCoupleGroupConversation( + params: CreateCoupleGroupConversationParams, + ): Promise + /** + * 修改群名称 + * @see https://developers.dingtalk.com/document/isvapp/modify-the-group-name + */ + updateGroupName( + params: UpdateGroupNameParams, + ): Promise + /** + * 修改群头像 + * @see https://developers.dingtalk.com/document/isvapp/modify-the-avatar-of-a-communication-group + */ + updateGroupAvatar( + params: UpdateGroupAvatarParams, + ): Promise + /** + * 批量查询群信息 + * @see https://developers.dingtalk.com/document/isvapp/batch-query-cross-nail-two-group-list + */ + querySingleGroup( + params: QuerySingleGroupParams, + ): Promise + /** + * 查询群成员列表 + * @see https://developers.dingtalk.com/document/isvapp/query-the-group-member-list + */ + queryGroupMember( + query: QueryGroupMemberQuery, + ): Promise + /** + * 批量查询未读消息数 + * @see https://developers.dingtalk.com/document/isvapp/query-the-number-of-unread-messages-for-users-outside-of + */ + queryUnReadMessage( + params: QueryUnReadMessageParams, + ): Promise + /** + * 发送ToB消息 + * @see https://developers.dingtalk.com/document/isvapp/a-user-outside-the-dingtalk-sends-a-message-to-the + */ + sendMessage(params: SendMessageParams): Promise + /** + * 移除群成员 + * @see https://developers.dingtalk.com/document/isvapp/remove-a-connected-group-member + */ + removeGroupMember( + params: RemoveGroupMemberParams, + ): Promise + /** + * 添加群成员 + * @see https://developers.dingtalk.com/document/isvapp/add-group-members + */ + addGroupMember( + params: AddGroupMemberParams, + ): Promise + /** + * 创建互通群(支持普通互通群、跨钉两人群) + * @see https://developers.dingtalk.com/document/isvapp/create-a-common-group-or-cross-nail-group + */ + createGroupConversation( + params: CreateGroupConversationParams, + ): Promise + /** + * 发送ToC消息 + * @see https://developers.dingtalk.com/document/isvapp/dingtalk-users-send-messages-to-the-group-or-dingtalk-users + */ + sendDingMessage( + params: SendDingMessageParams, + ): Promise + /** + * 创建ToB会话地址 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-session-address + */ + getConversationUrl( + params: GetConversationUrlParams, + ): Promise + /** + * 创建钉外账号 + * @see https://developers.dingtalk.com/document/isvapp/create-bc-account-association + */ + createInterconnection( + params: CreateInterconnectionParams, + ): Promise + /** + * 人与人会话中机器人发送互动卡片 + * @see https://developers.dingtalk.com/document/orgapp/send-dingtalk-interactive-cards-to-person-to-person-chat-sessions + */ + sendOTOInteractiveCard( + params: SendOTOInteractiveCardParams, + ): Promise + /** + * 关闭互动卡片吊顶 + * @see https://developers.dingtalk.com/document/orgapp/close-interactive-card-ceiling + */ + closeTopbox(params: CloseTopboxParams): Promise + /** + * 创建并开启互动卡片吊顶 + * @see https://developers.dingtalk.com/document/orgapp/create-and-open-an-interactive-card-ceiling + */ + createTopbox(params: CreateTopboxParams): Promise + } +} diff --git a/adapters/dingtalk/src/api/industry.ts b/adapters/dingtalk/src/api/industry.ts new file mode 100644 index 00000000..c8f97e67 --- /dev/null +++ b/adapters/dingtalk/src/api/industry.ts @@ -0,0 +1,152 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface CampusGetCampusQuery { + /** 园区项目的部门ID。 */ + campusDeptId: number +} + +export interface CampusGetCampusResponse { + campusName?: string + campusCorpId?: string + campusDeptId?: number + belongProjectGroupId?: string + telephone?: string + description?: string + area?: unknown + country?: string + provId?: number + cityId?: number + countyId?: number + address?: string + location?: string + capacity?: string + orderStartTime?: number + orderEndTime?: number + orderInfo?: string + extend?: string +} + +export interface CampusGetCampusGroupQuery { + /** 项目组ID。 */ + groupId: number +} + +export interface CampusGetCampusGroupResponse { + projectGroupName?: string + extend?: string +} + +export interface CampusCreateCampusParams { + /** 园区项目的名称。 */ + campusName: string + /** 归属的项目组ID。 */ + belongProjectGroupId?: number + /** 联系电话。 */ + telephone?: string + /** 园区项目的描述。 */ + description?: string + /** 园区项目面积。 */ + area?: unknown + /** 园区所在国家。 */ + country?: string + /** 园区所在省行政编码。 */ + provId?: number + /** 园区所在市行政编码。 */ + cityId?: number + /** 园区所在区/县行政编码。 */ + countyId?: number + /** 园区所在详细地址信息。 */ + address?: string + /** 园区容量。 */ + capacity?: number + /** 项目订购开始时间戳,单位毫秒。 */ + orderStartTime?: number + /** 项目订购结束时间戳,单位毫秒。 */ + orderEndTime?: number + /** 订单信息。 */ + orderInfo?: string + /** 扩展字段。 */ + extend?: string + /** 创建人的unionId。 */ + creatorUnionId: string + /** 经纬度,格式为:经度,维度。 */ + location?: string +} + +export interface CampusCreateCampusResponse { + campusCorpId?: string + campusDeptId?: string +} + +export interface CampusCreateCampusGroupParams { + /** 项目组名称。 */ + name: string + /** 扩展信息。 */ + extend?: string +} + +export interface CampusCreateCampusGroupResponse { + groupId?: number +} + +export interface CampusDeleteCampusGroupQuery { + /** 项目组ID。 */ + campusProjectGroupId: number +} + +export interface CampusDeleteCampusGroupResponse { + success?: unknown +} + +// funcName: isOldApi +Internal.define({ + '/industry/campuses/projectInfos': { GET: { campusGetCampus: false } }, + '/industry/campuses/projects/groupInfos': { + GET: { campusGetCampusGroup: false }, + }, + '/industry/campuses/projects': { POST: { campusCreateCampus: false } }, + '/industry/campuses/projects/groups': { + POST: { campusCreateCampusGroup: false }, + DELETE: { campusDeleteCampusGroup: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 查询园区项目详情 + * @see https://developers.dingtalk.com/document/isvapp/query-a-project-in-a-specified-campus + */ + campusGetCampus( + query: CampusGetCampusQuery, + ): Promise + /** + * 查询项目组信息 + * @see https://developers.dingtalk.com/document/isvapp/query-a-project-group-in-the-specified-park + */ + campusGetCampusGroup( + query: CampusGetCampusGroupQuery, + ): Promise + /** + * 创建园区项目 + * @see https://developers.dingtalk.com/document/isvapp/create-a-campus-project + */ + campusCreateCampus( + params: CampusCreateCampusParams, + ): Promise + /** + * 创建项目组 + * @see https://developers.dingtalk.com/document/isvapp/create-a-project-group + */ + campusCreateCampusGroup( + params: CampusCreateCampusGroupParams, + ): Promise + /** + * 删除项目组 + * @see https://developers.dingtalk.com/document/isvapp/delete-a-project-group + */ + campusDeleteCampusGroup( + query: CampusDeleteCampusGroupQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/jzcrm.ts b/adapters/dingtalk/src/api/jzcrm.ts new file mode 100644 index 00000000..5db755c8 --- /dev/null +++ b/adapters/dingtalk/src/api/jzcrm.ts @@ -0,0 +1,303 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface EditContactParams { + /** 数据类型,固定值**197**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditContactResponse { + time: string + msgid: number +} + +export interface EditCustomerPoolParams { + /** 数据类型,固定值**238**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditCustomerPoolResponse { + time: string + msgid: number +} + +export interface EditExchangeParams { + /** 数据类型,固定值**228**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditExchangeResponse { + time: string + msgid: number +} + +export interface EditGoodsParams { + /** 数据类型,固定值**154**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditGoodsResponse { + time: string + msgid: number +} + +export interface EditOutstockParams { + /** 数据类型,固定值**191**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditOutstockResponse { + time: string + msgid: number +} + +export interface EditIntostockParams { + /** 数据类型,固定值**189**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditIntostockResponse { + time: string + msgid: number +} + +export interface EditProductionParams { + /** 数据类型,固定值**156**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditProductionResponse { + time: string + msgid: number +} + +export interface EditPurchaseParams { + /** 数据类型,固定值**153**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditPurchaseResponse { + time: string + msgid: number +} + +export interface EditOrderParams { + /** 数据类型,固定填写**150**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditOrderResponse { + time: string + msgid: number +} + +export interface EditInvoiceParams { + /** 数据类型,固定值**169**。 */ + datatype: number + /** 时间戳。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditInvoiceResponse { + time: string + msgid: number +} + +export interface EditCustomerParams { + /** 数据类型,固定值**148**。 */ + datatype: number + /** 时间戳,单位:秒。 */ + stamp: number + /** 数据ID。 */ + msgid?: number + /** 编辑数据。 */ + data?: unknown +} + +export interface EditCustomerResponse { + time: string + msgid: number +} + +export interface GetDataViewQuery { + /** 数据类型。 */ + datatype: string + /** 数据ID。 */ + msgid: number +} + +export interface GetDataViewResponse { + data: { + detail: number + } + dataname: unknown + time: string +} + +export interface GetDataListQuery { + /** 数据类型。 */ + datatype: string + /** 页码。 */ + page: number + /** 分页条数。 */ + pagesize: number +} + +export interface GetDataListResponse { + data: { + detail: number + }[] + dataname: unknown + page: number + pageSize: number + totalCount: number + time: string +} + +// funcName: isOldApi +Internal.define({ + '/jzcrm/contacts': { POST: { editContact: false } }, + '/jzcrm/customerPools': { POST: { editCustomerPool: false } }, + '/jzcrm/exchanges': { POST: { editExchange: false } }, + '/jzcrm/goods': { POST: { editGoods: false } }, + '/jzcrm/outstocks': { POST: { editOutstock: false } }, + '/jzcrm/intostocks': { POST: { editIntostock: false } }, + '/jzcrm/productions': { POST: { editProduction: false } }, + '/jzcrm/purchases': { POST: { editPurchase: false } }, + '/jzcrm/orders': { POST: { editOrder: false } }, + '/jzcrm/invoices': { POST: { editInvoice: false } }, + '/jzcrm/customers': { POST: { editCustomer: false } }, + '/jzcrm/dataView': { GET: { getDataView: false } }, + '/jzcrm/data': { GET: { getDataList: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 联系人 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-contacts + */ + editContact(params: EditContactParams): Promise + /** + * 客户公共池 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-customer-public-pools + */ + editCustomerPool( + params: EditCustomerPoolParams, + ): Promise + /** + * 编辑销售换货单数据 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-a-sales-order + */ + editExchange(params: EditExchangeParams): Promise + /** + * 编辑产品数据 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-product-information + */ + editGoods(params: EditGoodsParams): Promise + /** + * 编辑出库单信息 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-an-issue-ticket + */ + editOutstock(params: EditOutstockParams): Promise + /** + * 编辑入库单数据 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-a-shipment-record + */ + editIntostock(params: EditIntostockParams): Promise + /** + * 生产单 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-a-production-order + */ + editProduction( + params: EditProductionParams, + ): Promise + /** + * 采购单 + * @see https://developers.dingtalk.com/document/isvapp/edit-purchase-order + */ + editPurchase(params: EditPurchaseParams): Promise + /** + * 合同订单 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-contract-orders + */ + editOrder(params: EditOrderParams): Promise + /** + * 发货单 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-invoices + */ + editInvoice(params: EditInvoiceParams): Promise + /** + * 客户资料 + * @see https://developers.dingtalk.com/document/isvapp/add-or-edit-customer-profile + */ + editCustomer(params: EditCustomerParams): Promise + /** + * 获取数据详情 + * @see https://developers.dingtalk.com/document/isvapp/queries-data-details + */ + getDataView(query: GetDataViewQuery): Promise + /** + * 获取数据列表 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-data-list + */ + getDataList(query: GetDataListQuery): Promise + } +} diff --git a/adapters/dingtalk/src/api/link.ts b/adapters/dingtalk/src/api/link.ts new file mode 100644 index 00000000..db0df842 --- /dev/null +++ b/adapters/dingtalk/src/api/link.ts @@ -0,0 +1,93 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetUserFollowStatusQuery { + /** 待查询的服务窗关注者userId。 */ + userId?: string + /** 待查询的服务窗关注者unionId。 */ + unionId?: string + /** 服务窗帐号ID,可通过[服务窗帐号信息查询](https://open.dingtalk.com/document/orgapp/queries-the-list-of-services-under-an-enterprise)接口,获取返回参数`accountId`字段值。 */ + accountId?: string +} + +export interface GetUserFollowStatusResponse { + result: { + status?: string + } +} + +export interface ListAccountResponse { + result?: { + accountId?: string + accountName?: string + }[] +} + +export interface ListFollowerQuery { + /** 分页游标。 */ + nextToken?: string + /** 每页最大条目数,最大值100。 */ + maxResults?: number + /** 服务窗帐号ID,可调用[获取企业下服务窗列表](https://open.dingtalk.com/document/orgapp-server/queries-the-list-of-services-under-an-enterprise)接口获取accountId参数值。 */ + accountId?: string +} + +export interface ListFollowerResponse { + requestId?: string + result: { + nextToken?: string + userList?: number + } +} + +export interface GetFollowerInfoQuery { + /** 关注服务窗用户的userId,可调用[批量获取关注服务窗用户信息](https://open.dingtalk.com/document/orgapp-server/obtains-the-follower-information-from-the-service-window)获得userId参数值。 */ + userId?: string + /** 关注服务窗用户的unionId,可通过[查询用户详情](https://open.dingtalk.com/document/orgapp-server/query-user-details)接口获取unionId参数值。 */ + unionId?: string + /** 服务窗帐号ID,可调用[获取企业下服务窗列表](https://open.dingtalk.com/document/orgapp-server/queries-the-list-of-services-under-an-enterprise)接口获取accountId参数值。 */ + accountId?: string +} + +export interface GetFollowerInfoResponse { + requestId?: string + result: { + user?: number + } +} + +// funcName: isOldApi +Internal.define({ + '/link/followers/statuses': { GET: { getUserFollowStatus: false } }, + '/link/accounts': { GET: { listAccount: false } }, + '/link/followers': { GET: { listFollower: false } }, + '/link/followers/infos': { GET: { getFollowerInfo: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取用户关注状态 + * @see https://developers.dingtalk.com/document/orgapp/obtain-the-attention-status-of-the-user-service-window + */ + getUserFollowStatus( + query: GetUserFollowStatusQuery, + ): Promise + /** + * 获取企业下服务窗帐号列表 + * @see https://developers.dingtalk.com/document/orgapp/queries-the-list-of-services-under-an-enterprise + */ + listAccount(): Promise + /** + * 批量获取关注服务窗用户信息 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-follower-information-from-the-service-window + */ + listFollower(query: ListFollowerQuery): Promise + /** + * 获取服务窗关注人信息 + * @see https://developers.dingtalk.com/document/orgapp/queries-the-follower-information-of-the-service-window + */ + getFollowerInfo( + query: GetFollowerInfoQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/live.ts b/adapters/dingtalk/src/api/live.ts new file mode 100644 index 00000000..039f1913 --- /dev/null +++ b/adapters/dingtalk/src/api/live.ts @@ -0,0 +1,161 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface DeleteLiveQuery { + /** 直播ID。 */ + liveId: string + /** 用户unionId。 */ + unionId: string +} + +export interface DeleteLiveResponse { + result?: { + success?: number + } +} + +export interface QueryLiveWatchUserListQuery { + /** 直播ID。 */ + liveId: string + /** 用户unionId。 */ + unionId: string + /** 分页起始位置,从0开始。 */ + pageNumber?: number + /** 分页大小。 */ + pageSize: number +} + +export interface QueryLiveWatchUserListResponse { + result?: { + orgUsesList?: number + outOrgUserList?: number + } +} + +export interface QueryLiveWatchDetailQuery { + /** 直播ID。 */ + liveId: string + /** 用户unionId。 */ + unionId: string +} + +export interface QueryLiveWatchDetailResponse { + result?: { + pv?: number + uv?: number + liveUv?: number + playbackUv?: number + totalWatchTime?: number + avgWatchTime?: number + praiseCount?: number + msgCount?: number + } +} + +export interface UpdateLiveParams { + /** 直播ID。 */ + liveId: string + /** 主播的unionId。 */ + unionId: string + /** 直播标题。 */ + title?: string + /** 直播简介。 */ + introduction?: string + /** 直播的封面地址。 */ + coverUrl?: string + /** 直播的预计开播时间戳,单位毫秒。 */ + preStartTime?: number + /** 直播的预计结束时间戳,单位毫秒。 */ + preEndTime?: number +} + +export interface UpdateLiveResponse { + result?: { + success?: number + } +} + +export interface CreateLiveParams { + /** 发起直播的主播unionId。 */ + unionId: string + /** 直播标题。 */ + title: string + /** 直播简介。 */ + introduction?: string + /** 预计开播时间戳,单位毫秒。 */ + preStartTime: number + /** 直播的封面地址。 */ + coverUrl?: string + /** 预计结束时间戳,单位毫秒。 */ + preEndTime: number + publicType?: number +} + +export interface CreateLiveResponse { + result?: { + liveId?: string + } +} + +export interface QueryLiveInfoQuery { + /** 直播ID。 */ + liveId: string + /** 操作者的unionId。 */ + unionId: string +} + +export interface QueryLiveInfoResponse { + result?: { + liveInfo?: number + } +} + +// funcName: isOldApi +Internal.define({ + '/live/lives': { + DELETE: { deleteLive: false }, + PUT: { updateLive: false }, + POST: { createLive: false }, + GET: { queryLiveInfo: false }, + }, + '/live/lives/watchUsers': { GET: { queryLiveWatchUserList: false } }, + '/live/lives/watchDetails': { GET: { queryLiveWatchDetail: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 删除直播 + * @see https://developers.dingtalk.com/document/isvapp/delete-live-streaming + */ + deleteLive(query: DeleteLiveQuery): Promise + /** + * 查询直播观看人员信息 + * @see https://developers.dingtalk.com/document/isvapp/queries-the-viewing-information-of-viewers + */ + queryLiveWatchUserList( + query: QueryLiveWatchUserListQuery, + ): Promise + /** + * 获取直播的观看数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-the-playback-data-of-a-live-stream + */ + queryLiveWatchDetail( + query: QueryLiveWatchDetailQuery, + ): Promise + /** + * 修改直播属性信息 + * @see https://developers.dingtalk.com/document/isvapp/modify-live-streaming + */ + updateLive(params: UpdateLiveParams): Promise + /** + * 创建直播 + * @see https://developers.dingtalk.com/document/isvapp/create-live-streaming + */ + createLive(params: CreateLiveParams): Promise + /** + * 查询直播详情 + * @see https://developers.dingtalk.com/document/isvapp/queries-the-live-streaming-information + */ + queryLiveInfo(query: QueryLiveInfoQuery): Promise + } +} diff --git a/adapters/dingtalk/src/api/microApp.ts b/adapters/dingtalk/src/api/microApp.ts new file mode 100644 index 00000000..3ee24d51 --- /dev/null +++ b/adapters/dingtalk/src/api/microApp.ts @@ -0,0 +1,308 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface RollbackInnerAppVersionParams { + /** 小程序版本id,用于唯一标识小程序版本信息。可通过调用服务端API-[获取企业内部小程序历史版本列表](https://open.dingtalk.com/document/orgapp/obtain-the-list-of-historical-versions-of-enterprise-internal-applets)接口,获取返回参数中`appVersionId`字段值。 */ + appVersionId: number + /** 操作人的unionId。可调用[查询用户详情](https://open.dingtalk.com/document/orgapp/query-user-details)接口获取`unionId`参数值。 */ + opUnionId: string +} + +export interface RollbackInnerAppVersionResponse { + result?: unknown +} + +export interface PublishInnerAppVersionParams { + appVersionId: number + /** 操作人的unionId。 */ + opUnionId: string + /** 小程序发布类型,取值: */ + publishType?: string + /** 是否支持PC端打开小程序,取值: */ + miniAppOnPc?: unknown +} + +export interface PublishInnerAppVersionResponse { + result?: unknown +} + +export interface PageInnerAppHistoryVersionQuery { + /** 当前页。 */ + pageNumber: number + /** 本次读取的最大数据记录数量。 */ + pageSize: number +} + +export interface PageInnerAppHistoryVersionResponse { + totalCount?: number + miniAppVersionList?: { + appVersionId: number + miniAppId?: string + appVersion: string + appVersionType: number + miniAppOnPc: number + createTime: string + modifyTime: string + }[] +} + +export interface ListInnerAppVersionResponse { + appVersionList?: { + appVersionId: number + miniAppId: string + appVersion: string + appVersionType: number + miniAppOnPc?: number + createTime: string + modifyTime: string + entranceLink?: string + }[] +} + +export interface ListAllInnerAppsResponse { + appList?: { + agentId: number + name?: string + desc?: string + icon?: string + homepageLink?: string + pcHomepageLink?: string + ompLink?: string + appId: number + appStatus: number + developType: number + }[] +} + +export interface GetMicroAppScopeResponse { + result?: { + userIds: number + deptIds: number + roleIds: number + onlyAdminVisible: number + } +} + +export interface SetMicroAppScopeParams { + /** 增加的可使用用户userId列表,最大长度100。 */ + addUserIds?: string[] + /** 删除的可使用用户userId列表,最大长度100。 */ + delUserIds?: string[] + /** 增加的可使用部门ID列表,最大长度100。 */ + addDeptIds?: number[] + /** 删除的可使用部门ID列表,最大长度100。 */ + delDeptIds?: number[] + /** 用户角色ID, */ + addRoleIds?: number[] + /** 删除的可使用角色列表,通过[获取角色列表](https://open.dingtalk.com/document/orgapp-server/obtains-a-list-of-enterprise-roles)接口获取,最大长度100。 */ + delRoleIds?: number[] + /** 是否仅管理员可使用。 */ + onlyAdminVisible?: unknown +} + +export interface SetMicroAppScopeResponse { + result?: unknown +} + +export interface ListUserVilebleAppResponse { + appList?: { + agentId: number + name?: string + desc?: string + icon?: string + homepageLink?: string + pcHomepageLink?: string + ompLink?: string + appId: number + appStatus: number + developType: number + }[] +} + +export interface ListAllAppResponse { + appList?: { + agentId: number + name?: string + desc?: string + icon?: string + homepageLink?: string + pcHomepageLink?: string + ompLink?: string + appId: number + appStatus: number + developType: number + }[] +} + +export interface DeleteInnerAppQuery { + /** 操作人的unionId,可调用[查询用户详情](https://open.dingtalk.com/document/orgapp/query-user-details)接口获取unionid参数值。 */ + opUnionId: string +} + +export interface DeleteInnerAppResponse { + result?: unknown +} + +export interface UpdateInnerAppParams { + /** 操作更新的员工unionId,可调用[查询用户信息](https://open.dingtalk.com/document/orgapp/query-user-details)接口获取unionid参数值。 */ + opUnionId: string + /** 应用名称,名称可以由中文、数字以及字母组成,长度范围要求2-20个字符。 */ + name?: string + /** 应用描述,最大长度200个字符。 */ + desc?: string + /** 应用图标,可调用[上传媒体文件](https://open.dingtalk.com/document/orgapp/upload-media-files)接口获取media_id参数值。 */ + icon?: string + /** 应用首页地址,请输入http或https开头的网址链接。 */ + homepageLink?: string + /** 应用PC端地址,请输入http或https开头的链接。 */ + pcHomepageLink?: string + /** 应用管理后台地址,输入http或https开头的链接。 */ + ompLink?: string + /** 服务器出口ip白名单,支持带一个*号通配符的IP格式。 */ + ipWhiteList?: string[] +} + +export interface UpdateInnerAppResponse { + result?: unknown +} + +export interface CreateInnerAppParams { + /** 操作人的unionId,该用户必须是拥有**应用管理权限**的管理员,可调用[查询用户详情](https://open.dingtalk.com/document/orgapp/query-user-details)接口获取unionid参数值。 */ + opUnionId: string + /** 应用名称。 */ + name: string + /** 应用描述。 */ + desc: string + /** 应用图标media,调用[上传媒体文件](https://open.dingtalk.com/document/orgapp/upload-media-files)接口获取media_id参数值。 */ + icon?: string + /** 应用首页地址。 */ + homepageLink?: string + /** 应用PC端地址。 */ + pcHomepageLink?: string + /** 应用管理后台地址。 */ + ompLink?: string + /** 服务器出口IP白名单列表,最大值50。 */ + ipWhiteList?: string[] + /** 权限类型,目前只支持BASE。 */ + scopeType?: string + /** 创建的内部应用类型:【默认为0】 */ + developType?: number +} + +export interface CreateInnerAppResponse { + agentId?: number + appKey?: string + appSecret?: string +} + +// funcName: isOldApi +Internal.define({ + '/microApp/innerMiniApps/{agentId}/versions/rollback': { + POST: { rollbackInnerAppVersion: false }, + }, + '/microApp/innerMiniApps/{agentId}/versions/publish': { + POST: { publishInnerAppVersion: false }, + }, + '/microApp/innerMiniApps/{agentId}/historyVersions': { + GET: { pageInnerAppHistoryVersion: false }, + }, + '/microApp/innerMiniApps/{agentId}/versions': { + GET: { listInnerAppVersion: false }, + }, + '/microApp/allInnerApps': { GET: { listAllInnerApps: false } }, + '/microApp/apps/{agentId}/scopes': { + GET: { getMicroAppScope: false }, + POST: { setMicroAppScope: false }, + }, + '/microApp/users/{userId}/apps': { GET: { listUserVilebleApp: false } }, + '/microApp/allApps': { GET: { listAllApp: false } }, + '/microApp/apps/{agentId}': { + DELETE: { deleteInnerApp: false }, + PUT: { updateInnerApp: false }, + }, + '/microApp/apps': { POST: { createInnerApp: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 回滚企业内部小程序版本 + * @see https://developers.dingtalk.com/document/app/rollback-of-enterprise-internal-applet-version + */ + rollbackInnerAppVersion( + agentId: number, + params: RollbackInnerAppVersionParams, + ): Promise + /** + * 发布企业内部小程序版本 + * @see https://developers.dingtalk.com/document/orgapp/release-internal-applet-version + */ + publishInnerAppVersion( + agentId: number, + params: PublishInnerAppVersionParams, + ): Promise + /** + * 获取企业内部小程序历史版本列表 + * @see https://developers.dingtalk.com/document/orgapp/obtain-the-list-of-historical-versions-of-enterprise-internal-applets + */ + pageInnerAppHistoryVersion( + agentId: number, + query: PageInnerAppHistoryVersionQuery, + ): Promise + /** + * 获取企业内部小程序的版本列表 + * @see https://developers.dingtalk.com/document/orgapp/get-the-version-list-of-the-enterprise-internal-applet + */ + listInnerAppVersion(agentId: number): Promise + /** + * 获取企业所有内部应用列表 + * @see https://developers.dingtalk.com/document/orgapp/get-a-list-of-all-applications-inside-the-enterprise + */ + listAllInnerApps(): Promise + /** + * 获取企业内部应用微应用的可使用范围 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-application-visible-range + */ + getMicroAppScope(agentId: number): Promise + /** + * 更新企业内部应用微应用的可使用范围 + * @see https://developers.dingtalk.com/document/orgapp/update-the-visible-range-of-micro-applications + */ + setMicroAppScope( + agentId: number, + params: SetMicroAppScopeParams, + ): Promise + /** + * 获取用户可见的企业应用列表 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-list-of-enterprise-applications-visible-to-a-user + */ + listUserVilebleApp(userId: string): Promise + /** + * 获取企业所有应用列表 + * @see https://developers.dingtalk.com/document/orgapp/obtains-a-list-of-all-enterprise-applications + */ + listAllApp(): Promise + /** + * 删除企业内部应用 + * @see https://developers.dingtalk.com/document/app/delete-an-internal-h5-application + */ + deleteInnerApp( + agentId: number, + query: DeleteInnerAppQuery, + ): Promise + /** + * 更新企业内部应用 + * @see https://developers.dingtalk.com/document/app/update-internal-h5-applications + */ + updateInnerApp( + agentId: number, + params: UpdateInnerAppParams, + ): Promise + /** + * 创建企业内部应用 + * @see https://developers.dingtalk.com/document/app/create-an-h5-application-for-your-enterprise + */ + createInnerApp( + params: CreateInnerAppParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/oapi.ts b/adapters/dingtalk/src/api/oapi.ts new file mode 100644 index 00000000..1b98780e --- /dev/null +++ b/adapters/dingtalk/src/api/oapi.ts @@ -0,0 +1,4082 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface OapiServiceGetCorpTokenParams { + /** 授权方corpid */ + auth_corpid?: string +} + +export interface OapiServiceGetCorpTokenResponse { + /** 授权方(企业)corp_access_token超时时间 */ + expires_in?: unknown + /** 授权方(企业)corp_access_token */ + access_token?: string + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiSsoGettokenQuery { + /** 企业Id */ + corpid?: string + /** 这里必须填写专属的SSOSecret */ + corpsecret?: string +} + +export interface OapiSsoGettokenResponse { + /** 获取到的凭证 */ + access_token?: string + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown +} + +export interface OapiGetJsapiTicketResponse { + /** 票据过期时间 */ + expires_in?: unknown + /** 用于JS API的临时票据 */ + ticket?: string + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiGettokenQuery { + /** 应用的唯一标识key */ + appkey?: string + /** 应用的密钥 */ + appsecret?: string +} + +export interface OapiGettokenResponse { + /** access_token */ + access_token?: string + /** expires_in */ + expires_in?: unknown + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiV2UserGetuserinfoParams { + /** 免登授权码 */ + code: string +} + +export interface OapiV2UserGetuserinfoResponse { + /** 错误码, 0代表成功,其它代表失败。 */ + errcode?: unknown + /** 错误信息。 */ + errmsg?: string + /** 返回结果 */ + result?: { + userid?: string + device_id?: string + sys?: number + sys_level?: number + unionid?: string + associated_unionid?: string + name?: string + } +} + +export interface OapiSnsGetuserinfoBycodeParams { + /** 登录的临时授权码 */ + tmp_auth_code?: string +} + +export interface OapiSnsGetuserinfoBycodeResponse { + /** user_info */ + user_info?: { + nick?: string + unionid?: string + openid?: string + main_org_auth_high_level?: number + } + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiSsoGetuserinfoQuery { + /** 再次强调,此token不同于一般的accesstoken,需要调用获取微应用管理员免登需要的AccessToken */ + code?: string + /** 通过Oauth认证给URL带上的CODE */ + access_token?: string +} + +export interface OapiSsoGetuserinfoResponse { + /** user_info */ + user_info?: { + avatar?: string + email?: string + name?: string + userid?: string + } + /** corp_info */ + corp_info?: { + corp_name?: string + corpid?: string + } + /** is_sys */ + is_sys?: unknown + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string +} + +export interface OapiServiceGetAuthInfoParams { + /** 套件key */ + suite_key?: string + /** 授权方corpid */ + auth_corpid?: string +} + +export interface OapiServiceGetAuthInfoResponse { + /** auth_info */ + auth_info?: { + agent?: number + } + /** auth_user_info */ + auth_user_info?: { + userId?: string + } + /** auth_corp_info */ + auth_corp_info?: { + corpid?: string + invite_code?: string + industry?: string + corp_name?: string + license_code?: string + auth_channel?: string + auth_channel_type?: string + is_authenticated?: number + auth_level?: number + invite_url?: string + corp_logo_url?: string + belong_corp_id?: string + unifiedSocialCredit?: string + full_corp_name?: string + } + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown + /** channel_auth_info */ + channel_auth_info?: { + channelAgent?: number + } +} + +export interface OapiV2UserUpdateParams { + /** 员工id,长度最大64个字符。员工在当前企业内的唯一标识。如果不传,服务器将自动生成一个userid。创建后不可修改,企业内必须唯一。 */ + userid: string + /** 员工名称,长度最大80个字符。 */ + name?: string + /** 手机号码,企业内必须唯一,不可重复。如果是国际号码,请使用+xx-xxxxxx的格式 */ + mobile?: string + /** 是否号码隐藏。隐藏手机号后,手机号在个人资料页隐藏,但仍可对其发DING、发起钉钉免费商务电话。 */ + hide_mobile?: unknown + /** 分机号,长度最大50个字符。企业内必须唯一,不可重复 */ + telephone?: string + /** 员工工号,长度最大50个字符。 */ + job_number?: string + /** 职位,长度最大200个字符。 */ + title?: string + /** 员工邮箱,长度最大50个字符。企业内必须唯一,不可重复。 */ + email?: string + /** 员工的企业邮箱,长度最大100个字符。员工的企业邮箱已开通,才能增加此字段。 */ + org_email?: string + /** 办公地点,长度最大100个字符。 */ + work_place?: string + /** 备注,长度最大2000个字符。 */ + remark?: string + /** 所属部门id列表 */ + dept_id_list?: number[] + /** 员工在对应的部门中的排序。 */ + dept_order_list?: object[] + /** 员工在对应的部门中的职位。 */ + dept_title_list?: object[] + /** 扩展属性,长度最大2000个字符。可以设置多种属性(手机上最多显示10个扩展属性,具体显示哪些属性,请到OA管理后台->设置->通讯录信息设置和OA管理后台->设置->手机端显示信息设置)。 该字段的值支持链接类型填写,同时链接支持变量通配符自动替换,目前支持通配符有:userid,corpid。示例: [工位地址](http://www.dingtalk.com?userid=#userid#&corpid=#corpid#) */ + extension?: unknown + /** 是否高管模式。开启后,手机号码对所有员工隐藏。普通员工无法对其发DING、发起钉钉免费商务电话。高管之间不受影响。 */ + senior_mode?: unknown + /** 入职时间,Unix时间戳,单位ms。 */ + hired_date?: unknown + /** 语言 */ + language?: string + /** 重置专属帐号密码 */ + init_password?: string + /** 修改专属帐号登录名 */ + loginId?: string + /** 部门内任职 */ + dept_position_list?: object[] + /** 企业邮箱类型(profession:标准版,base:基础版) */ + org_email_type?: string + /** 强制更新的字段,支持清空指定的字段,使用逗号分隔。目前支持字段:manager_userid */ + force_update_fields?: string[] + /** 直属主管 */ + manager_userid?: string + /** 专属帐号手机号 */ + exclusive_mobile?: string + /** 手机号验证状态 */ + exclusive_mobile_verify_status?: string + /** 修改本组织专属帐号时可指定昵称 */ + nickname?: string + /** 修改本组织专属帐号时可指定头像MediaId。只支持参考jpg/png,生成方法 https://developers.dingtalk.com/document/app/upload-media-files */ + avatarMediaId?: string + /** 自定义字段更新模式,0-覆盖方式 1-追加方式 (默认是覆盖) */ + ext_attrs_update_mode?: unknown + /** 更新自定义字段列表 */ + ext_attrs?: object[] + /** 自定义性别字段 */ + gender?: string +} + +export interface OapiV2UserUpdateResponse { + /** 错误码。0代表成功。 */ + errcode?: unknown + /** 错误信息。 */ + errmsg?: string +} + +export interface OapiV2UserCreateParams { + /** 员工id,长度最大64个字符。员工在当前企业内的唯一标识。 */ + userid?: string + /** 员工名称,长度最大80个字符。 */ + name: string + /** 手机号码,企业内必须唯一,不可重复。如果是国际号码,请使用+xx-xxxxxx的格式 */ + mobile?: string + /** 是否号码隐藏。隐藏手机号后,手机号在个人资料页隐藏,但仍可对其发DING、发起钉钉免费商务电话。 */ + hide_mobile?: unknown + /** 分机号,长度最大50个字符。企业内必须唯一,不可重复 */ + telephone?: string + /** 员工工号,长度最大50个字符。 */ + job_number?: string + /** 职位,长度最大200个字符。 */ + title?: string + /** 员工邮箱,长度最大50个字符。企业内必须唯一,不可重复。 */ + email?: string + /** 员工的企业邮箱,长度最大100个字符。员工的企业邮箱已开通,才能增加此字段。 */ + org_email?: string + /** 办公地点,长度最大100个字符。 */ + work_place?: string + /** 备注,长度最大2000个字符。 */ + remark?: string + /** 所属部门id列表 */ + dept_id_list?: number[] + /** 员工在对应的部门中的排序。 */ + dept_order_list?: object[] + /** 员工在对应的部门中的职位。 */ + dept_title_list?: object[] + /** 扩展属性,长度最大2000个字符。可以设置多种属性(手机上最多显示10个扩展属性,具体显示哪些属性,请到OA管理后台->设置->通讯录信息设置和OA管理后台->设置->手机端显示信息设置)。 该字段的值支持链接类型填写,同时链接支持变量通配符自动替换,目前支持通配符有:userid,corpid。示例: [工位地址](http://www.dingtalk.com?userid=#userid#&corpid=#corpid#) */ + extension?: unknown + /** 是否高管模式。开启后,手机号码对所有员工隐藏。普通员工无法对其发DING、发起钉钉免费商务电话。高管之间不受影响。 */ + senior_mode?: unknown + /** 入职时间,Unix时间戳,单位ms。 */ + hired_date?: unknown + /** 登录邮箱 */ + login_email?: string + /** 是否专属帐号(true时,不能指定loginEmail或mobile) */ + exclusive_account?: unknown + /** 专属帐号类型:sso: 企业自建专属帐号;dingtalk:钉钉自建专属帐号。 */ + exclusive_account_type?: string + /** 钉钉专属帐号登录名 */ + login_id?: string + /** 钉钉专属帐号初始密码 */ + init_password?: string + /** 部门内任职 */ + dept_position_list?: object[] + /** 企业邮箱类型(profession:标准版,base:基础版) */ + org_email_type?: string + /** 直属主管 */ + manager_userid?: string + /** 专属帐号手机号 */ + exclusive_mobile?: string + /** 专属帐号手机号验证状态 */ + exclusive_mobile_verify_status?: string + /** 需要添加的专属帐号所属corpid */ + outer_exclusive_corpid?: string + /** 需要添加的专属帐号所属userid */ + outer_exclusive_userid?: string + /** 创建本组织专属帐号时可指定头像MediaId。只支持参考jpg/png,生成方法 https://developers.dingtalk.com/document/app/upload-media-files */ + avatarMediaId?: string + /** 创建本组织专属帐号时可指定昵称 */ + nickname?: string + /** 自定义字段更新模式,0-覆盖方式 1-追加方式 (默认是覆盖) */ + ext_attrs_update_mode?: unknown + /** 自定义字段列表 */ + ext_attrs?: object[] + /** 自定义性别字段 */ + gender?: string +} + +export interface OapiV2UserCreateResponse { + /** 错误码。0代表成功。 */ + errcode?: unknown + /** 错误信息。 */ + errmsg?: string + /** 返回结果 */ + result?: { + userid?: string + unionId?: string + } +} + +export interface OapiOrgUnionTrunkGetResponse { + /** OpenOrgUnion */ + result?: { + org_name?: string + corpid?: string + }[] + /** 是否成功 */ + success?: unknown + /** 错误code */ + errcode?: unknown + /** 错误msg */ + errmsg?: string +} + +export interface OapiSmartworkHrmRosterMetaGetParams { + /** 微应用在企业的AgentId */ + agentid: unknown +} + +export interface OapiSmartworkHrmRosterMetaGetResponse { + /** 花名册分组定义 */ + result?: { + group_name?: string + group_id?: string + field_meta_info_list?: number + detail?: number + }[] + /** 服务调用成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiSmartworkHrmEmployeeV2ListParams { + /** 员工id列表 */ + userid_list: string[] + /** 需要获取的花名册字段信息(不传值时,企业调用获取全部字段,ISV调用获取所有有权限字段。查询字段越少,RT越低,建议按需查询) */ + field_filter_list?: string[] + /** 微应用在企业的agentId */ + agentid: unknown +} + +export interface OapiSmartworkHrmEmployeeV2ListResponse { + /** 返回结果 */ + result?: { + corp_id?: string + field_data_list?: number + userid?: string + unionid?: string + }[] + /** 调用是否成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiSmartworkHrmEmployeeV2UpdateParams { + /** 微应用在企业的AgentId */ + agentid: unknown + /** 编辑花名册入参 */ + param: unknown +} + +export interface OapiSmartworkHrmEmployeeV2UpdateResponse { + /** 调用是否成功 */ + result?: unknown + /** 调用结果 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiSmartworkHrmEmployeeFieldGrouplistParams { + /** 微应用在企业的AgentId,不需要自定义字段可不传 */ + agentid?: unknown +} + +export interface OapiSmartworkHrmEmployeeFieldGrouplistResponse { + /** 错误描述 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标记 */ + success?: unknown + /** 结果集 */ + result?: { + group_id?: string + has_detail?: number + field_list?: number + }[] +} + +export interface OapiSmartworkHrmEmployeeUpdateParams { + /** 添加待入职入参 */ + param: unknown + /** 微应用在企业的AgentId */ + agentid: unknown +} + +export interface OapiSmartworkHrmEmployeeUpdateResponse { + /** 业务处理是否成功 */ + result?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 调用结果 */ + success?: unknown +} + +export interface OapiSmartworkHrmEmployeeQueryonjobParams { + /** 在职员工子状态筛选。2,试用期;3,正式;5,待离职;-1,无状态 */ + status_list: number[] + /** 分页起始值,默认0开始 */ + offset: unknown + /** 分页大小,最大50 */ + size: unknown +} + +export interface OapiSmartworkHrmEmployeeQueryonjobResponse { + /** 分页结果 */ + result?: { + data_list?: number + next_cursor?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 调用结果 */ + success?: unknown +} + +export interface OapiSmartworkHrmEmployeeQuerypreentryParams { + /** 分页起始值,默认0开始 */ + offset: unknown + /** 分页大小,最大50 */ + size: unknown +} + +export interface OapiSmartworkHrmEmployeeQuerypreentryResponse { + /** 分页结果 */ + result?: { + next_cursor?: number + data_list?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 调用结果 */ + success?: unknown +} + +export interface OapiSmartworkHrmEmployeeAddpreentryParams { + /** 添加待入职入参 */ + param: unknown +} + +export interface OapiSmartworkHrmEmployeeAddpreentryResponse { + /** 员工id */ + userid?: string + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 调用结果 */ + success?: unknown +} + +export interface OapiSmartworkHrmEmployeeListParams { + /** 员工id列表 */ + userid_list: string[] + /** 需要获取的花名册字段信息 */ + field_filter_list?: string[] + /** 微应用在企业的agentId */ + agentid?: unknown +} + +export interface OapiSmartworkHrmEmployeeListResponse { + /** 返回结果 */ + result?: { + userid?: string + field_list?: number + partner?: number + }[] + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 调用是否成功 */ + success?: unknown +} + +export interface OapiReportTemplateGetbynameParams { + /** 员工id */ + userid: string + /** 模板名称 */ + template_name: string +} + +export interface OapiReportTemplateGetbynameResponse { + /** result */ + result?: { + default_receivers?: number + name?: string + id?: string + fields?: number + user_name?: string + userid?: string + default_received_convs?: number + } + /** 系统自动生成 */ + errcode?: unknown + /** 系统自动生成 */ + errmsg?: string +} + +export interface OapiReportCreateParams { + /** 创建日志的参数对象 */ + create_report_param: unknown +} + +export interface OapiReportCreateResponse { + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown + /** result */ + result?: string +} + +export interface OapiReportSavecontentParams { + /** 保存日志的参数对象 */ + create_report_param: unknown +} + +export interface OapiReportSavecontentResponse { + /** result */ + result?: string + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string +} + +export interface OapiReportSimplelistParams { + /** 查询起始时间 */ + start_time: unknown + /** 查询截止时间 */ + end_time: unknown + /** 要查询的模板名称 */ + template_name?: string + /** 员工的userid */ + userid?: string + /** 查询游标,初始传入0,后续从上一次的返回值中获取 */ + cursor: unknown + /** 每页数据量 */ + size: unknown +} + +export interface OapiReportSimplelistResponse { + /** result */ + result?: { + data_list?: number + size?: number + next_cursor?: number + has_more?: number + } + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string +} + +export interface OapiReportStatisticsListbytypeParams { + /** 日志id */ + report_id: string + /** 查询类型 0:已读人员列表 1:评论人员列表 2:点赞人员列表 */ + type: unknown + /** 分页查询的游标,最开始传0,后续传返回参数中的next_cursor值,默认值为0 */ + offset?: unknown + /** 分页参数,每页大小,最多传100,默认值为100 */ + size?: unknown +} + +export interface OapiReportStatisticsListbytypeResponse { + /** 成功 */ + success?: unknown + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 统计结果 */ + result?: { + next_cursor?: number + has_more?: number + userid_list?: number + } +} + +export interface OapiReportReceiverListParams { + /** 日志id */ + report_id: string + /** 分页查询的游标,最开始传0,后续传返回参数中next_cursor的值,默认值为0 */ + offset?: unknown + /** 分页参数,每页大小,最多传100,默认值为100 */ + size?: unknown +} + +export interface OapiReportReceiverListResponse { + /** 统计结果 */ + result?: { + has_more?: number + next_cursor?: number + userid_list?: number + } + /** 错误吗 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 成功 */ + success?: unknown +} + +export interface OapiReportCommentListParams { + /** 日志id */ + report_id: string + /** 分页查询的游标,最开始传0,后续传返回参数中的next_cursor值,默认值为0 */ + offset?: unknown + /** 分页参数,每页大小,最多传20,默认值为20 */ + size?: unknown +} + +export interface OapiReportCommentListResponse { + /** 统计结果 */ + result?: { + comments?: number + has_more?: number + next_cursor?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 成功 */ + success?: unknown +} + +export interface OapiReportStatisticsParams { + /** 日志id */ + report_id: string +} + +export interface OapiReportStatisticsResponse { + /** 统计结果 */ + result?: { + read_num?: number + comment_num?: number + comment_user_num?: number + like_num?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 是否成功 */ + success?: unknown +} + +export interface OapiReportGetunreadcountParams { + /** 员工id */ + userid?: string +} + +export interface OapiReportGetunreadcountResponse { + /** 员工日志未读数 */ + count?: unknown + /** errorMsg */ + errmsg?: string + /** 错误码 */ + errcode?: unknown +} + +export interface OapiReportListParams { + /** 查询的日志创建的开始时间 */ + start_time: unknown + /** 查询的日志创建的结束时间 */ + end_time: unknown + /** 要查询的模板名称 */ + template_name?: string + /** 员工的userid */ + userid?: string + /** 查询游标,初始传入0,后续从上一次的返回值中获取 */ + cursor: unknown + /** 每页数据量 */ + size: unknown + /** 查询的日志修改的开始时间 */ + modified_start_time?: unknown + /** 查询的日志修改的结束时间 */ + modified_end_time?: unknown +} + +export interface OapiReportListResponse { + /** result */ + result?: { + data_list?: number + size?: number + next_cursor?: number + has_more?: number + } + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string +} + +export interface OapiReportTemplateListbyuseridParams { + /** 员工userId, 不传递表示获取所有日志模板 */ + userid?: string + /** 分页游标,从0开始。根据返回结果里的next_cursor是否为空来判断是否还有下一页,且再次调用时offset设置成next_cursor的值 */ + offset?: unknown + /** 分页大小,最大可设置成100 */ + size?: unknown +} + +export interface OapiReportTemplateListbyuseridResponse { + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** result */ + result?: { + template_list?: number + next_cursor?: number + } +} + +export interface OapiCheckinRecordGetParams { + /** 需要查询的用户列表 */ + userid_list: string[] + /** 起始时间,单位毫秒 */ + start_time: unknown + /** 截止时间,单位毫秒。如果是取1个人的数据,时间范围最大到10天,如果是取多个人的数据,时间范围最大1天。 */ + end_time: unknown + /** 分页查询的游标,最开始可以传0 */ + cursor: unknown + /** 分页查询的每页大小,最大100 */ + size: unknown +} + +export interface OapiCheckinRecordGetResponse { + /** result */ + result?: { + next_cursor?: number + page_list?: number + } + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string +} + +export interface OapiCheckinRecordQuery { + /** 部门id(1 表示根部门) */ + department_id?: string + /** 开始时间,精确到毫秒,注意字段的位数 例:1520956800000 */ + end_time?: unknown + /** 结束时间,精确到毫秒,注意字段的位数 例:1520956800000(默认为当前时间) */ + start_time?: unknown + /** 支持分页查询,与size 参数同时设置时才生效,此参数代表偏移量,从0 开始 */ + offset?: unknown + /** 支持分页查询,与offset 参数同时设置时才生效,此参数代表分页大小,最大100 */ + size?: unknown + /** 排序,asc 为正序,desc 为倒序 */ + order?: string +} + +export interface OapiCheckinRecordResponse { + /** data */ + data?: { + name?: string + userId?: string + avatar?: string + timestamp?: number + place?: string + detailPlace?: string + remark?: string + imageList?: number + latitude?: string + longitude?: string + }[] + /** 对返回码的文本描述内容 */ + errmsg?: string + /** 返回码 */ + errcode?: unknown +} + +export interface OapiBlackboardCategoryListParams { + /** 操作人userId(必须是公告管理员) */ + operation_userid: string +} + +export interface OapiBlackboardCategoryListResponse { + /** 出参,success为true时,该值不为空,否则值为空 */ + result?: { + id?: string + name?: string + }[] + /** 本次调用是否成功,该值为false时,根据errcode和errMsg排查失败原因 */ + success?: unknown + /** 请求失败返回错误码 */ + errcode?: unknown + /** 请求失败返回错误信息 */ + errmsg?: string +} + +export interface OapiBlackboardUpdateParams { + /** 请求入参 */ + update_request?: unknown +} + +export interface OapiBlackboardUpdateResponse { + /** success为true时,该值不为空,否则值为空 */ + result?: unknown + /** 本次调用是否成功,该值为false时,根据errcode和errMsg排查失败原因 */ + success?: unknown + /** 请求失败返回的错误码 */ + errcode?: unknown + /** 请求失败返回的错误信息 */ + errmsg?: string +} + +export interface OapiBlackboardDeleteParams { + /** 公告id,可以通过https://oapi.dingtalk.com/blackboard/listids获取有效值 */ + blackboard_id: string + /** 操作人userId(必须是公告管理员) */ + operation_userid: string +} + +export interface OapiBlackboardDeleteResponse { + /** success为true时,该值不为空,否则值为空 */ + result?: unknown + /** 本次调用是否成功,该值为false时,根据errcode和errMsg排查失败原因 */ + success?: unknown + /** 请求失败返回的错误码 */ + errcode?: unknown + /** 请求失败返回的错误信息 */ + errmsg?: string +} + +export interface OapiBlackboardGetParams { + /** 公告id */ + blackboard_id: string + /** 操作人userId */ + operation_userid: string +} + +export interface OapiBlackboardGetResponse { + /** 出参,success为true时,该值不为空,否则值为空 */ + result?: { + id?: string + author?: string + title?: string + content?: string + category_id?: string + private_level?: number + depname_list?: number + username_list?: number + gmt_create?: string + gmt_modified?: string + read_count?: number + unread_count?: number + coverpic_url?: string + user_list?: number + deptList?: number + senderStaffId?: string + } + /** 本次调用是否成功,该值为false时,根据errcode和errMsg排查失败原因 */ + success?: unknown + /** 请求失败返回错误码,0代表无错误 */ + errcode?: unknown + /** 请求失败返回错误信息 */ + errmsg?: string +} + +export interface OapiBlackboardListidsParams { + /** 请求入参 */ + query_request?: unknown +} + +export interface OapiBlackboardListidsResponse { + /** success为true时,返回公告id列表。否则值为空 */ + result?: string[] + /** 本次调用是否成功,该值为false时,根据errcode和errMsg排查失败原因 */ + success?: unknown + /** 请求失败的错误码 */ + errcode?: unknown + /** 请求失败的错误原因 */ + errmsg?: string +} + +export interface OapiBlackboardCreateParams { + /** 请求入参 */ + create_request: unknown +} + +export interface OapiBlackboardCreateResponse { + /** success为true时,该值不为空,否则值为空 */ + result?: unknown + /** 本次调用是否成功,该值为false时,根据errcode和errMsg排查失败原因 */ + success?: unknown + /** 请求失败返回的错误码 */ + errcode?: unknown + /** 请求失败返回的错误信息 */ + errmsg?: string +} + +export interface OapiBlackboardListtoptenParams { + /** 用户id */ + userid: string + /** 公告分类id */ + categoryId?: string +} + +export interface OapiBlackboardListtoptenResponse { + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string + /** result */ + blackboard_list?: { + gmt_create?: string + title?: string + url?: string + categoryId?: string + id?: string + categoryName?: string + privateLevel?: number + isPushTop?: number + }[] +} + +export interface OapiHealthStepinfoGetuserstatusParams { + /** 用户id */ + userid: string +} + +export interface OapiHealthStepinfoGetuserstatusResponse { + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string + /** true表示开启,false表示未开启 */ + status?: unknown +} + +export interface OapiHealthStepinfoListbyuseridParams { + /** 员工userid列表,最多传50个 */ + userids: string[] + /** 时间,注意时间格式是YYMMDD */ + stat_date: string +} + +export interface OapiHealthStepinfoListbyuseridResponse { + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string + /** 步数列表 */ + stepinfo_list?: { + stat_date?: number + step_count?: number + userid?: string + }[] +} + +export interface OapiHealthStepinfoListParams { + /** 0表示取用户步数,1表示取部门步数 */ + type: unknown + /** 可以传入用户userid或者部门id */ + object_id: string + /** 时间列表,注意时间格式是YYYYMMDD */ + stat_dates: string[] +} + +export interface OapiHealthStepinfoListResponse { + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string + /** 步数列表 */ + stepinfo_list?: { + stat_date?: number + step_count?: number + }[] +} + +export interface OapiMicroappListByUseridQuery { + /** 员工userid */ + userid?: string +} + +export interface OapiMicroappListByUseridResponse { + /** 返回码 */ + errcode?: unknown + /** 对返回码的文本描述内容 */ + errmsg?: string + /** appList */ + appList?: { + agentId?: number + name?: string + appIcon?: string + appDesc?: string + isSelf?: number + appStatus?: number + homepageLink?: string + pcHomepageLink?: string + ompLink?: string + }[] +} + +export interface OapiMicroappListResponse { + /** appList */ + appList?: { + name?: string + agentId?: number + appIcon?: string + appDesc?: string + isSelf?: number + appStatus?: number + ompLink?: string + homepageLink?: string + pcHomepageLink?: string + appId?: number + }[] + /** 对返回码的文本描述内容 */ + errmsg?: string + /** 返回码 */ + errcode?: unknown +} + +export interface OapiMicroappDeleteParams { + /** 微应用实例化id,企业只能删除自建微应用 */ + agentId?: unknown +} + +export interface OapiMicroappDeleteResponse { + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiMicroappSetVisibleScopesParams { + /** 设置可见的员工id列表,格式为JSON数组 */ + userVisibleScopes?: string[] + /** 设置可见的部门id列表,格式为JSON数组 */ + deptVisibleScopes?: number[] + /** 是否仅限管理员可见,true代表仅限管理员可见 */ + isHidden?: unknown + /** 微应用实例化id */ + agentId?: unknown +} + +export interface OapiMicroappSetVisibleScopesResponse { + /** 返回码 */ + errmsg?: string + /** 对返回码的文本描述内容 */ + errcode?: unknown +} + +export interface OapiMicroappVisibleScopesParams { + /** 微应用实例化id */ + agentId?: unknown +} + +export interface OapiMicroappVisibleScopesResponse { + /** 微应用的可见用户id列表,格式为JSON数组 */ + userVisibleScopes?: string[] + /** 微应用的可见部门id列表,格式为JSON数组 */ + deptVisibleScopes?: number[] + /** 是否仅限管理员可见 */ + isHidden?: unknown + /** 对返回码的文本描述内容 */ + errmsg?: string + /** 返回码 */ + errcode?: unknown +} + +export interface OapiAsrVoiceTranslateParams { + /** media_id,获取方式见https://ding-doc.dingtalk.com/doc#/serverapi2/bcmg0i */ + media_id: string +} + +export interface OapiAsrVoiceTranslateResponse { + /** errorMsg */ + errmsg?: string + /** dingOpenErrcode */ + errcode?: unknown + /** result */ + result?: string +} + +export interface OapiAiMtTranslateParams { + /** 翻译源文字符串 */ + query: string + /** 翻译源语言类型 */ + source_language: string + /** 翻译目标语言类型 */ + target_language: string +} + +export interface OapiAiMtTranslateResponse { + /** 翻译结果字符串 */ + result?: string + /** 成功为0 */ + errcode?: unknown + /** 成功 */ + errmsg?: string +} + +export interface OapiOcrStructuredRecognizeParams { + /** 识别图片类型, 身份证idcard,营业执照增值税发票invoice,营业执照blicense,银行卡bank_card,车牌car_no,机动车发票car_invoice,驾驶证driving_license,行驶证vehicle_license,火车票train_ticket,定额发票quota_invoice,出租车发票taxi_ticket,机票行程单air_itinerary */ + type: string + /** 识别图片地址 */ + image_url: string +} + +export interface OapiOcrStructuredRecognizeResponse { + /** 错误码 */ + errcode?: unknown + /** 错误描述 */ + errmsg?: string + /** 识别结果 */ + result?: { + height?: number + width?: number + angle?: number + data?: string + original_height?: number + original_width?: number + } +} + +export interface OapiImChatScencegroupMessageSendV2Params { + /** 接收消息的群的openConversationId */ + target_open_conversation_id: string + /** 模板ID */ + msg_template_id: string + /** 消息模板内容替换参数-普通文本类型 */ + msg_param_map?: unknown + /** 消息模板内容替换参数-多媒体类型 */ + msg_media_id_param_map?: unknown + /** 消息接收人 userId 列表 (不设置任何接收人则全部可见) */ + receiver_user_ids?: string[] + /** 消息接收人 unionId 列表(不设置任何接收人则全部可见) */ + receiver_union_ids?: string[] + /** 消息接收人手机号列表(不设置任何接收人则全部可见) */ + receiver_mobiles?: string[] + /** @人的手机号列表 */ + at_mobiles?: string[] + /** 是否@所有人 */ + is_at_all?: unknown + /** 用于发送卡片的机器人编码,与场景群模板中的机器人编码保持一致 */ + robot_code?: string + /** @人的员工id列表 */ + at_users?: string[] + /** @人的unionId列表 */ + at_union_ids?: string[] +} + +export interface OapiImChatScencegroupMessageSendV2Response { + /** 成功 */ + succ?: unknown + /** 统一错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 开发消息ID */ + open_msg_id?: string +} + +export interface OapiImChatScenegroupTemplateCloseParams { + /** 群主userid */ + owner_user_id: string + /** 群模板ID */ + template_id: string + /** 启用模式 */ + apply_mode?: unknown + /** 加密cid,必填 */ + open_conversation_id: string +} + +export interface OapiImChatScenegroupTemplateCloseResponse { + /** 是否成功 */ + success?: unknown + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown +} + +export interface OapiImChatScenegroupTemplateApplyParams { + /** 群主userid */ + owner_user_id: string + /** 启用模式 */ + apply_mode?: unknown + /** 群模板ID */ + template_id: string + /** 加密cid,必填 */ + open_conversation_id: string +} + +export interface OapiImChatScenegroupTemplateApplyResponse { + /** 是否成功 */ + success?: unknown + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown +} + +export interface OapiImChatScencegroupInteractivecardCallbackRegisterParams { + /** 回调地址 */ + callback_url: string + /** 加密密钥用于校验来源 */ + api_secret?: string + /** callback地址的路由Key,一个key仅可映射一个callbackUrl,不传值企业内部应用默认为orgId,企业三方应用默认为SuiteKey */ + callbackRouteKey?: string + /** 是否强制覆盖更新 */ + forceUpdate?: unknown +} + +export interface OapiImChatScencegroupInteractivecardCallbackRegisterResponse { + /** 业务返回结果 */ + result?: { + apiSecret?: string + callbackUrl?: string + } + /** 成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiImChatScenegroupCreateParams { + /** 群主userid */ + owner_user_id: string + /** 群成员useridlist */ + user_ids?: string[] + /** 建群去重的业务id */ + uuid?: string + /** 群头像mediaId */ + icon?: string + /** @all 权限,0-默认,所有人,1-仅群主可@all */ + mention_all_authority?: unknown + /** 新成员是否可查看聊天历史消息,0-默认,否,1-是 */ + show_history_type?: unknown + /** 入群验证,0:不入群验证(默认) 1:入群验证 */ + validation_type?: unknown + /** 群可搜索,0-默认,不可搜索,1-可搜索 */ + searchable?: unknown + /** 群禁言,0-默认,不禁言,1-全员禁言 */ + chat_banned_type?: unknown + /** 管理类型,0-默认,所有人可管理,1-仅群主可管理 */ + management_type?: unknown + /** 群名称 */ + title: string + /** 群模板id */ + template_id: string + /** 群管理员useridlist */ + subadmin_ids?: string[] + /** 仅群主和管理员可在群内发DING 0-不开启,1-开启 */ + only_admin_can_ding?: unknown + /** 群会议 若开启,群内任意成员可发起视频和语音会议 0-不开启,1-开启 */ + all_members_can_create_mcs_conf?: unknown + /** 群日历 若开启,群内容非好友/同事的成员可相互发起钉钉日程 0-不开启,1-开启 */ + all_members_can_create_calendar?: unknown + /** 禁止发送群邮件 若开启,群内成员不可再对本群发送群邮件 0-不开启,1-开启 */ + group_email_disabled?: unknown + /** 仅群主和管理员可置顶群消息 0-不开启,1-开启 */ + only_admin_can_set_msg_top?: unknown + /** 禁止群成员私聊 若开启,普通群成员之间不能够加好友、单聊,且部分功能使用受限(管理员与非管理员之间不受影响)0-不开启,1-开启 */ + add_friend_forbidden?: unknown + /** 群直播 若开启,群内任意成员可发起群直播 0-不开启,1-开启 */ + group_live_switch?: unknown + /** 禁止非管理员向管理员发起单聊 若开启,非管理员不能向管理员发起单聊 0-不开启,1-开启 */ + members_to_admin_chat?: unknown +} + +export interface OapiImChatScenegroupCreateResponse { + /** 返回结果 */ + result?: { + open_conversation_id?: string + chat_id?: string + } + /** 是否成功 */ + success?: unknown + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown +} + +export interface OapiImChatScenegroupMemberAddParams { + /** 开放群id */ + open_conversation_id: string + /** 成员userid */ + user_ids?: string[] + /** 客户联系人staffIds */ + contact_staff_ids?: string[] +} + +export interface OapiImChatScenegroupMemberAddResponse { + /** 是否成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiImChatScenegroupMemberGetParams { + /** 分页游标 */ + cursor: string + /** 分页的pagesize */ + size: unknown + /** 开放群id */ + open_conversation_id: string +} + +export interface OapiImChatScenegroupMemberGetResponse { + /** 返回结果 */ + result?: { + member_user_ids?: number + next_cursor?: string + has_more?: number + member_contact_staff_ids?: number + union_ids?: number + staff_id_nick_map?: number + union_id_nick_map?: number + } + /** 请求是否成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiImChatScenegroupUpdateParams { + /** 群主userid */ + owner_user_id?: string + /** 群头像mediaId */ + icon?: string + /** @all 权限,0-默认,所有人,1-仅群主可@all */ + mention_all_authority?: unknown + /** 新成员是否可查看聊天历史消息,0-默认,否,1-是 */ + show_history_type?: unknown + /** 入群验证,0:不入群验证(默认) 1:入群验证 */ + validation_type?: unknown + /** 群可搜索,0-默认,不可搜索,1-可搜索 */ + searchable?: unknown + /** 群禁言,0-默认,不禁言,1-全员禁言 */ + chat_banned_type?: unknown + /** 管理类型,0-默认,所有人可管理,1-仅群主可管理 */ + management_type?: unknown + /** 群名称 */ + title?: string + /** 群id */ + open_conversation_id: string + /** 仅群主和管理员可在群内发DING 0-不开启,1-开启 */ + only_admin_can_ding?: unknown + /** 群会议 若开启,群内任意成员可发起视频和语音会议 0-不开启,1-开启 */ + all_members_can_create_mcs_conf?: unknown + /** 群日历 若开启,群内容非好友/同事的成员可相互发起钉钉日程 0-不开启,1-开启 */ + all_members_can_create_calendar?: unknown + /** 禁止发送群邮件 若开启,群内成员不可再对本群发送群邮件 0-不开启,1-开启 */ + group_email_disabled?: unknown + /** 仅群主和管理员可置顶群消息 0-不开启,1-开启 */ + only_admin_can_set_msg_top?: unknown + /** 禁止群成员私聊 若开启,普通群成员之间不能够加好友、单聊,且部分功能使用受限(管理员与非管理员之间不受影响)0-不开启,1-开启 */ + add_friend_forbidden?: unknown + /** 群直播 若开启,群内任意成员可发起群直播 0-不开启,1-开启 */ + group_live_switch?: unknown + /** 禁止非管理员向管理员发起单聊 若开启,非管理员不能向管理员发起单聊 0-不开启,1-开启 */ + members_to_admin_chat?: unknown + /** 自定义群插件是否需要群主和管理员审批0-不需要审批,1-需要审批 */ + plugin_customize_verify?: unknown +} + +export interface OapiImChatScenegroupUpdateResponse { + /** 返回结果 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiImChatScenegroupMemberDeleteParams { + /** 开放群id */ + open_conversation_id: string + /** 员工userid */ + user_ids?: string[] + /** 客户联系人staffId */ + contact_staff_ids?: string[] +} + +export interface OapiImChatScenegroupMemberDeleteResponse { + /** 请求是否成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiImChatScenegroupGetParams { + /** 群id */ + open_conversation_id: string +} + +export interface OapiImChatScenegroupGetResponse { + /** 返回结果 */ + result?: { + icon?: string + management_options?: number + title?: string + template_id?: string + open_conversation_id?: string + sub_admin_staff_ids?: number + owner_staff_id?: string + group_url?: string + member_amount?: number + scene_data?: string + } + /** 是否成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiRobotSendParams { + /** 消息类型 */ + msgtype: string + /** text类型 */ + text?: unknown + /** 被@人的手机号 */ + at?: unknown + /** 消息类型,此时固定为:link */ + link?: unknown + /** 此消息类型为固定markdown */ + markdown?: unknown + /** 此消息类型为固定actionCard */ + actionCard?: unknown + /** 此消息类型为固定feedCard */ + feedCard?: unknown +} + +export interface OapiRobotSendResponse { + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiAlitripBtripInvoiceSettingRuleParams { + /** 入参 */ + request: unknown +} + +export interface OapiAlitripBtripInvoiceSettingRuleResponse { + /** 操作是否成功 */ + success?: unknown + /** 返回值 */ + module?: { + add_num?: number + remove_num?: number + } + /** 状态码 */ + errcode?: unknown + /** 结果信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripInvoiceSettingAddParams { + /** 入参 */ + rq: unknown +} + +export interface OapiAlitripBtripInvoiceSettingAddResponse { + /** 是否成功 */ + success?: unknown + /** 状态码 */ + errcode?: unknown + /** 结果信息 */ + errmsg?: string + /** 结果值 */ + module?: unknown +} + +export interface OapiAlitripBtripProjectDeleteParams { + /** 企业id */ + corpid: string + /** 第三方项目ID */ + third_part_id: string +} + +export interface OapiAlitripBtripProjectDeleteResponse { + /** 错误码 */ + errcode?: unknown + /** 操作结果 */ + success?: unknown + /** 结果 */ + module?: unknown + /** 异常信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripProjectModifyParams { + /** 入参 */ + request: unknown +} + +export interface OapiAlitripBtripProjectModifyResponse { + /** 是否操作成功 */ + success?: unknown + /** 是否操作成功 */ + module?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripProjectAddParams { + /** 入参 */ + request: unknown +} + +export interface OapiAlitripBtripProjectAddResponse { + /** 是否操作成功 */ + success?: unknown + /** 结果 */ + module?: string + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripInvoiceSettingDeleteParams { + /** 入参 */ + request?: unknown +} + +export interface OapiAlitripBtripInvoiceSettingDeleteResponse { + /** 是否成功 */ + success?: unknown + /** 值 */ + module?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripInvoiceSettingModifyParams { + /** 入参 */ + request?: unknown +} + +export interface OapiAlitripBtripInvoiceSettingModifyResponse { + /** 是否成功 */ + success?: unknown + /** 返回值 */ + module?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripPriceQueryParams { + /** 请求入参 */ + req: unknown +} + +export interface OapiAlitripBtripPriceQueryResponse { + /** 接口返回 */ + result?: { + success?: number + module?: number + errcode?: number + errmsg?: string + } +} + +export interface OapiAlitripBtripTrainCitySuggestParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripTrainCitySuggestResponse { + /** 结果对象 */ + result?: { + cities?: number + } + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标识 */ + success?: unknown +} + +export interface OapiAlitripBtripMonthbillUrlGetParams { + /** 请求对象 */ + request: unknown +} + +export interface OapiAlitripBtripMonthbillUrlGetResponse { + /** 成功标识 */ + success?: unknown + /** 结果对象 */ + module?: { + start_date?: string + end_date?: string + url?: string + }[] + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripAddressGetParams { + /** 请求对象 */ + request?: unknown +} + +export interface OapiAlitripBtripAddressGetResponse { + /** 成功标识 */ + success?: unknown + /** 结果对象 */ + result?: { + url?: string + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripApprovalModifyParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripApprovalModifyResponse { + /** 成功标识 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 结果对象 */ + module?: { + apply_id?: number + thirdpart_apply_id?: string + } +} + +export interface OapiAlitripBtripFlightCitySuggestParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripFlightCitySuggestResponse { + /** 结果对象 */ + result?: { + cities?: number + nearby?: number + } + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标识 */ + success?: unknown +} + +export interface OapiAlitripBtripVehicleOrderSearchParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripVehicleOrderSearchResponse { + /** 返回码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 成功标识 */ + success?: unknown + /** 订单列表 */ + vehicle_order_list?: { + id?: number + gmt_create?: string + gmt_modified?: string + passenger_name?: string + corpid?: string + corp_name?: string + user_name?: string + userid?: string + dept_name?: string + deptid?: string + apply_show_id?: string + apply_id?: number + real_from_city_name?: string + real_to_city_name?: string + from_address?: string + to_address?: string + from_city_name?: string + to_city_name?: string + memo?: string + order_status?: number + car_level?: string + car_info?: string + estimate_price?: string + publish_time?: string + taken_time?: string + driver_confirm_time?: string + cancel_time?: string + travel_distance?: string + pay_time?: string + service_type?: number + business_category?: string + cost_center_id?: number + cost_center_number?: string + cost_center_name?: string + invoice_id?: number + invoice_title?: string + project_code?: string + project_title?: string + price_info_list?: number + thirdpart_itinerary_id?: string + user_affiliate_list?: number + user_confirm?: number + provider?: number + real_from_address?: string + real_to_address?: string + thirdpart_apply_id?: string + btrip_title?: string + is_special?: number + special_types?: number + project_id?: number + third_part_project_id?: string + }[] + /** 分页信息 */ + page_info?: { + page?: number + page_size?: number + total_number?: number + } +} + +export interface OapiAlitripBtripCostCenterQueryParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripCostCenterQueryResponse { + /** 成功标识 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 成本中心列表 */ + cost_center_list?: { + id?: number + corpid?: string + title?: string + number?: string + thirdpart_id?: string + scope?: number + alipay_no?: string + entity_list?: number + }[] +} + +export interface OapiAlitripBtripApprovalUpdateParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripApprovalUpdateResponse { + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标识 */ + success?: unknown +} + +export interface OapiAlitripBtripCostCenterNewParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripCostCenterNewResponse { + /** 成本中心对象 */ + result?: { + id?: number + } + /** 成功标识 */ + success?: unknown + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown +} + +export interface OapiAlitripBtripCostCenterModifyParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripCostCenterModifyResponse { + /** 成功标识 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripCostCenterDeleteParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripCostCenterDeleteResponse { + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标识 */ + success?: unknown +} + +export interface OapiAlitripBtripCostCenterEntitySetParams { + /** 请求对象 */ + rq?: unknown +} + +export interface OapiAlitripBtripCostCenterEntitySetResponse { + /** 成本标识 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 结果对象 */ + result?: { + add_num?: number + remove_num?: number + selected_user_num?: number + } +} + +export interface OapiAlitripBtripHotelOrderSearchParams { + /** rq */ + rq: unknown +} + +export interface OapiAlitripBtripHotelOrderSearchResponse { + /** 成功标识 */ + success?: unknown + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 酒店订单列表 */ + module?: { + id?: number + gmt_create?: string + gmt_modified?: string + corpid?: string + corp_name?: string + userid?: string + user_name?: string + deptid?: string + dept_name?: string + apply_id?: number + contact_name?: string + city?: string + hotel_name?: string + check_in?: string + check_out?: string + room_type?: string + room_num?: number + night?: number + guest?: string + order_type_desc?: string + order_status_desc?: string + cost_center?: number + invoice?: number + price_info_list?: number + thirdpart_itinerary_id?: string + order_status?: number + order_type?: number + user_affiliate_list?: number + thirdpart_apply_id?: string + btrip_title?: string + project_id?: number + project_code?: string + project_title?: string + thirdpart_Project_Id?: string + hotel_support_vat_invoice_type?: number + }[] + /** 分页相关信息 */ + page_info?: { + page?: number + page_size?: number + total_number?: number + } +} + +export interface OapiAlitripBtripTrainOrderSearchParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripTrainOrderSearchResponse { + /** 成功标识 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** module */ + train_order_list?: { + id?: number + gmt_create?: string + gmt_modified?: string + corpid?: string + corp_name?: string + userid?: string + user_name?: string + deptid?: string + dept_name?: string + apply_id?: number + contact_name?: string + dep_station?: string + arr_station?: string + dep_time?: string + arr_time?: string + train_number?: string + train_type?: string + seat_type?: string + run_time?: string + ticket_no_12306?: string + dep_city?: string + arr_city?: string + rider_name?: string + ticket_count?: number + status?: number + invoice?: number + cost_center?: number + price_info_list?: number + thirdpart_itinerary_id?: string + user_affiliate_list?: number + thirdpart_apply_id?: string + btrip_title?: string + project_id?: number + project_code?: string + project_title?: string + third_part_project_id?: string + }[] + /** 分页相关信息 */ + page_info?: { + page?: number + page_size?: number + total_number?: number + } +} + +export interface OapiAlitripBtripFlightOrderSearchParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripFlightOrderSearchResponse { + /** 成功标识 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 机票列表 */ + flight_order_list?: { + id?: number + gmt_modified?: string + userid?: string + corp_name?: string + corpid?: string + gmt_create?: string + user_name?: string + deptid?: string + dept_name?: string + apply_id?: string + contact_name?: string + dep_city?: string + arr_city?: string + dep_date?: string + ret_date?: string + trip_type?: number + passenger_count?: number + cabin_class?: string + status?: number + discount?: string + flight_no?: string + passenger_name?: string + dep_airport?: string + arr_airport?: string + invoice?: number + cost_center?: number + price_info_list?: number + insureInfo_list?: number + thirdpart_itinerary_id?: string + user_affiliate_list?: number + thirdpart_apply_id?: string + btrip_title?: string + project_id?: number + project_code?: string + project_title?: string + third_part_project_id?: string + }[] + /** 分页相关信息 */ + page_info?: { + page?: number + page_size?: number + total_number?: number + } +} + +export interface OapiAlitripBtripInvoiceSearchParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripInvoiceSearchResponse { + /** 发票列表 */ + invoice?: { + id?: number + title?: string + third_part_invoice_id?: string + }[] + /** 成功标识 */ + success?: unknown + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown +} + +export interface OapiAlitripBtripCostCenterTransferParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripCostCenterTransferResponse { + /** 成功标识 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiAlitripBtripApplyGetParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripApplyGetResponse { + /** 审批单对象 */ + module?: { + id?: number + apply_show_id?: string + gmt_create?: string + gmt_modified?: string + thirdpart_id?: string + corpid?: string + corp_name?: string + userid?: string + user_name?: string + deptid?: string + trip_day?: number + dept_name?: string + trip_cause?: string + trip_title?: string + status?: number + status_desc?: string + itinerary_list?: number + traveler_list?: number + approver_list?: number + type?: number + union_no?: string + external_traveler_list?: number + } + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标识 */ + success?: unknown +} + +export interface OapiAlitripBtripApplySearchParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripApplySearchResponse { + /** 审批单列表 */ + module?: { + id?: number + apply_show_id?: string + gmt_create?: string + gmt_modified?: string + thirdpart_id?: string + corpid?: string + userid?: string + deptid?: string + corp_name?: string + user_name?: string + dept_name?: string + trip_day?: number + trip_cause?: string + trip_title?: string + status?: number + status_desc?: string + itinerary_list?: number + traveler_list?: number + approver_list?: number + flow_code?: string + type?: number + union_no?: string + external_traveler_list?: number + }[] + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标识 */ + success?: unknown +} + +export interface OapiAlitripBtripApprovalNewParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripApprovalNewResponse { + /** 结果对象 */ + module?: { + thirdpart_apply_id?: string + apply_id?: number + } + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标识 */ + success?: unknown +} + +export interface OapiAlitripBtripCostCenterEntityDeleteParams { + /** 请求对象 */ + rq: unknown +} + +export interface OapiAlitripBtripCostCenterEntityDeleteResponse { + /** 结果对象 */ + result?: { + selected_user_num?: number + remove_num?: number + } + /** 错误信息 */ + errmsg?: string + /** 错误码 */ + errcode?: unknown + /** 成功标识 */ + success?: unknown +} + +export interface OapiWorkspaceAuditlogListParams { + /** 操作日志起始时间,unix时间戳,单位ms */ + start_date: unknown + /** 操作日志截止时间,unix时间戳,单位ms */ + end_date: unknown + /** 操作列表长度,最大500 */ + page_size: unknown + /** 操作记录生成时间,作为分页偏移量,分页查询时必传,unix时间戳,单位ms */ + load_more_gmt_create?: unknown + /** 操作记录文件id,作为分页偏移量,与load_more_gmt_create一起使用,返回记录的biz_id为load_more_biz_id且gmt_create为load_more_gmt_create之后的操作列表,分页查询获取下一页时,传最后一条记录的biz_id和gmt_create。 */ + load_more_bizId?: unknown +} + +export interface OapiWorkspaceAuditlogListResponse { + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string + /** 返回值 */ + result?: { + log_list?: number + } +} + +export interface OapiEduCertGetParams { + /** 学校人员id */ + userid: string +} + +export interface OapiEduCertGetResponse { + /** 请求是否成功 */ + success?: unknown + /** 返回结果值 */ + result?: { + current_cert_level?: number + cert_datas?: number + practical_task_data?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误消息 */ + errmsg?: string +} + +export interface OapiEduUserListParams { + /** 最大30条,最小1条 */ + page_size: unknown + /** 页码,从1开始 */ + page_no: unknown + /** 家校人员身份 */ + role: string + /** 班级id */ + class_id: unknown +} + +export interface OapiEduUserListResponse { + /** 结果值 */ + result?: { + has_more?: number + details?: number + } + /** 是否成功 */ + success?: unknown + /** 错误码,只有当success为false时才有效 */ + errcode?: unknown + /** 错误信息,只有当success为false时才有效 */ + errmsg?: string +} + +export interface OapiSmartdeviceDeviceQuerybyidParams { + /** 设备查询对象 */ + device_query_vo: unknown +} + +export interface OapiSmartdeviceDeviceQuerybyidResponse { + /** 返回结果 */ + result?: { + device_mac?: string + corp_id?: string + nick?: string + device_id?: string + device_name?: string + pk?: string + userid?: string + ext?: string + sn?: string + } + /** 是否成功 */ + success?: unknown + /** 错误代码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiSmartdeviceDeviceQuerylistParams { + /** 列表查询对象 */ + page_query_vo: unknown +} + +export interface OapiSmartdeviceDeviceQuerylistResponse { + /** 返回结果 */ + result?: { + next_cursor?: number + has_more?: number + list?: number + } + /** 是否成功 */ + success?: unknown + /** 错误代码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiSmartdeviceDeviceQueryParams { + /** 设备查询对象 */ + device_query_vo?: unknown +} + +export interface OapiSmartdeviceDeviceQueryResponse { + /** 返回结果 */ + result?: { + device_mac?: string + corp_id?: string + nick?: string + device_id?: string + device_name?: string + pk?: string + userid?: string + ext?: string + sn?: string + } + /** 是否成功 */ + success?: unknown + /** 错误代码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiSmartdeviceDeviceUpdatenickParams { + /** 昵称修改参数 */ + device_nick_modify_vo?: unknown +} + +export interface OapiSmartdeviceDeviceUpdatenickResponse { + /** 是否成功 */ + success?: unknown + /** 错误代码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiSmartdeviceDeviceUnbindParams { + /** 解绑参数 */ + device_unbind_vo?: unknown +} + +export interface OapiSmartdeviceDeviceUnbindResponse { + /** 是否成功 */ + success?: unknown + /** 错误代码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiSmartdeviceExternalBindParams { + /** 设备请求信息 */ + device_bind_req_vo: unknown +} + +export interface OapiSmartdeviceExternalBindResponse { + /** 返回结果 */ + result?: { + device_id?: string + } + /** 是否成功 */ + success?: unknown + /** 错误代码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataContactDeleteParams { + /** 操作人用户ID */ + operator_userid: string + /** 联系人实例ID */ + data_id: string +} + +export interface OapiCrmObjectdataContactDeleteResponse { + /** 删除结果 */ + result?: { + instance_id?: string + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataCustomobjectCreateParams { + /** 自定义对象数据 */ + instance: unknown +} + +export interface OapiCrmObjectdataCustomobjectCreateResponse { + /** 结果 */ + result?: { + instance_id?: string + } + /** 执行结果 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataCustomobjectUpdateParams { + /** 自定义对象数据 */ + instance: unknown +} + +export interface OapiCrmObjectdataCustomobjectUpdateResponse { + /** 结果 */ + result?: { + instance_id?: string + } + /** 执行结果 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataListParams { + /** 操作人用户ID */ + current_operator_userid?: string + /** 数据ID列表 */ + data_id_list: string[] + /** 表单名称 */ + name: string +} + +export interface OapiCrmObjectdataListResponse { + /** 实例数据 */ + result_list?: { + creator_nick?: string + gmt_modified?: string + creator_userid?: string + instance_id?: string + data?: number + extend_data?: number + gmt_create?: string + object_type?: string + permission?: number + proc_out_result?: string + proc_inst_status?: string + }[] + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataQueryParams { + /** 用户ID */ + current_operator_userid?: string + /** 分页游标 */ + cursor?: string + /** 分页大小 */ + page_size: unknown + /** 表单code */ + name: string + /** 查询条件 */ + query_dsl?: string +} + +export interface OapiCrmObjectdataQueryResponse { + /** 分页结果 */ + result?: { + next_cursor?: string + values?: number + has_more?: number + page_size?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectmetaDescribeParams { + /** 目标名称 */ + name: string +} + +export interface OapiCrmObjectmetaDescribeResponse { + /** result */ + result?: { + name?: string + customized?: number + fields?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataContactQueryParams { + /** 用户ID */ + current_operator_userid?: string + /** 分页游标 */ + cursor?: string + /** 分页大小 */ + page_size: unknown + /** 服务商组织 id,自建应用可以传入 */ + provider_corpid?: string + /** 查询条件 */ + query_dsl?: string +} + +export interface OapiCrmObjectdataContactQueryResponse { + /** 分页结果 */ + result?: { + next_cursor?: string + values?: number + has_more?: number + page_size?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataFollowrecordListParams { + /** 操作人用户ID */ + current_operator_userid?: string + /** 数据ID列表 */ + data_id_list: string[] +} + +export interface OapiCrmObjectdataFollowrecordListResponse { + /** 实例数据 */ + result_list?: { + creator_nick?: string + gmt_modified?: string + creator_userid?: string + instance_id?: string + data?: number + extend_data?: number + gmt_create?: string + object_type?: string + permission?: number + proc_inst_status?: string + proc_out_result?: string + }[] + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataFollowrecordQueryParams { + /** 用户ID */ + current_operator_userid?: string + /** 分页游标 */ + cursor?: string + /** 分页大小 */ + page_size: unknown + /** 查询条件 */ + query_dsl?: string +} + +export interface OapiCrmObjectdataFollowrecordQueryResponse { + /** 分页结果 */ + result?: { + next_cursor?: string + values?: number + has_more?: number + page_size?: number + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectdataContactListParams { + /** 操作人用户ID */ + current_operator_userid?: string + /** 数据ID列表 */ + data_id_list: string[] + /** 自建应用时传入定制服务商ID */ + provider_corpid?: string +} + +export interface OapiCrmObjectdataContactListResponse { + /** 实例数据 */ + result_list?: { + creator_nick?: string + gmt_modified?: string + creator_userid?: string + instance_id?: string + data?: number + extend_data?: number + gmt_create?: string + object_type?: string + permission?: number + proc_inst_status?: string + proc_out_result?: string + }[] + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectmetaContactDescribeResponse { + /** result */ + result?: { + name?: string + customized?: number + fields?: number + status?: string + code?: string + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCrmObjectmetaFollowrecordDescribeResponse { + /** result */ + result?: { + name?: string + customized?: number + fields?: number + status?: string + code?: string + } + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiCspaceAddToSingleChatParams { + /** 文件名(需包含含扩展名),需要utf-8 urlEncode */ + file_name?: string + /** 调用钉盘上传文件接口得到的mediaid,需要utf-8 urlEncode */ + media_id?: string + /** 文件发送者微应用的agentId */ + userid?: string + /** 文件接收人的userid */ + agent_id?: string +} + +export interface OapiCspaceAddToSingleChatResponse { + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiCspaceGrantCustomSpaceQuery { + /** ISV调用时传入,授权访问指定微应用的自定义空间 */ + agent_id?: string + /** 企业调用时传入,授权访问该domain的自定义空间 */ + domain?: string + /** 权限类型,目前支持上传和下载,上传请传add,下载请传download */ + type?: string + /** 企业用户userid */ + userid?: string + /** 授权访问的路径,如授权访问所有文件传“/”,授权访问/doc文件夹传“/doc/” 需要utf-8 urlEncode */ + path?: string + /** 授权访问的文件id列表,id之间用英文逗号隔开,如“fileId1,fileId2” */ + fileids?: string + /** 权限有效时间,有效范围为0~3600秒,超出此范围或不传默认为30秒 */ + duration?: unknown +} + +export interface OapiCspaceGrantCustomSpaceResponse { + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiCspaceGetCustomSpaceQuery { + /** 企业调用时传入,需要为10个字节以内的字符串,仅可包含字母和数字,大小写不敏感 */ + domain?: string + /** ISV调用时传入,微应用agentId */ + agent_id?: string +} + +export interface OapiCspaceGetCustomSpaceResponse { + /** spaceid */ + spaceid?: string + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiCspaceAddQuery { + /** 微应用的agentId */ + agent_id?: string + /** 如果是微应用,code值为微应用免登授权码,如果是服务窗应用,code值为服务窗免登授权码。code为临时授权码,只能消费一次,下次请求需要重新获取新的code。 */ + code?: string + /** 调用钉盘上传文件接口得到的mediaid, 需要utf-8 urlEncode */ + media_id?: string + /** 调用云盘选择控件后获取的用户钉盘空间ID */ + folder_id?: string + /** 调用云盘选择控件后获取的用户钉盘文件夹ID */ + space_id?: string + /** 上传文件的名称,不能包含非法字符,需要utf-8 urlEncode */ + name?: string + /** 遇到同名文件是否覆盖,若不覆盖,则会自动重命名本次新增的文件,默认为false */ + overwrite?: unknown +} + +export interface OapiCspaceAddResponse { + /** dentry */ + dentry?: string + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiChatSubadminUpdateParams { + /** 群会话id */ + chatid: string + /** 群成员id */ + userids: string[] + /** 设置2添加为管理员,设置3删除该管理员 */ + role: unknown +} + +export interface OapiChatSubadminUpdateResponse { + /** 是否调用成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiChatQrcodeGetParams { + /** 会话id(逐步淘汰推荐使用openConversationId) */ + chatid?: string + /** 分享二维码用户id */ + userid: string + /** 开放群id(与会话id 二选一) */ + openConversationId?: string +} + +export interface OapiChatQrcodeGetResponse { + /** 返回入群的链接 */ + result?: string + /** 是否调用成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiChatMemberFriendswitchUpdateParams { + /** 会话Id */ + chatid: string + /** true开启禁止开关,false关闭禁止开关 */ + is_prohibit: unknown +} + +export interface OapiChatMemberFriendswitchUpdateResponse { + /** 是否设置成功 */ + success?: unknown + /** 错误码 */ + errcode?: unknown + /** 错误信息 */ + errmsg?: string +} + +export interface OapiChatUpdategroupnickParams { + /** 用户userid */ + userid: string + /** chatid */ + chatid: string + /** 群昵称 */ + group_nick: string +} + +export interface OapiChatUpdategroupnickResponse { + /** dingOpenErrcode */ + errcode?: unknown + /** errorMsg */ + errmsg?: string + /** success */ + success?: unknown +} + +export interface OapiChatUpdateParams { + /** 群会话id */ + chatid?: string + /** 群名称 */ + name?: string + /** 群主的userId */ + owner?: string + /** 群主类型,emp:企业员工,ext:外部联系人 */ + ownerType?: string + /** 添加成员列表 */ + add_useridlist?: string[] + /** 删除成员列表 */ + del_useridlist?: string[] + /** 添加外部联系人成员列表 */ + add_extidlist?: string[] + /** 删除外部联系人成员列表 */ + del_extidlist?: string[] + /** 群头像mediaId */ + icon?: string + /** 是否禁言 */ + isBan?: unknown + /** 群可搜索,0-默认,不可搜索,1-可搜索 */ + searchable?: unknown + /** 入群验证,0:不入群验证(默认) 1:入群验证 */ + validationType?: unknown + /** @all 权限,0-默认,所有人,1-仅群主可@all */ + mentionAllAuthority?: unknown + /** 管理类型,0-默认,所有人可管理,1-仅群主可管理 */ + managementType?: unknown + /** 群禁言,0-默认,不禁言,1-全员禁言 */ + chatBannedType?: unknown + /** 新成员可查看聊天历史 0否 1是 */ + showHistoryType?: unknown +} + +export interface OapiChatUpdateResponse { + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiChatCreateParams { + /** 群名称 */ + name?: string + /** 群主的userId */ + owner?: string + /** 群成员userId列表 */ + useridlist?: string[] + /** 新成员可查看100条聊天历史消息的类型,1:可查看,默认或0:不可查看 */ + showHistoryType?: unknown + /** 群可搜索,0-默认,不可搜索,1-可搜索 */ + searchable?: unknown + /** 入群验证,0:不入群验证(默认) 1:入群验证 */ + validationType?: unknown + /** @all 权限,0-默认,所有人,1-仅群主可@all */ + mentionAllAuthority?: unknown + /** 管理类型,0-默认,所有人可管理,1-仅群主可管理 */ + managementType?: unknown + /** 群禁言,0-默认,不禁言,1-全员禁言 */ + chatBannedType?: unknown +} + +export interface OapiChatCreateResponse { + /** conversationTag */ + conversationTag?: unknown + /** openConversationId */ + openConversationId?: string + /** chatid */ + chatid?: string + /** errmsg */ + errmsg?: string + /** errcode */ + errcode?: unknown +} + +export interface OapiChatGetQuery { + /** 群会话的id */ + chatid?: string +} + +export interface OapiChatGetResponse { + /** errcode */ + errcode?: unknown + /** errmsg */ + errmsg?: string + /** chat_info */ + chat_info?: { + name?: string + owner?: string + useridlist?: number + extidlist?: number + agentidlist?: number + conversationTag?: number + chatBannedType?: number + searchable?: number + validationType?: number + mentionAllAuthority?: number + managementType?: number + showHistoryType?: number + icon?: string + status?: number + } +} + +export interface OapiSmartbotMsgPushParams { + /** 消息体,具体见文档 */ + msg: unknown + /** 接收者的用户userid列表 */ + user_id_list?: string[] + /** 接收者的会话chatid列表 */ + chat_id_list?: string[] + /** 是否发送给企业全部用户,”true“则忽略用户列表和会话列表 */ + to_all_user?: unknown +} + +export interface OapiSmartbotMsgPushResponse { + /** 创建的异步发送任务id */ + task_id?: string + /** 错误码 */ + errcode?: unknown + /** errorMsg */ + errmsg?: string +} + +// funcName: isOldApi +Internal.define({ + '/service/get_corp_token': { POST: { OapiServiceGetCorpToken: true } }, + '/sso/gettoken': { GET: { OapiSsoGettoken: true } }, + '/get_jsapi_ticket': { GET: { OapiGetJsapiTicket: true } }, + '/gettoken': { GET: { OapiGettoken: true } }, + '/v2/user/getuserinfo': { POST: { OapiV2UserGetuserinfo: true } }, + '/sns/getuserinfo_bycode': { POST: { OapiSnsGetuserinfoBycode: true } }, + '/sso/getuserinfo': { GET: { OapiSsoGetuserinfo: true } }, + '/service/get_auth_info': { POST: { OapiServiceGetAuthInfo: true } }, + '/v2/user/update': { POST: { OapiV2UserUpdate: true } }, + '/v2/user/create': { POST: { OapiV2UserCreate: true } }, + '/org/union/trunk/get': { POST: { OapiOrgUnionTrunkGet: true } }, + '/smartwork/hrm/roster/meta/get': { + POST: { OapiSmartworkHrmRosterMetaGet: true }, + }, + '/smartwork/hrm/employee/v2/list': { + POST: { OapiSmartworkHrmEmployeeV2List: true }, + }, + '/smartwork/hrm/employee/v2/update': { + POST: { OapiSmartworkHrmEmployeeV2Update: true }, + }, + '/smartwork/hrm/employee/field/grouplist': { + POST: { OapiSmartworkHrmEmployeeFieldGrouplist: true }, + }, + '/smartwork/hrm/employee/update': { + POST: { OapiSmartworkHrmEmployeeUpdate: true }, + }, + '/smartwork/hrm/employee/queryonjob': { + POST: { OapiSmartworkHrmEmployeeQueryonjob: true }, + }, + '/smartwork/hrm/employee/querypreentry': { + POST: { OapiSmartworkHrmEmployeeQuerypreentry: true }, + }, + '/smartwork/hrm/employee/addpreentry': { + POST: { OapiSmartworkHrmEmployeeAddpreentry: true }, + }, + '/smartwork/hrm/employee/list': { + POST: { OapiSmartworkHrmEmployeeList: true }, + }, + '/report/template/getbyname': { POST: { OapiReportTemplateGetbyname: true } }, + '/report/create': { POST: { OapiReportCreate: true } }, + '/report/savecontent': { POST: { OapiReportSavecontent: true } }, + '/report/simplelist': { POST: { OapiReportSimplelist: true } }, + '/report/statistics/listbytype': { + POST: { OapiReportStatisticsListbytype: true }, + }, + '/report/receiver/list': { POST: { OapiReportReceiverList: true } }, + '/report/comment/list': { POST: { OapiReportCommentList: true } }, + '/report/statistics': { POST: { OapiReportStatistics: true } }, + '/report/getunreadcount': { POST: { OapiReportGetunreadcount: true } }, + '/report/list': { POST: { OapiReportList: true } }, + '/report/template/listbyuserid': { + POST: { OapiReportTemplateListbyuserid: true }, + }, + '/checkin/record/get': { POST: { OapiCheckinRecordGet: true } }, + '/checkin/record': { GET: { OapiCheckinRecord: true } }, + '/blackboard/category/list': { POST: { OapiBlackboardCategoryList: true } }, + '/blackboard/update': { POST: { OapiBlackboardUpdate: true } }, + '/blackboard/delete': { POST: { OapiBlackboardDelete: true } }, + '/blackboard/get': { POST: { OapiBlackboardGet: true } }, + '/blackboard/listids': { POST: { OapiBlackboardListids: true } }, + '/blackboard/create': { POST: { OapiBlackboardCreate: true } }, + '/blackboard/listtopten': { POST: { OapiBlackboardListtopten: true } }, + '/health/stepinfo/getuserstatus': { + POST: { OapiHealthStepinfoGetuserstatus: true }, + }, + '/health/stepinfo/listbyuserid': { + POST: { OapiHealthStepinfoListbyuserid: true }, + }, + '/health/stepinfo/list': { POST: { OapiHealthStepinfoList: true } }, + '/microapp/list_by_userid': { GET: { OapiMicroappListByUserid: true } }, + '/microapp/list': { POST: { OapiMicroappList: true } }, + '/microapp/delete': { POST: { OapiMicroappDelete: true } }, + '/microapp/set_visible_scopes': { + POST: { OapiMicroappSetVisibleScopes: true }, + }, + '/microapp/visible_scopes': { POST: { OapiMicroappVisibleScopes: true } }, + '/asr/voice/translate': { POST: { OapiAsrVoiceTranslate: true } }, + '/ai/mt/translate': { POST: { OapiAiMtTranslate: true } }, + '/ocr/structured/recognize': { POST: { OapiOcrStructuredRecognize: true } }, + '/im/chat/scencegroup/message/send_v2': { + POST: { OapiImChatScencegroupMessageSendV2: true }, + }, + '/im/chat/scenegroup/template/close': { + POST: { OapiImChatScenegroupTemplateClose: true }, + }, + '/im/chat/scenegroup/template/apply': { + POST: { OapiImChatScenegroupTemplateApply: true }, + }, + '/im/chat/scencegroup/interactivecard/callback/register': { + POST: { OapiImChatScencegroupInteractivecardCallbackRegister: true }, + }, + '/im/chat/scenegroup/create': { POST: { OapiImChatScenegroupCreate: true } }, + '/im/chat/scenegroup/member/add': { + POST: { OapiImChatScenegroupMemberAdd: true }, + }, + '/im/chat/scenegroup/member/get': { + POST: { OapiImChatScenegroupMemberGet: true }, + }, + '/im/chat/scenegroup/update': { POST: { OapiImChatScenegroupUpdate: true } }, + '/im/chat/scenegroup/member/delete': { + POST: { OapiImChatScenegroupMemberDelete: true }, + }, + '/im/chat/scenegroup/get': { POST: { OapiImChatScenegroupGet: true } }, + '/robot/send': { POST: { OapiRobotSend: true } }, + '/alitrip/btrip/invoice/setting/rule': { + POST: { OapiAlitripBtripInvoiceSettingRule: true }, + }, + '/alitrip/btrip/invoice/setting/add': { + POST: { OapiAlitripBtripInvoiceSettingAdd: true }, + }, + '/alitrip/btrip/project/delete': { + POST: { OapiAlitripBtripProjectDelete: true }, + }, + '/alitrip/btrip/project/modify': { + POST: { OapiAlitripBtripProjectModify: true }, + }, + '/alitrip/btrip/project/add': { POST: { OapiAlitripBtripProjectAdd: true } }, + '/alitrip/btrip/invoice/setting/delete': { + POST: { OapiAlitripBtripInvoiceSettingDelete: true }, + }, + '/alitrip/btrip/invoice/setting/modify': { + POST: { OapiAlitripBtripInvoiceSettingModify: true }, + }, + '/alitrip/btrip/price/query': { POST: { OapiAlitripBtripPriceQuery: true } }, + '/alitrip/btrip/train/city/suggest': { + POST: { OapiAlitripBtripTrainCitySuggest: true }, + }, + '/alitrip/btrip/monthbill/url/get': { + POST: { OapiAlitripBtripMonthbillUrlGet: true }, + }, + '/alitrip/btrip/address/get': { POST: { OapiAlitripBtripAddressGet: true } }, + '/alitrip/btrip/approval/modify': { + POST: { OapiAlitripBtripApprovalModify: true }, + }, + '/alitrip/btrip/flight/city/suggest': { + POST: { OapiAlitripBtripFlightCitySuggest: true }, + }, + '/alitrip/btrip/vehicle/order/search': { + POST: { OapiAlitripBtripVehicleOrderSearch: true }, + }, + '/alitrip/btrip/cost/center/query': { + POST: { OapiAlitripBtripCostCenterQuery: true }, + }, + '/alitrip/btrip/approval/update': { + POST: { OapiAlitripBtripApprovalUpdate: true }, + }, + '/alitrip/btrip/cost/center/new': { + POST: { OapiAlitripBtripCostCenterNew: true }, + }, + '/alitrip/btrip/cost/center/modify': { + POST: { OapiAlitripBtripCostCenterModify: true }, + }, + '/alitrip/btrip/cost/center/delete': { + POST: { OapiAlitripBtripCostCenterDelete: true }, + }, + '/alitrip/btrip/cost/center/entity/set': { + POST: { OapiAlitripBtripCostCenterEntitySet: true }, + }, + '/alitrip/btrip/hotel/order/search': { + POST: { OapiAlitripBtripHotelOrderSearch: true }, + }, + '/alitrip/btrip/train/order/search': { + POST: { OapiAlitripBtripTrainOrderSearch: true }, + }, + '/alitrip/btrip/flight/order/search': { + POST: { OapiAlitripBtripFlightOrderSearch: true }, + }, + '/alitrip/btrip/invoice/search': { + POST: { OapiAlitripBtripInvoiceSearch: true }, + }, + '/alitrip/btrip/cost/center/transfer': { + POST: { OapiAlitripBtripCostCenterTransfer: true }, + }, + '/alitrip/btrip/apply/get': { POST: { OapiAlitripBtripApplyGet: true } }, + '/alitrip/btrip/apply/search': { + POST: { OapiAlitripBtripApplySearch: true }, + }, + '/alitrip/btrip/approval/new': { + POST: { OapiAlitripBtripApprovalNew: true }, + }, + '/alitrip/btrip/cost/center/entity/delete': { + POST: { OapiAlitripBtripCostCenterEntityDelete: true }, + }, + '/workspace/auditlog/list': { POST: { OapiWorkspaceAuditlogList: true } }, + '/edu/cert/get': { POST: { OapiEduCertGet: true } }, + '/edu/user/list': { POST: { OapiEduUserList: true } }, + '/smartdevice/device/querybyid': { + POST: { OapiSmartdeviceDeviceQuerybyid: true }, + }, + '/smartdevice/device/querylist': { + POST: { OapiSmartdeviceDeviceQuerylist: true }, + }, + '/smartdevice/device/query': { POST: { OapiSmartdeviceDeviceQuery: true } }, + '/smartdevice/device/updatenick': { + POST: { OapiSmartdeviceDeviceUpdatenick: true }, + }, + '/smartdevice/device/unbind': { POST: { OapiSmartdeviceDeviceUnbind: true } }, + '/smartdevice/external/bind': { POST: { OapiSmartdeviceExternalBind: true } }, + '/crm/objectdata/contact/delete': { + POST: { OapiCrmObjectdataContactDelete: true }, + }, + '/crm/objectdata/customobject/create': { + POST: { OapiCrmObjectdataCustomobjectCreate: true }, + }, + '/crm/objectdata/customobject/update': { + POST: { OapiCrmObjectdataCustomobjectUpdate: true }, + }, + '/crm/objectdata/list': { POST: { OapiCrmObjectdataList: true } }, + '/crm/objectdata/query': { POST: { OapiCrmObjectdataQuery: true } }, + '/crm/objectmeta/describe': { POST: { OapiCrmObjectmetaDescribe: true } }, + '/crm/objectdata/contact/query': { + POST: { OapiCrmObjectdataContactQuery: true }, + }, + '/crm/objectdata/followrecord/list': { + POST: { OapiCrmObjectdataFollowrecordList: true }, + }, + '/crm/objectdata/followrecord/query': { + POST: { OapiCrmObjectdataFollowrecordQuery: true }, + }, + '/crm/objectdata/contact/list': { + POST: { OapiCrmObjectdataContactList: true }, + }, + '/crm/objectmeta/contact/describe': { + POST: { OapiCrmObjectmetaContactDescribe: true }, + }, + '/crm/objectmeta/followrecord/describe': { + POST: { OapiCrmObjectmetaFollowrecordDescribe: true }, + }, + '/cspace/add_to_single_chat': { POST: { OapiCspaceAddToSingleChat: true } }, + '/cspace/grant_custom_space': { GET: { OapiCspaceGrantCustomSpace: true } }, + '/cspace/get_custom_space': { GET: { OapiCspaceGetCustomSpace: true } }, + '/cspace/add': { GET: { OapiCspaceAdd: true } }, + '/chat/subadmin/update': { POST: { OapiChatSubadminUpdate: true } }, + '/chat/qrcode/get': { POST: { OapiChatQrcodeGet: true } }, + '/chat/member/friendswitch/update': { + POST: { OapiChatMemberFriendswitchUpdate: true }, + }, + '/chat/updategroupnick': { POST: { OapiChatUpdategroupnick: true } }, + '/chat/update': { POST: { OapiChatUpdate: true } }, + '/chat/create': { POST: { OapiChatCreate: true } }, + '/chat/get': { GET: { OapiChatGet: true } }, + '/smartbot/msg/push': { POST: { OapiSmartbotMsgPush: true } }, +}) +declare module '../internal' { + interface Internal { + /** + * 该接口用于获取企业授权凭证 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-enterprise-authorized-credential + */ + OapiServiceGetCorpToken( + params: OapiServiceGetCorpTokenParams, + ): Promise + /** + * 获取应用后台免登的access_token + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-ssotoken-for-micro-application-background-logon-free + */ + OapiSsoGettoken( + query: OapiSsoGettokenQuery, + ): Promise + /** + * 获取jsapi ticket + * @see https://developers.dingtalk.com/document/isvapp/obtain-jsapi_ticket + */ + OapiGetJsapiTicket(): Promise + /** + * 获取企业内部应用的access_token + * @see https://developers.dingtalk.com/document/orgapp/obtain-orgapp-token + */ + OapiGettoken(query: OapiGettokenQuery): Promise + /** + * 通过免登码获取用户userid + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-userid-of-a-user-by-using-the-log-free + */ + OapiV2UserGetuserinfo( + params: OapiV2UserGetuserinfoParams, + ): Promise + /** + * 该接口用于获取授权用户信息 + * @see https://developers.dingtalk.com/document/isvapp-server/obtain-the-user-information-based-on-the-sns-temporary-authorization + */ + OapiSnsGetuserinfoBycode( + params: OapiSnsGetuserinfoBycodeParams, + ): Promise + /** + * 获取应用管理后台免登的用户信息 + * @see https://developers.dingtalk.com/document/isvapp/exchange-code-for-the-identity-information-of-a-microapplication-administrator + */ + OapiSsoGetuserinfo( + query: OapiSsoGetuserinfoQuery, + ): Promise + /** + * 获取企业授权信息 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-basic-information-of-an-enterprise + */ + OapiServiceGetAuthInfo( + params: OapiServiceGetAuthInfoParams, + ): Promise + /** + * 用户信息更新 + * @see https://developers.dingtalk.com/document/orgapp/update-dedicated-accounts-information + */ + OapiV2UserUpdate( + params: OapiV2UserUpdateParams, + ): Promise + /** + * 用户信息创建 + * @see https://developers.dingtalk.com/document/orgapp/user-information-creation + */ + OapiV2UserCreate( + params: OapiV2UserCreateParams, + ): Promise + /** + * 获取主干组织列表 + * @see https://developers.dingtalk.com/document/isvapp/obtain-backbone-organization-list + */ + OapiOrgUnionTrunkGet(): Promise + /** + * 获取员工花名册的元数据定义(包括花名册分组、字段定义) + * @see https://developers.dingtalk.com/document/isvapp/intelligent-personnel-roster-metadata-query + */ + OapiSmartworkHrmRosterMetaGet( + params: OapiSmartworkHrmRosterMetaGetParams, + ): Promise + /** + * 获取员工花名册指定字段的信息,支持明细分组字段 + * @see https://developers.dingtalk.com/document/orgapp/intelligent-personnel-obtain-employee-roster-information + */ + OapiSmartworkHrmEmployeeV2List( + params: OapiSmartworkHrmEmployeeV2ListParams, + ): Promise + /** + * 智能人事更新员工档案信息,支持明细分组 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-personnel-update-employee-file-information + */ + OapiSmartworkHrmEmployeeV2Update( + params: OapiSmartworkHrmEmployeeV2UpdateParams, + ): Promise + /** + * 提供给ISV查询花名册的员工档案信息中有权限的字段列表 + * @see https://developers.dingtalk.com/document/isvapp/get-roster-field-group-details + */ + OapiSmartworkHrmEmployeeFieldGrouplist( + params: OapiSmartworkHrmEmployeeFieldGrouplistParams, + ): Promise + /** + * 智能人事更新员工档案员工信息 + * @see https://developers.dingtalk.com/document/isvapp-server/update-employee-roster + */ + OapiSmartworkHrmEmployeeUpdate( + params: OapiSmartworkHrmEmployeeUpdateParams, + ): Promise + /** + * 智能人事业务,提供企业/ISV按在职状态分页查询公司在职员工id列表 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-personnel-query-the-list-of-on-the-job-employees-of-the + */ + OapiSmartworkHrmEmployeeQueryonjob( + params: OapiSmartworkHrmEmployeeQueryonjobParams, + ): Promise + /** + * 智能人事业务,企业/ISV分页查询公司待入职员工id列表 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-personnel-query-the-list-of-employees-to-be-hired + */ + OapiSmartworkHrmEmployeeQuerypreentry( + params: OapiSmartworkHrmEmployeeQuerypreentryParams, + ): Promise + /** + * 智能人事添加待入职员工信息 + * @see https://developers.dingtalk.com/document/isvapp/add-employees-to-be-hired-through-intelligent-personnel + */ + OapiSmartworkHrmEmployeeAddpreentry( + params: OapiSmartworkHrmEmployeeAddpreentryParams, + ): Promise + /** + * 智能人事业务,企业/ISV根据员工id批量访问员工花名册信息 + * @see https://developers.dingtalk.com/document/isvapp-server/obtaining-employee-roster-field-information + */ + OapiSmartworkHrmEmployeeList( + params: OapiSmartworkHrmEmployeeListParams, + ): Promise + /** + * 企业可以根据模板名称获取模板详情 + * @see https://developers.dingtalk.com/document/isvapp/query-template-details + */ + OapiReportTemplateGetbyname( + params: OapiReportTemplateGetbynameParams, + ): Promise + /** + * 提供企业员工创建日志的接口 + * @see https://developers.dingtalk.com/document/isvapp/create-a-log + */ + OapiReportCreate( + params: OapiReportCreateParams, + ): Promise + /** + * 第三方系统会调用这个接口保存日志内容,后续在写日志页面再拉取此内容。 + * @see https://developers.dingtalk.com/document/isvapp/save-custom-log-content + */ + OapiReportSavecontent( + params: OapiReportSavecontentParams, + ): Promise + /** + * 企业可以根据员工userid或者日志模板名称,分页获取员工一段时间范围内在【日志】微应用发送的日志概要信息 + * @see https://developers.dingtalk.com/document/orgapp/view-log-summary-data + */ + OapiReportSimplelist( + params: OapiReportSimplelistParams, + ): Promise + /** + * 分页获取日志相关人员列表,包括已读人员列表、评论人员列表、点赞人员列表 + * @see https://developers.dingtalk.com/document/orgapp/obtains-a-list-of-log-related-personnel-by-type + */ + OapiReportStatisticsListbytype( + params: OapiReportStatisticsListbytypeParams, + ): Promise + /** + * 获取日志的分享人员列表 + * @see https://developers.dingtalk.com/document/orgapp/queries-log-sharing-personnel + */ + OapiReportReceiverList( + params: OapiReportReceiverListParams, + ): Promise + /** + * 分页获取评论详情,包括评论人userid、评论内容、评论时间 + * @see https://developers.dingtalk.com/document/orgapp/queries-log-comment-details + */ + OapiReportCommentList( + params: OapiReportCommentListParams, + ): Promise + /** + * 获取日志统计数据 + * @see https://developers.dingtalk.com/document/orgapp/query-log-statistics + */ + OapiReportStatistics( + params: OapiReportStatisticsParams, + ): Promise + /** + * 查询企业员工的日志未读数 + * @see https://developers.dingtalk.com/document/orgapp/querying-the-employee-s-log-is-not-reading + */ + OapiReportGetunreadcount( + params: OapiReportGetunreadcountParams, + ): Promise + /** + * 企业可以根据员工userid或者日志模板名称,分页获取员工一段时间范围内在【日志】微应用发送和修改的日志详细信息 + * @see https://developers.dingtalk.com/document/isvapp/obtains-a-list-of-the-logs-that-are-sent-by + */ + OapiReportList( + params: OapiReportListParams, + ): Promise + /** + * 根据用户userId获取当前企业下可见的日志模板列表 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-list-of-visible-log-templates-based-on-the + */ + OapiReportTemplateListbyuserid( + params: OapiReportTemplateListbyuseridParams, + ): Promise + /** + * 查询多个用户一段时间范围内的签到记录,只给企业调用,ISV无法调用。 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-check-in-records-of-multiple-users + */ + OapiCheckinRecordGet( + params: OapiCheckinRecordGetParams, + ): Promise + /** + * 该接口用于获取部门用户签到记录 + * @see https://developers.dingtalk.com/document/orgapp/get-check-in-data + */ + OapiCheckinRecord( + query: OapiCheckinRecordQuery, + ): Promise + /** + * 获取企业公告未删除分类列表 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-list-of-categories-not-deleted-for-enterprise-announcements + */ + OapiBlackboardCategoryList( + params: OapiBlackboardCategoryListParams, + ): Promise + /** + * 根据公告id修改企业公告,只有以下身份可以修改:1、主管理员2、公告子管理员并且是待修改公告的创建者 + * @see https://developers.dingtalk.com/document/orgapp/modify-the-announcement-according-to-the-announcement-id + */ + OapiBlackboardUpdate( + params: OapiBlackboardUpdateParams, + ): Promise + /** + * 根据公告id删除企业公告,只有以下身份可以删除1、主管理员2、公告子管理员并且是待删除公告创建者 + * @see https://developers.dingtalk.com/document/orgapp/delete-announcements-based-on-the-announcement-id + */ + OapiBlackboardDelete( + params: OapiBlackboardDeleteParams, + ): Promise + /** + * 根据公告ID获取企业未删除公告详情,只有以下身份可以查看: +1、保密公告 +1.1 公告管理员 +1.2 公告的接收人 +2、非保密公告 +2.1 企业内的人都可见 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-details-of-a-bulletin-that-is-not-deleted + */ + OapiBlackboardGet( + params: OapiBlackboardGetParams, + ): Promise + /** + * 通过接口可以获取到企业未删除的钉钉公告id列表 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-id-list-of-announcements-that-are-not-deleted + */ + OapiBlackboardListids( + params: OapiBlackboardListidsParams, + ): Promise + /** + * 管理员可以通过该接口创建钉钉企业公告 + * @see https://developers.dingtalk.com/document/orgapp/create-an-enterprise-announcement + */ + OapiBlackboardCreate( + params: OapiBlackboardCreateParams, + ): Promise + /** + * 列出用户当前有权限看到的10条公告,可用于在企业自定义工作首页进行公告轮播展示 + * @see https://developers.dingtalk.com/document/orgapp/list-the-user-s-announcement-list + */ + OapiBlackboardListtopten( + params: OapiBlackboardListtoptenParams, + ): Promise + /** + * 查询用户是否参与企业步数排行榜 + * @see https://developers.dingtalk.com/document/isvapp/check-whether-dingtalk-is-enabled + */ + OapiHealthStepinfoGetuserstatus( + params: OapiHealthStepinfoGetuserstatusParams, + ): Promise + /** + * 批量获取钉钉运动数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-the-number-of-dingtalk-movement-steps-of-multiple-users + */ + OapiHealthStepinfoListbyuserid( + params: OapiHealthStepinfoListbyuseridParams, + ): Promise + /** + * 查询企业用户或部门每天的钉钉运动步数,最多可以查询31天的数据 + * @see https://developers.dingtalk.com/document/orgapp/queries-individual-or-department-dingtalk-exercise-steps + */ + OapiHealthStepinfoList( + params: OapiHealthStepinfoListParams, + ): Promise + /** + * 该接口用于获取员工可见的应用列表 + * @see https://developers.dingtalk.com/document/orgapp-server/list-the-microapplications-visible-to-employees + */ + OapiMicroappListByUserid( + query: OapiMicroappListByUseridQuery, + ): Promise + /** + * 列出微应用 + * @see https://developers.dingtalk.com/document/orgapp-server/manager-microapplications-api-permission + */ + OapiMicroappList(): Promise + /** + * 删除微应用 + * @see https://developers.dingtalk.com/document/orgapp-server/delete-an-h5-microapplication + */ + OapiMicroappDelete( + params: OapiMicroappDeleteParams, + ): Promise + /** + * 该接口用于设置应用的可见范围 + * @see https://developers.dingtalk.com/document/orgapp-server/set-the-visible-range-of-the-microapplication + */ + OapiMicroappSetVisibleScopes( + params: OapiMicroappSetVisibleScopesParams, + ): Promise + /** + * 获取应用的可见范围 + * @see https://developers.dingtalk.com/document/orgapp-server/gets-the-microapplication-visible-range-set-by-the-enterprise + */ + OapiMicroappVisibleScopes( + params: OapiMicroappVisibleScopesParams, + ): Promise + /** + * 用户使用音频 media_id 或 url 进行请求,服务通过回调的方式通知用户翻译结果 + * @see https://developers.dingtalk.com/document/isvapp/asr-short-sentence-recognition + */ + OapiAsrVoiceTranslate( + params: OapiAsrVoiceTranslateParams, + ): Promise + /** + * 输入一段文本,得到翻译指定语言后的译文,支持多种语言的互译 + * @see https://developers.dingtalk.com/document/isvapp/dingtalk-translation + */ + OapiAiMtTranslate( + params: OapiAiMtTranslateParams, + ): Promise + /** + * OCR文字识别 + * @see https://developers.dingtalk.com/document/isvapp/structured-image-recognition-api + */ + OapiOcrStructuredRecognize( + params: OapiOcrStructuredRecognizeParams, + ): Promise + /** + * 场开放场景下,基于群模板定义的机器人向群内发消息 + * @see https://developers.dingtalk.com/document/isvapp/send-group-helper-message + */ + OapiImChatScencegroupMessageSendV2( + params: OapiImChatScencegroupMessageSendV2Params, + ): Promise + /** + * 根据定义的模板id,创建自定义场景群 + * @see https://developers.dingtalk.com/document/isvapp/deactivate-group-template + */ + OapiImChatScenegroupTemplateClose( + params: OapiImChatScenegroupTemplateCloseParams, + ): Promise + /** + * 根据传入的模板id,启用群会话群模板功能 + * @see https://developers.dingtalk.com/document/isvapp/enable-group-template + */ + OapiImChatScenegroupTemplateApply( + params: OapiImChatScenegroupTemplateApplyParams, + ): Promise + /** + * 注册互动卡片回调地址 + * @see https://developers.dingtalk.com/document/orgapp/registration-card-interaction-callback-address-1 + */ + OapiImChatScencegroupInteractivecardCallbackRegister( + params: OapiImChatScencegroupInteractivecardCallbackRegisterParams, + ): Promise + /** + * 根据定义的模板id,创建自定义场景群 + * @see https://developers.dingtalk.com/document/isvapp/create-group + */ + OapiImChatScenegroupCreate( + params: OapiImChatScenegroupCreateParams, + ): Promise + /** + * 新增场景群成员 + * @see https://developers.dingtalk.com/document/isvapp/add-group-members-1 + */ + OapiImChatScenegroupMemberAdd( + params: OapiImChatScenegroupMemberAddParams, + ): Promise + /** + * 获取场景群成员 + * @see https://developers.dingtalk.com/document/group/obtains-scene-members + */ + OapiImChatScenegroupMemberGet( + params: OapiImChatScenegroupMemberGetParams, + ): Promise + /** + * 根据传入的群id,更新群相关内容 + * @see https://developers.dingtalk.com/document/isvapp/update-group + */ + OapiImChatScenegroupUpdate( + params: OapiImChatScenegroupUpdateParams, + ): Promise + /** + * 删除场景群成员 + * @see https://developers.dingtalk.com/document/isvapp/delete-group-members + */ + OapiImChatScenegroupMemberDelete( + params: OapiImChatScenegroupMemberDeleteParams, + ): Promise + /** + * 根据群id,获取群的基本信息 + * @see https://developers.dingtalk.com/document/isvapp/querying-group-information + */ + OapiImChatScenegroupGet( + params: OapiImChatScenegroupGetParams, + ): Promise + /** + * 自定义机器人发送消息 + * @see https://developers.dingtalk.com/document/isvapp/custom-bot-access-send-message + */ + OapiRobotSend(params: OapiRobotSendParams): Promise + /** + * 配置发票适用人群 + * @see https://developers.dingtalk.com/document/isvapp/configure-invoice-users + */ + OapiAlitripBtripInvoiceSettingRule( + params: OapiAlitripBtripInvoiceSettingRuleParams, + ): Promise + /** + * 新增发票配置 + * @see https://developers.dingtalk.com/document/isvapp/new-invoice-configuration + */ + OapiAlitripBtripInvoiceSettingAdd( + params: OapiAlitripBtripInvoiceSettingAddParams, + ): Promise + /** + * 删除项目 + * @see https://developers.dingtalk.com/document/isvapp/delete-a-project + */ + OapiAlitripBtripProjectDelete( + params: OapiAlitripBtripProjectDeleteParams, + ): Promise + /** + * 项目变更 + * @see https://developers.dingtalk.com/document/isvapp/project-change + */ + OapiAlitripBtripProjectModify( + params: OapiAlitripBtripProjectModifyParams, + ): Promise + /** + * 添加项目 + * @see https://developers.dingtalk.com/document/isvapp/add-a-project + */ + OapiAlitripBtripProjectAdd( + params: OapiAlitripBtripProjectAddParams, + ): Promise + /** + * 删除发票配置 + * @see https://developers.dingtalk.com/document/isvapp/delete-invoice-configuration + */ + OapiAlitripBtripInvoiceSettingDelete( + params: OapiAlitripBtripInvoiceSettingDeleteParams, + ): Promise + /** + * 修改发票配置 + * @see https://developers.dingtalk.com/document/isvapp/modify-invoice-configuration + */ + OapiAlitripBtripInvoiceSettingModify( + params: OapiAlitripBtripInvoiceSettingModifyParams, + ): Promise + /** + * 查询预估价 + * @see https://developers.dingtalk.com/document/isvapp/query-estimated-price + */ + OapiAlitripBtripPriceQuery( + params: OapiAlitripBtripPriceQueryParams, + ): Promise + /** + * 火车票城市搜索 + * @see https://developers.dingtalk.com/document/isvapp/train-ticket-city-search + */ + OapiAlitripBtripTrainCitySuggest( + params: OapiAlitripBtripTrainCitySuggestParams, + ): Promise + /** + * 获取月对账结算数据 + * @see https://developers.dingtalk.com/document/isvapp/obtain-monthly-reconciliation-settlement-data + */ + OapiAlitripBtripMonthbillUrlGet( + params: OapiAlitripBtripMonthbillUrlGetParams, + ): Promise + /** + * 获取商旅访问地址 + * @see https://developers.dingtalk.com/document/isvapp/obtain-business-travel-access-addresses + */ + OapiAlitripBtripAddressGet( + params: OapiAlitripBtripAddressGetParams, + ): Promise + /** + * 修改申请单 + * @see https://developers.dingtalk.com/document/isvapp/user-modify-approval-form + */ + OapiAlitripBtripApprovalModify( + params: OapiAlitripBtripApprovalModifyParams, + ): Promise + /** + * 机票城市搜索 + * @see https://developers.dingtalk.com/document/isvapp/air-ticket-city-search + */ + OapiAlitripBtripFlightCitySuggest( + params: OapiAlitripBtripFlightCitySuggestParams, + ): Promise + /** + * 获取用车订单数据 + * @see https://developers.dingtalk.com/document/isvapp/vehicle-order-query-interface + */ + OapiAlitripBtripVehicleOrderSearch( + params: OapiAlitripBtripVehicleOrderSearchParams, + ): Promise + /** + * 查询成本中心 + * @see https://developers.dingtalk.com/document/isvapp/query-cost-center + */ + OapiAlitripBtripCostCenterQuery( + params: OapiAlitripBtripCostCenterQueryParams, + ): Promise + /** + * 更新申请单状态 + * @see https://developers.dingtalk.com/document/isvapp/update-approval-form + */ + OapiAlitripBtripApprovalUpdate( + params: OapiAlitripBtripApprovalUpdateParams, + ): Promise + /** + * 新建成本中心 + * @see https://developers.dingtalk.com/document/isvapp/new-cost-center + */ + OapiAlitripBtripCostCenterNew( + params: OapiAlitripBtripCostCenterNewParams, + ): Promise + /** + * 修改成本中心基本信息 + * @see https://developers.dingtalk.com/document/isvapp/modify-basic-cost-center-information + */ + OapiAlitripBtripCostCenterModify( + params: OapiAlitripBtripCostCenterModifyParams, + ): Promise + /** + * 删除成本中心 + * @see https://developers.dingtalk.com/document/isvapp/delete-cost-center + */ + OapiAlitripBtripCostCenterDelete( + params: OapiAlitripBtripCostCenterDeleteParams, + ): Promise + /** + * 设置成本中心人员信息 + * @see https://developers.dingtalk.com/document/isvapp/set-up-cost-center-personnel-information + */ + OapiAlitripBtripCostCenterEntitySet( + params: OapiAlitripBtripCostCenterEntitySetParams, + ): Promise + /** + * 企业获取商旅酒店订单数据 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-order-data-of-enterprise-hotels + */ + OapiAlitripBtripHotelOrderSearch( + params: OapiAlitripBtripHotelOrderSearchParams, + ): Promise + /** + * 获取企业火车票订单数据 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-enterprise-train-ticket-order-data + */ + OapiAlitripBtripTrainOrderSearch( + params: OapiAlitripBtripTrainOrderSearchParams, + ): Promise + /** + * 获取企业机票订单数据 + * @see https://developers.dingtalk.com/document/isvapp/obtains-enterprise-ticket-order-data + */ + OapiAlitripBtripFlightOrderSearch( + params: OapiAlitripBtripFlightOrderSearchParams, + ): Promise + /** + * 查询可用发票列表 + * @see https://developers.dingtalk.com/document/isvapp/query-available-invoices + */ + OapiAlitripBtripInvoiceSearch( + params: OapiAlitripBtripInvoiceSearchParams, + ): Promise + /** + * 商旅成本中心转换为外部成本中心 + * @see https://developers.dingtalk.com/document/isvapp/business-travel-cost-center-converted-to-external-cost-center + */ + OapiAlitripBtripCostCenterTransfer( + params: OapiAlitripBtripCostCenterTransferParams, + ): Promise + /** + * 获取申请单详情 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-detailed-data-of-a-single-request + */ + OapiAlitripBtripApplyGet( + params: OapiAlitripBtripApplyGetParams, + ): Promise + /** + * 获取申请单列表 + * @see https://developers.dingtalk.com/document/isvapp/search-enterprise-approval-form-data + */ + OapiAlitripBtripApplySearch( + params: OapiAlitripBtripApplySearchParams, + ): Promise + /** + * 用户新建审批单 + * @see https://developers.dingtalk.com/document/isvapp/user-new-approval-form + */ + OapiAlitripBtripApprovalNew( + params: OapiAlitripBtripApprovalNewParams, + ): Promise + /** + * 删除成本中心人员信息 + * @see https://developers.dingtalk.com/document/isvapp/delete-cost-center-personnel-information + */ + OapiAlitripBtripCostCenterEntityDelete( + params: OapiAlitripBtripCostCenterEntityDeleteParams, + ): Promise + /** + * 获取钉钉项目空间任务中文件的操作日志列表 + * @see https://developers.dingtalk.com/document/orgapp/query-file-operation-logs-of-a-project + */ + OapiWorkspaceAuditlogList( + params: OapiWorkspaceAuditlogListParams, + ): Promise + /** + * 查询当前用户的数字化考试情况,是否获取了证书 + * @see https://developers.dingtalk.com/document/isvapp/obtain-digital-certificate + */ + OapiEduCertGet( + params: OapiEduCertGetParams, + ): Promise + /** + * 获取家校用户身份列表 + * @see https://developers.dingtalk.com/document/isvapp/obtains-a-list-of-home-school-user-identities + */ + OapiEduUserList( + params: OapiEduUserListParams, + ): Promise + /** + * 查询企业下的智能硬件设备详情 + * @see https://developers.dingtalk.com/document/isvapp/the-smart-hardware-can-query-details-based-on-the-device + */ + OapiSmartdeviceDeviceQuerybyid( + params: OapiSmartdeviceDeviceQuerybyidParams, + ): Promise + /** + * 查询企业下的智能硬件设备列表 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-hardware-list-query + */ + OapiSmartdeviceDeviceQuerylist( + params: OapiSmartdeviceDeviceQuerylistParams, + ): Promise + /** + * 查询企业下的智能硬件设备详情 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-hardware-device-query + */ + OapiSmartdeviceDeviceQuery( + params: OapiSmartdeviceDeviceQueryParams, + ): Promise + /** + * 解除企业下的智能硬件设备绑定 + * @see https://developers.dingtalk.com/document/isvapp/intelligent-hardware-device-nickname-modification + */ + OapiSmartdeviceDeviceUpdatenick( + params: OapiSmartdeviceDeviceUpdatenickParams, + ): Promise + /** + * 解除企业下的智能硬件设备绑定 + * @see https://developers.dingtalk.com/document/isvapp/unbind-a-smart-hardware-device + */ + OapiSmartdeviceDeviceUnbind( + params: OapiSmartdeviceDeviceUnbindParams, + ): Promise + /** + * 智能设备接入钉钉时,需要和组织建立绑定关系,此接口用于创建绑定关系。 + * @see https://developers.dingtalk.com/document/isvapp/establishing-a-binding-relationship-between-intelligent-hardware-and-cloud + */ + OapiSmartdeviceExternalBind( + params: OapiSmartdeviceExternalBindParams, + ): Promise + /** + * 删除当前组织CRM指定联系人的接口 + * @see https://developers.dingtalk.com/document/orgapp/delete-crm-contact + */ + OapiCrmObjectdataContactDelete( + params: OapiCrmObjectdataContactDeleteParams, + ): Promise + /** + * 创建CRM自定义对象数据 + * @see https://developers.dingtalk.com/document/orgapp/dingtalk-paas-master-create-custom-crm-object-data + */ + OapiCrmObjectdataCustomobjectCreate( + params: OapiCrmObjectdataCustomobjectCreateParams, + ): Promise + /** + * 钉钉PaaS主数据-更新CRM自定义对象数据 + * @see https://developers.dingtalk.com/document/orgapp/crm-master-data-opens-interface-for-updating-custom-object-data + */ + OapiCrmObjectdataCustomobjectUpdate( + params: OapiCrmObjectdataCustomobjectUpdateParams, + ): Promise + /** + * 根据实例ID列表批量获取CRM自定义表单数据,最多可一次获取200条数据 + * @see https://developers.dingtalk.com/document/orgapp/retrieves-custom-crm-forms-from-the-id-list + */ + OapiCrmObjectdataList( + params: OapiCrmObjectdataListParams, + ): Promise + /** + * 获取CRM自定义对象数据,最多可一次获取200条数据 + * @see https://developers.dingtalk.com/document/orgapp/retrieve-custom-crm-object-data + */ + OapiCrmObjectdataQuery( + params: OapiCrmObjectdataQueryParams, + ): Promise + /** + * 获取自定义对象的元数据 + * @see https://developers.dingtalk.com/document/orgapp/get-metadata-description-of-crm-custom-object + */ + OapiCrmObjectmetaDescribe( + params: OapiCrmObjectmetaDescribeParams, + ): Promise + /** + * 根据指定查询条件批量获取联系人数据,最多可一次获取200条数据 + * @see https://developers.dingtalk.com/document/isvapp/query-contact-data + */ + OapiCrmObjectdataContactQuery( + params: OapiCrmObjectdataContactQueryParams, + ): Promise + /** + * 根据实例ID列表批量获取跟进记录数据,最多可一次获取200条数据 + * @see https://developers.dingtalk.com/document/orgapp/dingtalk-the-primary-data-of-apsara-stack-agility-paas-allows-you + */ + OapiCrmObjectdataFollowrecordList( + params: OapiCrmObjectdataFollowrecordListParams, + ): Promise + /** + * 根据指定查询条件批量获取跟进记录数据,最多可一次获取200条数据 + * @see https://developers.dingtalk.com/document/orgapp/query-and-dingtalk-data-of-track-records-in-apsara-stack + */ + OapiCrmObjectdataFollowrecordQuery( + params: OapiCrmObjectdataFollowrecordQueryParams, + ): Promise + /** + * 按照ID列表批量获取联系人数据 + * @see https://developers.dingtalk.com/document/orgapp/retrieves-contact-data-in-batches-based-on-the-id-list + */ + OapiCrmObjectdataContactList( + params: OapiCrmObjectdataContactListParams, + ): Promise + /** + * 获取联系人对象的元数据 + * @see https://developers.dingtalk.com/document/isvapp/get-metadata-for-a-contact + */ + OapiCrmObjectmetaContactDescribe(): Promise + /** + * 获取跟进记录对象的元数据 + * @see https://developers.dingtalk.com/document/isvapp/get-the-metadata-of-the-follow-up-record-object + */ + OapiCrmObjectmetaFollowrecordDescribe(): Promise + /** + * 发送文件给指定用户 + * @see https://developers.dingtalk.com/document/isvapp-server/sends-a-file-to-a-specified-user + */ + OapiCspaceAddToSingleChat( + params: OapiCspaceAddToSingleChatParams, + ): Promise + /** + * 授权用户访问企业下的自定义空间 + * @see https://developers.dingtalk.com/document/isvapp-server/authorize-a-user-to-access-a-custom-workspace-of-an + */ + OapiCspaceGrantCustomSpace( + query: OapiCspaceGrantCustomSpaceQuery, + ): Promise + /** + * 获取企业下的自定义空间 + * @see https://developers.dingtalk.com/document/isvapp-server/obtain-user-space-under-the-enterprise + */ + OapiCspaceGetCustomSpace( + query: OapiCspaceGetCustomSpaceQuery, + ): Promise + /** + * 新增文件到用户钉盘 + * @see https://developers.dingtalk.com/document/isvapp-server/add-file-to-user-s-dingtalk-disk + */ + OapiCspaceAdd(query: OapiCspaceAddQuery): Promise + /** + * 增加和删除群管理员接口 + * @see https://developers.dingtalk.com/document/orgapp/set-chat-admin + */ + OapiChatSubadminUpdate( + params: OapiChatSubadminUpdateParams, + ): Promise + /** + * 获取群入群二维码邀请链接 + * @see https://developers.dingtalk.com/document/orgapp/obtain-a-qr-code-link + */ + OapiChatQrcodeGet( + params: OapiChatQrcodeGetParams, + ): Promise + /** + * 设置群成员之间是否可以添加好友和私聊的开关 + * @see https://developers.dingtalk.com/document/orgapp/set-private-chat + */ + OapiChatMemberFriendswitchUpdate( + params: OapiChatMemberFriendswitchUpdateParams, + ): Promise + /** + * 设置群成员的群昵称 + * @see https://developers.dingtalk.com/document/orgapp/set-a-group-nickname + */ + OapiChatUpdategroupnick( + params: OapiChatUpdategroupnickParams, + ): Promise + /** + * 修改群会话 + * @see https://developers.dingtalk.com/document/orgapp/modify-a-group-session + */ + OapiChatUpdate( + params: OapiChatUpdateParams, + ): Promise + /** + * 该接口用于创建会话 + * @see https://developers.dingtalk.com/document/orgapp/create-group-session + */ + OapiChatCreate( + params: OapiChatCreateParams, + ): Promise + /** + * 获取群会话 + * @see https://developers.dingtalk.com/document/orgapp/obtain-a-group-session + */ + OapiChatGet(query: OapiChatGetQuery): Promise + /** + * 通过工作助理机器人给企业员工发送消息 + * @see https://developers.dingtalk.com/document/orgapp/the-message-pushing-interface-of-the-assistant + */ + OapiSmartbotMsgPush( + params: OapiSmartbotMsgPushParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/oauth2.ts b/adapters/dingtalk/src/api/oauth2.ts new file mode 100644 index 00000000..655f0fd9 --- /dev/null +++ b/adapters/dingtalk/src/api/oauth2.ts @@ -0,0 +1,145 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface CreateJsapiTicketResponse { + jsapiTicket?: string + expireIn?: number +} + +export interface GetSsoAccessTokenParams { + /** 企业的corpId。 */ + corpid: string + /** sso密钥,可以在[开发者后台](https://open-dev.dingtalk.com/fe/old#/corpAuthInfo)**基本信息**—**开发信息**(****旧版****)页面查看。 */ + ssoSecret: string +} + +export interface GetSsoAccessTokenResponse { + accessToken?: string + expireIn?: number +} + +export interface GetPersonalAuthRuleResponse { + result?: { + resource: string + authItems: number + }[] +} + +export interface GetAccessTokenParams { + /** 已创建的企业内部应用的AppKey。 */ + appKey: string + /** 已创建的企业内部应用的AppSecret。 */ + appSecret?: string +} + +export interface GetAccessTokenResponse { + accessToken?: string + expireIn?: number +} + +export interface GetCorpAccessTokenParams { + /** 已创建的第三方企业应用的SuiteKey。 */ + suiteKey: string + /** 已创建的第三方企业应用的SuiteSecret。 */ + suiteSecret: string + /** 授权企业的CorpId。 */ + authCorpId: string + /** 钉钉推送的suiteTicket。 */ + suiteTicket: string +} + +export interface GetCorpAccessTokenResponse { + accessToken?: string + expireIn?: number +} + +export interface GetUserTokenParams { + /** 应用id。可使用扫码登录应用或者第三方个人小程序的appId。 */ + clientId: string + /** 应用密钥。 */ + clientSecret?: string + /** OAuth 2.0 临时授权码。 */ + code?: string + /** OAuth2.0刷新令牌,从返回结果里面获取。 */ + refreshToken?: string + /** - 如果使用授权码换token,传authorization\_code。 */ + grantType?: string +} + +export interface GetUserTokenResponse { + accessToken?: string + refreshToken?: string + expireIn?: number + corpId?: string +} + +export interface GetSsoUserInfoQuery { + /** 临时授权码,管理员在钉钉管理后台,跳转到应用管理页面时,该授权码会附带在URL中。 */ + code: string +} + +export interface GetSsoUserInfoResponse { + corpId: string + corpName: string + userId: string + email: string + userName: string + avatar: string + isAdmin: unknown +} + +// funcName: isOldApi +Internal.define({ + '/oauth2/jsapiTickets': { POST: { createJsapiTicket: false } }, + '/oauth2/ssoAccessToken': { POST: { getSsoAccessToken: false } }, + '/oauth2/authRules/user': { GET: { getPersonalAuthRule: false } }, + '/oauth2/accessToken': { POST: { getAccessToken: false } }, + '/oauth2/corpAccessToken': { POST: { getCorpAccessToken: false } }, + '/oauth2/userAccessToken': { POST: { getUserToken: false } }, + '/oauth2/ssoUserInfo': { GET: { getSsoUserInfo: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 生成jsapi ticket + * @see https://developers.dingtalk.com/document/isvapp/create-a-jsapi-ticket + */ + createJsapiTicket(): Promise + /** + * 生成微应用管理后台accessToken + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-access_token-of-the-micro-application-background-without-log-on + */ + getSsoAccessToken( + params: GetSsoAccessTokenParams, + ): Promise + /** + * 查询个人授权记录 + * @see https://developers.dingtalk.com/document/isvapp/query-individual-authorization-records + */ + getPersonalAuthRule(): Promise + /** + * 获取企业accessToken(企业内部应用) + * @see https://developers.dingtalk.com/document/orgapp/obtain-the-access_token-of-an-internal-app + */ + getAccessToken( + params: GetAccessTokenParams, + ): Promise + /** + * 获取企业accessToken(应用商店应用) + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-access_token-of-the-authorized-enterprise + */ + getCorpAccessToken( + params: GetCorpAccessTokenParams, + ): Promise + /** + * 获取用户token + * @see https://developers.dingtalk.com/document/isvapp/obtain-user-token + */ + getUserToken(params: GetUserTokenParams): Promise + /** + * 查询微应用后台免登的用户信息 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-identity-of-an-application-administrator + */ + getSsoUserInfo(query: GetSsoUserInfoQuery): Promise + } +} diff --git a/adapters/dingtalk/src/api/pedia.ts b/adapters/dingtalk/src/api/pedia.ts new file mode 100644 index 00000000..9b320c4a --- /dev/null +++ b/adapters/dingtalk/src/api/pedia.ts @@ -0,0 +1,221 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface PediaWordsQueryQuery { + /** 查询主键编号。 */ + uuid: number + /** 当前操作用户的userId。 */ + userId: string +} + +export interface PediaWordsQueryResponse { + data?: { + wordName?: string + uuid?: number + gmtCreate?: number + gmtModify?: number + wordAlias?: number + highLightWordAlias?: number + relatedDoc?: number + relatedLink?: number + creatorName?: string + updaterName?: string + approveName?: string + wordParaphrase?: string + simpleWordParaphrase?: string + contacts?: number + tagsList?: number + appLink?: number + imHighLight?: number + simHighLight?: number + picList?: number + contactList?: number + userId?: string + parentUuid?: number + } + success?: unknown +} + +export interface PediaWordsSearchParams { + /** 搜索关键词。 */ + wordName?: string + /** 操作人的userId。 */ + userId: string + /** 当前每页需要展示的数量,最大20。 */ + pageSize: number + /** 当前查询的页数,从1开始。 */ + pageNumber: number + /** 当前搜索列表的状态: */ + status: string +} + +export interface PediaWordsSearchResponse { + data?: { + wordName?: string + uuid?: number + gmtCreate?: number + gmtModify?: number + wordAlias?: number + highLightWordAlias?: number + relatedLink?: number + relatedDoc?: number + creatorName?: string + updaterName?: string + approveName?: string + wordParaphrase?: string + simpleWordParaphrase?: string + contacts?: number + tagsList?: number + appLink?: number + imHighLight?: number + simHighLight?: number + picList?: number + contactList?: number + userId?: string + parentUuid?: number + }[] + success?: unknown +} + +export interface PediaWordsApproveParams { + /** 当前审核的词条的主键编号。 */ + uuid: number + /** 操作人的组织员工userId。 */ + userId: string + /** 审核的结果: */ + approveStatus: string + /** 拒绝的原因。 */ + approveReason?: string + /** 当前内部群是否高亮: */ + imHighLight: unknown + /** 服务群是否高亮: */ + simHighLight: unknown +} + +export interface PediaWordsApproveResponse { + success?: unknown +} + +export interface PediaWordsDeleteQuery { + /** 当前需要删除的词条主键编号。 */ + uuid: number + /** 当前操作用户的userId。 */ + userId: string +} + +export interface PediaWordsDeleteResponse { + uuid?: number + success?: unknown +} + +export interface PediaWordsUpdateParams { + /** 需要更新的词条编号。 */ + uuid: number + /** 词条名称。 */ + wordName: string + /** 词条别名列表,最大值10。 */ + wordAlias?: string[] + /** 可高亮的别名列表,最大值10。 */ + highLightWordAlias?: string[] + /** 词条相关文档信息,最大值10。 */ + relatedDoc?: object[] + /** 词条相关链接信息,最大值10。 */ + relatedLink?: object[] + /** 词条释义。 */ + wordParaphrase: string + /** 相关应用对象。 */ + appLink?: object[] + /** 操作人的userId。 */ + userId?: string + /** 词条的相关图片信息,最大值10。 */ + picList?: object[] + /** 词条的相关联系人信息,最大值10。 */ + contactList?: object[] +} + +export interface PediaWordsUpdateResponse { + uuid?: number + success?: unknown +} + +export interface PediaWordsAddParams { + /** 新增词条的名称。 */ + wordName: string + /** 词条的别名列表,多个名字的时候可以添加,每次调用最多传10个。 */ + wordAlias?: string[] + /** 词条高亮别名列表,每次调用最多传10个。 */ + highLightWordAlias?: string[] + /** 词条相关的文档列表,每次调用最多传10个。 */ + relatedDoc?: object[] + /** 词条相关的链接信息,每次调用最多传10个。 */ + relatedLink?: object[] + /** 词条释义,针对词条的描述内容。 */ + wordParaphrase: string + /** 词条相关的图片信息,每次调用最多传10个。 */ + picList?: object[] + /** 组织对应的员工userId。 */ + userId: string + /** 词条相关的联系人信息,每次调用最多传10个。 */ + contactList?: object[] +} + +export interface PediaWordsAddResponse { + uuid?: number + success?: unknown +} + +// funcName: isOldApi +Internal.define({ + '/pedia/words/query': { POST: { pediaWordsQuery: false } }, + '/pedia/words/search': { POST: { pediaWordsSearch: false } }, + '/pedia/words/approve': { POST: { pediaWordsApprove: false } }, + '/pedia/words': { + DELETE: { pediaWordsDelete: false }, + PUT: { pediaWordsUpdate: false }, + POST: { pediaWordsAdd: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 根据词条主键ID查询当前词条详情 + * @see https://developers.dingtalk.com/document/app/entry-query + */ + pediaWordsQuery( + query: PediaWordsQueryQuery, + ): Promise + /** + * 分页获取企业词条信息 + * @see https://developers.dingtalk.com/document/app/entry-search + */ + pediaWordsSearch( + params: PediaWordsSearchParams, + ): Promise + /** + * 企业百科针对待审核词条进行审核 + * @see https://developers.dingtalk.com/document/app/entry-review + */ + pediaWordsApprove( + params: PediaWordsApproveParams, + ): Promise + /** + * 企业百科针对uuid删除当前词条 + * @see https://developers.dingtalk.com/document/app/entry-delete + */ + pediaWordsDelete( + query: PediaWordsDeleteQuery, + ): Promise + /** + * 企业百科对当前已经生效词条进行编辑 + * @see https://developers.dingtalk.com/document/app/update-entry + */ + pediaWordsUpdate( + params: PediaWordsUpdateParams, + ): Promise + /** + * 企业百科增加当前企业词条信息 + * @see https://developers.dingtalk.com/document/app/new-entry + */ + pediaWordsAdd(params: PediaWordsAddParams): Promise + } +} diff --git a/adapters/dingtalk/src/api/project.ts b/adapters/dingtalk/src/api/project.ts new file mode 100644 index 00000000..2ad6129f --- /dev/null +++ b/adapters/dingtalk/src/api/project.ts @@ -0,0 +1,1518 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface CreateProjectCustomfieldStatusParams { + /** 自定义字段ID。 */ + customFieldId?: string + /** 自定义字段名称(如果提供自定义字段ID 则忽略)。 */ + customFieldName?: string + /** 自定义字段InstanceId(如果提供自定义字段ID 或者 自定义字段名称 则忽略)。 */ + customFieldInstanceId?: string + /** 字段值集合。 */ + value: object[] +} + +export interface CreateProjectCustomfieldStatusResponse { + result?: { + customFieldId?: string + originalId?: string + name?: string + type?: string + advancedCustomFieldObjectType?: string + value?: number + } +} + +export interface UpdateTaskContentParams { + /** 任务标题。 */ + content?: string +} + +export interface UpdateTaskContentResponse { + result?: { + content?: string + updated?: string + } +} + +export interface UpdateTaskNoteParams { + /** 任务备注。 */ + note?: string +} + +export interface UpdateTaskNoteResponse { + result?: { + note?: string + updated?: string + } +} + +export interface UpdateTaskInvolvemembersParams { + /** 参与者用户userId。 */ + involveMembers?: string[] + /** 参与者用户userId。 */ + addInvolvers?: string[] + /** 参与者用户userId。 */ + delInvolvers?: string[] +} + +export interface UpdateTaskInvolvemembersResponse { + result?: { + involveMembers?: number + updated?: string + } +} + +export interface UpdateTaskExecutorParams { + /** 执行者用户userId。 */ + executorId?: string +} + +export interface UpdateTaskExecutorResponse { + result?: { + executorId?: string + updated?: string + } +} + +export interface UpdateTaskPriorityParams { + /** 优先级。 */ + priority?: number +} + +export interface UpdateTaskPriorityResponse { + result?: { + priority?: number + updated?: string + } +} + +export interface UpdateTaskDueDateParams { + /** 截止时间,格式:YYYY-MM-DDTHH:mm:ssZ(ISO 8601/RFC 3339)。 */ + dueDate?: string +} + +export interface UpdateTaskDueDateResponse { + result?: { + dueDate?: string + updated?: string + } +} + +export interface GetTaskByIdsQuery { + /** 任务ID集合,多个taskId,使用逗号分隔。 */ + taskId?: string + /** 父任务ID。 */ + parentTaskId?: string +} + +export interface GetTaskByIdsResponse { + result?: { + taskId?: string + content?: string + note?: string + projectId?: string + ancestorIds?: number + parentTaskId?: string + taskflowStatusId?: string + taskListId?: string + taskStageId?: string + tagIds?: number + creatorId?: string + executorId?: string + involveMembers?: number + priority?: number + storyPoint?: string + recurrence?: number + isDone?: number + isArchived?: number + visible?: string + uniqueId?: string + startDate?: string + dueDate?: string + accomplishTime?: string + created?: string + updated?: string + scenarioFieldConfigId?: string + sprintId?: string + customFields?: number + }[] +} + +export interface ArchiveTaskResponse { + result?: { + updated?: string + } +} + +export interface SearchUserTaskQuery { + /** 用户的任务角色。 */ + roleTypes: string + /** tql内容,详情参见[任务筛选TQL](https://open.dingtalk.com/document/orgapp/the-description-of-the-tql-task)使用说明。 */ + tql?: string + /** 分页标,从上一次请求结果中获取。 */ + nextToken?: string + /** 每页返回最大数量。 */ + maxResults?: string +} + +export interface SearchUserTaskResponse { + result?: { + taskId?: string + content?: string + note?: string + projectId?: string + ancestorIds?: number + parentTaskId?: string + taskflowStatusId?: string + taskListId?: string + taskStageId?: string + tagIds?: number + creatorId?: string + executorId?: string + involveMembers?: number + priority?: number + storyPoint?: string + recurrence?: number + isDone?: number + isArchived?: number + visible?: string + uniqueId?: string + startDate?: string + dueDate?: string + accomplishTime?: string + created?: string + updated?: string + scenarioFieldConfigId?: string + sprintId?: string + customFields?: number + }[] + requestId?: string +} + +export interface SeachTaskStageQuery { + /** 任务分组ID: */ + taskListId?: string + /** 任务列表名字。 */ + query?: string + /** 每页返回最大数量。 */ + maxResults?: number + /** 分页标,从上一次请求结果中获取。 */ + nextToken?: string + /** 任务列表 ID 集合。 */ + taskStageIds?: string +} + +export interface SeachTaskStageResponse { + result?: { + taskStageId?: string + name?: string + description?: string + projectId?: string + taskListId?: string + creatorId?: string + created?: string + updated?: string + }[] + nextToken?: string +} + +export interface SearchTaskListQuery { + /** 模糊任务分组名字。 */ + query?: string + /** 每页返回最大数量。 */ + maxResults?: number + /** 分页标,从上一次请求结果中获取。 */ + nextToken?: string + /** 任务分组ID集合,多个使用英文逗号隔开。 */ + taskListIds?: string +} + +export interface SearchTaskListResponse { + result?: { + taskListId?: string + title?: string + description?: string + projectId?: string + creatorId?: string + created?: string + updated?: string + }[] + nextToken?: string +} + +export interface SearchTaskFlowQuery { + /** 模糊查询工作流名字。 */ + query?: string + /** 每页返回最大数量。 */ + maxResults?: number + /** 分页标,从上一次请求结果中获取。 */ + nextToken?: string + /** 工作流ID集合。 */ + taskflowIds?: string +} + +export interface SearchTaskFlowResponse { + result?: { + taskflowId?: string + name?: string + boundToObjectId?: string + boundToObjectType?: string + creatorId?: string + isDeleted?: number + created?: string + updated?: string + }[] +} + +export interface GetProjectStatusListResponse { + result?: { + projectId?: string + name?: string + content?: string + degree?: string + creatorId?: string + created?: string + }[] +} + +export interface DeleteProjectMemberParams { + /** 用户userId。 */ + userIds: string[] +} + +export interface DeleteProjectMemberResponse { + result?: string[] +} + +export interface GetProjectMemebersQuery { + /** 用户ID。 */ + userIds?: string + /** 项目角色ID。 */ + projectRoleId?: string + /** 每页返回最大数量。默认10,最大300。 */ + maxResults?: number + /** 跳过的数据数量。 */ + skip?: number +} + +export interface GetProjectMemebersResponse { + result?: { + memberId?: string + userId?: string + role?: number + roleIds?: number + }[] +} + +export interface QueryProjectQuery { + /** 项目ID集合: */ + projectIds?: string + /** 项目名字(模糊匹配)。 */ + name?: string + /** 分页大小。每页返回最大数量。 */ + maxResults?: number + /** 分页标。供分页使用,下一页token,从当前页结果中获取。 */ + nextToken?: string + /** 原始项目ID。 */ + sourceId?: string +} + +export interface QueryProjectResponse { + result?: { + projectId?: string + name?: string + logo?: string + description?: string + organizationId?: string + visibility?: string + isTemplate?: number + creatorId?: string + isArchived?: number + isSuspended?: number + uniqueIdPrefix?: string + created?: string + updated?: string + startDate?: string + endDate?: string + customFields?: number + }[] + nextToken?: string + requestId?: string +} + +export interface SearchTaskflowStatusQuery { + /** 模糊查询工作流状态名字。 */ + query?: string + /** 每页返回最大数量。 */ + maxResults?: number + /** 分页标,从上一次请求结果中获取。 */ + nextToken?: string + /** 工作流ID集合。 */ + tfIds?: string + /** 工作流状态ID集合。 */ + tfsIds?: string +} + +export interface SearchTaskflowStatusResponse { + result?: { + taskflowStatusId?: string + name?: string + pos?: number + taskflowId?: string + rejectStatusIds?: number + kind?: string + creatorId?: string + isDeleted?: number + created?: string + updated?: string + isTaskflowstatusruleexector?: number + }[] +} + +export interface UpdateTaskTaskflowstatusParams { + /** 任务状态ID。 */ + taskflowStatusId?: string + taskflowStatusUpdateNote?: string +} + +export interface UpdateTaskTaskflowstatusResponse { + result?: { + updated?: string + } +} + +export interface UpdateTaskStartdateParams { + /** 任务开始时间,格式:YYYY-MM-DDTHH:mm:ssZ(ISO 8601/RFC 3339)。 */ + startDate?: string +} + +export interface UpdateTaskStartdateResponse { + result?: { + startDate?: string + updated?: string + } +} + +export interface CreateProjectParams { + /** 项目名称。 */ + name?: string +} + +export interface CreateProjectResponse { + result?: { + projectId?: string + name?: string + creatorId?: string + logo?: string + visibility?: string + uniqueIdPrefix?: string + created?: string + updated?: string + isArchived?: number + isSuspended?: number + normalType?: string + rootCollectionId?: string + sourceId?: string + defaultCollectionId?: string + isTemplate?: number + customFields?: number + } +} + +export interface GetUserJoinedProjectQuery { + /** 分页大小。 */ + maxResults?: number + /** 分页标。 */ + nextToken?: string +} + +export interface GetUserJoinedProjectResponse { + result?: string[] + nextToken?: string +} + +export interface ArchiveProjectResponse { + result?: { + isArchived?: number + updated?: string + } +} + +export interface UnSuspendProjectResponse { + result?: { + updated?: string + } +} + +export interface SuspendProjectResponse { + result?: { + updated?: string + } +} + +export interface QueryTaskOfProjectQuery { + /** 分页游标。 */ + nextToken?: string + /** 每页返回最大数量。默认10,最大500。 */ + maxResults?: number + /** 查询条件。 */ + query?: string +} + +export interface QueryTaskOfProjectResponse { + totalCount: number + nextToken: string + result?: { + taskId?: string + content?: string + involveMembers?: number + projectId?: string + executorId?: string + creatorId?: string + isDeleted?: number + labels?: number + created?: string + updated?: string + scenariofieldconfigId?: string + customfields?: number + note?: string + startDate?: string + dueDate?: string + priority?: number + taskflowstatusId?: string + isDone?: number + isArchived?: number + visible?: string + tagIds?: number + stageId?: string + sprintId?: string + accomplished?: string + storyPoint?: number + progress?: number + ancestorIds?: number + }[] +} + +export interface CreateWorkTimeParams { + /** 任务执行者userId。 */ + executorId: string + /** 对象ID,传项目任务ID。 */ + objectId: string + /** 对象类型,固定值为task,表示项目任务。 */ + objectType: string + /** 工时提交人员的userId。 */ + submitterId: string + /** 当startDate和endDate指定的时间跨天时,添加的工时时长是否连续。 */ + isDuration: unknown + /** 添加实际工时的日期是否包含假期。 */ + includesHolidays: unknown + /** 添加实际工时的开始日期。 */ + startDate: string + /** 结束时间。 */ + endDate: string + /** 实际工时时长,单位毫秒,1小时即为3600000。 */ + workTime: number +} + +export interface CreateWorkTimeQuery { + /** 接口校验类型,固定值:organization。 */ + tenantType: string +} + +export interface CreateWorkTimeResponse { + result?: { + ok?: number + message?: string + body?: number + } +} + +export interface CreatePlanTimeParams { + /** 目标任务的执行者userId。 */ + executorId: string + /** 对象ID,传项目任务ID。 */ + objectId: string + /** 对象类型,固定值为task,表示项目任务。 */ + objectType: string + /** 当startDate和endDate指定的时间跨天时,添加的工时时长是否连续。 */ + isDuration: unknown + /** 添加计划工时的日期是否包含假期。 */ + includesHolidays: unknown + /** 工时提交人员的userId。 */ + submitterId: string + /** 开始时间。 */ + startDate: string + /** 结束时间。 */ + endDate: string + /** 计划工时时长,单位毫秒,1小时即为3600000。 */ + planTime: number +} + +export interface CreatePlanTimeQuery { + /** 接口校验类型,目前为固定值:organization。 */ + tenantType: string +} + +export interface CreatePlanTimeResponse { + result?: { + ok?: number + message?: string + body?: number + } +} + +export interface UpdateCustomfieldValueParams { + /** 自定义字段名。 */ + customFieldName?: string + /** 自定义对象值。 */ + value: object[] + /** 自定义字段id。 */ + customFieldId?: string +} + +export interface UpdateCustomfieldValueResponse { + result?: { + customFields?: number + } +} + +export interface GetTbUserIdByStaffIdQuery { + /** 操作者userId。 */ + optUserId: string + /** 需要被查询的用户userId。 */ + userId: string +} + +export interface GetTbUserIdByStaffIdResponse { + result: { + tbUserId: string + } +} + +export interface GetTbOrgIdByDingOrgIdQuery { + /** 操作者userId。 */ + optUserId: string +} + +export interface GetTbOrgIdByDingOrgIdResponse { + result: { + tbOrganizationId: string + } +} + +export interface UpdateProjectGroupParams { + /** 将项目添加到的目标项目分组Id列表,最大值5。 */ + addProjectGroupIds?: string[] + /** 移除该项目的项目分组Id列表,最大值5。 */ + delProjectGroupIds?: string[] +} + +export interface UpdateProjectGroupResponse { + result?: { + ok?: number + } +} + +export interface AddProjectMemberParams { + /** 被添加的用户userId列表,建议一次不超过10个。 */ + userIds: string[] +} + +export interface AddProjectMemberResponse { + result?: { + nickname?: string + joined?: string + }[] +} + +export interface CreateProjectByTemplateParams { + /** 项目名字。 */ + name: string + /** 模板Id。 */ + templateId: string +} + +export interface CreateProjectByTemplateResponse { + result?: { + id?: string + name?: string + created?: string + logo?: string + } +} + +export interface GetProjectGroupQuery { + /** 查看者userId,即查询该员工可见的项目分组。 */ + viewerId?: string + /** 分页大小。从1开始,默认值10,最大值1000。 */ + pageSize?: number +} + +export interface GetProjectGroupResponse { + result?: { + id?: string + visible?: string + name?: string + created?: string + updated?: string + }[] +} + +export interface SearchProjectTemplateQuery { + /** 项目模板名称关键词。 */ + keyword?: string +} + +export interface SearchProjectTemplateResponse { + result?: { + id?: string + description?: string + visible?: string + isDemo?: number + isDeleted?: number + name?: string + logo?: string + created?: string + updated?: string + }[] +} + +export interface CreateTaskObjectLinkParams { + /** 关联内容信息。 */ + linkedData?: unknown +} + +export interface CreateTaskObjectLinkResponse { + result?: { + created?: string + objectLinkId?: string + } +} + +export interface CreateTaskParams { + /** 项目id。 */ + projectId: string + /** 任务标题。 */ + content: string + /** 任务执行者userId。 */ + executorId?: string + /** 任务截止时间,格式:YYYY-MM-DDTHH:mm:ssZ(ISO 8601/RFC 3339)。 */ + dueDate?: string + /** 任务备注。 */ + note?: string + /** 任务优先级。 */ + priority?: number + /** 自定义业务字段。 */ + customfields?: object[] + /** 任务列表ID。 */ + stageId?: string + /** 父任务id。 */ + parentTaskId?: string + /** 任务类型id,任务类型比如:缺陷、需求。 */ + scenariofieldconfigId?: string + /** 任务开始时间,iso8601格式,例如:2022-07-29T14:55Z。 */ + startDate?: string + /** 任务的可见性规则。 */ + visible?: string +} + +export interface CreateTaskResponse { + result?: { + taskId?: string + content?: string + involveMembers?: number + projectId?: string + executorId?: string + creatorId?: string + created?: string + updated?: string + note?: string + dueDate?: string + priority?: number + customfields?: number + } +} + +export interface GetOrganizatioTaskByIdsQuery { + /** 任务id列表,建议不超过20个,多个任务id之间使用`,`分开。 */ + taskIds: string +} + +export interface GetOrganizatioTaskByIdsResponse { + result?: { + note?: string + visible?: string + executorId?: string + created?: string + dueDate?: string + creatorId?: string + involveMembers?: number + priority?: number + isDone?: number + content?: string + labels?: number + isDeleted?: number + ancestorIds?: number + taskId?: string + updated?: string + startDate?: string + }[] +} + +export interface UpdateOrganizationTaskPriorityParams { + /** 自由任务优先级。 */ + priority: number + /** 是否禁止动态。 */ + disableActivity?: unknown + /** 是否禁止通知。 */ + disableNotification?: unknown +} + +export interface UpdateOrganizationTaskPriorityResponse { + result?: { + priority?: number + updated?: string + } +} + +export interface UpdateOrganizationTaskNoteParams { + /** 任务备注。 */ + note: string + /** 是否禁止动态。 */ + disableActivity?: unknown + /** 是否禁止通知。 */ + disableNotification?: unknown +} + +export interface UpdateOrganizationTaskNoteResponse { + result?: { + note?: string + updated?: string + } +} + +export interface UpdateOrganizationTaskInvolveMembersParams { + /** 所有参与者userId列表,建议参与者总人数不超过20个。 */ + involveMembers?: string[] + /** 增加的参与者userId列表,建议参与者总人数不超过20个。 */ + addInvolvers?: string[] + /** 删除的参与者userId列表。 */ + delInvolvers?: string[] + /** 是否禁止动态。 */ + disableActivity?: unknown + /** 是否禁止通知。 */ + disableNotification?: unknown +} + +export interface UpdateOrganizationTaskInvolveMembersResponse { + result?: { + involvers?: number + updated?: string + } +} + +export interface UpdateOrganizationTaskExecutorParams { + /** 任务执行者userId。 */ + executorId: string + /** 是否禁止动态。 */ + disableActivity?: unknown + /** 是否禁止通知。 */ + disableNotification?: unknown +} + +export interface UpdateOrganizationTaskExecutorResponse { + result?: { + executorId?: string + updated?: string + executor?: number + involvers?: number + } +} + +export interface UpdateOrganizationTaskDueDateParams { + /** 任务截止时间,格式:YYYY-MM-DDTHH:mm:ssZ(ISO 8601/RFC 3339)。 */ + dueDate: string + /** 是否禁止动态。 */ + disableActivity?: unknown + /** 是否禁止通知。 */ + disableNotification?: unknown +} + +export interface UpdateOrganizationTaskDueDateResponse { + result?: { + dueDate?: string + updateTime?: string + } +} + +export interface UpdateOrganizationTaskContentParams { + /** 任务标题。 */ + content: string + /** 是否禁止动态。 */ + disableActivity?: unknown + /** 是否禁止通知。 */ + disableNotification?: unknown +} + +export interface UpdateOrganizationTaskContentResponse { + result?: { + content?: string + updated?: string + } +} + +export interface UpdateOrganizationTaskStatusParams { + /** 自由任务状态。 */ + isDone: unknown + /** 是否禁止动态。 */ + disableActivity?: unknown + /** 是否禁止通知。 */ + disableNotification?: unknown +} + +export interface UpdateOrganizationTaskStatusResponse { + result?: { + isDone?: number + updateTime?: string + } +} + +export interface GetOrganizationPriorityListResponse { + result?: { + color?: string + name?: string + priorityId?: string + priority?: string + }[] +} + +export interface GetOrganizationTaskResponse { + result?: { + note?: string + visible?: string + executorId?: string + created?: string + dueDate?: string + creatorId?: string + involveMembers?: number + priority?: number + isDone?: number + content?: string + labels?: number + isDeleted?: number + ancestorIds?: number + taskId?: string + updated?: string + startDate?: string + } +} + +export interface DeleteTaskResponse { + result?: unknown +} + +export interface CreateOrganizationTaskParams { + /** 任务标题。 */ + content: string + /** 任务备注。 */ + note?: string + /** 自由任务优先级,如下图所示。用户是否有自定义更新优先级,获取该参数方法不同。 */ + priority: number + /** 参与者userId列表,建议参与者总人数不超过20个。 */ + involveMembers?: string[] + /** 执行者userId。 */ + executorId?: string + /** 任务截止日期,格式:YYYY-MM-DDTHH:mm:ssZ(ISO 8601/RFC 3339)。 */ + dueDate?: string + /** 任务创建日期,格式:YYYY-MM-DDTHH:mm:ssZ(ISO 8601/RFC 3339)。 */ + createTime?: string + /** 任务可见性。 */ + visible: string + /** 是否禁止通知。 */ + disableNotification?: unknown + /** 是否禁止动态。 */ + disableActivity?: unknown +} + +export interface CreateOrganizationTaskResponse { + result?: { + dueDate?: string + executor?: number + id?: string + visible?: string + created?: string + priority?: number + involvers?: number + updated?: string + note?: string + hasReminder?: number + creatorId?: string + content?: string + attachmentsCount?: number + isDeleted?: number + ancestorIds?: number + creator?: number + executorId?: string + involveMembers?: number + isDone?: string + } +} + +// funcName: isOldApi +Internal.define({ + '/project/users/{userId}/projects/{projectId}/customfields': { + PUT: { createProjectCustomfieldStatus: false }, + }, + '/project/users/{userId}/tasks/{taskId}/contents': { + PUT: { updateTaskContent: false }, + }, + '/project/users/{userId}/tasks/{taskId}/notes': { + PUT: { updateTaskNote: false }, + }, + '/project/users/{userId}/tasks/{taskId}/involveMembers': { + PUT: { updateTaskInvolvemembers: false }, + }, + '/project/users/{userId}/tasks/{taskId}/executors': { + PUT: { updateTaskExecutor: false }, + }, + '/project/users/{userId}/tasks/{taskId}/priorities': { + PUT: { updateTaskPriority: false }, + }, + '/project/users/{userId}/tasks/{taskId}/dueDates': { + PUT: { updateTaskDueDate: false }, + }, + '/project/users/{userId}/tasks': { + GET: { getTaskByIds: false }, + POST: { createTask: false }, + }, + '/project/users/{userId}/tasks/{taskId}/archive': { + POST: { archiveTask: false }, + }, + '/project/users/{userId}/tasks/search': { POST: { searchUserTask: false } }, + '/project/users/{userId}/projects/{projectId}/taskStages/search': { + POST: { seachTaskStage: false }, + }, + '/project/users/{userId}/projects/{projectId}/taskLists/search': { + POST: { searchTaskList: false }, + }, + '/project/users/{userId}/projects/{projectId}/taskflows/search': { + POST: { searchTaskFlow: false }, + }, + '/project/users/{userId}/projects/{projectId}/statuses': { + GET: { getProjectStatusList: false }, + }, + '/project/users/{userId}/projects/{projectId}/members/remove': { + POST: { deleteProjectMember: false }, + }, + '/project/users/{userId}/projects/{projectId}/members': { + GET: { getProjectMemebers: false }, + POST: { addProjectMember: false }, + }, + '/project/users/{userId}/projects/query': { POST: { queryProject: false } }, + '/project/users/{userId}/projects/{projectId}/taskflowStatuses/search': { + GET: { searchTaskflowStatus: false }, + }, + '/project/users/{userId}/tasks/{taskId}/taskflowStatuses': { + PUT: { updateTaskTaskflowstatus: false }, + }, + '/project/users/{userId}/tasks/{taskId}/startDates': { + PUT: { updateTaskStartdate: false }, + }, + '/project/users/{userId}/projects': { POST: { createProject: false } }, + '/project/users/{userId}/joinProjects': { + GET: { getUserJoinedProject: false }, + }, + '/project/users/{userId}/projects/{projectId}/archive': { + POST: { archiveProject: false }, + }, + '/project/users/{userId}/projects/{projectId}/unsuspend': { + POST: { unSuspendProject: false }, + }, + '/project/users/{userId}/projects/{projectId}/suspend': { + POST: { suspendProject: false }, + }, + '/project/users/{userId}/projectIds/{projectId}/tasks': { + GET: { queryTaskOfProject: false }, + }, + '/project/users/{userId}/workTimes': { POST: { createWorkTime: false } }, + '/project/users/{userId}/planTimes': { POST: { createPlanTime: false } }, + '/project/users/{userId}/tasks/{taskId}/customFields': { + PUT: { updateCustomfieldValue: false }, + }, + '/project/teambition/users': { GET: { getTbUserIdByStaffId: false } }, + '/project/teambition/organizations': { + GET: { getTbOrgIdByDingOrgId: false }, + }, + '/project/users/{userId}/projects/{projectId}/groups': { + PUT: { updateProjectGroup: false }, + }, + '/project/users/{userId}/templates/projects': { + POST: { createProjectByTemplate: false }, + }, + '/project/organizations/users/{userId}/groups': { + GET: { getProjectGroup: false }, + }, + '/project/organizations/users/{userId}/templates': { + GET: { searchProjectTemplate: false }, + }, + '/project/users/{userId}/tasks/{taskId}/objectLinks': { + POST: { createTaskObjectLink: false }, + }, + '/project/organizations/users/{userId}/tasks': { + GET: { getOrganizatioTaskByIds: false }, + POST: { createOrganizationTask: false }, + }, + '/project/organizations/users/{userId}/tasks/{taskId}/priorities': { + PUT: { updateOrganizationTaskPriority: false }, + }, + '/project/organizations/users/{userId}/tasks/{taskId}/notes': { + PUT: { updateOrganizationTaskNote: false }, + }, + '/project/organizations/users/{userId}/tasks/{taskId}/involveMembers': { + PUT: { updateOrganizationTaskInvolveMembers: false }, + }, + '/project/organizations/users/{userId}/tasks/{taskId}/executors': { + PUT: { updateOrganizationTaskExecutor: false }, + }, + '/project/organizations/users/{userId}/tasks/{taskId}/dueDates': { + PUT: { updateOrganizationTaskDueDate: false }, + }, + '/project/organizations/users/{userId}/tasks/{taskId}/contents': { + PUT: { updateOrganizationTaskContent: false }, + }, + '/project/organizations/users/{userId}/tasks/{taskId}/states': { + PUT: { updateOrganizationTaskStatus: false }, + }, + '/project/organizations/users/{userId}/priorities': { + GET: { getOrganizationPriorityList: false }, + }, + '/project/organizations/users/{userId}/tasks/{taskId}': { + GET: { getOrganizationTask: false }, + }, + '/project/users/{userId}/tasks/{taskId}': { DELETE: { deleteTask: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 创建或更新项目概览中自定义字段值 + * @see https://developers.dingtalk.com/document/orgapp/create-project-custom-fields + */ + createProjectCustomfieldStatus( + userId: string, + projectId: string, + params: CreateProjectCustomfieldStatusParams, + ): Promise + /** + * 更新任务标题 + * @see https://developers.dingtalk.com/document/orgapp/update-task-content + */ + updateTaskContent( + userId: string, + taskId: string, + params: UpdateTaskContentParams, + ): Promise + /** + * 更新任务备注 + * @see https://developers.dingtalk.com/document/orgapp/update-task-notes + */ + updateTaskNote( + userId: string, + taskId: string, + params: UpdateTaskNoteParams, + ): Promise + /** + * 更新任务参与者 + * @see https://developers.dingtalk.com/document/orgapp/update-task-participants + */ + updateTaskInvolvemembers( + userId: string, + taskId: string, + params: UpdateTaskInvolvemembersParams, + ): Promise + /** + * 更新任务执行者 + * @see https://developers.dingtalk.com/document/orgapp/update-task-performer + */ + updateTaskExecutor( + userId: string, + taskId: string, + params: UpdateTaskExecutorParams, + ): Promise + /** + * 更新任务优先级 + * @see https://developers.dingtalk.com/document/orgapp/update-task-priority + */ + updateTaskPriority( + userId: string, + taskId: string, + params: UpdateTaskPriorityParams, + ): Promise + /** + * 更新任务截止时间 + * @see https://developers.dingtalk.com/document/orgapp/update-task-deadline + */ + updateTaskDueDate( + userId: string, + taskId: string, + params: UpdateTaskDueDateParams, + ): Promise + /** + * 获取任务详情 + * @see https://developers.dingtalk.com/document/orgapp/get-task-details + */ + getTaskByIds( + userId: string, + query: GetTaskByIdsQuery, + ): Promise + /** + * 任务迁移至回收站 + * @see https://developers.dingtalk.com/document/orgapp/archive-tasks + */ + archiveTask(userId: string, taskId: string): Promise + /** + * 查询用户任务列表 + * @see https://developers.dingtalk.com/document/orgapp/querying-user-tasks + */ + searchUserTask( + userId: string, + query: SearchUserTaskQuery, + ): Promise + /** + * 获取任务列表 + * @see https://developers.dingtalk.com/document/orgapp/get-task-list + */ + seachTaskStage( + userId: string, + projectId: string, + query: SeachTaskStageQuery, + ): Promise + /** + * 查询任务分组 + * @see https://developers.dingtalk.com/document/orgapp/query-task-grouping + */ + searchTaskList( + userId: string, + projectId: string, + query: SearchTaskListQuery, + ): Promise + /** + * 查询任务工作流 + * @see https://developers.dingtalk.com/document/orgapp/query-task-workflow + */ + searchTaskFlow( + userId: string, + projectId: string, + query: SearchTaskFlowQuery, + ): Promise + /** + * 查询项目状态 + * @see https://developers.dingtalk.com/document/orgapp/query-project-status + */ + getProjectStatusList( + userId: string, + projectId: string, + ): Promise + /** + * 删除项目成员 + * @see https://developers.dingtalk.com/document/orgapp/delete-project-members + */ + deleteProjectMember( + userId: string, + projectId: string, + params: DeleteProjectMemberParams, + ): Promise + /** + * 获取项目成员 + * @see https://developers.dingtalk.com/document/orgapp/get-project-members + */ + getProjectMemebers( + userId: string, + projectId: string, + query: GetProjectMemebersQuery, + ): Promise + /** + * 查询项目 + * @see https://developers.dingtalk.com/document/orgapp/query-enterprise-all-projects + */ + queryProject( + userId: string, + query: QueryProjectQuery, + ): Promise + /** + * 搜索任务工作流状态 + * @see https://developers.dingtalk.com/document/isvapp/search-task-workflow-status + */ + searchTaskflowStatus( + userId: string, + projectId: string, + query: SearchTaskflowStatusQuery, + ): Promise + /** + * 更新任务工作流状态 + * @see https://developers.dingtalk.com/document/isvapp/update-task-workflow-status + */ + updateTaskTaskflowstatus( + userId: string, + taskId: string, + params: UpdateTaskTaskflowstatusParams, + ): Promise + /** + * 更新任务开始时间 + * @see https://developers.dingtalk.com/document/orgapp/update-task-start-time + */ + updateTaskStartdate( + userId: string, + taskId: string, + params: UpdateTaskStartdateParams, + ): Promise + /** + * 创建项目 + * @see https://developers.dingtalk.com/document/orgapp/create-project + */ + createProject( + userId: string, + params: CreateProjectParams, + ): Promise + /** + * 获取用户加入的项目 + * @see https://developers.dingtalk.com/document/orgapp/get-projects-joined-by-users + */ + getUserJoinedProject( + userId: string, + query: GetUserJoinedProjectQuery, + ): Promise + /** + * 项目放入回收站 + * @see https://developers.dingtalk.com/document/orgapp/items-in-recycle-bin + */ + archiveProject( + userId: string, + projectId: string, + ): Promise + /** + * 恢复项目归档 + * @see https://developers.dingtalk.com/document/orgapp/cancel-project-archiving + */ + unSuspendProject( + projectId: string, + userId: string, + ): Promise + /** + * 归档项目 + * @see https://developers.dingtalk.com/document/orgapp/archiving-project + */ + suspendProject( + projectId: string, + userId: string, + ): Promise + /** + * 查询项目中的任务 + * @see https://developers.dingtalk.com/document/isvapp/query-tasks-in-a-project + */ + queryTaskOfProject( + userId: string, + projectId: string, + query: QueryTaskOfProjectQuery, + ): Promise + /** + * 录入实际工时接口 + * @see https://developers.dingtalk.com/document/isvapp/create-actual-work + */ + createWorkTime( + userId: string, + query: CreateWorkTimeQuery, + params: CreateWorkTimeParams, + ): Promise + /** + * 录入计划工时 + * @see https://developers.dingtalk.com/document/isvapp/create-planned-work + */ + createPlanTime( + userId: string, + query: CreatePlanTimeQuery, + params: CreatePlanTimeParams, + ): Promise + /** + * 更新任务自定义字段的值 + * @see https://developers.dingtalk.com/document/isvapp/update-task-custom-field-value + */ + updateCustomfieldValue( + userId: string, + taskId: string, + params: UpdateCustomfieldValueParams, + ): Promise + /** + * 根据钉钉UserId获取Teambition用户Id + * @see https://developers.dingtalk.com/document/isvapp/obtain-dingtalk-teambition-user-id-based-on-userid + */ + getTbUserIdByStaffId( + query: GetTbUserIdByStaffIdQuery, + ): Promise + /** + * 获取Teambition企业Id + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-teambition-enterprise-id + */ + getTbOrgIdByDingOrgId( + query: GetTbOrgIdByDingOrgIdQuery, + ): Promise + /** + * 更新项目的分组 + * @see https://developers.dingtalk.com/document/isvapp/update-project-grouping + */ + updateProjectGroup( + userId: string, + projectId: string, + params: UpdateProjectGroupParams, + ): Promise + /** + * 增加项目成员 + * @see https://developers.dingtalk.com/document/isvapp/add-project-members + */ + addProjectMember( + userId: string, + projectId: string, + params: AddProjectMemberParams, + ): Promise + /** + * 根据项目模板创建项目 + * @see https://developers.dingtalk.com/document/isvapp/create-a-project-from-a-project-template + */ + createProjectByTemplate( + userId: string, + params: CreateProjectByTemplateParams, + ): Promise + /** + * 查询可见的项目分组 + * @see https://developers.dingtalk.com/document/isvapp/query-available-project-groups + */ + getProjectGroup( + userId: string, + query: GetProjectGroupQuery, + ): Promise + /** + * 按项目模板名字搜索企业自定义模板 + * @see https://developers.dingtalk.com/document/isvapp/search-for-enterprise-custom-templates-by-project-template-name + */ + searchProjectTemplate( + userId: string, + query: SearchProjectTemplateQuery, + ): Promise + /** + * 创建任务关联对象 + * @see https://developers.dingtalk.com/document/isvapp/create-a-linked-object-associated-with-a-task + */ + createTaskObjectLink( + userId: string, + taskId: string, + params: CreateTaskObjectLinkParams, + ): Promise + /** + * 创建项目任务 + * @see https://developers.dingtalk.com/document/isvapp/create-a-project-task + */ + createTask( + userId: string, + params: CreateTaskParams, + ): Promise + /** + * 批量获取任务详情 + * @see https://developers.dingtalk.com/document/isvapp/obtains-details-about-multiple-free-tasks-isv + */ + getOrganizatioTaskByIds( + userId: string, + query: GetOrganizatioTaskByIdsQuery, + ): Promise + /** + * 更新自由任务优先级 + * @see https://developers.dingtalk.com/document/isvapp/update-the-priority-of-a-free-migration-job + */ + updateOrganizationTaskPriority( + taskId: string, + userId: string, + params: UpdateOrganizationTaskPriorityParams, + ): Promise + /** + * 更改自由任务备注 + * @see https://developers.dingtalk.com/document/isvapp/update-free-task-notes-isv + */ + updateOrganizationTaskNote( + taskId: string, + userId: string, + params: UpdateOrganizationTaskNoteParams, + ): Promise + /** + * 更新自由任务参与者 + * @see https://developers.dingtalk.com/document/isvapp/add-or-remove-participants-of-free-tasks + */ + updateOrganizationTaskInvolveMembers( + taskId: string, + userId: string, + params: UpdateOrganizationTaskInvolveMembersParams, + ): Promise + /** + * 更改自由任务执行者 + * @see https://developers.dingtalk.com/document/isvapp/update-free-task-executor + */ + updateOrganizationTaskExecutor( + taskId: string, + userId: string, + params: UpdateOrganizationTaskExecutorParams, + ): Promise + /** + * 更新自由任务截止时间 + * @see https://developers.dingtalk.com/document/isvapp/update-free-task-deadline + */ + updateOrganizationTaskDueDate( + taskId: string, + userId: string, + params: UpdateOrganizationTaskDueDateParams, + ): Promise + /** + * 更改自由任务标题 + * @see https://developers.dingtalk.com/document/isvapp/update-free-task-title + */ + updateOrganizationTaskContent( + taskId: string, + userId: string, + params: UpdateOrganizationTaskContentParams, + ): Promise + /** + * 更改自由任务状态 + * @see https://developers.dingtalk.com/document/isvapp/update-free-task-status + */ + updateOrganizationTaskStatus( + taskId: string, + userId: string, + params: UpdateOrganizationTaskStatusParams, + ): Promise + /** + * 获取企业优先级列表 + * @see https://developers.dingtalk.com/document/isvapp/query-a-priority-list-isv + */ + getOrganizationPriorityList( + userId: string, + ): Promise + /** + * 获取自由任务详情 + * @see https://developers.dingtalk.com/document/isvapp/queries-free-task-details-isv + */ + getOrganizationTask( + taskId: string, + userId: string, + ): Promise + /** + * 删除任务 + * @see https://developers.dingtalk.com/document/orgapp/delete-task + */ + deleteTask(userId: string, taskId: string): Promise + /** + * 创建自由任务 + * @see https://developers.dingtalk.com/document/isvapp/create-a-free-task-isv + */ + createOrganizationTask( + userId: string, + params: CreateOrganizationTaskParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/resident.ts b/adapters/dingtalk/src/api/resident.ts new file mode 100644 index 00000000..a481f0c5 --- /dev/null +++ b/adapters/dingtalk/src/api/resident.ts @@ -0,0 +1,132 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface AddPointQuery { + /** 是否查询全员圈积分规则,取值: */ + isCircle: unknown + /** 加减积分的唯一幂等标志,由调用方自己生成。 */ + uuid: string + /** 用户userid,可以调用[通过免登码获取用户信息](https://developers.dingtalk.com/document/app/obtain-the-userid-of-a-user-by-using-the-log-free)接口获取。 */ + userId: string + /** 规则代码。可以为空。 */ + ruleCode?: string + /** 规则名字。 */ + ruleName: string + /** 增加积分的时间戳,单位毫秒。 */ + actionTime?: number + /** 本次增加积分。 */ + score: number +} + +export interface PagePointHistoryQuery { + /** 是否查询全员圈积分记录,否则查询积分管理积分记录,取值: */ + isCircle: unknown + /** 用户userid。 */ + userId?: string + /** 分页游标,第一次请求传0,后续取值是上一次调用此API返回的nextToken参数。 */ + nextToken: number + /** 本次读取的最大数据记录数量,最大值20。 */ + maxResults: number + /** 起始时间Unix时间戳,单位毫秒。 */ + startTime?: number + /** 结束时间Unix时间戳(不包含),单位毫秒。 */ + endTime?: number +} + +export interface PagePointHistoryResponse { + pointRecordList: { + userId: string + score: number + createAt: number + uuid: string + ruleCode?: string + ruleName: string + }[] + hasMore: unknown + nextToken: number + totalCount: number +} + +export interface ListPointRulesQuery { + /** 是否查询全员圈积分规则,否则查询积分管理积分规则,取值: */ + isCircle: unknown +} + +export interface ListPointRulesResponse { + pointRuleList: { + score: number + dayLimitTimes: number + status: number + ruleCode?: string + ruleName: string + extension: string + groupId: number + orderId: number + }[] +} + +export interface ListIndustryRoleUsersQuery { + /** 行业角色编码,有以下取值: */ + tagCode: string +} + +export interface ListIndustryRoleUsersResponse { + userIdList?: string[] +} + +export interface ListUserIndustryRolesQuery { + /** 用户userId。 */ + userId: string +} + +export interface ListUserIndustryRolesResponse { + roleList?: { + roleId?: number + roleName?: string + tagCode?: string + }[] +} + +// funcName: isOldApi +Internal.define({ + '/resident/points': { POST: { addPoint: false } }, + '/resident/points/records': { GET: { pagePointHistory: false } }, + '/resident/points/rules': { GET: { listPointRules: false } }, + '/resident/industryRoles/users': { GET: { listIndustryRoleUsers: false } }, + '/resident/users/industryRoles': { GET: { listUserIndustryRoles: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 增加或减少居民积分 + * @see https://developers.dingtalk.com/document/isvapp/increase-or-decrease-resident-points + */ + addPoint(query: AddPointQuery): Promise + /** + * 查询数字区县居民积分流水 + * @see https://developers.dingtalk.com/document/isvapp/query-the-integral-flow-records-by-page + */ + pagePointHistory( + query: PagePointHistoryQuery, + ): Promise + /** + * 查询组织维度配置的的积分规则 + * @see https://developers.dingtalk.com/document/isvapp/query-all-credit-rules + */ + listPointRules(query: ListPointRulesQuery): Promise + /** + * 获取行业角色下的用户列表 + * @see https://developers.dingtalk.com/document/isvapp/obtains-a-list-of-users-under-an-industry-role + */ + listIndustryRoleUsers( + query: ListIndustryRoleUsersQuery, + ): Promise + /** + * 获取用户所在的行业角色信息 + * @see https://developers.dingtalk.com/document/isvapp/obtains-information-about-the-industry-role-to-which-the-user + */ + listUserIndustryRoles( + query: ListUserIndustryRolesQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/robot.ts b/adapters/dingtalk/src/api/robot.ts new file mode 100644 index 00000000..ef1b1634 --- /dev/null +++ b/adapters/dingtalk/src/api/robot.ts @@ -0,0 +1,325 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetBotListInGroupParams { + /** 群ID: */ + openConversationId: string +} + +export interface GetBotListInGroupResponse { + chatbotInstanceVOList?: { + robotCode?: string + name?: string + downloadIconURL?: string + openRobotType?: number + }[] +} + +export interface RobotMessageFileDownloadParams { + /** 用户向机器人发送文件消息后,机器人回调给开发者消息中的下载码。 */ + downloadCode: string + /** 机器人的编码: */ + robotCode: string +} + +export interface RobotMessageFileDownloadResponse { + downloadUrl: string +} + +export interface ClearRobotPluginParams { + /** 机器人的编码,参见[机器人名词表-robotCode](https://open.dingtalk.com/document/orgapp/robot-overview#title-ed9-e7b-epe)内容,获取`robotCode`。 */ + robotCode: string +} + +export interface ClearRobotPluginResponse { + result?: unknown +} + +export interface SetRobotPluginParams { + /** 机器人的编码,参见[机器人名词表-robotCode](https://open.dingtalk.com/document/orgapp/robot-overview#title-ed9-e7b-epe)内容,获取`robotCode`。 */ + robotCode?: string + /** 插件信息。 */ + pluginInfoList?: object[] +} + +export interface SetRobotPluginResponse { + result?: unknown +} + +export interface QueryRobotPluginParams { + /** 机器人的编码,参见[机器人名词表-robotCode](https://open.dingtalk.com/document/orgapp/robot-overview#title-ed9-e7b-epe)内容,获取`robotCode`。 */ + robotCode: string +} + +export interface QueryRobotPluginResponse { + pluginInfoList?: { + name?: string + icon?: string + pcUrl?: string + mobileUrl?: string + }[] +} + +export interface OrgGroupRecallParams { + /** 开放的群ID。 */ + openConversationId: string + /** 机器人的编码。 */ + robotCode: string + processQueryKeys: string[] +} + +export interface OrgGroupRecallResponse { + successResult: string[] + failedResult: unknown +} + +export interface OrgGroupQueryParams { + /** 开放的群id。 */ + openConversationId?: string + /** 机器人的robotCode。 */ + robotCode?: string + /** 机器人在群内安装后,群内机器人的webhook属性中中的access_token部分的值。 */ + token?: string + /** 发送消息返回的加密消息id。 */ + processQueryKey: string + /** 分页查询每页的数量。 */ + maxResults?: number + /** 一次查询后返回的加密的分页凭证,首次查询不填。 */ + nextToken?: string +} + +export interface OrgGroupQueryResponse { + sendStatus?: string + readUserIds?: string[] + nextToken?: string + hasMore?: unknown +} + +export interface OrgGroupSendParams { + /** 消息模板参数。 */ + msgParam: string + /** 消息模板key。 */ + msgKey: string + /** 群id: */ + openConversationId?: string + /** 机器人的编码。 */ + robotCode?: string + /** 机器人在群内安装后,群内机器人的webhook属性中中的`access_token`的参数值。 */ + token?: string + /** 群聊酷应用编码。 */ + coolAppCode?: string +} + +export interface OrgGroupSendResponse { + processQueryKey: string +} + +export interface BatchRecallOTOParams { + /** 机器人的编码。 */ + robotCode: string + processQueryKeys: string[] +} + +export interface BatchRecallOTOResponse { + successResult?: string[] + failedResult?: unknown +} + +export interface BatchOTOQueryQuery { + /** - 企业内部开发-机器人,此处为企业自建应用的appKey。 */ + robotCode: string + /** 加密的消息id,可通过调用[发送批量单聊信息](https://open.dingtalk.com/document/group/chatbots-send-one-on-one-chat-messages-in-batches)接口获取。 */ + processQueryKey: string +} + +export interface BatchOTOQueryResponse { + sendStatus?: string + messageReadInfoList?: { + name: string + userId: string + readStatus: string + readTimestamp: number + }[] +} + +export interface BatchSendOTOParams { + /** 机器人的编码。 */ + robotCode: string + /** 用户的userid。 */ + userIds: string[] + /** 消息的msgKey。 */ + msgKey: string + /** 消息体。 */ + msgParam: string +} + +export interface BatchSendOTOResponse { + processQueryKey?: string + invalidStaffIdList?: string[] + flowControlledStaffIdList?: string[] +} + +export interface PrivateChatSendParams { + /** 消息体。 */ + msgParam: string + /** 消息类型的key。 */ + msgKey: string + /** 会话ID。 */ + openConversationId?: string + /** 机器人编码。 */ + robotCode?: string + /** 酷应用的code。 */ + coolAppCode?: string +} + +export interface PrivateChatSendResponse { + processQueryKey: string +} + +export interface PrivateChatQueryParams { + /** 人与人单聊开放会话ID: */ + openConversationId?: string + /** 机器人的编码,参见[机器人名词表-robotCode](https://open.dingtalk.com/document/group/robot-overview)内容,获取`robotCode`。 */ + robotCode?: string + /** 发送消息返回的加密消息id */ + processQueryKey: string + /** 分页查询每页的数量 */ + maxResults?: number + /** 一次查询后返回的加密的分页凭证,首次查询不填 */ + nextToken?: string +} + +export interface PrivateChatQueryResponse { + sendStatus?: string + readUserIds?: string[] + nextToken?: string + hasMore?: unknown +} + +export interface BatchRecallPrivateChatParams { + /** 人与人单聊开放会话ID: */ + openConversationId: string + /** 机器人的编码,参见[机器人名词表-robotCode](https://open.dingtalk.com/document/group/robot-overview)内容,获取`robotCode`。 */ + robotCode: string + /** 消息id */ + processQueryKeys: string[] +} + +export interface BatchRecallPrivateChatResponse { + successResult: string[] + failedResult: unknown +} + +// funcName: isOldApi +Internal.define({ + '/robot/groups/robots/query': { POST: { getBotListInGroup: false } }, + '/robot/messageFiles/download': { POST: { robotMessageFileDownload: false } }, + '/robot/plugins/clear': { POST: { clearRobotPlugin: false } }, + '/robot/plugins/set': { POST: { setRobotPlugin: false } }, + '/robot/plugins/query': { POST: { queryRobotPlugin: false } }, + '/robot/groupMessages/recall': { POST: { orgGroupRecall: false } }, + '/robot/groupMessages/query': { POST: { orgGroupQuery: false } }, + '/robot/groupMessages/send': { POST: { orgGroupSend: false } }, + '/robot/otoMessages/batchRecall': { POST: { batchRecallOTO: false } }, + '/robot/oToMessages/readStatus': { GET: { batchOTOQuery: false } }, + '/robot/oToMessages/batchSend': { POST: { batchSendOTO: false } }, + '/robot/privateChatMessages/send': { POST: { privateChatSend: false } }, + '/robot/privateChatMessages/query': { POST: { privateChatQuery: false } }, + '/robot/privateChatMessages/batchRecall': { + POST: { batchRecallPrivateChat: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 查询群内的机器人列表 + * @see https://developers.dingtalk.com/document/orgapp/obtain-the-list-of-robots-in-the-group + */ + getBotListInGroup( + params: GetBotListInGroupParams, + ): Promise + /** + * 获取机器人消息中文件下载链接 + * @see https://developers.dingtalk.com/document/isvapp/download-the-file-content-of-the-robot-receiving-message + */ + robotMessageFileDownload( + params: RobotMessageFileDownloadParams, + ): Promise + /** + * 清空单聊机器人快捷入口 + * @see https://developers.dingtalk.com/document/orgapp/clear-single-chat-robot-quick-entry + */ + clearRobotPlugin( + params: ClearRobotPluginParams, + ): Promise + /** + * 设置单聊机器人快捷入口 + * @see https://developers.dingtalk.com/document/orgapp/set-robot-quick-entrance + */ + setRobotPlugin( + params: SetRobotPluginParams, + ): Promise + /** + * 查询单聊机器人快捷入口 + * @see https://developers.dingtalk.com/document/orgapp/quick-entrance-of-inquiry-single-chat-robot + */ + queryRobotPlugin( + params: QueryRobotPluginParams, + ): Promise + /** + * 企业机器人撤回内部群消息 + * @see https://developers.dingtalk.com/document/orgapp/enterprise-chatbot-withdraws-internal-group-messages + */ + orgGroupRecall( + params: OrgGroupRecallParams, + ): Promise + /** + * 查询企业机器人群聊消息用户已读状态 + * @see https://developers.dingtalk.com/document/orgapp/chatbot-queries-the-read-status-of-a-message + */ + orgGroupQuery(params: OrgGroupQueryParams): Promise + /** + * 机器人发送群聊消息 + * @see https://developers.dingtalk.com/document/orgapp/the-robot-sends-a-group-message + */ + orgGroupSend(params: OrgGroupSendParams): Promise + /** + * 批量撤回人与机器人会话中机器人消息 + * @see https://developers.dingtalk.com/document/orgapp/batch-message-recall-chat + */ + batchRecallOTO( + params: BatchRecallOTOParams, + ): Promise + /** + * 批量查询人与机器人会话机器人消息是否已读 + * @see https://developers.dingtalk.com/document/orgapp/chatbot-batch-query-the-read-status-of-messages + */ + batchOTOQuery(query: BatchOTOQueryQuery): Promise + /** + * 批量发送人与机器人会话中机器人消息 + * @see https://developers.dingtalk.com/document/orgapp/chatbots-send-one-on-one-chat-messages-in-batches + */ + batchSendOTO(params: BatchSendOTOParams): Promise + /** + * 人与人会话中机器人发送普通消息 + * @see https://developers.dingtalk.com/document/orgapp/the-robot-sends-ordinary-messages-in-a-person-to-person-conversation + */ + privateChatSend( + params: PrivateChatSendParams, + ): Promise + /** + * 查询人与人会话中机器人已读消息 + * @see https://developers.dingtalk.com/document/orgapp/query-the-read-list-of-robot-messages-in-person-to-person-conversations + */ + privateChatQuery( + params: PrivateChatQueryParams, + ): Promise + /** + * 批量撤回人与人会话中机器人消息 + * @see https://developers.dingtalk.com/document/orgapp/batch-withdrawal-of-single-chat-robot-messages-in-person-to-person-conversations + */ + batchRecallPrivateChat( + params: BatchRecallPrivateChatParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/rooms.ts b/adapters/dingtalk/src/api/rooms.ts new file mode 100644 index 00000000..b42ac973 --- /dev/null +++ b/adapters/dingtalk/src/api/rooms.ts @@ -0,0 +1,333 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface QueryDevicePropertiesParams { + /** 设备属性名称列表,最大值10。 */ + propertyNames?: string[] +} + +export interface QueryDevicePropertiesQuery { + /** 操作查询的人员unionId,可调用[查询用户详情](https://open.dingtalk.com/document/orgapp/query-user-details)接口获取。 */ + operatorUnionId: string + /** 需要查询的设备ID,该参数可从订阅[设备绑定会议室变更](https://open.dingtalk.com/document/orgapp/device-binding-meeting-room-change-event)事件中获取。 */ + deviceId?: string + /** 需要查询的设备unionId,该参数可从订阅[设备绑定会议室变更](https://open.dingtalk.com/document/orgapp/device-binding-meeting-room-change-event)事件中获取。 */ + deviceUnionId?: string +} + +export interface QueryDevicePropertiesResponse { + result?: { + propertyName?: string + propertyValue?: string + }[] +} + +export interface QueryMeetingRoomDeviceQuery { + /** 操作查询的人员unionId,可调用[查询用户详情](https://open.dingtalk.com/document/orgapp/query-user-details)接口获取。 */ + operatorUnionId: string + /** 需要查询的设备ID,该参数从订阅[设备绑定会议室变更](https://open.dingtalk.com/document/orgapp/device-binding-meeting-room-change-event)事件中获取。 */ + deviceId?: string + /** 需要查询的设备unionId,该参数从订阅[设备绑定会议室变更](https://open.dingtalk.com/document/orgapp/device-binding-meeting-room-change-event)事件中获取。 */ + deviceUnionId?: string +} + +export interface QueryMeetingRoomDeviceResponse { + result?: { + deviceId?: string + deviceUnionId?: string + openRoomId?: string + corpId?: string + deviceName?: string + shareCode?: string + deviceSn?: string + deviceMac?: string + deviceType?: string + deviceServiceId?: number + deviceModel?: string + deviceStatus?: string + controllers?: number + } +} + +export interface DeleteMeetingRoomGroupQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface DeleteMeetingRoomGroupResponse { + result?: unknown +} + +export interface UpdateMeetingRoomGroupParams { + /** 操作人的unionId。 */ + unionId: string + /** 修改后的分组名称。 */ + groupName?: string + /** 分组ID。 */ + groupId: number +} + +export interface UpdateMeetingRoomGroupResponse { + result?: unknown +} + +export interface QueryMeetingRoomGroupListQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface QueryMeetingRoomGroupListResponse { + result?: { + groupId?: number + groupName?: string + parentId?: number + }[] +} + +export interface QueryMeetingRoomGroupQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface QueryMeetingRoomGroupResponse { + groupId?: number + groupName?: string + parentId?: number +} + +export interface CreateMeetingRoomGroupParams { + /** 操作人的unionId。 */ + unionId: string + /** 分组名称。 */ + groupName?: string + /** 父分组ID,传0表示根分组。 */ + parentGroupId: number +} + +export interface CreateMeetingRoomGroupResponse { + result?: number +} + +export interface DeleteMeetingRoomQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface DeleteMeetingRoomResponse { + result?: unknown +} + +export interface QueryMeetingRoomListQuery { + /** 分页游标。 */ + nextToken?: number + /** 请求分页大小,默认值20,目前未限制最大值。 */ + maxResults?: number + /** 操作人的unionId。 */ + unionId: string +} + +export interface QueryMeetingRoomListResponse { + hasMore?: unknown + nextToken?: number + result?: { + roomId?: string + roomStaffId?: string + corpId?: string + roomName?: string + roomStatus?: number + roomLabels?: number + roomCapacity?: number + roomLocation?: number + roomPicture?: string + isvRoomId?: string + roomGroup?: number + }[] +} + +export interface UpdateMeetingRoomParams { + /** 操作人的unionId。 */ + unionId: string + /** 会议室ID。 */ + roomId: string + /** 会议室名称。 */ + roomName?: string + /** 会议室可容纳人数。 */ + roomCapacity?: number + /** 会议室图片。 */ + roomPicture?: string + /** 会议室状态。 */ + roomStatus?: number + /** 会议室位置信息。 */ + roomLocation?: unknown + /** 标签ID。 */ + roomLabelIds?: number[] + /** 调用方外部会议室ID,调用方可传入自有系统内的会议室ID。 */ + isvRoomId?: string + /** 会议室所属分组ID。 */ + groupId?: number +} + +export interface UpdateMeetingRoomResponse { + result?: unknown +} + +export interface QueryMeetingRoomQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface QueryMeetingRoomResponse { + result?: { + roomId?: string + roomStaffId?: string + corpId?: string + roomName?: string + roomStatus?: number + roomLabels?: number + roomCapacity?: number + roomLocation?: number + roomPicture?: string + isvRoomId?: string + roomGroup?: number + } +} + +export interface CreateMeetingRoomParams { + /** 操作人的unionId。 */ + unionId: string + /** 会议室名称。 */ + roomName: string + /** 会议室可容纳人数,目前无最大值限制。 */ + roomCapacity?: number + /** 会议室图片。 */ + roomPicture?: string + /** 会议室状态。 */ + roomStatus: number + /** 会议室位置信息。 */ + roomLocation?: unknown + /** 标签ID。 */ + roomLabelIds?: number[] + /** 调用方外部会议室ID,调用方可传入自有系统内的会议室ID。 */ + isvRoomId: string + /** 分组ID。 */ + groupId?: number +} + +export interface CreateMeetingRoomResponse { + result?: string +} + +// funcName: isOldApi +Internal.define({ + '/rooms/devices/properties/query': { POST: { queryDeviceProperties: false } }, + '/rooms/devices': { GET: { queryMeetingRoomDevice: false } }, + '/rooms/groups/{groupId}': { + DELETE: { deleteMeetingRoomGroup: false }, + GET: { queryMeetingRoomGroup: false }, + }, + '/rooms/groups': { + PUT: { updateMeetingRoomGroup: false }, + POST: { createMeetingRoomGroup: false }, + }, + '/rooms/groupLists': { GET: { queryMeetingRoomGroupList: false } }, + '/rooms/meetingRooms/{roomId}': { + DELETE: { deleteMeetingRoom: false }, + GET: { queryMeetingRoom: false }, + }, + '/rooms/meetingRoomLists': { GET: { queryMeetingRoomList: false } }, + '/rooms/meetingRooms': { PUT: { updateMeetingRoom: false } }, + '/rooms/meetingrooms': { POST: { createMeetingRoom: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 查询设备属性 + * @see https://developers.dingtalk.com/document/app/querying-video-conference-device-attribute-information + */ + queryDeviceProperties( + query: QueryDevicePropertiesQuery, + params: QueryDevicePropertiesParams, + ): Promise + /** + * 查询设备信息 + * @see https://developers.dingtalk.com/document/app/querying-video-conference-device-information + */ + queryMeetingRoomDevice( + query: QueryMeetingRoomDeviceQuery, + ): Promise + /** + * 删除会议室分组 + * @see https://developers.dingtalk.com/document/isvapp/delete-a-conference-room-group + */ + deleteMeetingRoomGroup( + groupId: number, + query: DeleteMeetingRoomGroupQuery, + ): Promise + /** + * 更新会议室分组信息 + * @see https://developers.dingtalk.com/document/isvapp/update-meeting-room-group-information + */ + updateMeetingRoomGroup( + params: UpdateMeetingRoomGroupParams, + ): Promise + /** + * 查询会议室分组列表 + * @see https://developers.dingtalk.com/document/isvapp/query-meeting-room-groups + */ + queryMeetingRoomGroupList( + query: QueryMeetingRoomGroupListQuery, + ): Promise + /** + * 查询会议室分组信息 + * @see https://developers.dingtalk.com/document/isvapp/query-meeting-room-group-information + */ + queryMeetingRoomGroup( + groupId: number, + query: QueryMeetingRoomGroupQuery, + ): Promise + /** + * 创建会议室分组 + * @see https://developers.dingtalk.com/document/isvapp/create-a-meeting-room-group + */ + createMeetingRoomGroup( + params: CreateMeetingRoomGroupParams, + ): Promise + /** + * 删除会议室 + * @see https://developers.dingtalk.com/document/isvapp/delete-a-meeting-room + */ + deleteMeetingRoom( + roomId: string, + query: DeleteMeetingRoomQuery, + ): Promise + /** + * 查询会议室列表 + * @see https://developers.dingtalk.com/document/isvapp/check-the-meeting-room-list + */ + queryMeetingRoomList( + query: QueryMeetingRoomListQuery, + ): Promise + /** + * 更新会议室信息 + * @see https://developers.dingtalk.com/document/isvapp/update-meeting-room-information + */ + updateMeetingRoom( + params: UpdateMeetingRoomParams, + ): Promise + /** + * 查询会议室详情 + * @see https://developers.dingtalk.com/document/isvapp/check-meeting-room-details + */ + queryMeetingRoom( + roomId: string, + query: QueryMeetingRoomQuery, + ): Promise + /** + * 创建智能会议室 + * @see https://developers.dingtalk.com/document/isvapp/create-a-meeting-room + */ + createMeetingRoom( + params: CreateMeetingRoomParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/serviceGroup.ts b/adapters/dingtalk/src/api/serviceGroup.ts new file mode 100644 index 00000000..24edde77 --- /dev/null +++ b/adapters/dingtalk/src/api/serviceGroup.ts @@ -0,0 +1,215 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface AddMemberToServiceGroupParams { + /** 开放团队ID。如下图所示,查看**ID信息**内的**团队ID**值。 */ + openTeamId: string + /** 服务群openConversionId,调用[创建场景服务群](https://open.dingtalk.com/document/orgapp-server/create-a-scenario-service-group)接口获取openConversationId参数值。 */ + openConversationId: string + /** 待添加员工在钉钉组织内的的userId列表,最大值100。 */ + userIds: string[] +} + +export interface AddMemberToServiceGroupResponse { + success?: unknown +} + +export interface SendMsgByTaskParams { + /** 团队ID。 */ + openTeamId: string + /** 群发任务名称。 */ + taskName: string + /** 群发内容。 */ + messageContent: unknown + /** 查询条件。 */ + queryGroup: unknown + /** 发送配置。 */ + sendConfig: unknown +} + +export interface SendMsgByTaskResponse { + openBatchTaskId?: string +} + +export interface UpgradeNormalGroupParams { + /** 升级的目标群组ID。 */ + openGroupSetId?: string + /** 升级的目标群模板ID。 */ + templateId?: string + /** 群ID。 */ + openConversationId: string + /** 升级的目标团队ID。 */ + openTeamId?: string +} + +export interface UpgradeCloudGroupParams { + /** 群ID。 */ + openConversationId: string + /** 升级的目标群模板ID。 */ + templateId?: string + /** 升级的目标群组ID。 */ + openGroupSetId?: string + /** 智能云客服租户ID。 */ + ccsInstanceId: string + /** 升级的目标团队ID。 */ + openTeamId?: string +} + +export interface QueryActiveUsersQuery { + /** 开放团队ID。 */ + openTeamId?: string + /** 群ID。 */ + openConversationId: string + /** 活跃度排名topN,如top5,最多支持top100 */ + topN?: number +} + +export interface QueryActiveUsersResponse { + activeUserInfos: { + unionId: string + nickName: string + actionIndexL7d: number + actionIndexL14d: number + actionIndexL30d: number + activeScore: number + ranking: number + }[] +} + +export interface SendServiceGroupMessageParams { + /** 开放群ID。 */ + targetOpenConversationId: string + /** 标题。 */ + title: string + /** 消息内容。 */ + content: string + /** 是否 at所有人 */ + isAtAll?: unknown + /** 被@人的手机号列表。 */ + atMobiles?: string[] + /** 被@人的dingtalkId列表。 */ + atDingtalkIds?: string[] + /** 被@人的unionId列表。 */ + atUnionIds?: string[] + /** 手机号接收者列表。 */ + receiverMobiles?: string[] + /** dingtalkId接收者列表。 */ + receiverDingtalkIds?: string[] + /** unionId接收者列表。 */ + receiverUnionIds?: string[] + /** 消息类型,取值。 */ + messageType: string + /** 排列方式。 */ + btnOrientation?: string + /** actionCard按钮。 */ + btns?: object[] + /** 消息内容是否含有链接。 */ + hasContentLinks?: unknown +} + +export interface SendServiceGroupMessageResponse { + openMsgTaskId: string +} + +export interface ServiceGroupCreateGroupParams { + /** 业务关联ID,自定义参数值。 */ + groupBizId?: string + /** 开放团队ID。 */ + openTeamId: string + /** 开放群组ID。 */ + openGroupSetId: string + /** 群名称。 */ + groupName: string + /** 群主员工userid。 */ + ownerStaffId: string + /** 群成员员工ID列表,最大值20。 */ + memberStaffIds?: string[] + /** 群标签。 */ + groupTagNames?: string[] +} + +export interface ServiceGroupCreateGroupResponse { + openConversationId: string + groupUrl: string +} + +export interface ServiceGroupUpdateGroupSetParams { + /** 开放团队ID。 */ + openTeamId?: string + /** 开放群ID,可调用[创建服务群](https://open.dingtalk.com/document/orgapp-server/create-a-scenario-service-group)接口获取openConversationId参数值。 */ + openConversationId?: string + /** 开放群组ID。 */ + openGroupSetId?: string +} + +export interface ServiceGroupUpdateGroupSetResponse { + success?: unknown +} + +// funcName: isOldApi +Internal.define({ + '/serviceGroup/groups/members': { POST: { addMemberToServiceGroup: false } }, + '/serviceGroup/messages/tasks/send': { POST: { sendMsgByTask: false } }, + '/serviceGroup/normalGroups/upgrade': { POST: { upgradeNormalGroup: false } }, + '/serviceGroup/cloudGroups/upgrade': { POST: { upgradeCloudGroup: false } }, + '/serviceGroup/groups/queryActiveUsers': { GET: { queryActiveUsers: false } }, + '/serviceGroup/messages/send': { POST: { sendServiceGroupMessage: false } }, + '/serviceGroup/groups': { POST: { serviceGroupCreateGroup: false } }, + '/serviceGroup/groups/configurations': { + PUT: { serviceGroupUpdateGroupSet: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 添加服务群成员 + * @see https://developers.dingtalk.com/document/orgapp/add-service-group-members + */ + addMemberToServiceGroup( + params: AddMemberToServiceGroupParams, + ): Promise + /** + * 服务群发任务 + * @see https://developers.dingtalk.com/document/orgapp/service-group-sending-task-interface + */ + sendMsgByTask(params: SendMsgByTaskParams): Promise + /** + * 升级普通群为服务群 + * @see https://developers.dingtalk.com/document/orgapp/a-dingtalk-group-is-upgraded-to-one-of-the-intelligent + */ + upgradeNormalGroup(params: UpgradeNormalGroupParams): Promise + /** + * 升级云客服服务群为钉钉智能服务群 + * @see https://developers.dingtalk.com/document/orgapp/upgraded-the-cloud-customer-service-group-to-the-dingtalk-intelligent + */ + upgradeCloudGroup(params: UpgradeCloudGroupParams): Promise + /** + * 查询服务群活跃成员 + * @see https://developers.dingtalk.com/document/orgapp/queries-active-service-users + */ + queryActiveUsers( + query: QueryActiveUsersQuery, + ): Promise + /** + * 服务群发消息 + * @see https://developers.dingtalk.com/document/orgapp/service-group-message-sending-interface + */ + sendServiceGroupMessage( + params: SendServiceGroupMessageParams, + ): Promise + /** + * 创建服务群 + * @see https://developers.dingtalk.com/document/orgapp/create-a-scenario-service-group + */ + serviceGroupCreateGroup( + params: ServiceGroupCreateGroupParams, + ): Promise + /** + * 更换服务群所在的群分组 + * @see https://developers.dingtalk.com/document/isvapp/modify-a-service-group + */ + serviceGroupUpdateGroupSet( + params: ServiceGroupUpdateGroupSetParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/storage.ts b/adapters/dingtalk/src/api/storage.ts new file mode 100644 index 00000000..abfe2935 --- /dev/null +++ b/adapters/dingtalk/src/api/storage.ts @@ -0,0 +1,1700 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface SearchWorkspacesParams { + /** 搜索关键词。 */ + keyword: string + /** 可选参数。 */ + option?: unknown +} + +export interface SearchWorkspacesQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface SearchWorkspacesResponse { + items?: { + workspaceId?: string + name?: string + url?: string + }[] + nextToken?: string +} + +export interface SetPermissionInheritanceParams { + /** 权限继承模式,枚举值: */ + inheritance: string +} + +export interface SetPermissionInheritanceQuery { + /** 用户unionId。 */ + unionId: string +} + +export interface SetPermissionInheritanceResponse { + success?: unknown +} + +export interface GetPermissionInheritanceQuery { + /** 用户unionId。 */ + unionId: string +} + +export interface GetPermissionInheritanceResponse { + inheritance?: string +} + +export interface StorageUpdatePermissionParams { + /** 角色id,枚举值: */ + roleId: string + /** 权限成员。 */ + members: object[] + /** 可选参数。 */ + option?: unknown +} + +export interface StorageUpdatePermissionQuery { + /** 用户unionId。 */ + unionId: string +} + +export interface StorageUpdatePermissionResponse { + success?: unknown +} + +export interface StorageDeletePermissionParams { + /** 角色id,枚举值: */ + roleId: string + /** 权限成员。 */ + members: object[] +} + +export interface StorageDeletePermissionQuery { + /** 用户unionId。 */ + unionId: string +} + +export interface StorageDeletePermissionResponse { + success?: unknown +} + +export interface StorageAddPermissionParams { + /** 角色id,枚举值: */ + roleId: string + /** 权限成员。 */ + members: object[] + /** 可选参数。 */ + option?: unknown +} + +export interface StorageAddPermissionQuery { + /** 用户id */ + unionId: string +} + +export interface StorageAddPermissionResponse { + success?: unknown +} + +export interface ListPermissionsOrgParams { + /** 可选参数。 */ + option?: unknown +} + +export interface ListPermissionsOrgQuery { + /** 用户unionId。 */ + unionId: string +} + +export interface ListPermissionsOrgResponse { + permissions?: { + dentryUuid?: string + member?: number + role?: number + duration?: number + }[] + nextToken?: string +} + +export interface SearchDentriesParams { + /** 搜索关键词。 */ + keyword: string + /** 可选参数。 */ + option?: unknown +} + +export interface SearchDentriesQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface SearchDentriesResponse { + items?: { + dentryUuid?: string + name?: string + creator?: number + modifier?: number + }[] + nextToken?: string +} + +export interface StorageCommitFileParams { + /** 添加文件唯一标识,可通过DentryService.getUploadInfo来生成。 */ + uploadKey: string + /** 名称(文件名+后缀), 规则: */ + name: string + /** 可选参数 */ + option?: unknown +} + +export interface StorageCommitFileQuery { + /** 用户unionId。 */ + unionId: string +} + +export interface StorageCommitFileResponse { + dentry?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + thumbnail?: number + category?: string + } +} + +export interface StorageGetFileUploadInfoParams { + /** 通过指定上传协议返回不同协议上传所需要的信息 */ + protocol: string + /** 可选参数 */ + option?: unknown +} + +export interface StorageGetFileUploadInfoQuery { + /** 用户id */ + unionId: string +} + +export interface StorageGetFileUploadInfoResponse { + uploadKey?: string + storageDriver?: string + protocol?: string + headerSignatureInfo?: { + resourceUrls?: number + headers?: number + expirationSeconds?: number + region?: string + internalResourceUrls?: number + } +} + +export interface UnsubscribeEventParams { + /** 订阅范围对应的id */ + scopeId: string + /** 订阅范围 */ + scope: string +} + +export interface UnsubscribeEventQuery { + /** 用户id */ + unionId: string +} + +export interface UnsubscribeEventResponse { + success?: unknown +} + +export interface ListAllDentriesParams { + /** 可选参数。 */ + option?: unknown +} + +export interface ListAllDentriesQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface ListAllDentriesResponse { + dentries?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + thumbnail?: number + }[] + nextToken?: string +} + +export interface GetDentriesParams { + /** 文件或文件夹的ID列表,最大值30。 */ + dentryIds: string[] + /** 可选参数。 */ + option?: unknown +} + +export interface GetDentriesQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface GetDentriesResponse { + resultItems?: { + spaceId?: string + dentryId?: string + success?: number + errorCode?: string + dentry?: number + }[] +} + +export interface GetDentryThumbnailsParams { + /** 文件ID,最大值30。 */ + dentryIds: string[] +} + +export interface GetDentryThumbnailsQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface GetDentryThumbnailsResponse { + resultItems?: { + spaceId?: string + dentryId?: string + success?: number + errorCode?: string + thumbnail?: number + }[] +} + +export interface MoveDentriesParams { + /** 目标空间ID。 */ + targetSpaceId: string + /** 目标文件夹id, 根目录id值为0。 */ + targetFolderId: string + /** 源文件或文件夹的ID列表,最大值30。 */ + dentryIds: string[] + /** 可选参数。 */ + option?: unknown +} + +export interface MoveDentriesQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface MoveDentriesResponse { + resultItems?: { + spaceId?: string + dentryId?: string + async?: number + success?: number + errorCode?: string + taskId?: string + targetSpaceId?: string + targetDentryId?: string + }[] +} + +export interface CopyDentriesParams { + /** 目标文件或文件夹所在的空间ID。 */ + targetSpaceId: string + /** 目标文件夹ID, 根目录ID值为0。 */ + targetFolderId: string + /** 源文件或文件夹的ID列表,最大值30。 */ + dentryIds: string[] + /** 可选参数。 */ + option?: unknown +} + +export interface CopyDentriesQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface CopyDentriesResponse { + resultItems?: { + spaceId?: string + dentryId?: string + async?: number + success?: number + errorCode?: string + taskId?: string + targetSpaceId?: string + targetDentryId?: string + }[] +} + +export interface DeleteDentriesParams { + /** 文件或文件夹ID列表,最大值50。 */ + dentryIds: string[] + /** 可选参数。 */ + option?: unknown +} + +export interface DeleteDentriesQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface DeleteDentriesResponse { + resultItems?: { + spaceId?: string + dentryId?: string + async?: number + success?: number + errorCode?: string + taskId?: string + }[] +} + +export interface GetTaskQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface GetTaskResponse { + task?: { + id?: string + status?: string + totalCount?: number + successCount?: number + failCount?: number + failMessage?: string + beginTime?: string + endTime?: string + } +} + +export interface InitMultipartFileUploadParams { + /** 可选参数。 */ + option?: unknown +} + +export interface InitMultipartFileUploadQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface InitMultipartFileUploadResponse { + uploadKey?: string + storageDriver?: string +} + +export interface GetMultipartFileUploadInfosParams { + /** 上传唯一标识。 */ + uploadKey: string + /** 每片文件的Id,文件的分片数量最大值10000,每片文件大小限制范围是100KB~5GB,最多传30。 */ + partNumbers: number[] + /** 可选参数。 */ + option?: unknown +} + +export interface GetMultipartFileUploadInfosQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface GetMultipartFileUploadInfosResponse { + multipartHeaderSignatureInfos?: { + partNumber?: number + headerSignatureInfo?: number + }[] +} + +export interface GetOrgQuery { + /** 用户unionId。 */ + unionId: string +} + +export interface GetOrgResponse { + org?: { + corpId?: string + partitions?: number + } +} + +export interface RestoreRecycleItemParams { + /** 可选参数。 */ + option?: unknown +} + +export interface RestoreRecycleItemQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface RestoreRecycleItemResponse { + async?: unknown + taskId?: string + spaceId?: string + dentryId?: string +} + +export interface GetRecycleBinQuery { + /** 回收站范围类型。 */ + recycleBinScope: string + /** 回收站范围Id。 */ + scopeId: string + /** 操作者unionId。 */ + unionId: string +} + +export interface GetRecycleBinResponse { + recycleBin?: { + id?: string + scope?: string + scopeId?: string + } +} + +export interface GetRecycleItemQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface GetRecycleItemResponse { + item?: { + id?: string + spaceId?: string + dentryId?: string + size?: number + type?: string + originalName?: string + originalPath?: string + operatorId?: string + operatorTime?: string + } +} + +export interface DeleteRecycleItemQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface DeleteRecycleItemResponse { + success?: unknown +} + +export interface ClearRecycleBinQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface ClearRecycleBinResponse { + success?: unknown +} + +export interface DeleteRecycleItemsParams { + /** 回收项Id列表,最大值50。 */ + recycleItemIds: string[] +} + +export interface DeleteRecycleItemsQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface DeleteRecycleItemsResponse { + success?: unknown +} + +export interface RestoreRecycleItemsParams { + /** 回收项ID列表,最大值30。 */ + recycleItemIds: string[] + /** 可选参数。 */ + option?: unknown +} + +export interface RestoreRecycleItemsQuery { + /** 操作人的unionId。 */ + unionId: string +} + +export interface RestoreRecycleItemsResponse { + resultItems?: { + recycleBinId?: string + recycleItemId?: string + async?: number + success?: number + errorCode?: string + taskId?: string + spaceId?: string + dentryId?: string + }[] +} + +export interface ListDentryVersionsQuery { + /** 分页游标。 */ + nextToken?: string + /** 每页条目数,默认100,最大100。 */ + maxResults?: number + /** 操作者unionId。 */ + unionId: string +} + +export interface ListDentryVersionsResponse { + dentries?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + }[] + nextToken?: string +} + +export interface GetDentryOpenInfoParams { + /** 可选参数。 */ + option?: unknown +} + +export interface GetDentryOpenInfoQuery { + /** 操作用户unionId。 */ + unionId: string +} + +export interface GetDentryOpenInfoResponse { + url?: string + hasWaterMark?: unknown +} + +export interface MoveDentryParams { + /** 需要存放的目标空间Id。 */ + targetSpaceId: string + /** 需要存放的位置父目录Id。根目录时,该参数是0。 */ + targetFolderId: string + /** 可选参数。 */ + option?: unknown +} + +export interface MoveDentryQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface MoveDentryResponse { + dentry?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + } + async?: unknown + taskId?: string +} + +export interface ListPermissionsIsvParams { + /** 可选参数。 */ + option?: unknown +} + +export interface ListPermissionsIsvQuery { + /** 操作者的unionId。 */ + unionId: string +} + +export interface ListPermissionsIsvResponse { + permissions?: { + spaceId?: string + dentryId?: string + member?: number + role?: number + duration?: number + createTime?: string + modifiedTime?: string + operatorId?: string + }[] + nextToken?: string +} + +export interface GetFileDownloadInfoParams { + /** 可选参数。 */ + option?: unknown +} + +export interface GetFileDownloadInfoQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface GetFileDownloadInfoResponse { + protocol?: string + headerSignatureInfo?: { + resourceUrls?: number + headers?: number + expirationSeconds?: number + region?: string + internalResourceUrls?: number + } +} + +export interface ListRecycleItemsQuery { + /** 分页游标。 */ + nextToken?: string + /** 每页最大条目数,默认值50,最大值50。 */ + maxResults?: number + /** 操作者unionId。 */ + unionId: string +} + +export interface ListRecycleItemsResponse { + recycleItems?: { + id?: string + spaceId?: string + dentryId?: string + size?: number + type?: string + originalName?: string + originalPath?: string + operatorId?: string + operatorTime?: string + }[] + nextToken?: string +} + +export interface DeleteDentryQuery { + /** 删除后,是否备份到回收站。 */ + toRecycleBin?: unknown + /** 操作者unionId。 */ + unionId: string +} + +export interface DeleteDentryResponse { + async?: unknown + taskId?: string +} + +export interface RenameDentryParams { + /** 文件或文件夹的新名称,命名规则如下: */ + newName: string +} + +export interface RenameDentryQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface RenameDentryResponse { + dentry?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + } +} + +export interface ListDentriesQuery { + /** 父目录Id。根目录时,该参数是0。 */ + parentId: string + /** 分页游标。 */ + nextToken?: string + /** 每页条目数,最大值50。 */ + maxResults?: number + /** 排序字段。 */ + orderBy?: string + /** 排序规则。 */ + order?: string + /** 是否获取文件缩略图临时链接。按需获取,会影响接口耗时。 */ + withThumbnail?: unknown + /** 操作者的unionId。 */ + unionId: string +} + +export interface ListDentriesResponse { + dentries?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + thumbnail?: number + }[] + nextToken?: string +} + +export interface RevertDentryVersionQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface RevertDentryVersionResponse { + success?: unknown +} + +export interface CopyDentryParams { + /** 需要存放的目标空间Id。 */ + targetSpaceId: string + /** 需要存放的位置父目录Id。 */ + targetFolderId: string + /** 可选参数。 */ + option?: unknown +} + +export interface CopyDentryQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface CopyDentryResponse { + dentry?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + } + async?: unknown + taskId?: string +} + +export interface GetCurrentAppQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface GetCurrentAppResponse { + app?: { + corpId?: string + appId?: string + name?: string + createTime?: string + modifiedTime?: string + partitions?: number + } +} + +export interface StorageGetSpaceQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface StorageGetSpaceResponse { + space?: { + id?: string + corpId?: string + creatorId?: string + ownerType?: string + ownerId?: string + modifierId?: string + usedQuota?: number + quota?: number + status?: string + createTime?: string + modifiedTime?: string + appId?: string + scene?: string + sceneId?: string + capabilities?: number + name?: string + partitions?: number + } +} + +export interface AddFolderParams { + /** 文件夹的名称,命名有以下要求: */ + name: string + /** 可选参数。 */ + option?: unknown +} + +export interface AddFolderQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface AddFolderResponse { + dentry?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + } +} + +export interface GetDentryParams { + /** 可选参数。 */ + option?: unknown +} + +export interface GetDentryQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface GetDentryResponse { + dentry?: { + id?: string + spaceId?: string + parentId?: string + type?: string + name?: string + size?: number + path?: string + version?: number + status?: string + extension?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + properties?: number + appProperties?: number + uuid?: string + partitionType?: string + storageDriver?: string + thumbnail?: number + } +} + +export interface DeleteDentryAppPropertiesParams { + /** 文件或文件夹的应用属性名称列表,最大值3。 */ + propertyNames: string[] +} + +export interface DeleteDentryAppPropertiesQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface DeleteDentryAppPropertiesResponse { + success?: unknown +} + +export interface UpdateDentryAppPropertiesParams { + /** 应用属性列表,最大值3。 */ + appProperties: object[] +} + +export interface UpdateDentryAppPropertiesQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface UpdateDentryAppPropertiesResponse { + success?: unknown +} + +export interface StorageCommitFileParams { + /** 添加文件唯一标识。 */ + uploadKey: string + /** 文件的名称,带后缀。命名有以下要求: */ + name: string + /** 父目录Id。根目录时,该参数是0。 */ + parentId: string + /** 可选参数。 */ + option?: unknown +} + +export interface StorageCommitFileQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface StorageGetFileUploadInfoParams { + /** 通过指定上传协议返回不同协议上传所需要的信息。 */ + protocol: string + /** 是否需要分片上传。 */ + multipart: unknown + /** 可选参数。 */ + option?: unknown +} + +export interface StorageGetFileUploadInfoQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface StorageGetFileUploadInfoResponse { + uploadKey?: string + storageDriver?: string + protocol?: string + headerSignatureInfo?: { + resourceUrls?: number + headers?: number + expirationSeconds?: number + region?: string + internalResourceUrls?: number + } +} + +export interface StorageUpdatePermissionParams { + /** 权限角色Id。 */ + roleId: string + /** 权限成员信息。 */ + members: object[] + /** 可选参数。 */ + option?: unknown +} + +export interface StorageUpdatePermissionQuery { + /** 操作用户的unionId。 */ + unionId: string +} + +export interface StorageUpdatePermissionResponse { + success?: unknown +} + +export interface StorageDeletePermissionParams { + /** 权限角色Id。 */ + roleId: string + /** 权限成员信息。 */ + members: object[] +} + +export interface StorageDeletePermissionQuery { + /** 操作者的unionId。 */ + unionId: string +} + +export interface StorageDeletePermissionResponse { + success?: unknown +} + +export interface StorageAddPermissionParams { + /** 权限角色Id。 */ + roleId: string + /** 权限成员信息。 */ + members: object[] + /** 可选参数。 */ + option?: unknown +} + +export interface StorageAddPermissionQuery { + /** 操作用户的unionId。 */ + unionId: string +} + +export interface StorageAddPermissionResponse { + success?: unknown +} + +export interface StorageAddSpaceParams { + /** 可选参数。 */ + option?: unknown +} + +export interface StorageAddSpaceQuery { + /** 操作者unionId。 */ + unionId: string +} + +export interface StorageAddSpaceResponse { + space?: { + id?: string + corpId?: string + creatorId?: string + ownerType?: string + ownerId?: string + modifierId?: string + usedQuota?: number + quota?: number + status?: string + createTime?: string + modifiedTime?: string + appId?: string + scene?: string + sceneId?: string + capabilities?: number + name?: string + partitions?: number + } +} + +// funcName: isOldApi +Internal.define({ + '/storage/workspaces/search': { POST: { searchWorkspaces: false } }, + '/storage/spaces/dentries/{dentryUuid}/permissions/inheritances': { + PUT: { setPermissionInheritance: false }, + GET: { getPermissionInheritance: false }, + }, + '/storage/spaces/dentries/{dentryUuid}/permissions': { + PUT: { storageUpdatePermission: false }, + POST: { storageAddPermission: false }, + }, + '/storage/spaces/dentries/{dentryUuid}/permissions/remove': { + POST: { storageDeletePermission: false }, + }, + '/storage/spaces/dentries/{dentryUuid}/permissions/query': { + POST: { listPermissionsOrg: false }, + }, + '/storage/dentries/search': { POST: { searchDentries: false } }, + '/storage/spaces/files/{parentDentryUuid}/commit': { + POST: { storageCommitFile: false }, + }, + '/storage/spaces/files/{parentDentryUuid}/uploadInfos/query': { + POST: { storageGetFileUploadInfo: false }, + }, + '/storage/events/unsubscribe': { POST: { unsubscribeEvent: false } }, + '/storage/spaces/{spaceId}/dentries/listAll': { + POST: { listAllDentries: false }, + }, + '/storage/spaces/{spaceId}/dentries/query': { POST: { getDentries: false } }, + '/storage/spaces/{spaceId}/thumbnails/query': { + POST: { getDentryThumbnails: false }, + }, + '/storage/spaces/{spaceId}/dentries/batchMove': { + POST: { moveDentries: false }, + }, + '/storage/spaces/{spaceId}/dentries/batchCopy': { + POST: { copyDentries: false }, + }, + '/storage/spaces/{spaceId}/dentries/batchRemove': { + POST: { deleteDentries: false }, + }, + '/storage/tasks/{taskId}': { GET: { getTask: false } }, + '/storage/spaces/{spaceId}/files/multiPartUploadInfos/init': { + POST: { initMultipartFileUpload: false }, + }, + '/storage/spaces/files/multiPartUploadInfos/query': { + POST: { getMultipartFileUploadInfos: false }, + }, + '/storage/orgs/{corpId}': { GET: { getOrg: false } }, + '/storage/recycleBins/{recycleBinId}/recycleItems/{recycleItemId}/restore': { + POST: { restoreRecycleItem: false }, + }, + '/storage/recycleBins': { GET: { getRecycleBin: false } }, + '/storage/recycleBins/{recycleBinId}/recycleItems/{recycleItemId}': { + GET: { getRecycleItem: false }, + DELETE: { deleteRecycleItem: false }, + }, + '/storage/recycleBins/{recycleBinId}/clear': { + POST: { clearRecycleBin: false }, + }, + '/storage/recycleBins/{recycleBinId}/recycleItems/batchRemove': { + POST: { deleteRecycleItems: false }, + }, + '/storage/recycleBins/{recycleBinId}/recycleItems/batchRestore': { + POST: { restoreRecycleItems: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/versions': { + GET: { listDentryVersions: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/openInfos/query': { + POST: { getDentryOpenInfo: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/move': { + POST: { moveDentry: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/permissions/query': { + POST: { listPermissionsIsv: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/downloadInfos/query': { + POST: { getFileDownloadInfo: false }, + }, + '/storage/recycleBins/{recycleBinId}/recycleItems': { + GET: { listRecycleItems: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}': { + DELETE: { deleteDentry: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/rename': { + POST: { renameDentry: false }, + }, + '/storage/spaces/{spaceId}/dentries': { GET: { listDentries: false } }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/versions/{version}/revert': { + POST: { revertDentryVersion: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/copy': { + POST: { copyDentry: false }, + }, + '/storage/currentApps/query': { POST: { getCurrentApp: false } }, + '/storage/spaces/{spaceId}': { GET: { storageGetSpace: false } }, + '/storage/spaces/{spaceId}/dentries/{parentId}/folders': { + POST: { addFolder: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/query': { + POST: { getDentry: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/appProperties/remove': { + POST: { deleteDentryAppProperties: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/appProperties': { + PUT: { updateDentryAppProperties: false }, + }, + '/storage/spaces/{spaceId}/files/commit': { + POST: { storageCommitFile: false }, + }, + '/storage/spaces/{spaceId}/files/uploadInfos/query': { + POST: { storageGetFileUploadInfo: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/permissions': { + PUT: { storageUpdatePermission: false }, + POST: { storageAddPermission: false }, + }, + '/storage/spaces/{spaceId}/dentries/{dentryId}/permissions/remove': { + POST: { storageDeletePermission: false }, + }, + '/storage/spaces': { POST: { storageAddSpace: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 搜索知识库 + * @see https://developers.dingtalk.com/document/orgapp/search-knowledge-base + */ + searchWorkspaces( + query: SearchWorkspacesQuery, + params: SearchWorkspacesParams, + ): Promise + /** + * 设置权限继承模式 + * @see https://developers.dingtalk.com/document/orgapp/set-permission-inheritance-mode + */ + setPermissionInheritance( + dentryUuid: string, + query: SetPermissionInheritanceQuery, + params: SetPermissionInheritanceParams, + ): Promise + /** + * 获取权限继承模式 + * @see https://developers.dingtalk.com/document/orgapp/get-permission-inheritance-mode + */ + getPermissionInheritance( + dentryUuid: string, + query: GetPermissionInheritanceQuery, + ): Promise + /** + * 修改权限 + * @see https://developers.dingtalk.com/document/orgapp/modify-permissions-file + */ + storageUpdatePermission( + dentryUuid: string, + query: StorageUpdatePermissionQuery, + params: StorageUpdatePermissionParams, + ): Promise + /** + * 删除权限 + * @see https://developers.dingtalk.com/document/orgapp/delete-permissions-file + */ + storageDeletePermission( + dentryUuid: string, + query: StorageDeletePermissionQuery, + params: StorageDeletePermissionParams, + ): Promise + /** + * 添加权限 + * @see https://developers.dingtalk.com/document/orgapp/add-permissions-file + */ + storageAddPermission( + dentryUuid: string, + query: StorageAddPermissionQuery, + params: StorageAddPermissionParams, + ): Promise + /** + * 获取权限列表 + * @see https://developers.dingtalk.com/document/orgapp/get-permission-list + */ + listPermissionsOrg( + dentryUuid: string, + query: ListPermissionsOrgQuery, + params: ListPermissionsOrgParams, + ): Promise + /** + * 搜索文件 + * @see https://developers.dingtalk.com/document/orgapp/search-for-files + */ + searchDentries( + query: SearchDentriesQuery, + params: SearchDentriesParams, + ): Promise + /** + * 提交文件 + * @see https://developers.dingtalk.com/document/app/submittal-file + */ + storageCommitFile( + parentDentryUuid: string, + query: StorageCommitFileQuery, + params: StorageCommitFileParams, + ): Promise + /** + * 获取文件上传信息 + * @see https://developers.dingtalk.com/document/app/obtain-file-upload-informations + */ + storageGetFileUploadInfo( + parentDentryUuid: string, + query: StorageGetFileUploadInfoQuery, + params: StorageGetFileUploadInfoParams, + ): Promise + /** + * 取消订阅文件变更事件 + * @see https://developers.dingtalk.com/document/isvapp/unsubscribe-from-file-change-event + */ + unsubscribeEvent( + query: UnsubscribeEventQuery, + params: UnsubscribeEventParams, + ): Promise + /** + * 获取文件列表 + * @see https://developers.dingtalk.com/document/isvapp/get-the-list-of-files-or-folders-under-a-space + */ + listAllDentries( + spaceId: string, + query: ListAllDentriesQuery, + params: ListAllDentriesParams, + ): Promise + /** + * 批量获取文件(夹)信息 + * @see https://developers.dingtalk.com/document/isvapp/get-file-or-folder-information-in-bulk + */ + getDentries( + spaceId: string, + query: GetDentriesQuery, + params: GetDentriesParams, + ): Promise + /** + * 批量获取文件缩略图 + * @see undefined + */ + getDentryThumbnails( + spaceId: string, + query: GetDentryThumbnailsQuery, + params: GetDentryThumbnailsParams, + ): Promise + /** + * 批量移动文件或文件夹 + * @see https://developers.dingtalk.com/document/isvapp/bulk-move-files-or-folders + */ + moveDentries( + spaceId: string, + query: MoveDentriesQuery, + params: MoveDentriesParams, + ): Promise + /** + * 批量拷贝文件或文件夹 + * @see https://developers.dingtalk.com/document/isvapp/copy-files-or-folders-in-bulk + */ + copyDentries( + spaceId: string, + query: CopyDentriesQuery, + params: CopyDentriesParams, + ): Promise + /** + * 批量删除文件或文件夹 + * @see https://developers.dingtalk.com/document/isvapp/delete-files-or-folders-in-bulk + */ + deleteDentries( + spaceId: string, + query: DeleteDentriesQuery, + params: DeleteDentriesParams, + ): Promise + /** + * 获取异步任务信息 + * @see https://developers.dingtalk.com/document/isvapp/get-the-asynchronous-task-information-in-storage + */ + getTask(taskId: string, query: GetTaskQuery): Promise + /** + * 初始化文件分片上传 + * @see https://developers.dingtalk.com/document/isvapp/initialize-a-multipart-upload-object + */ + initMultipartFileUpload( + spaceId: string, + query: InitMultipartFileUploadQuery, + params: InitMultipartFileUploadParams, + ): Promise + /** + * 获取文件上传信息(分片上传) + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-information-about-multipart-uploads-of-an-object + */ + getMultipartFileUploadInfos( + query: GetMultipartFileUploadInfosQuery, + params: GetMultipartFileUploadInfosParams, + ): Promise + /** + * 获取企业存储中企业维度的信息 + * @see https://developers.dingtalk.com/document/isvapp/obtain-enterprise-information-1 + */ + getOrg(corpId: string, query: GetOrgQuery): Promise + /** + * 还原回收站中的回收项 + * @see https://developers.dingtalk.com/document/isvapp/restore-recycle-items + */ + restoreRecycleItem( + recycleBinId: string, + recycleItemId: string, + query: RestoreRecycleItemQuery, + params: RestoreRecycleItemParams, + ): Promise + /** + * 获取回收站信息 + * @see https://developers.dingtalk.com/document/isvapp/obtain-information-about-the-recycle-bin + */ + getRecycleBin(query: GetRecycleBinQuery): Promise + /** + * 获取回收项详情 + * @see https://developers.dingtalk.com/document/isvapp/obtain-recycling-item-information + */ + getRecycleItem( + recycleBinId: string, + recycleItemId: string, + query: GetRecycleItemQuery, + ): Promise + /** + * 删除回收项, 删除之后该记录从回收站删除, 后续文件就无法恢复了 + * @see https://developers.dingtalk.com/document/isvapp/delete-recycle-item + */ + deleteRecycleItem( + recycleBinId: string, + recycleItemId: string, + query: DeleteRecycleItemQuery, + ): Promise + /** + * 清空回收站 + * @see https://developers.dingtalk.com/document/isvapp/empty-the-recycle-bin + */ + clearRecycleBin( + recycleBinId: string, + query: ClearRecycleBinQuery, + ): Promise + /** + * 批量删除回收项, 删除之后该记录从回收站删除, 后续文件就无法恢复了 + * @see https://developers.dingtalk.com/document/isvapp/batch-delete-recycle-items + */ + deleteRecycleItems( + recycleBinId: string, + query: DeleteRecycleItemsQuery, + params: DeleteRecycleItemsParams, + ): Promise + /** + * 批量还原回收站中的回收项 + * @see https://developers.dingtalk.com/document/isvapp/batch-restore-recycled-items + */ + restoreRecycleItems( + recycleBinId: string, + query: RestoreRecycleItemsQuery, + params: RestoreRecycleItemsParams, + ): Promise + /** + * 获取文件历史版本 + * @see https://developers.dingtalk.com/document/isvapp/obtains-a-list-of-file-versions + */ + listDentryVersions( + spaceId: string, + dentryId: string, + query: ListDentryVersionsQuery, + ): Promise + /** + * 获取文件打开链接 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-object-preview-or-editing-information + */ + getDentryOpenInfo( + spaceId: string, + dentryId: string, + query: GetDentryOpenInfoQuery, + params: GetDentryOpenInfoParams, + ): Promise + /** + * 移动文件或文件夹 + * @see https://developers.dingtalk.com/document/isvapp/move-a-file-or-folder + */ + moveDentry( + spaceId: string, + dentryId: string, + query: MoveDentryQuery, + params: MoveDentryParams, + ): Promise + /** + * 获取权限列表 + * @see https://developers.dingtalk.com/document/isvapp/obtain-a-permission-list-storage + */ + listPermissionsIsv( + spaceId: string, + dentryId: string, + query: ListPermissionsIsvQuery, + params: ListPermissionsIsvParams, + ): Promise + /** + * 获取文件下载信息 + * @see https://developers.dingtalk.com/document/orgapp/obtains-the-download-information-about-a-file + */ + getFileDownloadInfo( + spaceId: string, + dentryId: string, + query: GetFileDownloadInfoQuery, + params: GetFileDownloadInfoParams, + ): Promise + /** + * 获取回收项列表 + * @see https://developers.dingtalk.com/document/isvapp/gets-the-list-of-recycle-items + */ + listRecycleItems( + recycleBinId: string, + query: ListRecycleItemsQuery, + ): Promise + /** + * 删除文件或文件夹 + * @see https://developers.dingtalk.com/document/isvapp/delete-a-file-or-folder + */ + deleteDentry( + spaceId: string, + dentryId: string, + query: DeleteDentryQuery, + ): Promise + /** + * 重命名文件或文件夹 + * @see https://developers.dingtalk.com/document/isvapp/rename-a-file-or-folder + */ + renameDentry( + spaceId: string, + dentryId: string, + query: RenameDentryQuery, + params: RenameDentryParams, + ): Promise + /** + * 获取文件列表 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-file-list-storage + */ + listDentries( + spaceId: string, + query: ListDentriesQuery, + ): Promise + /** + * 恢复文件历史版本 + * @see https://developers.dingtalk.com/document/isvapp/restore-previous-versions-of-files + */ + revertDentryVersion( + spaceId: string, + dentryId: string, + version: number, + query: RevertDentryVersionQuery, + ): Promise + /** + * 拷贝文件或文件夹 + * @see https://developers.dingtalk.com/document/isvapp/copy-an-object + */ + copyDentry( + spaceId: string, + dentryId: string, + query: CopyDentryQuery, + params: CopyDentryParams, + ): Promise + /** + * 获取开放平台应用在企业存储中的相关应用信息 + * @see https://developers.dingtalk.com/document/isvapp/queries-application-information-1 + */ + getCurrentApp(query: GetCurrentAppQuery): Promise + /** + * 获取空间信息 + * @see https://developers.dingtalk.com/document/isvapp/get-space-information + */ + storageGetSpace( + spaceId: string, + query: StorageGetSpaceQuery, + ): Promise + /** + * 添加文件夹 + * @see https://developers.dingtalk.com/document/isvapp/add-folder + */ + addFolder( + spaceId: string, + parentId: string, + query: AddFolderQuery, + params: AddFolderParams, + ): Promise + /** + * 获取文件(夹)信息 + * @see https://developers.dingtalk.com/document/isvapp/obtain-file-or-folder-information + */ + getDentry( + spaceId: string, + dentryId: string, + query: GetDentryQuery, + params: GetDentryParams, + ): Promise + /** + * 删除文件上的App属性值 + * @see https://developers.dingtalk.com/document/isvapp/delete-file-app-attribute + */ + deleteDentryAppProperties( + spaceId: number, + dentryId: number, + query: DeleteDentryAppPropertiesQuery, + params: DeleteDentryAppPropertiesParams, + ): Promise + /** + * 修改文件上的App属性值 + * @see https://developers.dingtalk.com/document/isvapp/update-the-application-properties-of-a-file-or-folder + */ + updateDentryAppProperties( + spaceId: number, + dentryId: number, + query: UpdateDentryAppPropertiesQuery, + params: UpdateDentryAppPropertiesParams, + ): Promise + /** + * 提交文件 + * @see https://developers.dingtalk.com/document/orgapp/submit-documents + */ + storageCommitFile( + spaceId: string, + query: StorageCommitFileQuery, + params: StorageCommitFileParams, + ): Promise + /** + * 获取文件上传信息 + * @see https://developers.dingtalk.com/document/orgapp/obtain-storage-upload-information + */ + storageGetFileUploadInfo( + spaceId: string, + query: StorageGetFileUploadInfoQuery, + params: StorageGetFileUploadInfoParams, + ): Promise + /** + * 修改权限 + * @see https://developers.dingtalk.com/document/isvapp/modify-storage-permissions + */ + storageUpdatePermission( + spaceId: string, + dentryId: string, + query: StorageUpdatePermissionQuery, + params: StorageUpdatePermissionParams, + ): Promise + /** + * 删除权限 + * @see https://developers.dingtalk.com/document/isvapp/delete-storage-permissions + */ + storageDeletePermission( + spaceId: string, + dentryId: string, + query: StorageDeletePermissionQuery, + params: StorageDeletePermissionParams, + ): Promise + /** + * 添加权限 + * @see https://developers.dingtalk.com/document/isvapp/add-permissions-storage + */ + storageAddPermission( + spaceId: string, + dentryId: string, + query: StorageAddPermissionQuery, + params: StorageAddPermissionParams, + ): Promise + /** + * 添加空间 + * @see https://developers.dingtalk.com/document/isvapp/add-space + */ + storageAddSpace( + query: StorageAddSpaceQuery, + params: StorageAddSpaceParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/swform.ts b/adapters/dingtalk/src/api/swform.ts new file mode 100644 index 00000000..7f41b9ea --- /dev/null +++ b/adapters/dingtalk/src/api/swform.ts @@ -0,0 +1,93 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetFormInstanceQuery { + /** 填表类型。 */ + bizType?: number +} + +export interface GetFormInstanceResponse { + success?: unknown + result?: { + createTime?: string + modifyTime?: string + formCode?: string + title?: string + creator?: string + forms?: number + } +} + +export interface ListFormInstancesQuery { + /** 填表类型。 */ + bizType?: number + /** 时间,格式要求为yyyy-MM-dd。 */ + actionDate?: string + /** 分页游标。 */ + nextToken: number + /** 每页最大条目数,最大值100。 */ + maxResults: number +} + +export interface ListFormInstancesResponse { + success?: unknown + result?: { + hasMore?: number + nextToken?: number + list?: number + } +} + +export interface ListFormSchemasByCreatorQuery { + /** 每页最大条目数,最大值200。 */ + maxResults: number + /** 填表类型。 */ + bizType?: number + /** 填表创建人userid。 */ + creator?: string + /** 分页游标。 */ + nextToken: number +} + +export interface ListFormSchemasByCreatorResponse { + success?: unknown + result?: { + hasMore?: number + nextToken?: number + list?: number + } +} + +// funcName: isOldApi +Internal.define({ + '/swform/instances/{formInstanceId}': { GET: { getFormInstance: false } }, + '/swform/forms/{formCode}/instances': { GET: { listFormInstances: false } }, + '/swform/users/forms': { GET: { listFormSchemasByCreator: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取单条填表实例详情 + * @see https://developers.dingtalk.com/document/isvapp/obtains-the-instance-details-of-a-single-fill-table + */ + getFormInstance( + formInstanceId: string, + query: GetFormInstanceQuery, + ): Promise + /** + * 获取填表实例列表 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-table-filling-instance-list-data + */ + listFormInstances( + formCode: string, + query: ListFormInstancesQuery, + ): Promise + /** + * 获取用户创建的填表模板列表 + * @see https://developers.dingtalk.com/document/isvapp/new-obtains-the-template-that-a-user-creates + */ + listFormSchemasByCreator( + query: ListFormSchemasByCreatorQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/todo.ts b/adapters/dingtalk/src/api/todo.ts new file mode 100644 index 00000000..0711600f --- /dev/null +++ b/adapters/dingtalk/src/api/todo.ts @@ -0,0 +1,219 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface QueryOrgTodoTasksParams { + /** 分页游标。 */ + nextToken?: string + /** 待办完成状态。 */ + isDone?: unknown +} + +export interface QueryOrgTodoTasksResponse { + nextToken?: string + todoCards?: { + taskId?: string + subject?: string + dueTime?: number + detailUrl?: number + todoCardView?: number + priority?: number + createdTime?: number + modifiedTime?: number + todoStatus?: string + creatorId?: string + sourceId?: string + category?: string + bizTag?: string + originalSource?: number + isDone?: number + orgInfo?: number + }[] + totalCount?: number +} + +export interface UpdateTodoTaskExecutorStatusParams { + /** 执行者状态列表,id需传用户的unionId。 */ + executorStatusList?: object[] +} + +export interface UpdateTodoTaskExecutorStatusQuery { + /** 当前操作者的用户的unionId。 */ + operatorId?: string +} + +export interface UpdateTodoTaskExecutorStatusResponse { + result?: unknown +} + +export interface CreateTodoTaskParams { + /** 业务系统侧的唯一标识ID,即业务ID。 */ + sourceId?: string + /** 待办标题,最大长度1024。 */ + subject: string + /** 创建者的unionId。 */ + creatorId?: string + /** 待办备注描述,最大长度4096。 */ + description?: string + /** 截止时间,Unix时间戳,单位毫秒。 */ + dueTime?: number + /** 执行者的unionId,最大数量1000。 */ + executorIds?: string[] + /** 参与者的unionId,最大数量1000。 */ + participantIds?: string[] + /** 详情页url跳转地址。 */ + detailUrl?: unknown + /** 待办卡片内容区表单自定义字段列表 */ + contentFieldList?: object[] + /** 生成的待办是否仅展示在执行者的待办列表中。 */ + isOnlyShowExecutor?: unknown + /** 优先级,取值: */ + priority?: number + /** 待办通知配置。 */ + notifyConfigs?: unknown + /** 二级分类。 */ + bizCategoryId?: string + /** 编辑 */ + actionList?: object[] +} + +export interface CreateTodoTaskQuery { + /** 当前操作者用户的unionId。 */ + operatorId?: string +} + +export interface CreateTodoTaskResponse { + id: string + subject: string + description?: string + startTime?: number + dueTime?: number + finishTime?: number + done?: unknown + executorIds?: string[] + participantIds?: string[] + detailUrl?: { + pcUrl?: string + appUrl?: string + } + source?: string + sourceId?: string + createdTime: number + modifiedTime?: number + creatorId: string + modifierId?: string + tenantId?: string + tenantType?: string + bizTag?: string + requestId?: string + cardTypeId?: string + contentFieldList?: { + fieldKey?: string + fieldValue?: string + }[] + isOnlyShowExecutor?: unknown + priority?: number + sourceTitle?: string + notifyConfigs?: { + singleChat?: string + dingNotify?: string + } +} + +export interface UpdateTodoTaskParams { + /** 待办标题,最大长度1024。 */ + subject?: string + /** 待办描述,最大长度4096。 */ + description?: string + /** 截止时间,Unix时间戳,单位毫秒。 */ + dueTime?: number + /** 完成状态。 */ + done?: unknown + /** 执行者的unionId列表,最大数量1000。 */ + executorIds?: string[] + /** 参与者的unionId列表,最大数量1000。 */ + participantIds?: string[] +} + +export interface UpdateTodoTaskQuery { + /** 当前操作者的unionId。 */ + operatorId?: string +} + +export interface UpdateTodoTaskResponse { + result?: unknown +} + +export interface DeleteTodoTaskQuery { + /** 当前操作者的用户的unionId。 */ + operatorId?: string +} + +export interface DeleteTodoTaskResponse { + result?: unknown + requestId?: string +} + +// funcName: isOldApi +Internal.define({ + '/todo/users/{unionId}/org/tasks/query': { + POST: { queryOrgTodoTasks: false }, + }, + '/todo/users/{unionId}/tasks/{taskId}/executorStatus': { + PUT: { updateTodoTaskExecutorStatus: false }, + }, + '/todo/users/{unionId}/tasks': { POST: { createTodoTask: false } }, + '/todo/users/{unionId}/tasks/{taskId}': { + PUT: { updateTodoTask: false }, + DELETE: { deleteTodoTask: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 查询企业下用户待办列表 + * @see https://developers.dingtalk.com/document/isvapp/query-the-to-do-list-of-enterprise-users + */ + queryOrgTodoTasks( + unionId: string, + params: QueryOrgTodoTasksParams, + ): Promise + /** + * 更新钉钉待办执行者状态 + * @see https://developers.dingtalk.com/document/isvapp/update-dingtalk-to-do-status + */ + updateTodoTaskExecutorStatus( + unionId: string, + taskId: string, + query: UpdateTodoTaskExecutorStatusQuery, + params: UpdateTodoTaskExecutorStatusParams, + ): Promise + /** + * 创建待办 + * @see https://developers.dingtalk.com/document/isvapp/add-dingtalk-to-do-task + */ + createTodoTask( + unionId: string, + query: CreateTodoTaskQuery, + params: CreateTodoTaskParams, + ): Promise + /** + * 更新钉钉待办任务 + * @see https://developers.dingtalk.com/document/isvapp/updates-dingtalk-to-do-tasks + */ + updateTodoTask( + unionId: string, + taskId: string, + query: UpdateTodoTaskQuery, + params: UpdateTodoTaskParams, + ): Promise + /** + * 删除钉钉待办任务 + * @see https://developers.dingtalk.com/document/isvapp/delete-dingtalk-to-do-tasks + */ + deleteTodoTask( + unionId: string, + taskId: string, + query: DeleteTodoTaskQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/wiki.ts b/adapters/dingtalk/src/api/wiki.ts new file mode 100644 index 00000000..7aa8738c --- /dev/null +++ b/adapters/dingtalk/src/api/wiki.ts @@ -0,0 +1,230 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface ListNodesQuery { + /** 父节点id(父节点dentryUuid): */ + parentNodeId: string + /** 分页游标, 首次拉取不用传。 */ + nextToken?: string + /** 分页大小,默认值50。 */ + maxResults?: number + /** 是否获取权限信息: */ + withPermissionRole?: unknown + /** 操作人unionId。 */ + operatorId: string +} + +export interface ListNodesResponse { + nodes?: { + nodeId?: string + workspaceId?: string + name?: string + size?: number + type?: string + category?: string + extension?: string + url?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + hasChildren?: number + statisticalInfo?: number + permissionRole?: string + }[] + nextToken?: string +} + +export interface GetNodeByUrlParams { + /** 文档链接 */ + url: string + /** 可选参数 */ + option?: unknown +} + +export interface GetNodeByUrlQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface GetNodeByUrlResponse { + node?: { + nodeId?: string + workspaceId?: string + name?: string + size?: number + type?: string + category?: string + extension?: string + url?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + hasChildren?: number + statisticalInfo?: number + permissionRole?: string + } +} + +export interface GetNodesParams { + /** 节点id。 */ + nodeIds: string[] + /** 可选参数。 */ + option?: unknown +} + +export interface GetNodesQuery { + /** 操作人unionId。 */ + operatorId: string +} + +export interface GetNodesResponse { + nodes?: { + nodeId?: string + workspaceId?: string + name?: string + size?: number + type?: string + category?: string + extension?: string + url?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + hasChildren?: number + statisticalInfo?: number + permissionRole?: string + }[] +} + +export interface GetNodeQuery { + /** 是否获取统计信息: */ + withStatisticalInfo?: unknown + /** 是否获取权限信息: */ + withPermissionRole?: unknown + /** 操作人unionId。 */ + operatorId: string +} + +export interface GetNodeResponse { + node?: { + nodeId?: string + workspaceId?: string + name?: string + size?: number + type?: string + category?: string + extension?: string + url?: string + creatorId?: string + modifierId?: string + createTime?: string + modifiedTime?: string + hasChildren?: number + statisticalInfo?: number + permissionRole?: string + } +} + +export interface WikiWordsDetailQuery { + /** 词条名称,最大长度50个字符。 */ + wordName: string +} + +export interface WikiWordsDetailResponse { + data: { + wordName: string + uuid: number + gmtCreate: number + gmtModify: number + orgName: string + wordAlias: number + highLightWordAlias: number + wordFullName: string + relatedDoc: number + relatedLink: number + creatorName: string + updaterName: string + approveName: string + wordParaphrase: string + simpleWordParaphrase: string + contacts: number + tagsList: number + appLink: number + imHighLight: number + simHighLight: number + }[] + errMsg: string + success: unknown +} + +export interface WikiWordsParseParams { + /** 待匹配词条的文本,最大长度4096个字符。 */ + content: string +} + +export interface WikiWordsParseResponse { + success?: unknown + errMsg: string + data: { + startIndex: number + endIndex: number + wordName: string + }[] +} + +// funcName: isOldApi +Internal.define({ + '/wiki/nodes': { GET: { listNodes: false } }, + '/wiki/nodes/queryByUrl': { POST: { getNodeByUrl: false } }, + '/wiki/nodes/batchQuery': { POST: { getNodes: false } }, + '/wiki/nodes/{nodeId}': { GET: { getNode: false } }, + '/wiki/words/details': { GET: { wikiWordsDetail: false } }, + '/wiki/words/parse': { POST: { wikiWordsParse: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取节点列表 + * @see https://developers.dingtalk.com/document/orgapp/get-node-list + */ + listNodes(query: ListNodesQuery): Promise + /** + * 通过链接获取节点 + * @see https://developers.dingtalk.com/document/orgapp/get-node-by-link + */ + getNodeByUrl( + query: GetNodeByUrlQuery, + params: GetNodeByUrlParams, + ): Promise + /** + * 批量获取节点 + * @see https://developers.dingtalk.com/document/orgapp/obtain-nodes-in-batch + */ + getNodes( + query: GetNodesQuery, + params: GetNodesParams, + ): Promise + /** + * 获取节点 + * @see https://developers.dingtalk.com/document/orgapp/get-node + */ + getNode(nodeId: string, query: GetNodeQuery): Promise + /** + * 根据词条名称获取该词条释义 + * @see https://developers.dingtalk.com/document/orgapp/enterprise-encyclopedia-query-entry-details-by-entry-name + */ + wikiWordsDetail( + query: WikiWordsDetailQuery, + ): Promise + /** + * 外部传递过来的消息根据百科词库分词 + * @see https://developers.dingtalk.com/document/orgapp/enterprise-encyclopedia-match-entries-in-a-text + */ + wikiWordsParse( + params: WikiWordsParseParams, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/workbench.ts b/adapters/dingtalk/src/api/workbench.ts new file mode 100644 index 00000000..c17d51ce --- /dev/null +++ b/adapters/dingtalk/src/api/workbench.ts @@ -0,0 +1,72 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface AddRecentUserAppListParams { + /** 组织CorpId */ + corpId: string + /** 最近使用应用列表 */ + usedAppDetailList: object[] + /** 员工staffId */ + userId: string +} + +export interface AddRecentUserAppListResponse { + result: unknown +} + +export interface GetPluginRuleCheckInfoQuery { + /** 插件的appId。 */ + miniAppId?: string +} + +export interface GetPluginRuleCheckInfoResponse { + packCode?: string + pluginRuleCheckDetail?: string +} + +export interface GetPluginPermissionPointQuery { + /** 插件ID。 */ + miniAppId?: string +} + +export interface GetPluginPermissionPointResponse { + permissionPointList?: string[] +} + +// funcName: isOldApi +Internal.define({ + '/workbench/components/recentUsed/batch': { + POST: { addRecentUserAppList: false }, + }, + '/workbench/plugins/validationRules': { + GET: { getPluginRuleCheckInfo: false }, + }, + '/workbench/plugins/permissions': { + GET: { getPluginPermissionPoint: false }, + }, +}) +declare module '../internal' { + interface Internal { + /** + * 批量添加最近使用记录 + * @see https://developers.dingtalk.com/document/app/add-recently-used-apps-in-bulk + */ + addRecentUserAppList( + params: AddRecentUserAppListParams, + ): Promise + /** + * 获取插件的校验规则 + * @see https://developers.dingtalk.com/document/dashboard/you-can-call-this-operation-to-obtain-the-information-about + */ + getPluginRuleCheckInfo( + query: GetPluginRuleCheckInfoQuery, + ): Promise + /** + * 获取工作台插件的权限点 + * @see https://developers.dingtalk.com/document/dashboard/obtain-the-permissions-of-the-workbench-plug-in + */ + getPluginPermissionPoint( + query: GetPluginPermissionPointQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/api/yida.ts b/adapters/dingtalk/src/api/yida.ts new file mode 100644 index 00000000..f7d540af --- /dev/null +++ b/adapters/dingtalk/src/api/yida.ts @@ -0,0 +1,2164 @@ +import { Internal } from '../internal' +// GENERATED CONTENT + +export interface GetFormListInAppQuery { + /** 应用编码。 */ + appType: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 表单类型。 */ + formTypes?: string + /** 每页条目数,默认值100,最大值100。 */ + pageSize?: number + /** 页码,不传默认为1。 */ + pageNumber?: number + /** 操作人userId。 */ + userId: string +} + +export interface GetFormListInAppResponse { + success?: unknown + result?: { + data?: number + totalCount?: number + currentPage?: number + } +} + +export interface GetFieldDefByUuidQuery { + /** 应用编码。 */ + appType: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 表单唯一标识。 */ + formUuid: string + /** 操作人userId。 */ + userId: string +} + +export interface GetFieldDefByUuidResponse { + success?: unknown + result?: { + componentName?: string + fieldId?: string + behavior?: string + label?: number + props?: number + children?: string + }[] +} + +export interface ExecuteBatchTaskParams { + /** 审批动作,目前支持的审批动作如下: */ + outResult: string + /** 宜搭应用编码。 */ + appType: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 审批意见。 */ + remark?: string + /** 操作人userId。 */ + userId: string + /** 批量执行的审批任务列表,数组对象格式,每个元素值包含taskId和formInstId两个子属性。 */ + taskInformationList: string +} + +export interface ExecuteBatchTaskResponse { + failNumber: number + successNumber: number + total: number +} + +export interface ListOperationLogsParams { + /** 表单编码。 */ + formUuid: string + /** 宜搭应用编码。 */ + appType: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 宜搭表单实例Id。 */ + formInstanceIdList?: string[] + /** 用户userId。 */ + userId: string +} + +export interface ListOperationLogsResponse { + operationLogMap: unknown +} + +export interface ListFormRemarksParams { + /** 表单编码。 */ + formUuid: string + /** 宜搭应用编码。 */ + appType: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 宜搭表单实例Id。 */ + formInstanceIdList?: string[] + /** 操作者userId。 */ + userId: string +} + +export interface ListFormRemarksResponse { + formRemarkVoMap?: unknown +} + +export interface QueryServiceRecordQuery { + /** 操作人的userId。 */ + userId: string + /** 服务类型,目前只有HTTP服务调用。 */ + hookType?: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 本次服务调用的唯一ID,自定义参数。 */ + hookUuid?: string + /** 被重试的服务调用唯一ID。 */ + sourceUuid?: string + /** 服务调用地址中包含的部分字符串,用于模糊查询。 */ + requestUrl?: string + /** 服务调用是否成功。 */ + success?: unknown + /** 当前页码,从1开始。 */ + pageNumber?: number + /** 宜搭表单实例Id。 */ + instanceId: string + /** 查询调用服务的开始时间。 */ + invokeAfterDateGMT?: string + /** 每页最大条目数,最大值100。 */ + pageSize?: number + /** 服务调用状态,可选值: */ + invokeStatus?: string + /** 宜搭应用编码。 */ + appType: string + /** 查询调用服务的结束时间。 */ + invokeBeforeDateGMT?: string + /** 宜搭表单编码。 */ + formUuid: string +} + +export interface QueryServiceRecordResponse { + totalCount?: number + values?: { + serviceContent?: string + formUuid?: string + sourceUuid?: string + invokeStatus?: string + invokeUrl?: string + invokeResult?: string + invokeParameter?: string + hookUuid?: string + formInstanceId?: string + serviceParameter?: string + serviceName?: string + hookType?: string + invokeSuccess?: string + }[] +} + +export interface BatchRemovalByFormInstanceIdListParams { + /** 表单编码。 */ + formUuid: string + /** 宜搭应用编码。 */ + appType: string + /** 是否需要宜搭服务端异步执行该任务。 */ + asynchronousExecution?: unknown + /** 宜搭应用密钥。 */ + systemToken: string + /** 宜搭表单实例Id。 */ + formInstanceIdList: string[] + /** 员工userId。 */ + userId: string + /** 是否需要触发表单绑定的校验规则、关联业务规则和第三方服务回调。 */ + executeExpression?: unknown +} + +export interface BatchUpdateFormDataByInstanceIdParams { + /** 是否不触发表单绑定的校验规则、关联业务规则和第三方服务回调。 */ + noExecuteExpression?: unknown + /** 表单编码。 */ + formUuid: string + /** 用于更新表单实例的数据。 */ + updateFormDataJson: string + /** 宜搭应用编码。 */ + appType: string + /** 是否忽略空值。 */ + ignoreEmpty?: unknown + /** 宜搭应用密钥。 */ + systemToken: string + /** 是否使用最新的表单schema版本。 */ + useLatestFormSchemaVersion?: unknown + /** 是否需要宜搭服务端异步执行该任务。 */ + asynchronousExecution?: unknown + /** 表单实例Id。 */ + formInstanceIdList: string[] + /** 用户userId。 */ + userId: string +} + +export interface BatchUpdateFormDataByInstanceIdResponse { + result?: string[] +} + +export interface BatchUpdateFormDataByInstanceMapParams { + /** 是否不触发表单绑定的校验规则、关联业务规则和第三方服务回调。 */ + noExecuteExpression?: unknown + /** 表单编码。 */ + formUuid: string + /** 该任务是否需要服务端异步执行。 */ + asynchronousExecution?: unknown + /** 宜搭应用编码。 */ + appType: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 是否忽略空值。 */ + ignoreEmpty?: unknown + updateFormDataJsonMap: unknown + /** 是否使用最新的表单schema版本。 */ + useLatestFormSchemaVersion?: unknown + /** 用户userId。 */ + userId: string +} + +export interface BatchUpdateFormDataByInstanceMapResponse { + result?: string[] +} + +export interface ListApplicationQuery { + /** 应用过滤条件。 */ + appFilter?: string + /** 页码数,从1开始。 */ + pageNumber?: number + /** 钉钉企业的corpId值。 */ + corpId: string + /** 每页最大条目数,最大值100。 */ + pageSize?: number + /** 根据应用名称检索时的关键词。 */ + appNameSearchKeyword?: string + /** 操作人userId。 */ + userId: string + /** 根据corpId、userId和CorpToken使用md5加密计算生成的字符串。 */ + token: string +} + +export interface ListApplicationResponse { + pageNumber?: number + totalCount?: number + data?: { + creatorUserId?: string + corpId?: string + icon?: string + description?: string + applicationStatus?: string + appConfig?: string + inexistence?: string + subCorpId?: string + appType?: string + name?: string + }[] +} + +export interface BatchSaveFormDataParams { + /** 是否不触发表单绑定的校验规则、关联业务规则和第三方服务回调。 */ + noExecuteExpression?: unknown + /** 表单编码。 */ + formUuid: string + /** 宜搭应用编码。 */ + appType: string + /** 是否需要宜搭服务端异步执行该任务。 */ + asynchronousExecution?: unknown + /** 宜搭应用密钥。 */ + systemToken: string + /** 批量保存多条表单实例数据发生异常时是否跳过异常的表单实例并继续保存下一个表单实例数据。 */ + keepRunningAfterException?: unknown + /** 用户userId。 */ + userId: string + /** 表单实例数据。 */ + formDataJsonList: string[] +} + +export interface BatchSaveFormDataResponse { + result?: string[] +} + +export interface SearchFormDataSecondGenerationNoTableFieldParams { + /** 当前页码,从1开始。 */ + pageNumber?: number + /** 表单编码。 */ + formUuid: string + /** 用于检索表单实例数据的检索条件。 */ + searchCondition?: string + /** 表单实例修改截止时间。 */ + modifiedToTimeGMT?: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 表单实例修改开始时间。 */ + modifiedFromTimeGMT?: string + /** 每页条目数,最大值100。 */ + pageSize?: number + /** 用户userId。 */ + userId: string + /** 宜搭应用编码。 */ + appType: string + /** 排序规则 */ + orderConfigJson?: string + /** 表单实例提交人的userId。 */ + originatorId?: string + /** 表单实例创建截止时间。 */ + createToTimeGMT?: string + /** 表单实例创建开始时间。 */ + createFromTimeGMT?: string +} + +export interface SearchFormDataSecondGenerationNoTableFieldResponse { + pageNumber?: number + data?: { + createTimeGMT?: string + modifyUser?: number + sequence?: string + creatorUserId?: string + formUuid?: string + serialNumber?: string + modifiedTimeGMT?: string + modifier?: string + formData?: number + originator?: number + formInstanceId?: string + id?: number + title?: string + version?: number + instanceValue?: string + }[] + totalCount?: number +} + +export interface CreateOrUpdateFormDataParams { + /** 是否不要触发表单绑定的校验规则、关联业务规则和第三方服务回调。 */ + noExecuteExpression?: unknown + /** 表单编码。 */ + formUuid: string + /** 用于检索表单实例数据的检索条件。 */ + searchCondition: string + /** 宜搭应用编码。 */ + appType: string + /** 用于更新或新增表单实例的数据。 */ + formDataJson: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 用户userId。 */ + userId: string +} + +export interface CreateOrUpdateFormDataResponse { + result?: string[] +} + +export interface SearchFormDataSecondGenerationParams { + /** 当前的页码数,从1开始。 */ + pageNumber?: number + /** 表单编码。 */ + formUuid: string + /** 用于检索表单实例数据的检索条件。 */ + searchCondition?: string + /** 修改的截止时间,格式yyyy-MM-dd HH:mm:ss。 */ + modifiedToTimeGMT?: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 修改开始时间,格式yyyy-MM-dd HH:mm:ss。 */ + modifiedFromTimeGMT?: string + /** 每页最大条目数,最大值100。 */ + pageSize?: number + /** 用户userId。 */ + userId: string + /** 宜搭应用编码。 */ + appType: string + /** 排序规则。 */ + orderConfigJson?: string + /** 表单提交人的userId。 */ + originatorId?: string + /** 创建的开始时间,格式yyyy-MM-dd HH:mm:ss。 */ + createToTimeGMT?: string + /** 创建的开始时间,格式yyyy-MM-dd HH:mm:ss。 */ + createFromTimeGMT?: string +} + +export interface SearchFormDataSecondGenerationResponse { + pageNumber?: number + data?: { + createTimeGMT?: string + modifyUser?: number + sequence?: string + creatorUserId?: string + formUuid?: string + serialNumber?: string + modifiedTimeGMT?: string + modifier?: string + formData?: number + originator?: number + formInstanceId?: string + id?: number + title?: string + version?: number + instanceValue?: string + }[] + totalCount?: number +} + +export interface BatchGetFormDataByIdListParams { + /** 宜搭表单编码。 */ + formUuid: string + /** 宜搭应用编码。 */ + appType: string + /** 宜搭应用密钥。 */ + systemToken: string + /** 宜搭表单实例Id。 */ + formInstanceIdList: string[] + /** 是否需要宜搭表单组件格式的实例数据。 */ + needFormInstanceValue?: unknown + /** 用户userId。 */ + userId: string +} + +export interface BatchGetFormDataByIdListResponse { + result?: { + createTimeGMT?: string + modifyUser?: number + sequence?: string + creatorUserId?: string + formUuid?: string + serialNumber?: string + modifiedTimeGMT?: string + modifier?: string + formData?: number + originator?: number + formInstanceId?: string + id?: number + title?: string + version?: number + instanceValue?: string + }[] +} + +export interface GetTaskCopiesQuery { + /** 应用ID。 */ + appType: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 分页大小。 */ + pageSize?: number + /** 语言,取值: */ + language?: string + /** 分页页码。 */ + pageNumber?: number + /** 表单中组件数据模糊搜索。 */ + keyword?: string + /** 用户userid。 */ + userId: string + /** 流程code列表。 */ + processCodes?: string + /** 创建时间起始值。 */ + createFromTimeGMT?: number + /** 创建时间终止值。 */ + createToTimeGMT?: number +} + +export interface GetTaskCopiesResponse { + pageNumber?: number + totalCount?: number + data?: { + actionExecutorId?: number + processInstanceId?: string + formUuid?: string + serialNumber?: string + processInstanceStatus?: string + originatorDisplayName?: string + modifiedTimeGMT?: string + carbonActivityId?: string + dataType?: string + actionExecutorName?: number + originatorAvatar?: string + processInstanceStatusText?: string + processApprovedResultText?: string + formInstanceId?: string + title?: string + version?: number + instanceValue?: string + createTimeGMT?: string + processApprovedResult?: string + processId?: number + processName?: string + processCode?: string + appType?: string + dataMap?: number + currentActivityInstances?: number + finishTimeGMT?: string + originatorId?: string + }[] +} + +export interface SearchFormDataIdListParams { + /** 修改时间终止值。 */ + modifiedToTimeGMT?: string + /** 应用秘钥。 */ + systemToken: string + /** 修改时间起始值。 */ + modifiedFromTimeGMT?: string + /** 语言,取值: */ + language?: string + /** 根据表单内组件值查询。 */ + searchFieldJson?: string + /** 用户userid。 */ + userId: string + /** 根据流程发起人工号查询。 */ + originatorId?: string + /** 创建时间终止值。 */ + createToTimeGMT?: string + /** 创建时间起始值。 */ + createFromTimeGMT?: string +} + +export interface SearchFormDataIdListQuery { + /** 分页页吗。 */ + pageNumber?: number + /** 分页大小。 */ + pageSize?: number +} + +export interface SearchFormDataIdListResponse { + totalCount?: number + pageNumber?: number + data?: string[] +} + +export interface ListTableDataByFormInstanceIdTableIdQuery { + /** 表单ID。 */ + formUuid: string + /** 宜搭应用的唯一编码。 */ + appType: string + /** 需要查找的子表单组件ID。 */ + tableFieldId: string + /** 分页页码。 */ + pageNumber?: number + /** 分页大小。 */ + pageSize?: number + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 用户的userid。 */ + userId: string +} + +export interface ListTableDataByFormInstanceIdTableIdResponse { + totalCount?: number + pageNumber?: number + data?: object[] +} + +export interface GetCorpAccomplishmentTasksQuery { + /** 分页大小。 */ + pageSize?: number + /** 语言,取值: */ + language?: string + /** 分页页码。 */ + pageNumber?: number + /** 表单中组件数据模糊搜索。 */ + keyword?: string + /** 应用标识。 */ + appTypes?: string + /** 流程code。 */ + processCodes?: string + /** 创建时间起始值。 */ + createFromTimeGMT?: number + /** 创建时间终止值。 */ + createToTimeGMT?: number + /** 验权token。 */ + token: string +} + +export interface GetCorpAccomplishmentTasksResponse { + totalCount?: number + pageNumber?: number + data?: { + originatorNickName?: string + processInstanceId?: string + originatorName?: string + finishTimeGMT?: string + activeTimeGMT?: string + actualActionerId?: string + originatorEmail?: string + title?: string + outResultName?: string + outResult?: string + originatorPhoto?: string + taskType?: string + originatorNickNameInEnglish?: string + createTimeGMT?: string + titleInEnglish?: string + appType?: string + originatorNameInEnglish?: string + originatorId?: string + taskId?: string + status?: string + }[] +} + +export interface GetFormComponentDefinitionListQuery { + /** 应用秘钥。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 版本。 */ + version?: number +} + +export interface GetFormComponentDefinitionListResponse { + result?: { + label?: string + componentName?: string + fieldId?: string + parentId?: string + }[] +} + +export interface GetInstanceIdListParams { + /** 表单ID。 */ + formUuid: string + /** 修改时间终止值。 */ + modifiedToTimeGMT?: string + /** 应用秘钥。 */ + systemToken: string + /** 修改时间起始值。 */ + modifiedFromTimeGMT?: string + /** 语言,取值: */ + language?: string + /** 根据表单内组件值查询。 */ + searchFieldJson?: string + /** 用户userid。 */ + userId: string + /** 实例状态。 */ + instanceStatus?: string + /** 流程审批结果。 */ + approvedResult?: string + /** 应用编码。 */ + appType: string + /** 根据流程发起人工号查询。 */ + originatorId?: string + /** 创建时间终止值。 */ + createToTimeGMT?: string + /** 任务ID。 */ + taskId?: string + /** 创建时间起始值。 */ + createFromTimeGMT?: string +} + +export interface GetInstanceIdListQuery { + /** 分页大小。 */ + pageSize?: number + /** 分页页码。 */ + pageNumber?: number +} + +export interface GetInstanceIdListResponse { + totalCount?: number + pageNumber?: number + data?: string[] +} + +export interface GetInstancesByIdListQuery { + /** 应用ID。 */ + appType: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 流程实例ID列表,多个流程实例ID之间使用英文逗号分隔。 */ + processInstanceIds: string +} + +export interface GetInstancesByIdListResponse { + result?: { + actionExecutor?: number + processInstanceId?: string + formUuid?: string + processCode?: string + title?: string + instanceStatus?: string + approvedResult?: string + originator?: number + data?: number + }[] +} + +export interface GetMeCorpSubmissionQuery { + /** 组织的corpId。 */ + corpId: string + /** 分页大小。 */ + pageSize?: number + /** 语言,取值: */ + language?: string + /** 分页页码。 */ + pageNumber?: number + /** 表单中组件数据模糊搜索。 */ + keyword?: string + /** 应用标识。 */ + appTypes?: string + /** 流程code。 */ + processCodes?: string + /** 创建时间起始值。 */ + createFromTimeGMT?: number + /** 创建时间终止值。 */ + createToTimeGMT?: number + /** 验权token。 */ + token: string +} + +export interface GetMeCorpSubmissionResponse { + totalCount?: number + pageNumber?: number + data?: { + actionerName?: number + processInstanceId?: string + modifiedTimeGMT?: string + finishTimeGMT?: string + formUuid?: string + processInstanceStatus?: string + originatorDisplayName?: string + dataType?: string + originatorAvatar?: string + processInstanceStatusText?: string + actioner?: number + processApprovedResultText?: string + formInstanceId?: string + title?: string + version?: number + instanceValue?: string + processApprovedResult?: string + createTimeGMT?: string + processId?: number + processName?: string + processCode?: string + appType?: string + actionerId?: number + dataMap?: number + currentActivityInstances?: number + originatorId?: string + }[] +} + +export interface GetProcessDefinitionQuery { + /** 组织的corpId。 */ + corpId?: string + /** 组ID。 */ + groupId?: string + /** 应用ID。 */ + appType?: string + /** 订单号。 */ + orderNumber?: string + /** 应用的秘钥。 */ + systemType?: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken?: string + /** 名称空间。 */ + nameSpace?: string + /** 语言,取值: */ + language?: string + /** 用户的userid。 */ + userId?: string +} + +export interface GetProcessDefinitionResponse { + outResult?: string + processInstanceId?: string + variables?: unknown + formUuid?: string + processId?: string + owners?: { + userInfo?: string + tbWang?: string + orderNumber?: string + departmentDescription?: string + displayName?: string + masterDataDepartments?: number + displayEnName?: string + userId?: string + personalPhoto?: string + status?: string + }[] + originator?: { + userInfo?: string + tbWang?: string + orderNumber?: string + departmentDescription?: string + displayName?: string + masterDataDepartments?: number + displayEnName?: string + userId?: string + personalPhoto?: string + status?: string + } + title?: string + tasks?: { + actionerId?: string + activity?: number + taskId?: number + status?: string + }[] + status?: string +} + +export interface GetCorpTasksQuery { + /** 组织corpId。 */ + corpId: string + /** 分页大小。 */ + pageSize?: number + /** 语言,取值: */ + language?: string + /** 分页页码。 */ + pageNumber?: number + /** 表单中组件数据模糊搜索。 */ + keyword?: string + /** 应用标识列表。 */ + appTypes?: string + /** 流程code列表。 */ + processCodes?: string + /** 创建时间起始值。 */ + createFromTimeGMT?: number + /** 创建时间终止值。 */ + createToTimeGMT?: number + /** 用户的userid。 */ + userId: string + /** 验权token。 */ + token: string +} + +export interface GetCorpTasksResponse { + totalCount?: number + pageNumber?: number + data?: { + originatorNickName?: string + processInstanceId?: string + originatorName?: string + finishTimeGMT?: string + activeTimeGMT?: string + actualActionerId?: string + originatorEmail?: string + title?: string + outResultName?: string + outResult?: string + originatorPhoto?: string + taskType?: string + originatorNickNameEn?: string + createTimeGMT?: string + titleInEnglish?: string + appType?: string + originatorNameInEnglish?: string + originatorId?: string + taskId?: string + status?: string + }[] +} + +export interface GetNotifyMeQuery { + /** 组织的corpId。 */ + corpId: string + /** 验权token。 */ + token: string + /** 分页页码。 */ + pageNumber?: number + /** 分页大小。 */ + pageSize?: number + /** 语言,取值: */ + language?: string + /** 表单中组件数据模糊搜索。 */ + keyword?: string + /** 应用标识列表。 */ + appTypes?: string + /** 流程code列表。 */ + processCodes?: string + /** 流程创建时间起始值。 */ + instanceCreateFromTimeGMT?: number + /** 流程创建时间终止值。 */ + instanceCreateToTimeGMT?: number + /** 创建时间起始值。 */ + createFromTimeGMT?: number + /** 创建时间终止值。 */ + createToTimeGMT?: number +} + +export interface GetNotifyMeResponse { + totalCount?: number + pageNumber?: number + data?: { + createTimeGMT?: string + activityId?: string + creatorUserId?: string + corpId?: string + titleInEnglish?: string + modifiedTimeGMT?: string + appType?: string + processCode?: string + mobileUrl?: string + formInstanceId?: string + instStatus?: string + title?: string + url?: string + }[] +} + +export interface GetActivityButtonListQuery { + /** 应用秘钥。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string +} + +export interface GetActivityButtonListResponse { + result?: { + aliasInEnglish?: string + aliasInChinese?: string + }[] +} + +export interface GetApplicationAuthorizationServicePlatformResourceQuery { + /** 实例ID。 */ + instanceId?: string + /** 访问秘钥。 */ + accessKey?: string + /** 调用者的unionId。 */ + callerUid?: string +} + +export interface GetApplicationAuthorizationServicePlatformResourceResponse { + appTotalAmount?: number + instanceId?: string + instanceTotalAmount?: number + instanceUsageAmount?: number + accountUsageAmount?: number + accountTotalAmount?: number + pluginUsageAmount?: number + attachmentTotalAmount?: number + attachmentUsageAmount?: number +} + +export interface UpdateInstanceParams { + /** 流程实例ID。 */ + processInstanceId: string + /** 应用ID。 */ + appType: string + /** 更新的表单数据。 */ + updateFormDataJson: string + /** 应用秘钥。 */ + systemToken: string + /** 语言,取值: */ + language?: string + /** 用户的userid。 */ + userId: string +} + +export interface DeleteInstanceQuery { + /** 应用标识。 */ + appType: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 流程实例ID。 */ + processInstanceId: string +} + +export interface GetOperationRecordsQuery { + /** 应用ID。 */ + appType: string + /** 应用秘钥。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 流程实例ID。 */ + processInstanceId: string +} + +export interface GetOperationRecordsResponse { + result?: { + processInstanceId?: string + showName?: string + operatorNickName?: string + activeTimeGMT?: string + operateTimeGMT?: string + operateType?: string + operatorStatus?: string + remark?: string + taskHoldTimeGMT?: number + type?: string + operatorName?: string + operatorUserId?: string + activityId?: string + taskType?: string + taskExecuteType?: string + size?: number + operatorDisplayName?: string + files?: string + action?: string + actionExit?: string + dataId?: number + taskId?: string + digitalSign?: string + operatorPhotoUrl?: string + }[] +} + +export interface TerminateInstanceQuery { + /** 应用ID。 */ + appType: string + /** 应用秘钥。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 流程实例ID。 */ + processInstanceId: string +} + +export interface ExecuteTaskParams { + /** 审批结果。 */ + outResult: string + /** 是否不执行校验和关联操作,取值: */ + noExecuteExpressions?: string + /** 应用ID。 */ + appType: string + /** 更新的表单值。 */ + formDataJson?: string + /** 应用秘钥。 */ + systemToken: string + /** 语言,取值: */ + language?: string + /** 审批意见。 */ + remark: string + /** 实例ID。 */ + processInstanceId: string + /** 用户的userid。 */ + userId: string + /** 任务ID。 */ + taskId: number + /** 电子签名地址。 */ + digitalSignUrl?: string +} + +export interface ExecutePlatformTaskParams { + /** 审批结果,取值: */ + outResult: string + /** 是否不执行校验和关联操作,取值: */ + noExecuteExpressions?: string + /** 应用ID。 */ + appType: string + /** 更新的表单数据。 */ + formDataJson?: string + /** 应用秘钥。 */ + systemToken: string + /** 语言,取值: */ + language?: string + /** 审批意见。 */ + remark: string + /** 流程实例ID。 */ + processInstanceId: string + /** 用户的userid。 */ + userId: string +} + +export interface RedirectTaskParams { + /** 流程实例ID。 */ + processInstanceId: string + /** 是否应用管理员进行转交,取值: */ + byManager?: string + /** 应用ID。 */ + appType: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 语言,取值: */ + language?: string + /** 审批意见。 */ + remark: string + /** 新的任务处理人工号。 */ + nowActionExecutorId: string + /** 处理人的userid。 */ + userId: string + /** 任务ID。 */ + taskId: number +} + +export interface GetOpenUrlQuery { + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 宜搭附件地址。 */ + fileUrl: string + /** 临时地址失效时间,单位毫秒。 */ + timeout?: number +} + +export interface GetOpenUrlResponse { + result?: string +} + +export interface SaveFormRemarkParams { + /** 应用ID。 */ + appType: string + /** 应用秘钥。 */ + systemToken: string + /** 对评论进行回复。 */ + replyId?: number + /** 语言,取值: */ + language?: string + /** 实例ID。 */ + formInstanceId: string + /** 评论人的的useid。 */ + userId: string + /** 被@的用户userid,将评论内容通过钉钉发给指定用户。 */ + atUserId?: string + /** 评论内容。 */ + content: string +} + +export interface SaveFormRemarkResponse { + result?: number +} + +export interface ListNavigationByFormTypeQuery { + /** 应用ID。 */ + appType: string + /** 应用秘钥。 */ + systemToken: string + /** 评论人的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 页面类型,取值: */ + formType: string +} + +export interface ListNavigationByFormTypeResponse { + result?: { + title?: number + processCode?: string + formUuid?: string + }[] +} + +export interface ValidateOrderBuyQuery { + /** 访问秘钥。 */ + accessKey?: string + /** 调用者unionId。 */ + callerUid?: string +} + +export interface ValidateOrderBuyResponse { + message?: string + status?: number +} + +export interface GetRunningTasksQuery { + /** 流程实例ID。 */ + processInstanceId?: string + /** 应用ID。 */ + appType?: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken?: string + /** 语言,取值: */ + language?: string + /** 用户的userid。 */ + userId?: string +} + +export interface GetRunningTasksResponse { + result?: { + createTimeGMT?: string + activityId?: string + processInstanceId?: string + taskType?: string + titleInEnglish?: string + activeTimeGMT?: string + actualActionerId?: string + originatorId?: string + finishTimeGMT?: string + title?: string + taskId?: string + status?: string + }[] +} + +export interface GetActivityListQuery { + /** 流程编码。 */ + processCode?: string + /** 应用ID。 */ + appType?: string + /** 应用的秘钥。 */ + systemToken?: string + /** 语言,取值: */ + language?: string + /** 用户userid。 */ + userId?: string +} + +export interface GetActivityListResponse { + result?: { + activityName?: string + activityNameInEnglish?: string + activityId?: string + }[] +} + +export interface ExecuteCustomApiQuery { + /** 数据。 */ + data: string + /** 应用ID。 */ + appType: string + /** 应用秘钥。 */ + systemToken: string + /** 语言,取值: */ + language?: string + /** 服务ID。 */ + serviceId: string + /** 用户的userid。 */ + userId: string +} + +export interface ExecuteCustomApiResponse { + result?: string +} + +export interface SearchActivationCodeQuery { + /** 访问秘钥。 */ + accessKey?: string + /** 调用者unionId。 */ + callerUid: string +} + +export interface SearchActivationCodeResponse { + instanceId?: string + activationCode?: string + authType?: string + expireTimeGMT?: string + status?: number +} + +export interface GetSaleUserInfoByUserIdQuery { + /** 组织ID。 */ + corpId: string + /** 名称空间。 */ + namespace: string + /** 用户的userid。 */ + userId: string +} + +export interface GetSaleUserInfoByUserIdResponse { + userName?: string + userId?: string + accountId?: number + corpList?: { + namespace?: string + corpId?: string + corpName?: string + }[] +} + +export interface GetCorpLevelByAccountIdQuery { + /** 账户ID。 */ + accountId?: string +} + +export interface GetCorpLevelByAccountIdResponse { + result?: string +} + +export interface UpdateStatusParams { + /** 导入序列。 */ + importSequence?: string + /** 错误行列表。 */ + errorLines?: number[] + /** 应用ID。 */ + appType?: string + /** 应用秘钥。 */ + systemToken?: string + /** 语言,取值: */ + language?: string + /** 用户的userid。 */ + userId?: string + /** 状态。 */ + status?: string +} + +export interface ValidateOrderUpgradeQuery { + /** 实例ID。 */ + instanceId?: string + /** 访问秘钥。 */ + accessKey?: string + /** 调用者的unionId。 */ + callerUid?: string +} + +export interface ValidateOrderUpgradeResponse { + message?: string + status?: number +} + +export interface ReleaseCommodityQuery { + /** 实例ID。 */ + instanceId?: string + /** 访问秘钥。 */ + accessKey?: string + /** 调用者的unionId。 */ + callerUid?: string +} + +export interface ReleaseCommodityResponse { + message?: string + success?: unknown +} + +export interface ExpireCommodityQuery { + /** 实例ID。 */ + instanceId?: string + /** 访问秘钥。 */ + accessKey?: string + /** 调用者的unionId。 */ + callerUid?: string +} + +export interface ExpireCommodityResponse { + message?: string + success?: unknown +} + +export interface RefundCommodityQuery { + /** 实例ID。 */ + instanceId?: string + /** 访问秘钥。 */ + accessKey?: string + /** 调用者的unionId。 */ + callerUid?: string +} + +export interface RefundCommodityResponse { + message?: string + success?: unknown +} + +export interface SearchEmployeeFieldValuesParams { + /** 目标组件ID列表,JSON字符串。 */ + targetFieldJson?: string + /** 表单ID。 */ + formUuid?: string + /** 应用ID。 */ + appType?: string + /** 修改时间终止值。 */ + modifiedToTimeGMT?: string + /** 应用秘钥。 */ + systemToken?: string + /** 修改时间起始值。 */ + modifiedFromTimeGMT?: string + /** 语言,取值: */ + language?: string + /** 根据表单内组件值查询。 */ + searchFieldJson?: string + /** 根据流程发起人工号查询。 */ + originatorId?: string + /** 用户的userid。 */ + userId?: string + /** 创建时间终止值。 */ + createToTimeGMT?: string + /** 创建时间起始值。 */ + createFromTimeGMT?: string +} + +export interface SearchEmployeeFieldValuesResponse { + result?: string +} + +export interface DeleteSequenceQuery { + /** 用户的userid。 */ + userId?: string + /** 序列。 */ + sequence?: string + /** 应用秘钥。 */ + systemToken?: string + /** 语言,取值: */ + language?: string + /** 应用ID。 */ + appType?: string +} + +export interface SaveFormDataParams { + /** 应用编码。 */ + appType: string + /** 应用秘钥。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 表单ID。 */ + formUuid: string + /** 表单数据,示例:```"{\"textField_jcpm6agt\": \"单行\",\"employeeField_jcos0sar\": [\"workno\"]}"``` */ + formDataJson: string +} + +export interface SaveFormDataResponse { + result?: string +} + +export interface UpdateFormDataParams { + /** 应用ID。 */ + appType?: string + /** 应用秘钥。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 流程实例ID。 */ + formInstanceId: string + /** 使用最新的表单版本进行更新 */ + useLatestVersion?: unknown + /** 更新的表单数据,示例:```"{\"textField_jcpm6agt\": \"单行\",\"employeeField_jcos0sar\": [\"workno\"]}"``` */ + updateFormDataJson: string +} + +export interface SearchFormDatasParams { + /** 应用编码。 */ + appType: string + /** 应用秘钥。在应用数据中获取。 */ + systemToken: string + /** 用户userid。 */ + userId: string + /** 语言。取值: */ + language?: string + /** 表单ID。 */ + formUuid: string + /** 根据表单内组件值查询,示例值如下: */ + searchFieldJson?: string + /** 分页参数,当前页。 */ + currentPage?: number + /** 分页参数,每页显示条数。 */ + pageSize?: number + /** 根据数据提交人工号查询。 */ + originatorId?: string + /** 查询创建数据列表的开始时间,格式:`yyyy-MM-dd`。 */ + createFromTimeGMT?: string + /** 查询创建数据列表的结束时间,格式:`yyyy-MM-dd`。 */ + createToTimeGMT?: string + /** 查询修改数据列表的开始时间,格式:`yyyy-MM-dd`。 */ + modifiedFromTimeGMT?: string + /** 查询修改数据列表的结束时间,格式:`yyyy-MM-dd`。 */ + modifiedToTimeGMT?: string + /** 指定排序字段。 */ + dynamicOrder?: string +} + +export interface SearchFormDatasResponse { + currentPage?: number + totalCount?: number + data?: { + dataId?: number + formInstanceId?: string + createdTimeGMT?: string + modifiedTimeGMT?: string + formUuid?: string + modelUuid?: string + originator?: number + modifyUser?: number + formData?: number + title?: string + serialNo?: string + instanceValue?: string + version?: number + creatorUserId?: string + modifierUserId?: string + sequence?: string + }[] +} + +export interface GetInstancesParams { + /** 应用ID。 */ + appType: string + /** 应用密钥。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 表单ID。 */ + formUuid: string + /** + * 查询过滤条件,支持2种模式的过滤规则。 + * - 模式1:根据组件值模糊匹配,示例:{"textField_jcr0069m":"danhang","selectField_jcr0069q":"K"} + * - 模式2: 采用数据管理的查询过滤条件,匹配功能更强大,示例:[{"key":"currentNodeName","value":"步凡","type":"TEXT","operator":"like","componentName":"TextField”}],详情参考 + */ + searchFieldJson?: string + /** 根据流程发起人工号查询。 */ + originatorId?: string + /** 创建时间起始值。 */ + createFromTimeGMT?: string + /** 创建时间终止值。 */ + createToTimeGMT?: string + /** 修改时间起始值。 */ + modifiedFromTimeGMT?: string + /** 修改时间终止值。 */ + modifiedToTimeGMT?: string + /** 任务ID。 */ + taskId?: string + /** 实例状态。 */ + instanceStatus?: string + /** 流程审批结果。 */ + approvedResult?: string + /** 排序规则,参数值参考[宜搭使用手册](https://www.yuque.com/yida/support/agb8im#CQro8)。 */ + orderConfigJson?: string +} + +export interface GetInstancesQuery { + /** 分页页码。 */ + pageNumber?: number + /** 分页大小。 */ + pageSize?: number +} + +export interface GetInstancesResponse { + totalCount?: number + pageNumber?: number + data?: { + createTimeGMT?: string + processInstanceId?: string + actionExecutor?: number + approvedResult?: string + formUuid?: string + data?: number + processCode?: string + modifiedTimeGMT?: string + originator?: number + title?: string + instanceStatus?: string + version?: number + }[] +} + +export interface DeleteFormDataQuery { + /** 应用编码。 */ + appType: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 表单实例ID。 */ + formInstanceId: string +} + +export interface GetInstanceByIdQuery { + /** 应用ID。 */ + appType: string + /** 应用秘钥,在应用数据中获取。 */ + systemToken: string + /** 用户userid。 */ + userId: string + /** 语言,取值: */ + language?: string +} + +export interface GetInstanceByIdResponse { + createTimeGMT?: string + processInstanceId?: string + actionExecutor?: { + name?: number + deptName?: string + userId?: string + email?: string + }[] + approvedResult?: string + formUuid?: string + data?: unknown + modifiedTimeGMT?: string + processCode?: string + originator?: { + name?: number + deptName?: string + userId?: string + email?: string + } + title?: string + instanceStatus?: string + version?: number +} + +export interface StartInstanceParams { + /** 应用编码。 */ + appType: string + /** 应用秘钥。在应用数据中获取。 */ + systemToken: string + /** 用户的userid。 */ + userId: string + /** 语言,取值: */ + language?: string + /** 表单唯一编码。 */ + formUuid: string + /** 表单数据,示例: */ + formDataJson: string + /** 流程编码。 */ + processCode?: string + /** 发起人所在部门ID。 */ + departmentId?: string +} + +export interface StartInstanceResponse { + result?: string +} + +export interface GetFormDataByIDQuery { + /** 应用编码。 */ + appType?: string + /** 应用秘钥。 */ + systemToken?: string + /** 用户的userid。 */ + userId?: string + /** 语言,取值: */ + language?: string +} + +export interface GetFormDataByIDResponse { + originator?: { + userId?: string + name?: number + departmentName?: string + email?: string + } + modifiedTimeGMT?: string + formInstId?: string + formData?: unknown +} + +// funcName: isOldApi +Internal.define({ + '/yida/forms': { GET: { getFormListInApp: false } }, + '/yida/forms/formFields': { GET: { getFieldDefByUuid: false } }, + '/yida/tasks/batches/execute': { POST: { executeBatchTask: false } }, + '/yida/forms/operationsLogs/query': { POST: { listOperationLogs: false } }, + '/yida/forms/remarks/query': { POST: { listFormRemarks: false } }, + '/yida/services/invocationRecords': { GET: { queryServiceRecord: false } }, + '/yida/forms/instances/batchRemove': { + POST: { batchRemovalByFormInstanceIdList: false }, + }, + '/yida/forms/instances/components': { + PUT: { batchUpdateFormDataByInstanceId: false }, + }, + '/yida/forms/instances/datas': { + PUT: { batchUpdateFormDataByInstanceMap: false }, + }, + '/yida/organizations/applications': { GET: { listApplication: false } }, + '/yida/forms/instances/batchSave': { POST: { batchSaveFormData: false } }, + '/yida/forms/instances/advances/query': { + POST: { searchFormDataSecondGenerationNoTableField: false }, + }, + '/yida/forms/instances/insertOrUpdate': { + POST: { createOrUpdateFormData: false }, + }, + '/yida/forms/instances/advances/queryAll': { + POST: { searchFormDataSecondGeneration: false }, + }, + '/yida/forms/instances/ids/query': { + POST: { batchGetFormDataByIdList: false }, + }, + '/yida/tasks/taskCopies': { GET: { getTaskCopies: false } }, + '/yida/forms/instances/ids/{appType}/{formUuid}': { + POST: { searchFormDataIdList: false }, + }, + '/yida/forms/innerTables/{formInstanceId}': { + GET: { listTableDataByFormInstanceIdTableId: false }, + }, + '/yida/tasks/completedTasks/{corpId}/{userId}': { + GET: { getCorpAccomplishmentTasks: false }, + }, + '/yida/forms/definitions/{appType}/{formUuid}': { + GET: { getFormComponentDefinitionList: false }, + }, + '/yida/processes/instanceIds': { POST: { getInstanceIdList: false } }, + '/yida/processes/instances/searchWithIds': { + GET: { getInstancesByIdList: false }, + }, + '/yida/tasks/myCorpSubmission/{userId}': { + GET: { getMeCorpSubmission: false }, + }, + '/yida/processes/definitions/{processInstanceId}': { + GET: { getProcessDefinition: false }, + }, + '/yida/corpTasks': { GET: { getCorpTasks: false } }, + '/yida/corpNotifications/{userId}': { GET: { getNotifyMe: false } }, + '/yida/processDefinitions/buttons/{appType}/{processCode}/{activityId}': { + GET: { getActivityButtonList: false }, + }, + '/yida/authorization/platformResources': { + GET: { getApplicationAuthorizationServicePlatformResource: false }, + }, + '/yida/processes/instances': { + PUT: { updateInstance: false }, + DELETE: { deleteInstance: false }, + POST: { getInstances: false }, + }, + '/yida/processes/operationRecords': { GET: { getOperationRecords: false } }, + '/yida/processes/instances/terminate': { PUT: { terminateInstance: false } }, + '/yida/tasks/execute': { POST: { executeTask: false } }, + '/yida/tasks/platformTasks/execute': { POST: { executePlatformTask: false } }, + '/yida/tasks/redirect': { POST: { redirectTask: false } }, + '/yida/apps/temporaryUrls/{appType}': { GET: { getOpenUrl: false } }, + '/yida/forms/remarks': { POST: { saveFormRemark: false } }, + '/yida/apps/navigations': { GET: { listNavigationByFormType: false } }, + '/yida/apps/orderBuy/validate': { GET: { validateOrderBuy: false } }, + '/yida/processes/tasks/getRunningTasks': { GET: { getRunningTasks: false } }, + '/yida/processes/activities': { GET: { getActivityList: false } }, + '/yida/apps/customApi/execute': { POST: { executeCustomApi: false } }, + '/yida/apps/activationCode/information': { + GET: { searchActivationCode: false }, + }, + '/yida/apps/saleUserInfo': { GET: { getSaleUserInfoByUserId: false } }, + '/yida/apps/corpLevel': { GET: { getCorpLevelByAccountId: false } }, + '/yida/forms/status': { PUT: { updateStatus: false } }, + '/yida/apps/orderUpgrade/validate': { GET: { validateOrderUpgrade: false } }, + '/yida/appAuth/commodities/release': { DELETE: { releaseCommodity: false } }, + '/yida/appAuth/commodities/expire': { PUT: { expireCommodity: false } }, + '/yida/appAuth/commodities/refund': { POST: { refundCommodity: false } }, + '/yida/forms/employeeFields': { POST: { searchEmployeeFieldValues: false } }, + '/yida/forms/deleteSequence': { DELETE: { deleteSequence: false } }, + '/yida/forms/instances': { + POST: { saveFormData: false }, + PUT: { updateFormData: false }, + DELETE: { deleteFormData: false }, + }, + '/yida/forms/instances/search': { POST: { searchFormDatas: false } }, + '/yida/processes/instancesInfos/{id}': { GET: { getInstanceById: false } }, + '/yida/processes/instances/start': { POST: { startInstance: false } }, + '/yida/forms/instances/{id}': { GET: { getFormDataByID: false } }, +}) +declare module '../internal' { + interface Internal { + /** + * 获取应用内表单列表信息 + * @see https://developers.dingtalk.com/document/app/depending-on-the-application-id-to-get-the-form-list + */ + getFormListInApp( + query: GetFormListInAppQuery, + ): Promise + /** + * 根据表单ID获取字段信息 + * @see https://developers.dingtalk.com/document/isvapp/get-form-field-information-based-on-form-uuid + */ + getFieldDefByUuid( + query: GetFieldDefByUuidQuery, + ): Promise + /** + * 批量审批 + * @see https://developers.dingtalk.com/document/app/bulk-approval + */ + executeBatchTask( + params: ExecuteBatchTaskParams, + ): Promise + /** + * 查询表单的变更记录 + * @see https://developers.dingtalk.com/document/app/query-the-operation-records-of-a-form + */ + listOperationLogs( + params: ListOperationLogsParams, + ): Promise + /** + * 查询表单实例评论列表 + * @see https://developers.dingtalk.com/document/isvapp/batch-query-of-comments-appropriate-for-form-instances + */ + listFormRemarks( + params: ListFormRemarksParams, + ): Promise + /** + * 查询服务调用记录 + * @see https://developers.dingtalk.com/document/isvapp/execution-records-of-form-service-calls + */ + queryServiceRecord( + query: QueryServiceRecordQuery, + ): Promise + /** + * 批量删除指定的表单实例 + * @see https://developers.dingtalk.com/document/isvapp/delete-multiple-form-instances + */ + batchRemovalByFormInstanceIdList( + params: BatchRemovalByFormInstanceIdListParams, + ): Promise + /** + * 将多条表单实例的指定表单组件更新成指定值 + * @see https://developers.dingtalk.com/document/isvapp/batch-update-of-component-values-in-form-instances + */ + batchUpdateFormDataByInstanceId( + params: BatchUpdateFormDataByInstanceIdParams, + ): Promise + /** + * 通过表单实例数据批量更新表单实例 + * @see https://developers.dingtalk.com/document/isvapp/batch-update-of-form-instances-through-form-component-data + */ + batchUpdateFormDataByInstanceMap( + params: BatchUpdateFormDataByInstanceMapParams, + ): Promise + /** + * 获取组织下的宜搭应用列表 + * @see https://developers.dingtalk.com/document/isvapp/query-the-application-list + */ + listApplication( + query: ListApplicationQuery, + ): Promise + /** + * 批量保存表单实例数据 + * @see https://developers.dingtalk.com/document/isvapp/create-multiple-form-instances + */ + batchSaveFormData( + params: BatchSaveFormDataParams, + ): Promise + /** + * 通过高级查询条件查询表单实例数据(不返回子表单组件数据) + * @see https://developers.dingtalk.com/document/isvapp/obtain-form-instance-data-using-advanced-query-conditions-excluding-subform + */ + searchFormDataSecondGenerationNoTableField( + params: SearchFormDataSecondGenerationNoTableFieldParams, + ): Promise + /** + * 新增或更新表单实例 + * @see https://developers.dingtalk.com/document/isvapp/add-or-update-form-instances + */ + createOrUpdateFormData( + params: CreateOrUpdateFormDataParams, + ): Promise + /** + * 通过高级检索条件查询表单实例 + * @see https://developers.dingtalk.com/document/isvapp/query-form-instances-using-advanced-search-conditions + */ + searchFormDataSecondGeneration( + params: SearchFormDataSecondGenerationParams, + ): Promise + /** + * 批量获取指定表单实例ID列表对应的表单实例数据 + * @see https://developers.dingtalk.com/document/isvapp/obtain-multiple-form-instance-data + */ + batchGetFormDataByIdList( + params: BatchGetFormDataByIdListParams, + ): Promise + /** + * 查询抄送我的任务列表(应用维度) + * @see https://developers.dingtalk.com/document/app/query-copied-my-task-list-application-dimension + */ + getTaskCopies(query: GetTaskCopiesQuery): Promise + /** + * 根据条件搜索表单实例 ID 列表 + * @see https://developers.dingtalk.com/document/app/obtain-the-ids-of-multiple-form-instances + */ + searchFormDataIdList( + appType: string, + formUuid: string, + query: SearchFormDataIdListQuery, + params: SearchFormDataIdListParams, + ): Promise + /** + * 获取子表单数据 + * @see https://developers.dingtalk.com/document/app/obtain-child-table-component-data + */ + listTableDataByFormInstanceIdTableId( + formInstanceId: string, + query: ListTableDataByFormInstanceIdTableIdQuery, + ): Promise + /** + * 查询已完成任务列表 + * @see https://developers.dingtalk.com/document/app/obtains-the-completed-approval-tasks-in-an-organization + */ + getCorpAccomplishmentTasks( + corpId: string, + userId: string, + query: GetCorpAccomplishmentTasksQuery, + ): Promise + /** + * 获取表单定义 + * @see https://developers.dingtalk.com/document/app/get-a-list-of-form-component-definitions + */ + getFormComponentDefinitionList( + appType: string, + formUuid: string, + query: GetFormComponentDefinitionListQuery, + ): Promise + /** + * 根据条件搜索流程实例 ID + * @see https://developers.dingtalk.com/document/app/obtains-a-list-of-instance-ids + */ + getInstanceIdList( + query: GetInstanceIdListQuery, + params: GetInstanceIdListParams, + ): Promise + /** + * 根据实例 ID 列表批量获取流程实例详情 + * @see https://developers.dingtalk.com/document/app/queries-multiple-process-instances + */ + getInstancesByIdList( + query: GetInstancesByIdListQuery, + ): Promise + /** + * 获取组织内某人提交的任务 + * @see https://developers.dingtalk.com/document/app/obtains-the-tasks-submitted-by-someone-in-an-organization + */ + getMeCorpSubmission( + userId: string, + query: GetMeCorpSubmissionQuery, + ): Promise + /** + * 获取流程定义 + * @see https://developers.dingtalk.com/document/isvapp-server/obtain-process-definition + */ + getProcessDefinition( + processInstanceId: string, + query: GetProcessDefinitionQuery, + ): Promise + /** + * 查询待办任务列表 + * @see https://developers.dingtalk.com/document/app/query-tasks-from-the-organization-dimension + */ + getCorpTasks(query: GetCorpTasksQuery): Promise + /** + * 查询抄送我的任务列表(企业维度) + * @see https://developers.dingtalk.com/document/app/get-notifications-sent-to-users + */ + getNotifyMe( + userId: string, + query: GetNotifyMeQuery, + ): Promise + /** + * 获取流程节点按钮列表 + * @see https://developers.dingtalk.com/document/isvapp-server/obtain-a-list-of-process-node-buttons-1 + */ + getActivityButtonList( + appType: string, + processCode: string, + activityId: string, + query: GetActivityButtonListQuery, + ): Promise + /** + * 获取平台服务资源 + * @see https://developers.dingtalk.com/document/isvapp-server/obtain-platform-service-resources + */ + getApplicationAuthorizationServicePlatformResource( + query: GetApplicationAuthorizationServicePlatformResourceQuery, + ): Promise + /** + * 更新流程实例 + * @see https://developers.dingtalk.com/document/isvapp-server/update-process-instance-1 + */ + updateInstance(params: UpdateInstanceParams): Promise + /** + * 删除流程实例 + * @see https://developers.dingtalk.com/document/app/delete-process-instance + */ + deleteInstance(query: DeleteInstanceQuery): Promise + /** + * 获取审批记录 + * @see https://developers.dingtalk.com/document/app/queries-an-approval-record + */ + getOperationRecords( + query: GetOperationRecordsQuery, + ): Promise + /** + * 终止流程实例 + * @see https://developers.dingtalk.com/document/app/terminate-a-process-instance + */ + terminateInstance(query: TerminateInstanceQuery): Promise + /** + * 执行审批任务 + * @see https://developers.dingtalk.com/document/app/execute-approval-tasks + */ + executeTask(params: ExecuteTaskParams): Promise + /** + * 执行宜搭平台的审批任务 + * @see https://developers.dingtalk.com/document/isvapp-server/execute-appropriate-approval-tasks + */ + executePlatformTask(params: ExecutePlatformTaskParams): Promise + /** + * 执行转交任务 + * @see https://developers.dingtalk.com/document/app/transfer-tasks + */ + redirectTask(params: RedirectTaskParams): Promise + /** + * 附件地址转临时免登地址 + * @see https://developers.dingtalk.com/document/isvapp/obtain-the-temporary-free-access-address-of-yixian-accessories + */ + getOpenUrl( + appType: string, + query: GetOpenUrlQuery, + ): Promise + /** + * 提交表单/流程实例下的评论 + * @see https://developers.dingtalk.com/document/app/submit-comment + */ + saveFormRemark( + params: SaveFormRemarkParams, + ): Promise + /** + * 获取应用下的页面列表 + * @see https://developers.dingtalk.com/document/isvapp-server/obtains-the-page-list-under-an-application + */ + listNavigationByFormType( + query: ListNavigationByFormTypeQuery, + ): Promise + /** + * 多渠道新购校验 + * @see https://developers.dingtalk.com/document/isvapp-server/multi-channel-new-purchase-verification + */ + validateOrderBuy( + query: ValidateOrderBuyQuery, + ): Promise + /** + * 查询流程运行任务(vpc) + * @see https://developers.dingtalk.com/document/app/query-process-running-tasks-vpc + */ + getRunningTasks( + query: GetRunningTasksQuery, + ): Promise + /** + * 获取流程设计的节点信息 + * @see https://developers.dingtalk.com/document/isvapp-server/obtain-the-information-about-the-nodes-in-process-design-1 + */ + getActivityList( + query: GetActivityListQuery, + ): Promise + /** + * 执行自定义API + * @see https://developers.dingtalk.com/document/isvapp-server/run-custom-api + */ + executeCustomApi( + query: ExecuteCustomApiQuery, + ): Promise + /** + * 查询激活码 + * @see https://developers.dingtalk.com/document/isvapp-server/query-activation-code + */ + searchActivationCode( + query: SearchActivationCodeQuery, + ): Promise + /** + * 查询销售用户信息 + * @see https://developers.dingtalk.com/document/isvapp-server/query-sales-user-information + */ + getSaleUserInfoByUserId( + query: GetSaleUserInfoByUserIdQuery, + ): Promise + /** + * 查询企业级别 + * @see https://developers.dingtalk.com/document/isvapp-server/query-enterprise-level + */ + getCorpLevelByAccountId( + query: GetCorpLevelByAccountIdQuery, + ): Promise + /** + * 更新状态 + * @see https://developers.dingtalk.com/document/isvapp-server/update-status + */ + updateStatus(params: UpdateStatusParams): Promise + /** + * 校验订单的升级 + * @see https://developers.dingtalk.com/document/isvapp-server/verification-order-upgrade + */ + validateOrderUpgrade( + query: ValidateOrderUpgradeQuery, + ): Promise + /** + * 发布商品 + * @see https://developers.dingtalk.com/document/isvapp-server/release-products + */ + releaseCommodity( + query: ReleaseCommodityQuery, + ): Promise + /** + * 使商品过期 + * @see https://developers.dingtalk.com/document/isvapp-server/make-goods-expire + */ + expireCommodity( + query: ExpireCommodityQuery, + ): Promise + /** + * 退还商品 + * @see https://developers.dingtalk.com/document/isvapp-server/refund-of-goods + */ + refundCommodity( + query: RefundCommodityQuery, + ): Promise + /** + * 搜索表单中指定人员组件的值 + * @see https://developers.dingtalk.com/document/app/gets-the-value-of-the-employee-component + */ + searchEmployeeFieldValues( + params: SearchEmployeeFieldValuesParams, + ): Promise + /** + * 删除序列 + * @see https://developers.dingtalk.com/document/isvapp-server/delete-sequence + */ + deleteSequence(query: DeleteSequenceQuery): Promise + /** + * 新增表单实例 + * @see https://developers.dingtalk.com/document/app/save-form-data + */ + saveFormData(params: SaveFormDataParams): Promise + /** + * 更新表单实例 + * @see https://developers.dingtalk.com/document/orgapp/update-form-data + */ + updateFormData(params: UpdateFormDataParams): Promise + /** + * 根据条件搜索表单实例详情列表,对应原searchFormDatas + * @see https://developers.dingtalk.com/document/app/querying-form-instance-data + */ + searchFormDatas( + params: SearchFormDatasParams, + ): Promise + /** + * 根据搜索条件获取流程表单实例详情 + * @see https://developers.dingtalk.com/document/app/obtain-process-instance + */ + getInstances( + query: GetInstancesQuery, + params: GetInstancesParams, + ): Promise + /** + * 删除表单实例 + * @see https://developers.dingtalk.com/document/app/delete-form-data + */ + deleteFormData(query: DeleteFormDataQuery): Promise + /** + * 根据实例 ID 获取流程实例详情 + * @see https://developers.dingtalk.com/document/app/queries-a-process-instance-based-on-its-id + */ + getInstanceById( + id: string, + query: GetInstanceByIdQuery, + ): Promise + /** + * 发起新的流程实例 + * @see https://developers.dingtalk.com/document/app/initiate-the-approval-process + */ + startInstance(params: StartInstanceParams): Promise + /** + * 根据表单 ID 查询实例详情 + * @see https://developers.dingtalk.com/document/app/query-form-data + */ + getFormDataByID( + id: string, + query: GetFormDataByIDQuery, + ): Promise + } +} diff --git a/adapters/dingtalk/src/bot.ts b/adapters/dingtalk/src/bot.ts new file mode 100644 index 00000000..8d73a5d0 --- /dev/null +++ b/adapters/dingtalk/src/bot.ts @@ -0,0 +1,110 @@ +import { Bot, Context, Logger, Quester, Schema } from '@satorijs/satori' +import { HttpServer } from './http' +import { DingtalkMessageEncoder } from './message' +import { WsClient } from './ws' +import { Internal } from './internal' + +const logger = new Logger('dingtalk') + +// https://open.dingtalk.com/document/orgapp/enterprise-created-chatbot +export class DingtalkBot extends Bot { + static MessageEncoder = DingtalkMessageEncoder + public oldHttp: Quester + public http: Quester + public internal: Internal + refreshTokenTimer: NodeJS.Timeout + + constructor(ctx: Context, config: DingtalkBot.Config) { + super(ctx, config) + this.platform = 'dingtalk' + this.http = ctx.http.extend(config.api) + this.oldHttp = ctx.http.extend(config.oldApi) + this.internal = new Internal(this) + + if (config.protocol === 'http') { + ctx.plugin(HttpServer, this) + } else if (config.protocol === 'ws') { + ctx.plugin(WsClient, this) + } + } + + async initialize() { + const { appList } = await this.internal.OapiMicroappList() + const self = appList.find(v => v.agentId === this.config.agentId) + this.username = self.name + this.avatar = self.appIcon + } + + // @ts-ignore + stop(): Promise { + clearTimeout(this.refreshTokenTimer) + } + + public token: string + + async refreshToken() { + const data = await this.internal.getAccessToken({ + appKey: this.config.appkey, + appSecret: this.config.secret, + }) + logger.debug('gettoken result: %o', data) + this.token = data.accessToken + // https://open.dingtalk.com/document/orgapp/authorization-overview + this.http = this.http.extend({ + headers: { + 'x-acs-dingtalk-access-token': data.accessToken, + }, + }).extend(this.config.api) + this.refreshTokenTimer = setTimeout(this.refreshToken.bind(this), (data.expireIn - 10) * 1000) + } + + // https://open.dingtalk.com/document/orgapp/download-the-file-content-of-the-robot-receiving-message + async downloadFile(downloadCode: string): Promise { + const { downloadUrl } = await this.internal.robotMessageFileDownload({ + downloadCode, robotCode: this.selfId, + }) + return downloadUrl + } + + async deleteMessage(channelId: string, messageId: string): Promise { + if (channelId.startsWith('cid')) { + await this.internal.orgGroupRecall({ + robotCode: this.selfId, + processQueryKeys: [messageId], + openConversationId: channelId, + }) + } else { + await this.internal.batchRecallOTO({ + robotCode: this.selfId, + processQueryKeys: [messageId], + }) + } + } +} + +export namespace DingtalkBot { + export interface Config extends Bot.Config, WsClient.Config { + secret: string + protocol: string + appkey: string + agentId: number + api: Quester.Config + oldApi: Quester.Config + } + + export const Config: Schema = Schema.intersect([ + Schema.object({ + protocol: process.env.KOISHI_ENV === 'browser' + ? Schema.const('ws').default('ws') + : Schema.union(['http', 'ws']).description('选择要使用的协议。').required(), + }), + Schema.object({ + secret: Schema.string().required().description('机器人密钥。'), + agentId: Schema.number().required().description('AgentId'), + appkey: Schema.string().required(), + api: Quester.createConfig('https://api.dingtalk.com/v1.0/'), + oldApi: Quester.createConfig('https://oapi.dingtalk.com/'), + }), + WsClient.Config, + ]) +} diff --git a/adapters/dingtalk/src/http.ts b/adapters/dingtalk/src/http.ts new file mode 100644 index 00000000..a9af42fe --- /dev/null +++ b/adapters/dingtalk/src/http.ts @@ -0,0 +1,39 @@ +import { Adapter, Context, Logger } from '@satorijs/satori' +import { DingtalkBot } from './bot' +import crypto from 'node:crypto' +import { Message } from './types' +import { decodeMessage } from './utils' + +export class HttpServer extends Adapter.Server { + logger = new Logger('dingtalk') + constructor(ctx: Context, bot: DingtalkBot) { + super() + } + + async start(bot: DingtalkBot) { + await bot.refreshToken() + bot.selfId = bot.config.appkey + await bot.initialize() + // https://open.dingtalk.com/document/orgapp/receive-message + bot.ctx.router.post('/dingtalk', async (ctx) => { + const timestamp = ctx.get('timestamp') + const sign = ctx.get('sign') + + if (!timestamp || !sign) return ctx.status = 403 + const timeDiff = Math.abs(Date.now() - Number(timestamp)) + if (timeDiff > 3600000) return ctx.status = 401 + const signContent = timestamp + '\n' + bot.config.secret + const computedSign = crypto + .createHmac('sha256', bot.config.secret) + .update(signContent) + .digest('base64') + + if (computedSign !== sign) return ctx.status = 403 + const body = ctx.request.body as Message + this.logger.debug(require('util').inspect(body, false, null, true)) + const session = await decodeMessage(bot, body) + this.logger.debug(require('util').inspect(session, false, null, true)) + if (session) bot.dispatch(session) + }) + } +} diff --git a/adapters/dingtalk/src/index.ts b/adapters/dingtalk/src/index.ts new file mode 100644 index 00000000..1a34536a --- /dev/null +++ b/adapters/dingtalk/src/index.ts @@ -0,0 +1,9 @@ +import { DingtalkBot } from './bot' + +export * from './bot' +export * from './utils' +export * from './types' +export * from './http' +export * from './message' + +export default DingtalkBot diff --git a/adapters/dingtalk/src/internal.ts b/adapters/dingtalk/src/internal.ts new file mode 100644 index 00000000..00d73bd2 --- /dev/null +++ b/adapters/dingtalk/src/internal.ts @@ -0,0 +1,47 @@ +import { Dict, Quester } from '@satorijs/satori' +import { DingtalkBot } from './bot' + +export class Internal { + constructor(private bot: DingtalkBot) { } + + static define(routes: Dict>>>) { + for (const path in routes) { + for (const key in routes[path]) { + const method = key as Quester.Method + for (const name of Object.keys(routes[path][method])) { + const isOldApi = routes[path][method][name] + Internal.prototype[name] = async function (this: Internal, ...args: any[]) { + const raw = args.join(', ') + const url = path.replace(/\{([^}]+)\}/g, () => { + if (!args.length) throw new Error(`too few arguments for ${path}, received ${raw}`) + return args.shift() + }) + const config: Quester.AxiosRequestConfig = {} + if (args.length === 1) { + if (method === 'GET' || method === 'DELETE') { + config.params = args[0] + } else { + config.data = args[0] + } + } else if (args.length === 2 && method !== 'GET' && method !== 'DELETE') { + config.data = args[0] + config.params = args[1] + } else if (args.length > 1) { + throw new Error(`too many arguments for ${path}, received ${raw}`) + } + const quester = isOldApi ? this.bot.oldHttp : this.bot.http + if (isOldApi) { + config.params = { ...config.params, access_token: this.bot.token } + } + try { + return await quester(method, url, config) + } catch (error) { + if (!Quester.isAxiosError(error) || !error.response) throw error + throw new Error(`[${error.response.status}] ${JSON.stringify(error.response.data)}`) + } + } + } + } + } + } +} diff --git a/adapters/dingtalk/src/message.ts b/adapters/dingtalk/src/message.ts new file mode 100644 index 00000000..8ca36f8c --- /dev/null +++ b/adapters/dingtalk/src/message.ts @@ -0,0 +1,137 @@ +import { Dict, h, MessageEncoder } from '@satorijs/satori' +import { DingtalkBot } from './bot' +import FormData from 'form-data' +import { SendMessageData } from './types' + +export const escape = (val: string) => + val + .replace(/(?])/g, '\\$&') + .replace(/([\-\*]|\d\.) /g, '\u200B$&') + .replace(/^(\s{4})/gm, '\u200B    ') + +export const unescape = (val: string) => + val + .replace(/\u200b([\*_~`])/g, '$1') + +export class DingtalkMessageEncoder extends MessageEncoder { + buffer = '' + + /** + * Markdown: https://open.dingtalk.com/document/isvapp/robot-message-types-and-data-format + */ + + hasRichContent = true + async flush(): Promise { + if (this.buffer.length && !this.hasRichContent) { + await this.sendMessage('sampleText', { + content: this.buffer, + }) + } else if (this.buffer.length && this.hasRichContent) { + await this.sendMessage('sampleMarkdown', { + text: this.buffer.replace(/\n/g, '\n\n'), + }) + } + } + + // https://open.dingtalk.com/document/orgapp/the-robot-sends-a-group-message + async sendMessage(msgType: T, msgParam: SendMessageData[T]) { + const { processQueryKey } = this.session.isDirect ? await this.bot.internal.batchSendOTO({ + msgKey: msgType, + msgParam: JSON.stringify(msgParam), + robotCode: this.bot.config.appkey, + userIds: [this.session.channelId], + }) : await this.bot.internal.orgGroupSend({ + // https://open.dingtalk.com/document/orgapp/types-of-messages-sent-by-robots + msgKey: msgType, + msgParam: JSON.stringify(msgParam), + robotCode: this.bot.config.appkey, + openConversationId: this.channelId, + }) + const session = this.bot.session() + session.messageId = processQueryKey + session.channelId = this.session.channelId + session.guildId = this.session.guildId + console.log(session, processQueryKey) + session.app.emit(session, 'send', session) + this.results.push(session) + } + + // https://open.dingtalk.com/document/orgapp/upload-media-files?spm=ding_open_doc.document.0.0.3b166172ERBuHw + async uploadMedia(attrs: Dict) { + const { data, mime } = await this.bot.ctx.http.file(attrs.url, attrs) + const form = new FormData() + // https://github.com/form-data/form-data/issues/468 + const value = process.env.KOISHI_ENV === 'browser' + ? new Blob([data], { type: mime }) + : Buffer.from(data) + let type + if (mime.startsWith('image/') || mime.startsWith('video/')) { + type = mime.split('/')[0] + } else if (mime.startsWith('audio/')) { + type = 'voice' + } else { + type = 'file' + } + form.append('type', type) + form.append('media', value) + const { media_id } = await this.bot.oldHttp.post('/media/upload', form, { + headers: form.getHeaders(), + }) + return media_id + } + + private listType: 'ol' | 'ul' = null + + async visit(element: h) { + const { type, attrs, children } = element + if (type === 'text') { + this.buffer += escape(attrs.content) + } else if (type === 'image' && attrs.url) { + // await this.flush() + // await this.sendMessage('sampleImageMsg', { + // photoURL: attrs.url + // }) + this.buffer += `![${attrs.alt}](${attrs.url})` + } else if (type === 'message') { + await this.flush() + await this.render(children) + } else if (type === 'at') { + this.buffer += `@${attrs.id}` + } else if (type === 'p') { + this.buffer += '\n' + await this.render(children) + this.buffer += '\n' + } else if (type === 'b' || type === 'strong') { + this.buffer += ` **` + await this.render(children) + this.buffer += `** ` + } else if (type === 'i' || type === 'em') { + this.buffer += ` *` + await this.render(children) + this.buffer += `* ` + } else if (type === 'a' && attrs.href) { + this.buffer += `[` + await this.render(children) + this.buffer += `](${encodeURI(attrs.href)})` + } else if (type === 'ul' || type === 'ol') { + this.listType = type + await this.render(children) + this.listType = null + } else if (type === 'li') { + if (!this.buffer.endsWith('\n')) this.buffer += '\n' + if (this.listType === 'ol') { + this.buffer += `1. ` + } else if (this.listType === 'ul') { + this.buffer += '- ' + } + this.render(children) + this.buffer += '\n' + } else if (type === 'blockquote') { + if (!this.buffer.endsWith('\n')) this.buffer += '\n' + this.buffer += '> ' + await this.render(children) + this.buffer += '\n\n' + } + } +} diff --git a/adapters/dingtalk/src/types/index.ts b/adapters/dingtalk/src/types/index.ts new file mode 100644 index 00000000..31ad1834 --- /dev/null +++ b/adapters/dingtalk/src/types/index.ts @@ -0,0 +1,140 @@ +export type AtUser = { + dingtalkId: string + staffId?: string // 企业内部群有的发送者在企业内的userid +} + +export type DingtalkRequestBase = { + msgtype: string // 消息类型 + msgId: string // 加密的消息ID + createAt: string // 消息的时间戳,单位毫秒 + conversationType: string // 1:单聊 2:群聊 + conversationId: string // 会话ID + conversationTitle?: string // 群聊时才有的会话标题 + senderId: string // 加密的发送者ID + senderNick: string // 发送者昵称 + senderCorpId?: string // 企业内部群有的发送者当前群的企业corpId + sessionWebhook: string // 当前会话的Webhook地址 + sessionWebhookExpiredTime: number // 当前会话的Webhook地址过期时间 + isAdmin?: boolean // 是否为管理员 + chatbotCorpId?: string // 加密的机器人所在的企业corpId + isInAtList?: boolean // 是否在@列表中 + senderStaffId?: string // 企业内部群中@该机器人的成员userid + chatbotUserId: string // 加密的机器人ID + atUsers?: AtUser[] // 被@人的信息 + robotCode: string +} + +export type Message = TextMessage | RichTextMessage | PictureMessage | FileMessage + +export interface TextMessage extends DingtalkRequestBase { + msgtype: 'text' + text: { + content: string + } +} + +export interface FileMessage extends DingtalkRequestBase { + msgtype: 'file' + content: { + spaceId: string + fileName: string + downloadCode: string + fileId: string + } +} + +export interface PictureMessage extends DingtalkRequestBase { + msgtype: 'picture' + content: { + downloadCode: string + } +} + +export interface RichTextMessage extends DingtalkRequestBase { + msgtype: 'richText' + content: { + richText: ({ + text: string + } & { + pictureDownloadCode: string + downloadCode: string + type: 'picture' + })[] + } +} + +// https://open.dingtalk.com/document/orgapp/types-of-messages-sent-by-robots +export interface SendMessageData { + sampleText: { content: string } + sampleMarkdown: { + title?: string + text: string + } + sampleImageMsg: { + photoURL: string + } + sampleLink: { + text: string + title: string + picUrl: string + messageUrl: string + } + sampleAudio: { + mediaId: string + duration: string + } + sampleFile: { + mediaId: string + fileName: string + fileType: string + } + sampleVideo: { + duration: string + videoMediaId: string + videoType: string + picMediaId: string + } +} + +export * from '../api/oauth2' +export * from '../api/oapi' +export * from '../api/contact' +export * from '../api/swform' +export * from '../api/hrm' +export * from '../api/todo' +export * from '../api/attendance' +export * from '../api/calendar' +export * from '../api/blackboard' +export * from '../api/microApp' +export * from '../api/im' +export * from '../api/connector' +export * from '../api/exclusive' +export * from '../api/alitrip' +export * from '../api/project' +export * from '../api/edu' +export * from '../api/crm' +export * from '../api/yida' +export * from '../api/drive' +export * from '../api/workbench' +export * from '../api/robot' +export * from '../api/conference' +export * from '../api/serviceGroup' +export * from '../api/customerService' +export * from '../api/esign' +export * from '../api/jzcrm' +export * from '../api/badge' +export * from '../api/datacenter' +export * from '../api/resident' +export * from '../api/wiki' +export * from '../api/storage' +export * from '../api/doc' +export * from '../api/diot' +export * from '../api/h3yun' +export * from '../api/link' +export * from '../api/pedia' +export * from '../api/devicemng' +export * from '../api/convFile' +export * from '../api/industry' +export * from '../api/live' +export * from '../api/card' +export * from '../api/rooms' diff --git a/adapters/dingtalk/src/utils.ts b/adapters/dingtalk/src/utils.ts new file mode 100644 index 00000000..ffc2d09d --- /dev/null +++ b/adapters/dingtalk/src/utils.ts @@ -0,0 +1,49 @@ +import { h, Session } from '@satorijs/satori' +import { Message } from './types' +import { DingtalkBot } from './bot' + +export async function decodeMessage(bot: DingtalkBot, body: Message): Promise { + const session = bot.session() + session.type = 'message' + session.messageId = body.msgId + session.isDirect = body.conversationType === '1' + session.guildId = body.chatbotCorpId + + if (body.conversationTitle) session.channelName = body.conversationTitle + session.userId = body.senderStaffId + session.author = { + userId: body.senderStaffId, + username: body.senderNick, + roles: body.isAdmin ? ['admin'] : [], + } + session.timestamp = Number(body.createAt) + if (body.msgtype === 'text') { + session.elements = [h.text(body.text.content)] + } else if (body.msgtype === 'richText') { + const elements: h[] = [] + for (const item of body.content.richText) { + if (item.text) elements.push(h.text(item.text)) + if (item.downloadCode) { + const url = await bot.downloadFile(item.downloadCode) + elements.push(h.image(url)) + } + } + session.elements = elements + } else if (body.msgtype === 'picture') { + session.elements = [h.image(await bot.downloadFile(body.content.downloadCode))] + } else if (body.msgtype === 'file') { + session.elements = [h.file(await bot.downloadFile(body.content.downloadCode))] + } else { + return + } + if (!session.isDirect) { + // group message + const atUsers = body.atUsers.filter(v => v.dingtalkId !== body.chatbotUserId).map(v => h.at(v.staffId)) + session.elements = [h.at(body.robotCode), ...atUsers, ...session.elements] + session.channelId = body.conversationId + } else { + session.channelId = session.userId + } + session.content = session.elements.join('') + return session +} diff --git a/adapters/dingtalk/src/ws.ts b/adapters/dingtalk/src/ws.ts new file mode 100644 index 00000000..ba3d853d --- /dev/null +++ b/adapters/dingtalk/src/ws.ts @@ -0,0 +1,55 @@ +import { Adapter, Schema } from '@satorijs/satori' +import { DingtalkBot } from './bot' +import { decodeMessage } from './utils' + +export class WsClient extends Adapter.WsClient { + async prepare() { + await this.bot.refreshToken() + this.bot.selfId = this.bot.config.appkey + await this.bot.initialize() + const { endpoint, ticket } = await this.bot.http.post<{ + endpoint: string + ticket: string + }>('/gateway/connections/open', { + clientId: this.bot.config.appkey, + clientSecret: this.bot.config.secret, + subscriptions: [ + { + type: 'CALLBACK', + topic: '/v1.0/im/bot/messages/get', + }, + ], + }) + return this.bot.http.ws(`${endpoint}?ticket=${ticket}`) + } + + accept() { + this.bot.online() + this.bot.socket.addEventListener('message', async ({ data }) => { + const parsed = JSON.parse(data.toString()) + this.ctx.logger('dingtalk').debug(require('util').inspect(parsed, false, null, true)) + if (parsed.type === 'SYSTEM') { + if (parsed.headers.topic === 'ping') { + this.bot.socket.send(JSON.stringify({ + code: 200, + headers: parsed.headers, + message: 'OK', + data: parsed.data, + })) + } + } else if (parsed.type === 'CALLBACK') { + this.ctx.logger('dingtalk').debug(require('util').inspect(JSON.parse(parsed.data), false, null, true)) + const session = await decodeMessage(this.bot, JSON.parse(parsed.data)) + if (session) this.bot.dispatch(session) + this.ctx.logger('dingtalk').debug(require('util').inspect(session, false, null, true)) + } + }) + } +} + +export namespace WsClient { + export interface Config extends Adapter.WsClient.Config { } + export const Config: Schema = Schema.intersect([ + Adapter.WsClient.Config, + ] as const) +} diff --git a/adapters/dingtalk/tsconfig.json b/adapters/dingtalk/tsconfig.json new file mode 100644 index 00000000..a14e38f4 --- /dev/null +++ b/adapters/dingtalk/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src", + }, + "include": [ + "src", + ], +} diff --git a/adapters/discord/.npmignore b/adapters/discord/.npmignore new file mode 100644 index 00000000..7e5fcbc1 --- /dev/null +++ b/adapters/discord/.npmignore @@ -0,0 +1,2 @@ +.DS_Store +tsconfig.tsbuildinfo diff --git a/adapters/discord/package.json b/adapters/discord/package.json index 05d2964a..500f9a11 100644 --- a/adapters/discord/package.json +++ b/adapters/discord/package.json @@ -1,7 +1,7 @@ { "name": "@satorijs/adapter-discord", "description": "Discord Adapter for Satorijs", - "version": "3.6.2", + "version": "3.8.5", "main": "lib/index.js", "typings": "lib/index.d.ts", "files": [ @@ -29,7 +29,7 @@ "satori" ], "peerDependencies": { - "@satorijs/satori": "^2.3.10" + "@satorijs/satori": "^2.6.1" }, "dependencies": { "form-data": "^4.0.0" diff --git a/adapters/discord/src/bot.ts b/adapters/discord/src/bot.ts index b21eb308..553c684c 100644 --- a/adapters/discord/src/bot.ts +++ b/adapters/discord/src/bot.ts @@ -1,20 +1,27 @@ -import { Bot, Context, Fragment, h, Quester, Schema, SendOptions } from '@satorijs/satori' -import { adaptChannel, adaptGuild, adaptMessage, adaptUser } from './utils' -import { DiscordMessenger } from './message' +import { Bot, Context, defineProperty, Fragment, h, isNullable, Logger, Quester, Schema, SendOptions, Universal } from '@satorijs/satori' +import { decodeChannel, decodeGuild, decodeMessage, decodeRole, decodeUser, encodeRole } from './utils' +import * as Discord from './utils' +import { DiscordMessageEncoder } from './message' import { Internal, Webhook } from './types' import { WsClient } from './ws' // @ts-ignore import { version } from '../package.json' +const logger = new Logger('discord') + export class DiscordBot extends Bot { + static MessageEncoder = DiscordMessageEncoder + public http: Quester public internal: Internal public webhooks: Record = {} public webhookLock: Record> = {} + public commands: Universal.Command[] = [] constructor(ctx: Context, config: DiscordBot.Config) { super(ctx, config) + this.platform = 'discord' this.http = ctx.http.extend({ ...config, headers: { @@ -27,6 +34,10 @@ export class DiscordBot extends Bot { ctx.plugin(WsClient, this) } + session(payload?: any, input?: any) { + return defineProperty(super.session(payload), 'discord', Object.assign(Object.create(this.internal), input)) + } + private async _ensureWebhook(channelId: string) { let webhook: Webhook const webhooks = await this.internal.getChannelWebhooks(channelId) @@ -56,15 +67,7 @@ export class DiscordBot extends Bot { async getSelf() { const data = await this.internal.getCurrentUser() - return adaptUser(data) - } - - async sendMessage(channelId: string, content: Fragment, guildId?: string, options?: SendOptions) { - return new DiscordMessenger(this, channelId, guildId, options).send(content) - } - - async sendPrivateMessage(channelId: string, content: Fragment, options?: SendOptions) { - return new DiscordMessenger(this, channelId, null, options).send(content) + return decodeUser(data) } async deleteMessage(channelId: string, messageId: string) { @@ -85,35 +88,35 @@ export class DiscordBot extends Bot { async getMessage(channelId: string, messageId: string) { const data = await this.internal.getChannelMessage(channelId, messageId) - return await adaptMessage(this, data) + return await decodeMessage(this, data) } async getMessageList(channelId: string, before?: string) { // doesn't include `before` message // 从旧到新 const data = (await this.internal.getChannelMessages(channelId, { before, limit: 50 })).reverse() - return await Promise.all(data.map(data => adaptMessage(this, data))) + return await Promise.all(data.map(data => decodeMessage(this, data))) } async getUser(userId: string) { const data = await this.internal.getUser(userId) - return adaptUser(data) + return decodeUser(data) } async getGuildMemberList(guildId: string) { const data = await this.internal.listGuildMembers(guildId) - return data.map(v => adaptUser(v.user)) + return data.map(v => decodeUser(v.user)) } async getChannel(channelId: string) { const data = await this.internal.getChannel(channelId) - return adaptChannel(data) + return decodeChannel(data) } async getGuildMember(guildId: string, userId: string) { const member = await this.internal.getGuildMember(guildId, userId) return { - ...adaptUser(member.user), + ...decodeUser(member.user), nickname: member.nick, } } @@ -124,22 +127,125 @@ export class DiscordBot extends Bot { async getGuild(guildId: string) { const data = await this.internal.getGuild(guildId) - return adaptGuild(data) + return decodeGuild(data) } async getGuildList() { const data = await this.internal.getCurrentUserGuilds() - return data.map(v => adaptGuild(v)) + return data.map(decodeGuild) } async getChannelList(guildId: string) { const data = await this.internal.getGuildChannels(guildId) - return data.map(v => adaptChannel(v)) + return data.map(decodeChannel) + } + + createReaction(channelId: string, messageId: string, emoji: string) { + return this.internal.createReaction(channelId, messageId, emoji) + } + + deleteReaction(channelId: string, messageId: string, emoji: string, userId?: string) { + if (!userId) { + return this.internal.deleteOwnReaction(channelId, messageId, emoji) + } else { + return this.internal.deleteUserReaction(channelId, messageId, emoji, userId) + } + } + + clearReaction(channelId: string, messageId: string, emoji?: string) { + if (!emoji) { + return this.internal.deleteAllReactions(channelId, messageId) + } else { + return this.internal.deleteAllReactionsForEmoji(channelId, messageId, emoji) + } + } + + async getReactions(channelId: string, messageId: string, emoji: string) { + const data = await this.internal.getReactions(channelId, messageId, emoji) + return data.map(decodeUser) + } + + setGuildMemberRole(guildId: string, userId: string, roleId: string) { + return this.internal.addGuildMemberRole(guildId, userId, roleId) + } + + unsetGuildMemberRole(guildId: string, userId: string, roleId: string) { + return this.internal.removeGuildMemberRole(guildId, userId, roleId) + } + + async getGuildRoles(guildId: string) { + const data = await this.internal.getGuildRoles(guildId) + return data.map(decodeRole) + } + + async createGuildRole(guildId: string, data: Partial) { + const role = await this.internal.createGuildRole(guildId, encodeRole(data)) + return role.id + } + + async modifyGuildRole(guildId: string, roleId: string, data: Partial) { + await this.internal.modifyGuildRole(guildId, roleId, encodeRole(data)) + } + + deleteGuildRole(guildId: string, roleId: string) { + return this.internal.deleteGuildRole(guildId, roleId) + } + + async sendPrivateMessage(userId: string, content: Fragment, options?: SendOptions) { + const channel = await this.internal.createDM({ + recipient_id: userId, + }) + return this.sendMessage(channel.id, content, null, options) + } + + async updateCommands(commands: Universal.Command[]) { + this.commands = commands + const local = Object.fromEntries(commands.map(cmd => [cmd.name, cmd] as const)) + const remote = Object.fromEntries((await this.internal.getGlobalApplicationCommands(this.selfId)) + .filter(cmd => cmd.type === Discord.ApplicationCommand.Type.CHAT_INPUT) + .map(cmd => [cmd.name, cmd] as const)) + + for (const key in { ...local, ...remote }) { + if (!local[key]) { + logger.debug('delete command %s', key) + await this.internal.deleteGlobalApplicationCommand(this.selfId, remote[key].id) + continue + } + + const data = Discord.encodeCommand(local[key]) + logger.debug(data, remote[key]) + if (!remote[key]) { + logger.debug('create command: %s', local[key].name) + await this.internal.createGlobalApplicationCommand(this.selfId, data) + } else if (shapeEqual(data, remote[key])) { + logger.debug('edit command: %s', local[key].name) + await this.internal.editGlobalApplicationCommand(this.selfId, remote[key].id, data) + } + } } } +function shapeEqual(a: any, b: any, strict = false) { + if (a === b) return true + if (!strict && isNullable(a) && isNullable(b)) return true + if (typeof a !== typeof b) return false + if (typeof a !== 'object') return false + if (!a || !b) return false + + // check array + if (Array.isArray(a)) { + if (!Array.isArray(b) || a.length !== b.length) return false + return a.every((item, index) => shapeEqual(item, b[index])) + } else if (Array.isArray(b)) { + return false + } + + // check object + return Object.keys(a).every(key => shapeEqual(a[key], b[key], strict)) +} + export namespace DiscordBot { - export interface Config extends Bot.Config, Quester.Config, DiscordMessenger.Config, WsClient.Config { + export interface Config extends Bot.Config, Quester.Config, DiscordMessageEncoder.Config, WsClient.Config { token: string } @@ -148,9 +254,7 @@ export namespace DiscordBot { token: Schema.string().description('机器人的用户令牌。').role('secret').required(), }), WsClient.Config, - DiscordMessenger.Config, + DiscordMessageEncoder.Config, Quester.createConfig('https://discord.com/api/v10'), ]) } - -DiscordBot.prototype.platform = 'discord' diff --git a/adapters/discord/src/index.ts b/adapters/discord/src/index.ts index 684d7901..c1f8d5f8 100644 --- a/adapters/discord/src/index.ts +++ b/adapters/discord/src/index.ts @@ -1,17 +1,27 @@ import { DiscordBot } from './bot' -import * as Discord from './types' +import * as Discord from './utils' export { Discord } export * from './bot' export * from './message' -export * from './utils' export * from './ws' export default DiscordBot +type ParamCase = + | S extends `${infer L}${infer R}` + ? `${L extends '_' ? '-' : Lowercase}${ParamCase}` + : S + +type DiscordEvents = { + [T in keyof Discord.GatewayEvents as `discord/${ParamCase}`]: (input: Discord.GatewayEvents[T]) => void +} + declare module '@satorijs/core' { interface Session { - discord?: Discord.GatewayPayload & Discord.Internal + discord?: Discord.Gateway.Payload & Discord.Internal } + + interface Events extends DiscordEvents {} } diff --git a/adapters/discord/src/message.ts b/adapters/discord/src/message.ts index d4b4e39e..487f1da1 100644 --- a/adapters/discord/src/message.ts +++ b/adapters/discord/src/message.ts @@ -1,8 +1,8 @@ -import { Dict, h, Logger, Messenger, Quester, Schema, segment, Session, Universal } from '@satorijs/satori' +import { Dict, h, Logger, MessageEncoder, Quester, Schema, Session, Universal } from '@satorijs/satori' import FormData from 'form-data' import { DiscordBot } from './bot' import { Channel, Message } from './types' -import { adaptMessage, sanitize } from './utils' +import { decodeMessage, sanitize } from './utils' type RenderMode = 'default' | 'figure' const MaxResourcePerMessage = 10 @@ -19,33 +19,44 @@ class State { constructor(public type: 'message' | 'forward') { } } -export class DiscordMessenger extends Messenger { +export class DiscordMessageEncoder extends MessageEncoder { private stack: State[] = [new State('message')] private buffer: string = '' private addition: Dict = {} private figure: h = null private mode: RenderMode = 'default' private resourceBuffer: h[] = [] + private listType: 'ol' | 'ul' = null - async post(data?: any, headers?: any) { - try { - let url = `/channels/${this.channelId}/messages` - if (this.stack[0].author.nickname || this.stack[0].author.avatar || (this.stack[0].type === 'forward' && !this.stack[0].threadCreated)) { + private async getUrl() { + const input = this.options?.session?.discord + if (input?.t === 'INTERACTION_CREATE') { + // 消息交互 + return `/webhooks/${input.d.application_id}/${input.d.token}` + } else if (this.stack[0].type === 'forward' && this.stack[0].channel?.id) { + // 发送到子区 + if (this.stack[1].author.nickname || this.stack[1].author.avatar) { const webhook = await this.ensureWebhook() - url = `/webhooks/${webhook.id}/${webhook.token}?wait=true` + return `/webhooks/${webhook.id}/${webhook.token}?wait=true&thread_id=${this.stack[0].channel?.id}` + } else { + return `/channels/${this.stack[0].channel.id}/messages` } - if (this.stack[0].type === 'forward' && this.stack[0].channel?.id) { - // 发送到子区 - if (this.stack[1].author.nickname || this.stack[1].author.avatar) { - const webhook = await this.ensureWebhook() - url = `/webhooks/${webhook.id}/${webhook.token}?wait=true&thread_id=${this.stack[0].channel?.id}` - } else { - url = `/channels/${this.stack[0].channel.id}/messages` - } + } else { + if (this.stack[0].author.nickname || this.stack[0].author.avatar || (this.stack[0].type === 'forward' && !this.stack[0].threadCreated)) { + const webhook = await this.ensureWebhook() + return `/webhooks/${webhook.id}/${webhook.token}?wait=true` + } else { + return `/channels/${this.channelId}/messages` } + } + } + + async post(data?: any, headers?: any) { + try { + const url = await this.getUrl() const result = await this.bot.http.post(url, data, { headers }) const session = this.bot.session() - const message = await adaptMessage(this.bot, result, session) + const message = await decodeMessage(this.bot, result, session) session.app.emit(session, 'send', session) this.results.push(session) @@ -60,11 +71,15 @@ export class DiscordMessenger extends Messenger { return message } catch (e) { - if (Quester.isAxiosError(e) && e.response?.data.code === 10015) { - logger.debug('webhook has been deleted, recreating..., %o', e.response.data) - if (!this.bot.webhookLock[this.channelId]) this.bot.webhooks[this.channelId] = null - await this.ensureWebhook() - return this.post(data, headers) + if (Quester.isAxiosError(e) && e.response) { + if (e.response.data?.code === 10015) { + logger.debug('webhook has been deleted, recreating..., %o', e.response.data) + if (!this.bot.webhookLock[this.channelId]) this.bot.webhooks[this.channelId] = null + await this.ensureWebhook() + return this.post(data, headers) + } else { + e = new Error(`[${e.response.status}] ${JSON.stringify(e.response.data)}`) + } } this.errors.push(e) } @@ -90,7 +105,7 @@ export class DiscordMessenger extends Messenger { async sendAsset(element: h, addition: Dict) { const { attrs, type } = element - const { handleMixedContent, handleExternalAsset } = this.bot.config as DiscordMessenger.Config + const { handleMixedContent, handleExternalAsset } = this.bot.config as DiscordMessageEncoder.Config if (handleMixedContent === 'separate' && this.buffer.trim().length) { await this.post({ content: this.buffer.trim() }) @@ -115,7 +130,7 @@ export class DiscordMessenger extends Messenger { return sendDownload() } - const mode = attrs.mode as DiscordMessenger.HandleExternalAsset || handleExternalAsset + const mode = attrs.mode as DiscordMessageEncoder.HandleExternalAsset || handleExternalAsset if (mode === 'download' || handleMixedContent === 'attach' || type === 'file') { return sendDownload() } else if (mode === 'direct') { @@ -136,7 +151,7 @@ export class DiscordMessenger extends Messenger { } async flushAssets(content: string) { - const { handleExternalAsset } = this.bot.config as DiscordMessenger.Config + const { handleExternalAsset } = this.bot.config as DiscordMessageEncoder.Config const mode = handleExternalAsset if (mode === 'download') { return this.sendEmbed(this.resourceBuffer, { ...this.addition, content }) @@ -201,8 +216,27 @@ export class DiscordMessenger extends Messenger { this.buffer += ` (<${attrs.href}>) ` } } else if (type === 'p') { + if (!this.buffer.endsWith('\n')) this.buffer += '\n' + await this.render(children) + this.buffer += '\n' + } else if (type === 'blockquote') { + if (!this.buffer.endsWith('\n')) this.buffer += '\n' + this.buffer += '> ' await this.render(children) this.buffer += '\n' + } else if (type === 'ul' || type === 'ol') { + this.listType = type + await this.render(children) + this.listType = null + } else if (type === 'li') { + if (!this.buffer.endsWith('\n')) this.buffer += '\n' + if (this.listType === 'ol') { + this.buffer += '0. ' + } else if (this.listType === 'ul') { + this.buffer += '- ' + } + this.render(children) + this.buffer += '\n' } else if (type === 'at') { if (attrs.id) { this.buffer += `<@${attrs.id}>` @@ -233,10 +267,51 @@ export class DiscordMessenger extends Messenger { ...this.addition, embeds: [{ ...attrs }], }) - } else if (type === 'audio') { + } else if (type === 'audio' || type === 'file') { await this.sendAsset(element, { ...this.addition }) + } else if (type === 'author') { + const { avatar, nickname } = attrs + if (avatar) this.addition.avatar_url = avatar + if (nickname) this.addition.username = nickname + if (this.stack[0].type === 'message') { + this.stack[0].author = attrs + } + if (this.stack[0].type === 'forward') { + this.stack[1].author = attrs + } + } else if (type === 'quote') { + await this.flush() + const parse = (val: string) => val.replace(/\\([\\*_`~|()\[\]])/g, '$1') + + const message = this.stack[this.stack[0].type === 'forward' ? 1 : 0] + if (!message.author.avatar && !message.author.nickname && this.stack[0].type !== 'forward') { + // no quote and author, send by bot + await this.flush() + this.addition.message_reference = { + message_id: attrs.id, + } + } else { + // quote + let replyId = attrs.id, channelId = this.channelId + if (this.stack[0].type === 'forward' && this.stack[0].fakeMessageMap[attrs.id]?.length >= 1) { + // quote to fake message, eg. 1st message has id (in channel or thread), later message quote to it + replyId = this.stack[0].fakeMessageMap[attrs.id][0].messageId + channelId = this.stack[0].fakeMessageMap[attrs.id][0].channelId + } + const quoted = await this.bot.getMessage(channelId, replyId) + this.addition.embeds = [{ + description: [ + sanitize(parse(quoted.elements.filter(v => v.type === 'text').join('')).slice(0, 30)), + ` [[ ↑ ]](https://discord.com/channels/${this.guildId}/${channelId}/${replyId})`, + ].join('\n\n'), + author: { + name: quoted.author.nickname || quoted.author.username, + icon_url: quoted.author.avatar, + }, + }] + } } else if (type === 'figure') { await this.flush() this.mode = 'figure' @@ -256,54 +331,6 @@ export class DiscordMessenger extends Messenger { const resultLength = +this.results.length await this.flush() - // author - const [author] = segment.select(children, 'author') - if (author) { - const { avatar, nickname } = author.attrs - if (avatar) this.addition.avatar_url = avatar - if (nickname) this.addition.username = nickname - if (this.stack[0].type === 'message') { - this.stack[0].author = author.attrs - } - if (this.stack[0].type === 'forward') { - this.stack[1].author = author.attrs - } - } - - // quote - const [quote] = segment.select(children, 'quote') - if (quote) { - const parse = (val: string) => val.replace(/\\([\\*_`~|()\[\]])/g, '$1') - - const message = this.stack[this.stack[0].type === 'forward' ? 1 : 0] - if (!message.author.avatar && !message.author.nickname && this.stack[0].type !== 'forward') { - // no quote and author, send by bot - await this.flush() - this.addition.message_reference = { - message_id: quote.attrs.id, - } - } else { - // quote - let replyId = quote.attrs.id, channelId = this.channelId - if (this.stack[0].type === 'forward' && this.stack[0].fakeMessageMap[quote.attrs.id]?.length >= 1) { - // quote to fake message, eg. 1st message has id (in channel or thread), later message quote to it - replyId = this.stack[0].fakeMessageMap[quote.attrs.id][0].messageId - channelId = this.stack[0].fakeMessageMap[quote.attrs.id][0].channelId - } - const quoted = await this.bot.getMessage(channelId, replyId) - this.addition.embeds = [{ - description: [ - sanitize(parse(quoted.elements.filter(v => v.type === 'text').join('')).slice(0, 30)), - ` [[ ↑ ]](https://discord.com/channels/${this.guildId}/${channelId}/${replyId})`, - ].join('\n\n'), - author: { - name: quoted.author.nickname || quoted.author.username, - icon_url: quoted.author.avatar, - }, - }] - } - } - await this.render(children) await this.flush() const newLength = +this.results.length @@ -333,7 +360,7 @@ export class DiscordMessenger extends Messenger { } } -export namespace DiscordMessenger { +export namespace DiscordMessageEncoder { export type HandleExternalAsset = 'auto' | 'download' | 'direct' export type HandleMixedContent = 'auto' | 'separate' | 'attach' @@ -354,16 +381,16 @@ export namespace DiscordMessenger { handleMixedContent?: HandleMixedContent } - export const Config: Schema = Schema.object({ + export const Config: Schema = Schema.object({ handleExternalAsset: Schema.union([ - Schema.const('download' as const).description('先下载后发送'), - Schema.const('direct' as const).description('直接发送链接'), - Schema.const('auto' as const).description('发送一个 HEAD 请求,根据返回的 Content-Type 决定发送方式'), + Schema.const('download').description('先下载后发送'), + Schema.const('direct').description('直接发送链接'), + Schema.const('auto').description('发送一个 HEAD 请求,根据返回的 Content-Type 决定发送方式'), ]).role('radio').description('发送外链资源时采用的方式。').default('auto'), handleMixedContent: Schema.union([ - Schema.const('separate' as const).description('将每个不同形式的内容分开发送'), - Schema.const('attach' as const).description('图片前如果有文本内容,则将文本作为图片的附带信息进行发送'), - Schema.const('auto' as const).description('如果图片本身采用直接发送则与前面的文本分开,否则将文本作为图片的附带信息发送'), + Schema.const('separate').description('将每个不同形式的内容分开发送'), + Schema.const('attach').description('图片前如果有文本内容,则将文本作为图片的附带信息进行发送'), + Schema.const('auto').description('如果图片本身采用直接发送则与前面的文本分开,否则将文本作为图片的附带信息发送'), ]).role('radio').description('发送图文等混合内容时采用的方式。').default('auto'), }).description('发送设置') } diff --git a/adapters/discord/src/types/channel.ts b/adapters/discord/src/types/channel.ts index cb93c981..9571f068 100644 --- a/adapters/discord/src/types/channel.ts +++ b/adapters/discord/src/types/channel.ts @@ -385,12 +385,12 @@ declare module './internal' { * Create a new DM channel with a user. Returns a DM channel object. * @see https://discord.com/developers/docs/resources/user#create-dm */ - createDM(params: Channel.Params.CreateDM): Promise + createDM(params: Channel.Params.CreateDM): Promise /** * Create a new group DM channel with multiple users. Returns a DM channel object. This endpoint was intended to be used with the now-deprecated GameBridge SDK. DMs created with this endpoint will not be shown in the Discord client * @see https://discord.com/developers/docs/resources/user#create-group-dm */ - createGroupDM(params: Channel.Params.CreateGroupDM): Promise + createGroupDM(params: Channel.Params.CreateGroupDM): Promise } } diff --git a/adapters/discord/src/types/gateway.ts b/adapters/discord/src/types/gateway.ts index f1897660..ea792f61 100644 --- a/adapters/discord/src/types/gateway.ts +++ b/adapters/discord/src/types/gateway.ts @@ -1,286 +1,290 @@ import { Activity, integer, Internal, snowflake, StatusType } from '.' -/** https://discord.com/developers/docs/topics/gateway-events#payload-structure */ -export interface GatewayPayloadStructure { - /** opcode for the payload */ - op: O - /** event data */ - d?: D - /** the event name for this payload */ - t?: T - /** sequence number, used for resuming sessions and heartbeats */ - s?: number -} +export namespace Gateway { + /** https://discord.com/developers/docs/topics/gateway-events#payload-structure */ + export interface PayloadStructure { + /** opcode for the payload */ + op: O + /** event data */ + d?: D + /** the event name for this payload */ + t?: T + /** sequence number, used for resuming sessions and heartbeats */ + s?: number + } -export type GatewayPayload = { - [O in GatewayOpcode]: O extends GatewayOpcode.DISPATCH - ? { - [T in keyof GatewayEvents]: GatewayPayloadStructure - }[keyof GatewayEvents] - : GatewayPayloadStructure -}[GatewayOpcode] + export type Payload = { + [O in Opcode]: O extends Opcode.DISPATCH + ? { + [T in keyof GatewayEvents]: PayloadStructure + }[keyof GatewayEvents] + : PayloadStructure + }[Opcode] -/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes */ -export enum GatewayOpcode { - /** An event was dispatched. */ - DISPATCH = 0, - /** Fired periodically by the client to keep the connection alive. */ - HEARTBEAT = 1, - /** Starts a new session during the initial handshake. */ - IDENTIFY = 2, - /** Update the client's presence. */ - PRESENCE_UPDATE = 3, - /** Used to join/leave or move between voice channels. */ - VOICE_STATE_UPDATE = 4, - /** Resume a previous session that was disconnected. */ - RESUME = 6, - /** You should attempt to reconnect and resume immediately. */ - RECONNECT = 7, - /** Request information about offline guild members in a large guild. */ - REQUEST_GUILD_MEMBERS = 8, - /** The session has been invalidated. You should reconnect and identify/resume accordingly. */ - INVALID_SESSION = 9, - /** Sent immediately after connecting, contains the `heartbeat_interval` to use. */ - HELLO = 10, - /** Sent in response to receiving a heartbeat to acknowledge that it has been received. */ - HEARTBEAT_ACK = 11, -} + /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes */ + export enum Opcode { + /** An event was dispatched. */ + DISPATCH = 0, + /** Fired periodically by the client to keep the connection alive. */ + HEARTBEAT = 1, + /** Starts a new session during the initial handshake. */ + IDENTIFY = 2, + /** Update the client's presence. */ + PRESENCE_UPDATE = 3, + /** Used to join/leave or move between voice channels. */ + VOICE_STATE_UPDATE = 4, + /** Resume a previous session that was disconnected. */ + RESUME = 6, + /** You should attempt to reconnect and resume immediately. */ + RECONNECT = 7, + /** Request information about offline guild members in a large guild. */ + REQUEST_GUILD_MEMBERS = 8, + /** The session has been invalidated. You should reconnect and identify/resume accordingly. */ + INVALID_SESSION = 9, + /** Sent immediately after connecting, contains the `heartbeat_interval` to use. */ + HELLO = 10, + /** Sent in response to receiving a heartbeat to acknowledge that it has been received. */ + HEARTBEAT_ACK = 11, + } -/** https://discord.com/developers/docs/topics/gateway#gateway-intents */ -export enum GatewayIntent { - /** - * - GUILD_CREATE - * - GUILD_UPDATE - * - GUILD_DELETE - * - GUILD_ROLE_CREATE - * - GUILD_ROLE_UPDATE - * - GUILD_ROLE_DELETE - * - CHANNEL_CREATE - * - CHANNEL_UPDATE - * - CHANNEL_DELETE - * - CHANNEL_PINS_UPDATE - * - THREAD_CREATE - * - THREAD_UPDATE - * - THREAD_DELETE - * - THREAD_LIST_SYNC - * - THREAD_MEMBER_UPDATE - * - THREAD_MEMBERS_UPDATE - * - STAGE_INSTANCE_CREATE - * - STAGE_INSTANCE_UPDATE - * - STAGE_INSTANCE_DELETE - */ - GUILDS = 1 << 0, - /** - * - GUILD_MEMBER_ADD - * - GUILD_MEMBER_UPDATE - * - GUILD_MEMBER_REMOVE - * - THREAD_MEMBERS_UPDATE - */ - GUILD_MEMBERS = 1 << 1, - /** - * - GUILD_BAN_ADD - * - GUILD_BAN_REMOVE - */ - GUILD_BANS = 1 << 2, - /** - * - GUILD_EMOJIS_UPDATE - * - GUILD_STICKERS_UPDATE - */ - GUILD_EMOJIS_AND_STICKERS = 1 << 3, - /** - * - GUILD_INTEGRATIONS_UPDATE - * - INTEGRATION_CREATE - * - INTEGRATION_UPDATE - * - INTEGRATION_DELETE - */ - GUILD_INTEGRATIONS = 1 << 4, - /** - * - WEBHOOKS_UPDATE - */ - GUILD_WEBHOOKS = 1 << 5, - /** - * - INVITE_CREATE - * - INVITE_DELETE - */ - GUILD_INVITES = 1 << 6, - /** - * - VOICE_STATE_UPDATE - */ - GUILD_VOICE_STATES = 1 << 7, - /** - * - PRESENCE_UPDATE - */ - GUILD_PRESENCES = 1 << 8, - /** - * - MESSAGE_CREATE - * - MESSAGE_UPDATE - * - MESSAGE_DELETE - * - MESSAGE_DELETE_BULK - */ - GUILD_MESSAGES = 1 << 9, - /** - * - MESSAGE_REACTION_ADD - * - MESSAGE_REACTION_REMOVE - * - MESSAGE_REACTION_REMOVE_ALL - * - MESSAGE_REACTION_REMOVE_EMOJI - */ - GUILD_MESSAGE_REACTIONS = 1 << 10, - /** - * - TYPING_START - */ - GUILD_MESSAGE_TYPING = 1 << 11, - /** - * - MESSAGE_CREATE - * - MESSAGE_UPDATE - * - MESSAGE_DELETE - * - CHANNEL_PINS_UPDATE - */ - DIRECT_MESSAGES = 1 << 12, - /** - * - MESSAGE_REACTION_ADD - * - MESSAGE_REACTION_REMOVE - * - MESSAGE_REACTION_REMOVE_ALL - * - MESSAGE_REACTION_REMOVE_EMOJI - */ - DIRECT_MESSAGE_REACTIONS = 1 << 13, - /** - * - TYPING_START - */ - DIRECT_MESSAGE_TYPING = 1 << 14, - /** - * `MESSAGE_CONTENT` is a unique privileged intent that isn't directly associated with any Gateway events. - * Instead, access to `MESSAGE_CONTENT` permits your app to receive message content data across the APIs. - * - * Any fields affected by the message content intent are noted in the relevant documentation. - * For example, the content, embeds, attachments, and components fields in message objects all contain message content and therefore require the intent. - * - * Like other privileged intents, `MESSAGE_CONTENT` must be approved for your app. - * After your app is verified, you can apply for the intent from your app's settings within the Developer Portal. - * You can read more about the message content intent review policy in the [Help Center](https://support-dev.discord.com/hc/en-us/articles/5324827539479). - * - * Apps without the intent will receive empty values in fields that contain user-inputted content with a few exceptions: - * - Content in messages that an app sends - * - Content in DMs with the app - * - Content in which the app is mentioned - * - * @see https://discord.com/developers/docs/topics/gateway#message-content-intent - */ - MESSAGE_CONTENT = 1 << 15, - /** - * - GUILD_SCHEDULED_EVENT_CREATE - * - GUILD_SCHEDULED_EVENT_UPDATE - * - GUILD_SCHEDULED_EVENT_DELETE - * - GUILD_SCHEDULED_EVENT_USER_ADD - * - GUILD_SCHEDULED_EVENT_USER_REMOVE - */ - GUILD_SCHEDULED_EVENTS = 1 << 16, - /** - * - AUTO_MODERATION_RULE_CREATE - * - AUTO_MODERATION_RULE_UPDATE - * - AUTO_MODERATION_RULE_DELETE - */ - AUTO_MODERATION_CONFIGURATION = 1 << 20, - /** - * - AUTO_MODERATION_ACTION_EXECUTION - */ - AUTO_MODERATION_EXECUTION = 1 << 21, -} + /** https://discord.com/developers/docs/topics/gateway#gateway-intents */ + export enum Intent { + /** + * - GUILD_CREATE + * - GUILD_UPDATE + * - GUILD_DELETE + * - GUILD_ROLE_CREATE + * - GUILD_ROLE_UPDATE + * - GUILD_ROLE_DELETE + * - CHANNEL_CREATE + * - CHANNEL_UPDATE + * - CHANNEL_DELETE + * - CHANNEL_PINS_UPDATE + * - THREAD_CREATE + * - THREAD_UPDATE + * - THREAD_DELETE + * - THREAD_LIST_SYNC + * - THREAD_MEMBER_UPDATE + * - THREAD_MEMBERS_UPDATE + * - STAGE_INSTANCE_CREATE + * - STAGE_INSTANCE_UPDATE + * - STAGE_INSTANCE_DELETE + */ + GUILDS = 1 << 0, + /** + * - GUILD_MEMBER_ADD + * - GUILD_MEMBER_UPDATE + * - GUILD_MEMBER_REMOVE + * - THREAD_MEMBERS_UPDATE + */ + GUILD_MEMBERS = 1 << 1, + /** + * - GUILD_BAN_ADD + * - GUILD_BAN_REMOVE + */ + GUILD_BANS = 1 << 2, + /** + * - GUILD_EMOJIS_UPDATE + * - GUILD_STICKERS_UPDATE + */ + GUILD_EMOJIS_AND_STICKERS = 1 << 3, + /** + * - GUILD_INTEGRATIONS_UPDATE + * - INTEGRATION_CREATE + * - INTEGRATION_UPDATE + * - INTEGRATION_DELETE + */ + GUILD_INTEGRATIONS = 1 << 4, + /** + * - WEBHOOKS_UPDATE + */ + GUILD_WEBHOOKS = 1 << 5, + /** + * - INVITE_CREATE + * - INVITE_DELETE + */ + GUILD_INVITES = 1 << 6, + /** + * - VOICE_STATE_UPDATE + */ + GUILD_VOICE_STATES = 1 << 7, + /** + * - PRESENCE_UPDATE + */ + GUILD_PRESENCES = 1 << 8, + /** + * - MESSAGE_CREATE + * - MESSAGE_UPDATE + * - MESSAGE_DELETE + * - MESSAGE_DELETE_BULK + */ + GUILD_MESSAGES = 1 << 9, + /** + * - MESSAGE_REACTION_ADD + * - MESSAGE_REACTION_REMOVE + * - MESSAGE_REACTION_REMOVE_ALL + * - MESSAGE_REACTION_REMOVE_EMOJI + */ + GUILD_MESSAGE_REACTIONS = 1 << 10, + /** + * - TYPING_START + */ + GUILD_MESSAGE_TYPING = 1 << 11, + /** + * - MESSAGE_CREATE + * - MESSAGE_UPDATE + * - MESSAGE_DELETE + * - CHANNEL_PINS_UPDATE + */ + DIRECT_MESSAGES = 1 << 12, + /** + * - MESSAGE_REACTION_ADD + * - MESSAGE_REACTION_REMOVE + * - MESSAGE_REACTION_REMOVE_ALL + * - MESSAGE_REACTION_REMOVE_EMOJI + */ + DIRECT_MESSAGE_REACTIONS = 1 << 13, + /** + * - TYPING_START + */ + DIRECT_MESSAGE_TYPING = 1 << 14, + /** + * `MESSAGE_CONTENT` is a unique privileged intent that isn't directly associated with any Gateway events. + * Instead, access to `MESSAGE_CONTENT` permits your app to receive message content data across the APIs. + * + * Any fields affected by the message content intent are noted in the relevant documentation. + * For example, the content, embeds, attachments, and components fields in message objects all contain message content and therefore require the intent. + * + * Like other privileged intents, `MESSAGE_CONTENT` must be approved for your app. + * After your app is verified, you can apply for the intent from your app's settings within the Developer Portal. + * You can read more about the message content intent review policy in the [Help Center](https://support-dev.discord.com/hc/en-us/articles/5324827539479). + * + * Apps without the intent will receive empty values in fields that contain user-inputted content with a few exceptions: + * - Content in messages that an app sends + * - Content in DMs with the app + * - Content in which the app is mentioned + * + * @see https://discord.com/developers/docs/topics/gateway#message-content-intent + */ + MESSAGE_CONTENT = 1 << 15, + /** + * - GUILD_SCHEDULED_EVENT_CREATE + * - GUILD_SCHEDULED_EVENT_UPDATE + * - GUILD_SCHEDULED_EVENT_DELETE + * - GUILD_SCHEDULED_EVENT_USER_ADD + * - GUILD_SCHEDULED_EVENT_USER_REMOVE + */ + GUILD_SCHEDULED_EVENTS = 1 << 16, + /** + * - AUTO_MODERATION_RULE_CREATE + * - AUTO_MODERATION_RULE_UPDATE + * - AUTO_MODERATION_RULE_DELETE + */ + AUTO_MODERATION_CONFIGURATION = 1 << 20, + /** + * - AUTO_MODERATION_ACTION_EXECUTION + */ + AUTO_MODERATION_EXECUTION = 1 << 21, + } -export interface GatewayParams { - [GatewayOpcode.HELLO]: HelloParams - [GatewayOpcode.IDENTIFY]: IdentifyParams - [GatewayOpcode.RESUME]: ResumeParams - [GatewayOpcode.REQUEST_GUILD_MEMBERS]: RequestGuildMembersParams - [GatewayOpcode.VOICE_STATE_UPDATE]: VoiceStateUpdateParams - [GatewayOpcode.PRESENCE_UPDATE]: PresenceUpdateParams -} + export interface Params { + [Opcode.HELLO]: Params.Hello + [Opcode.IDENTIFY]: Params.Identify + [Opcode.RESUME]: Params.Resume + [Opcode.REQUEST_GUILD_MEMBERS]: Params.RequestGuildMembers + [Opcode.VOICE_STATE_UPDATE]: Params.VoiceStateUpdate + [Opcode.PRESENCE_UPDATE]: Params.PresenceUpdate + } -/** https://discord.com/developers/docs/topics/gateway-events#gateway-events */ -export interface GatewayEvents {} + export namespace Params { + /** https://discord.com/developers/docs/topics/gateway-events#hello-hello-structure */ + export interface Hello { + /** the interval (in milliseconds) the client should heartbeat with */ + heartbeat_interval: integer + } -/** https://discord.com/developers/docs/topics/gateway-events#identify-identify-structure */ -export interface IdentifyParams { - /** authentication token */ - token: string - /** connection properties */ - properties: ConnectionProperties - /** whether this connection supports compression of packets */ - compress?: boolean - /** value between 50 and 250, total number of members where the gateway will stop sending offline members in the guild member list */ - large_threshold?: integer - /** used for Guild Sharding */ - shard?: [shard_id: integer, num_shards: integer] - /** presence structure for initial presence information */ - presence?: PresenceUpdateParams - /** the Gateway Intents you wish to receive */ - intents: integer -} + /** https://discord.com/developers/docs/topics/gateway-events#identify-identify-structure */ + export interface Identify { + /** authentication token */ + token: string + /** connection properties */ + properties: ConnectionProperties + /** whether this connection supports compression of packets */ + compress?: boolean + /** value between 50 and 250, total number of members where the gateway will stop sending offline members in the guild member list */ + large_threshold?: integer + /** used for Guild Sharding */ + shard?: [shard_id: integer, num_shards: integer] + /** presence structure for initial presence information */ + presence?: PresenceUpdate + /** the Gateway Intents you wish to receive */ + intents: integer + } -/** https://discord.com/developers/docs/topics/gateway-events#identify-identify-connection-properties */ -export interface ConnectionProperties { - /** Your operating system */ - os: string - /** Your library name */ - browser: string - /** Your library name */ - device: string -} + /** https://discord.com/developers/docs/topics/gateway-events#identify-identify-connection-properties */ + export interface ConnectionProperties { + /** Your operating system */ + os: string + /** Your library name */ + browser: string + /** Your library name */ + device: string + } -/** https://discord.com/developers/docs/topics/gateway-events#resume-resume-structure */ -export interface ResumeParams { - /** session token */ - token: string - /** session id */ - session_id: string - /** last sequence number received */ - seq: integer -} + /** https://discord.com/developers/docs/topics/gateway-events#resume-resume-structure */ + export interface Resume { + /** session token */ + token: string + /** session id */ + session_id: string + /** last sequence number received */ + seq: integer + } -/** https://discord.com/developers/docs/topics/gateway-events#request-guild-members-guild-request-members-structure */ -export interface RequestGuildMembersParams { - /** id of the guild to get members for */ - guild_id: snowflake - /** string that username starts with, or an empty string to return all members */ - query?: string - /** maximum number of members to send matching the query; a limit of 0 can be used with an empty string query to return all members */ - limit: integer - /** used to specify if we want the presences of the matched members */ - presences?: boolean - /** used to specify which users you wish to fetch */ - user_ids?: snowflake | snowflake[] - /** nonce to identify the Guild Members Chunk response */ - nonce?: string -} + /** https://discord.com/developers/docs/topics/gateway-events#request-guild-members-guild-request-members-structure */ + export interface RequestGuildMembers { + /** id of the guild to get members for */ + guild_id: snowflake + /** string that username starts with, or an empty string to return all members */ + query?: string + /** maximum number of members to send matching the query; a limit of 0 can be used with an empty string query to return all members */ + limit: integer + /** used to specify if we want the presences of the matched members */ + presences?: boolean + /** used to specify which users you wish to fetch */ + user_ids?: snowflake | snowflake[] + /** nonce to identify the Guild Members Chunk response */ + nonce?: string + } -/** https://discord.com/developers/docs/topics/gateway-events#update-voice-state-gateway-voice-state-update-structure */ -export interface VoiceStateUpdateParams { - /** id of the guild */ - guild_id: snowflake - /** id of the voice channel client wants to join (null if disconnecting) */ - channel_id?: snowflake - /** is the client muted */ - self_mute: boolean - /** is the client deafened */ - self_deaf: boolean -} + /** https://discord.com/developers/docs/topics/gateway-events#update-voice-state-gateway-voice-state-update-structure */ + export interface VoiceStateUpdate { + /** id of the guild */ + guild_id: snowflake + /** id of the voice channel client wants to join (null if disconnecting) */ + channel_id?: snowflake + /** is the client muted */ + self_mute: boolean + /** is the client deafened */ + self_deaf: boolean + } -/** https://discord.com/developers/docs/topics/gateway-events#update-presence-gateway-presence-update-structure */ -export interface PresenceUpdateParams { - /** unix time (in milliseconds) of when the client went idle, or null if the client is not idle */ - since?: integer - /** the user's activities */ - activities: Activity[] - /** the user's new status */ - status: StatusType - /** whether or not the client is afk */ - afk: boolean + /** https://discord.com/developers/docs/topics/gateway-events#update-presence-gateway-presence-update-structure */ + export interface PresenceUpdate { + /** unix time (in milliseconds) of when the client went idle, or null if the client is not idle */ + since?: integer + /** the user's activities */ + activities: Activity[] + /** the user's new status */ + status: StatusType + /** whether or not the client is afk */ + afk: boolean + } + } } -/** https://discord.com/developers/docs/topics/gateway-events#hello-hello-structure */ -export interface HelloParams { - /** the interval (in milliseconds) the client should heartbeat with */ - heartbeat_interval: integer -} +/** https://discord.com/developers/docs/topics/gateway-events#gateway-events */ +export interface GatewayEvents {} /** https://discord.com/developers/docs/topics/gateway-events#session-start-limit-object-session-start-limit-structure */ export interface SessionStartLimit { diff --git a/adapters/discord/src/types/guild-member.ts b/adapters/discord/src/types/guild-member.ts index 2ae100a9..841f4165 100644 --- a/adapters/discord/src/types/guild-member.ts +++ b/adapters/discord/src/types/guild-member.ts @@ -1,4 +1,4 @@ -import { integer, Internal, PresenceUpdateParams, snowflake, timestamp, User } from '.' +import { Gateway, integer, Internal, snowflake, timestamp, User } from '.' /** https://discord.com/developers/docs/resources/guild#guild-member-object-guild-member-structure */ export interface GuildMember { @@ -153,7 +153,7 @@ export namespace GuildMember { /** if passing an invalid id to REQUEST_GUILD_MEMBERS, it will be returned here */ not_found?: snowflake[] /** if passing true to REQUEST_GUILD_MEMBERS, presences of the returned members will be here */ - presences?: PresenceUpdateParams[] + presences?: Gateway.Params.PresenceUpdate[] /** the nonce used in the Guild Members Request */ nonce?: string } diff --git a/adapters/discord/src/types/index.ts b/adapters/discord/src/types/index.ts index aa6f025e..1fdf56b3 100644 --- a/adapters/discord/src/types/index.ts +++ b/adapters/discord/src/types/index.ts @@ -37,10 +37,13 @@ export type snowflake = string export type timestamp = string /** @see https://discord.com/developers/docs/reference#locales */ -export type Locale = - | 'da' | 'de' | 'en-GB' | 'en-US' | 'es-ES' - | 'fr' | 'hr' | 'it' | 'lt' | 'hu' - | 'nl' | 'no' | 'pl' | 'pt-BR' | 'ro' - | 'fi' | 'sv-SE' | 'vi' | 'tr' | 'cs' - | 'el' | 'bg' | 'ru' | 'uk' | 'hi' - | 'th' | 'zh-CN' | 'ja' | 'zh-TW' | 'ko' +export type Locale = typeof Locale[number] + +export const Locale = [ + 'da', 'de', 'en-GB', 'en-US', 'es-ES', + 'fr', 'hr', 'it', 'lt', 'hu', + 'nl', 'no', 'pl', 'pt-BR', 'ro', + 'fi', 'sv-SE', 'vi', 'tr', 'cs', + 'el', 'bg', 'ru', 'uk', 'hi', + 'th', 'zh-CN', 'ja', 'zh-TW', 'ko', +] as const diff --git a/adapters/discord/src/types/interaction.ts b/adapters/discord/src/types/interaction.ts index d0e63ad2..29acecfb 100644 --- a/adapters/discord/src/types/interaction.ts +++ b/adapters/discord/src/types/interaction.ts @@ -1,4 +1,5 @@ import { AllowedMentions, ApplicationCommand, Attachment, Channel, Component, ComponentType, Embed, GuildMember, integer, Internal, Message, Role, snowflake, User } from '.' +import * as Discord from '.' /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-structure */ export interface Interaction { @@ -7,7 +8,7 @@ export interface Interaction { /** id of the application this interaction is for */ application_id: snowflake /** the type of interaction */ - type: InteractionType + type: Interaction.Type /** the command data payload */ data?: InteractionData /** the guild it was sent from */ @@ -49,13 +50,29 @@ export namespace InteractionData { /** converted users + roles + channels */ resolved?: ResolvedData /** the params + values from the user */ - options?: ApplicationCommandInteractionDataOption[] + options?: ApplicationCommand.Option[] /** the id of the guild the command is registered to */ guild_id?: snowflake /** id of the user or message targeted by a user or message command */ target_id?: snowflake } + export namespace ApplicationCommand { + /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-application-command-interaction-data-option-structure */ + export interface Option { + /** the name of the parameter */ + name: string + /** value of application command option type */ + type: Discord.ApplicationCommand.OptionType + /** the value of the pair */ + value?: any + /** present if this option is a group or subcommand */ + options?: Option[] + /** true if this option is the currently focused option for autocomplete */ + focused?: boolean + } + } + /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-message-component-data-structure */ export interface MessageComponent { /** the custom_id of the component */ @@ -73,27 +90,15 @@ export namespace InteractionData { } } -/** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-type */ -export enum InteractionType { - PING = 1, - APPLICATION_COMMAND = 2, - MESSAGE_COMPONENT = 3, - APPLICATION_COMMAND_AUTOCOMPLETE = 4, - MODAL_SUBMIT = 5, -} - -/** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-application-command-interaction-data-option-structure */ -export interface ApplicationCommandInteractionDataOption { - /** the name of the parameter */ - name: string - /** value of application command option type */ - type: ApplicationCommand.OptionType - /** the value of the pair */ - value?: any - /** present if this option is a group or subcommand */ - options?: ApplicationCommandInteractionDataOption[] - /** true if this option is the currently focused option for autocomplete */ - focused?: boolean +export namespace Interaction { + /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-type */ + export enum Type { + PING = 1, + APPLICATION_COMMAND = 2, + MESSAGE_COMPONENT = 3, + APPLICATION_COMMAND_AUTOCOMPLETE = 4, + MODAL_SUBMIT = 5, + } } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-resolved-data-structure */ @@ -117,7 +122,7 @@ export interface MessageInteraction { /** id of the interaction */ id: snowflake /** the type of interaction */ - type: InteractionType + type: Interaction.Type /** the name of the application command */ name: string /** the user who invoked the interaction */ @@ -126,80 +131,81 @@ export interface MessageInteraction { member?: Partial } -/** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-interaction-response-structure */ -export interface InteractionResponse { - /** the type of response */ - type: InteractionCallbackType - /** an optional response message */ - data?: InteractionCallbackData -} - -/** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-interaction-callback-type */ -export enum InteractionCallbackType { - /** ACK a Ping */ - PONG = 1, - /** respond to an interaction with a message */ - CHANNEL_MESSAGE_WITH_SOURCE = 4, - /** ACK an interaction and edit a response later, the user sees a loading state */ - DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE = 5, - /** - * for components, ACK an interaction and edit the original message later; the user does not see a loading state - * (only valid for [component-based](https://discord.com/developers/docs/interactions/message-components) interactions) - */ - DEFERRED_UPDATE_MESSAGE = 6, - /** - * for components, edit the message the component was attached to - * (only valid for [component-based](https://discord.com/developers/docs/interactions/message-components) interactions) - */ - UPDATE_MESSAGE = 7, - /** respond to an autocomplete interaction with suggested choices */ - APPLICATION_COMMAND_AUTOCOMPLETE_RESULT = 8, - /** - * respond to an interaction with a popup modal - * (not available for `MODAL_SUBMIT` and `PING` interactions) - */ - MODAL = 9, -} +export namespace Interaction { + /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-interaction-response-structure */ + export interface Response { + /** the type of response */ + type: CallbackType + /** an optional response message */ + data?: CallbackData + } -export type InteractionCallbackData = - | InteractionCallbackData.Messages - | InteractionCallbackData.Autocomplete - | InteractionCallbackData.Modal + /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-interaction-callback-type */ + export enum CallbackType { + /** ACK a Ping */ + PONG = 1, + /** respond to an interaction with a message */ + CHANNEL_MESSAGE_WITH_SOURCE = 4, + /** ACK an interaction and edit a response later, the user sees a loading state */ + DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE = 5, + /** + * for components, ACK an interaction and edit the original message later; the user does not see a loading state + * (only valid for [component-based](https://discord.com/developers/docs/interactions/message-components) interactions) + */ + DEFERRED_UPDATE_MESSAGE = 6, + /** + * for components, edit the message the component was attached to + * (only valid for [component-based](https://discord.com/developers/docs/interactions/message-components) interactions) + */ + UPDATE_MESSAGE = 7, + /** respond to an autocomplete interaction with suggested choices */ + APPLICATION_COMMAND_AUTOCOMPLETE_RESULT = 8, + /** + * respond to an interaction with a popup modal + * (not available for `MODAL_SUBMIT` and `PING` interactions) + */ + MODAL = 9, + } -export namespace InteractionCallbackData { + export type CallbackData = + | CallbackData.Messages + | CallbackData.Autocomplete + | CallbackData.Modal - /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-messages */ - export interface Messages { - /** is the response TTS */ - tts?: boolean - /** message content */ - content?: string - /** supports up to 10 embeds */ - embeds?: Embed[] - /** allowed mentions object */ - allowed_mentions?: AllowedMentions - /** interaction callback data flags */ - flags?: integer - /** message components */ - components?: Component[] - /** attachment objects with filename and description */ - attachments?: Partial[] - } + export namespace CallbackData { + /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-messages */ + export interface Messages { + /** is the response TTS */ + tts?: boolean + /** message content */ + content?: string + /** supports up to 10 embeds */ + embeds?: Embed[] + /** allowed mentions object */ + allowed_mentions?: AllowedMentions + /** interaction callback data flags */ + flags?: integer + /** message components */ + components?: Component[] + /** attachment objects with filename and description */ + attachments?: Partial[] + } - /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-autocomplete */ - export interface Autocomplete { - /** autocomplete choices (max of 25 choices) */ - choices: ApplicationCommand.OptionChoice[] - } + /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-autocomplete */ + export interface Autocomplete { + /** autocomplete choices (max of 25 choices) */ + choices: ApplicationCommand.OptionChoice[] + } - /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-modal */ - export interface Modal { - /** a developer-defined identifier for the modal, max 100 characters */ - custom_id: string - /** the title of the popup modal, max 45 characters */ - title: string - /** between 1 and 5 (inclusive) components that make up the modal */ - components: Component[] + /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-modal */ + export interface Modal { + /** a developer-defined identifier for the modal, max 100 characters */ + custom_id: string + /** the title of the popup modal, max 45 characters */ + title: string + /** between 1 and 5 (inclusive) components that make up the modal */ + components: Component[] + } } } @@ -218,17 +224,17 @@ declare module './internal' { * Create a response to an Interaction from the gateway. Takes an interaction response. This endpoint also supports file attachments similar to the webhook endpoints. Refer to Uploading Files for details on uploading files and multipart/form-data requests. * @see https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response */ - createInteractionResponse(interaction_id: snowflake, token: string, params: InteractionResponse): Promise + createInteractionResponse(interaction_id: snowflake, token: string, params: Interaction.Response): Promise /** * Returns the initial Interaction response. Functions the same as Get Webhook Message. * @see https://discord.com/developers/docs/interactions/receiving-and-responding#get-original-interaction-response */ - getOriginalInteractionResponse(application_id: snowflake, token: string): Promise + getOriginalInteractionResponse(application_id: snowflake, token: string): Promise /** * Edits the initial Interaction response. Functions the same as Edit Webhook Message. * @see https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response */ - editOriginalInteractionResponse(application_id: snowflake, token: string): Promise + editOriginalInteractionResponse(application_id: snowflake, token: string): Promise /** * Deletes the initial Interaction response. Returns 204 No Content on success. * @see https://discord.com/developers/docs/interactions/receiving-and-responding#delete-original-interaction-response diff --git a/adapters/discord/src/types/internal.ts b/adapters/discord/src/types/internal.ts index 0346def0..17e77ebc 100644 --- a/adapters/discord/src/types/internal.ts +++ b/adapters/discord/src/types/internal.ts @@ -8,7 +8,7 @@ export class Internal { for (const key in routes[path]) { const method = key as Quester.Method for (const name of makeArray(routes[path][method])) { - Internal.prototype[name] = function (this: Internal, ...args: any[]) { + Internal.prototype[name] = async function (this: Internal, ...args: any[]) { const raw = args.join(', ') const url = path.replace(/\{([^}]+)\}/g, () => { if (!args.length) throw new Error(`too few arguments for ${path}, received ${raw}`) @@ -27,7 +27,12 @@ export class Internal { } else if (args.length > 1) { throw new Error(`too many arguments for ${path}, received ${raw}`) } - return this.http(method, url, config) + try { + return await this.http(method, url, config) + } catch (error) { + if (!Quester.isAxiosError(error) || !error.response) throw error + throw new Error(`[${error.response.status}] ${JSON.stringify(error.response.data)}`) + } } } } diff --git a/adapters/discord/src/types/message.ts b/adapters/discord/src/types/message.ts index bb93f9d0..56789f7b 100644 --- a/adapters/discord/src/types/message.ts +++ b/adapters/discord/src/types/message.ts @@ -6,8 +6,6 @@ export interface Message { id: snowflake /** id of the channel the message was sent in */ channel_id: snowflake - /** id of the guild the message was sent in */ - guild_id?: snowflake /** the author of this message (not guaranteed to be a valid user, see below) */ author: User /** member properties for this message's author */ @@ -343,11 +341,20 @@ export interface ChannelMention { export namespace Message { export namespace Event { - export interface Create extends Message {} + /** https://discord.com/developers/docs/topics/gateway-events#message-create */ + export interface Create extends Message { + /** ID of the guild the message was sent in - unless it is an ephemeral message */ + guild_id?: snowflake + /** Member properties for this message's author. Missing for ephemeral messages and messages from webhooks */ + member?: Partial + /** Users specifically mentioned in the message */ + mentions: (User & { member: Partial })[] + } - export interface Update extends Message {} + /** https://discord.com/developers/docs/topics/gateway-events#message-update */ + export interface Update extends Partial {} - /** https://discord.com/developers/docs/topics/gateway-events#message-delete-message-delete-event-fields */ + /** https://discord.com/developers/docs/topics/gateway-events#message-delete-message-delete */ export interface Delete { /** the id of the message */ id: snowflake @@ -357,7 +364,7 @@ export namespace Message { guild_id?: snowflake } - /** https://discord.com/developers/docs/topics/gateway-events#message-delete-bulk-message-delete-bulk-event-fields */ + /** https://discord.com/developers/docs/topics/gateway-events#message-delete-bulk-message-delete-bulk */ export interface DeleteBulk { /** the ids of the messages */ ids: snowflake[] diff --git a/adapters/discord/src/types/reaction.ts b/adapters/discord/src/types/reaction.ts index 5331913f..1afe22c8 100644 --- a/adapters/discord/src/types/reaction.ts +++ b/adapters/discord/src/types/reaction.ts @@ -1,4 +1,4 @@ -import { Emoji, GuildMember, integer, Internal, snowflake } from '.' +import { Emoji, GuildMember, integer, Internal, snowflake, User } from '.' /** https://discord.com/developers/docs/resources/channel#reaction-object-reaction-structure */ export interface Reaction { @@ -107,7 +107,7 @@ declare module './internal' { * Get a list of users that reacted with this emoji. Returns an array of user objects on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id. * @see https://discord.com/developers/docs/resources/channel#get-reactions */ - getReactions(channel_id: snowflake, message_id: snowflake, emoji: string, params?: Reaction.GetParams): Promise + getReactions(channel_id: snowflake, message_id: snowflake, emoji: string, params?: Reaction.GetParams): Promise /** * Deletes all reactions on a message. This endpoint requires the 'MANAGE_MESSAGES' permission to be present on the current user. Fires a Message Reaction Remove All Gateway event. * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions diff --git a/adapters/discord/src/types/role.ts b/adapters/discord/src/types/role.ts index 51fb5d6b..c51a3390 100644 --- a/adapters/discord/src/types/role.ts +++ b/adapters/discord/src/types/role.ts @@ -115,19 +115,19 @@ export namespace Role { /** https://discord.com/developers/docs/resources/guild#create-guild-role-json-params */ export interface Create { /** name of the role */ - name: string + name?: string /** bitwise value of the enabled/disabled permissions */ - permissions: string + permissions?: string /** RGB color value */ - color: integer + color?: integer /** whether the role should be displayed separately in the sidebar */ - hoist: boolean + hoist?: boolean /** the role's icon image (if the guild has the ROLE_ICONS feature) */ - icon: string + icon?: string /** the role's unicode emoji as a standard emoji (if the guild has the ROLE_ICONS feature) */ - unicode_emoji: string + unicode_emoji?: string /** whether the role should be mentionable */ - mentionable: boolean + mentionable?: boolean } /** https://discord.com/developers/docs/resources/guild#modify-guild-role-positions-json-params */ @@ -141,19 +141,19 @@ export namespace Role { /** https://discord.com/developers/docs/resources/guild#modify-guild-role-json-params */ export interface Modify { /** name of the role */ - name: string + name?: string /** bitwise value of the enabled/disabled permissions */ - permissions: string + permissions?: string /** RGB color value */ - color: integer + color?: integer /** whether the role should be displayed separately in the sidebar */ - hoist: boolean + hoist?: boolean /** the role's icon image (if the guild has the ROLE_ICONS feature) */ - icon: string + icon?: string /** the role's unicode emoji as a standard emoji (if the guild has the ROLE_ICONS feature) */ - unicode_emoji: string + unicode_emoji?: string /** whether the role should be mentionable */ - mentionable: boolean + mentionable?: boolean } } } diff --git a/adapters/discord/src/utils.ts b/adapters/discord/src/utils.ts index 251c7928..0e2621ca 100644 --- a/adapters/discord/src/utils.ts +++ b/adapters/discord/src/utils.ts @@ -1,14 +1,16 @@ -import { h, Session, Universal } from '@satorijs/satori' +import { h, pick, Session, Universal } from '@satorijs/satori' import { DiscordBot } from './bot' import * as Discord from './types' +export * from './types' + export const sanitize = (val: string) => val .replace(/[\\*_`~|()\[\]]/g, '\\$&') .replace(/@everyone/g, () => '\\@everyone') .replace(/@here/g, () => '\\@here') -export const adaptUser = (user: Discord.User): Universal.User => ({ +export const decodeUser = (user: Discord.User): Universal.User => ({ userId: user.id, avatar: `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png`, username: user.username, @@ -16,29 +18,39 @@ export const adaptUser = (user: Discord.User): Universal.User => ({ isBot: user.bot || false, }) -export const adaptGuild = (data: Discord.Guild): Universal.Guild => ({ +export const decodeGuild = (data: Discord.Guild): Universal.Guild => ({ guildId: data.id, guildName: data.name, }) -export const adaptChannel = (data: Discord.Channel): Universal.Channel => ({ +export const decodeChannel = (data: Discord.Channel): Universal.Channel => ({ channelId: data.id, channelName: data.name, }) -export const adaptAuthor = (author: Discord.User): Universal.Author => ({ - ...adaptUser(author), +export const decodeAuthor = (author: Discord.User): Universal.Author => ({ + ...decodeUser(author), nickname: author.username, }) -export async function adaptMessage(bot: DiscordBot, meta: Discord.Message, session: Partial = {}) { +export const decodeRole = (role: Discord.Role): Universal.Role => ({ + ...role, + permissions: BigInt(role.permissions), +}) + +export const encodeRole = (role: Partial): Partial => ({ + ...role, + permissions: role.permissions && '' + role.permissions, +}) + +export async function decodeMessage(bot: DiscordBot, meta: Discord.Message, session: Partial = {}) { const { platform } = bot - prepareMessage(session, meta) session.messageId = meta.id + session.channelId = meta.channel_id session.timestamp = new Date(meta.timestamp).valueOf() || Date.now() if (meta.author) { - session.author = adaptAuthor(meta.author) + session.author = decodeAuthor(meta.author) session.userId = meta.author.id } if (meta.member?.nick) { @@ -124,25 +136,32 @@ export async function adaptMessage(bot: DiscordBot, meta: Discord.Message, sessi return session as Universal.Message } -export function prepareMessage(session: Partial, data: Partial) { - session.guildId = data.guild_id - session.subtype = data.guild_id ? 'group' : 'private' - session.channelId = data.channel_id +export function setupMessageGuildId(session: Partial, guildId: string) { + session.guildId = guildId + session.isDirect = !guildId + session.subtype = guildId ? 'group' : 'private' } -function prepareReactionSession(session: Partial, data: any) { +type ReactionEvent = Partial< + & Discord.Reaction.Event.Add + & Discord.Reaction.Event.Remove + & Discord.Reaction.Event.RemoveAll + & Discord.Reaction.Event.RemoveEmoji> + +function setupReaction(session: Partial, data: ReactionEvent) { session.userId = data.user_id session.messageId = data.message_id session.guildId = data.guild_id session.channelId = data.channel_id + session.isDirect = !data.guild_id session.subtype = data.guild_id ? 'group' : 'private' if (!data.emoji) return const { id, name } = data.emoji session.content = id ? `${name}:${id}` : name } -export async function adaptSession(bot: DiscordBot, input: Discord.GatewayPayload) { - const session = bot.session() +export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Payload) { + const session = bot.session({}, input) if (input.t === 'MESSAGE_CREATE') { if (input.d.webhook_id) { const webhook = await bot.ensureWebhook(input.d.channel_id) @@ -152,35 +171,69 @@ export async function adaptSession(bot: DiscordBot, input: Discord.GatewayPayloa } } session.type = 'message' - await adaptMessage(bot, input.d, session) + await decodeMessage(bot, input.d, session) + setupMessageGuildId(session, input.d.guild_id) // dc 情况特殊 可能有 embeds 但是没有消息主体 // if (!session.content) return } else if (input.t === 'MESSAGE_UPDATE') { session.type = 'message-updated' - const msg = await bot.internal.getChannelMessage(input.d.channel_id, input.d.id) + const message = await bot.internal.getChannelMessage(input.d.channel_id, input.d.id) // Unlike creates, message updates may contain only a subset of the full message object payload // https://discord.com/developers/docs/topics/gateway-events#message-update - await adaptMessage(bot, msg, session) + await decodeMessage(bot, message, session) + const channel = await bot.internal.getChannel(input.d.channel_id) + setupMessageGuildId(session, channel.guild_id) // if (!session.content) return } else if (input.t === 'MESSAGE_DELETE') { session.type = 'message-deleted' session.messageId = input.d.id - prepareMessage(session, input.d) + session.channelId = input.d.channel_id + setupMessageGuildId(session, input.d.guild_id) } else if (input.t === 'MESSAGE_REACTION_ADD') { session.type = 'reaction-added' - prepareReactionSession(session, input.d) + setupReaction(session, input.d) } else if (input.t === 'MESSAGE_REACTION_REMOVE') { session.type = 'reaction-deleted' session.subtype = 'one' - prepareReactionSession(session, input.d) + setupReaction(session, input.d) } else if (input.t === 'MESSAGE_REACTION_REMOVE_ALL') { session.type = 'reaction-deleted' session.subtype = 'all' - prepareReactionSession(session, input.d) + setupReaction(session, input.d) } else if (input.t === 'MESSAGE_REACTION_REMOVE_EMOJI') { session.type = 'reaction-deleted' session.subtype = 'emoji' - prepareReactionSession(session, input.d) + setupReaction(session, input.d) + } else if (input.t === 'GUILD_ROLE_CREATE') { + session.type = 'guild-role-added' + session.guildId = input.d.guild_id + session.roleId = input.d.role.id + session.data.role = decodeRole(input.d.role) + } else if (input.t === 'GUILD_ROLE_UPDATE') { + session.type = 'guild-role-updated' + session.guildId = input.d.guild_id + session.roleId = input.d.role.id + session.data.role = decodeRole(input.d.role) + } else if (input.t === 'GUILD_ROLE_DELETE') { + session.type = 'guild-role-added' + session.guildId = input.d.guild_id + session.roleId = input.d.role_id + } else if (input.t === 'INTERACTION_CREATE' && input.d.type === Discord.Interaction.Type.APPLICATION_COMMAND) { + const data = input.d.data as Discord.InteractionData.ApplicationCommand + const command = bot.commands.find(cmd => cmd.name === data.name) + if (!command) return + await bot.internal.createInteractionResponse(input.d.id, input.d.token, { + type: Discord.Interaction.CallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE, + }) + session.type = 'interaction/command' + session.isDirect = !input.d.guild_id + session.subtype = input.d.guild_id ? 'group' : 'private' + session.channelId = input.d.channel_id + session.guildId = input.d.guild_id + session.userId = input.d.member.user.id + session.messageId = input.d.id + session.content = '' + session.data.argv = decodeArgv(data, command) } else if (input.t === 'CHANNEL_UPDATE') { session.type = 'channel-updated' session.guildId = input.d.guild_id @@ -191,3 +244,72 @@ export async function adaptSession(bot: DiscordBot, input: Discord.GatewayPayloa } return session } + +const types = { + text: Discord.ApplicationCommand.OptionType.STRING, + string: Discord.ApplicationCommand.OptionType.STRING, + boolean: Discord.ApplicationCommand.OptionType.BOOLEAN, + number: Discord.ApplicationCommand.OptionType.NUMBER, + integer: Discord.ApplicationCommand.OptionType.INTEGER, + posint: Discord.ApplicationCommand.OptionType.INTEGER, + user: Discord.ApplicationCommand.OptionType.STRING, + channel: Discord.ApplicationCommand.OptionType.STRING, + guild: Discord.ApplicationCommand.OptionType.STRING, +} + +export const encodeCommand = (cmd: Universal.Command): Discord.ApplicationCommand.Params.Create => ({ + name: cmd.name, + type: Discord.ApplicationCommand.Type.CHAT_INPUT, + description: cmd.description[''] || cmd.name, + description_localizations: pick(cmd.description, Discord.Locale), + options: encodeCommandOptions(cmd), +}) + +const decodeArgv = (data: Discord.InteractionData.ApplicationCommand, command: Universal.Command) => { + const result = { name: data.name, arguments: [], options: {} } as Universal.Argv + for (const argument of command.arguments) { + const value = data.options?.find(opt => opt.name === argument.name)?.value + if (value !== undefined) result.arguments.push(value) + } + for (const option of command.options) { + const value = data.options?.find(opt => opt.name === option.name)?.value + if (value !== undefined) result.options[option.name] = value + } + return result +} + +export function encodeCommandOptions(cmd: Universal.Command): Discord.ApplicationCommand.Option[] { + const result: Discord.ApplicationCommand.Option[] = [] + if (cmd.children.length) { + result.push(...cmd.children.map(child => ({ + name: child.name.slice(cmd.name.length + 1), + type: child.children.length + ? Discord.ApplicationCommand.OptionType.SUB_COMMAND_GROUP + : Discord.ApplicationCommand.OptionType.SUB_COMMAND, + options: encodeCommandOptions(child), + description: cmd.description[''] || child.name, + description_localizations: pick(cmd.description, Discord.Locale), + }))) + } else { + for (const arg of cmd.arguments) { + result.push({ + name: arg.name.toLowerCase().replace(/[^a-z0-9]/g, ''), + description: arg.description[''] || arg.name, + description_localizations: pick(arg.description, Discord.Locale), + type: types[arg.type] ?? types.text, + required: arg.required ?? false, + }) + } + for (const option of cmd.options) { + result.push({ + name: option.name.toLowerCase(), + description: option.description[''] || option.name, + description_localizations: pick(option.description, Discord.Locale), + type: types[option.type] ?? types.text, + required: option.required ?? false, + min_value: option.type === 'posint' ? 1 : undefined, + }) + } + } + return result.sort((a, b) => +b.required - +a.required) +} diff --git a/adapters/discord/src/ws.ts b/adapters/discord/src/ws.ts index f8206d6b..6302574d 100644 --- a/adapters/discord/src/ws.ts +++ b/adapters/discord/src/ws.ts @@ -1,6 +1,6 @@ import { Adapter, Logger, Schema } from '@satorijs/satori' -import { GatewayIntent, GatewayOpcode, GatewayPayload } from './types' -import { adaptSession, adaptUser } from './utils' +import { Gateway } from './types' +import { adaptSession, decodeUser } from './utils' import { DiscordBot } from './bot' const logger = new Logger('discord') @@ -22,14 +22,14 @@ export class WsClient extends Adapter.WsClient { heartbeat() { logger.debug(`heartbeat d ${this._d}`) this.bot.socket.send(JSON.stringify({ - op: GatewayOpcode.HEARTBEAT, + op: Gateway.Opcode.HEARTBEAT, d: this._d, })) } accept() { this.bot.socket.addEventListener('message', async ({ data }) => { - let parsed: GatewayPayload + let parsed: Gateway.Payload try { parsed = JSON.parse(data.toString()) } catch (error) { @@ -41,12 +41,12 @@ export class WsClient extends Adapter.WsClient { } // https://discord.com/developers/docs/topics/gateway#connection-lifecycle - if (parsed.op === GatewayOpcode.HELLO) { + if (parsed.op === Gateway.Opcode.HELLO) { this._ping = setInterval(() => this.heartbeat(), parsed.d.heartbeat_interval) if (this._sessionId) { logger.debug('resuming') this.bot.socket.send(JSON.stringify({ - op: GatewayOpcode.RESUME, + op: Gateway.Opcode.RESUME, d: { token: this.bot.config.token, session_id: this._sessionId, @@ -55,7 +55,7 @@ export class WsClient extends Adapter.WsClient { })) } else { this.bot.socket.send(JSON.stringify({ - op: GatewayOpcode.IDENTIFY, + op: Gateway.Opcode.IDENTIFY, d: { token: this.bot.config.token, properties: {}, @@ -66,7 +66,7 @@ export class WsClient extends Adapter.WsClient { } } - if (parsed.op === GatewayOpcode.INVALID_SESSION) { + if (parsed.op === Gateway.Opcode.INVALID_SESSION) { if (parsed.d) return this._sessionId = '' logger.warn('offline: invalid session') @@ -74,14 +74,13 @@ export class WsClient extends Adapter.WsClient { this.bot.socket?.close() } - if (parsed.op === GatewayOpcode.DISPATCH) { + if (parsed.op === Gateway.Opcode.DISPATCH) { + this.bot.ctx.emit('discord/' + parsed.t.toLowerCase().replace(/_/g, '-') as any, parsed) if (parsed.t === 'READY') { this._sessionId = parsed.d.session_id this._resumeUrl = parsed.d.resume_gateway_url - const self: any = adaptUser(parsed.d.user) - self.selfId = self.userId - delete self.userId - Object.assign(this.bot, self) + const user = decodeUser(parsed.d.user) + Object.assign(this.bot, user) logger.debug('session_id ' + this._sessionId) return this.bot.online() } @@ -92,7 +91,7 @@ export class WsClient extends Adapter.WsClient { if (session) this.bot.dispatch(session) } - if (parsed.op === GatewayOpcode.RECONNECT) { + if (parsed.op === Gateway.Opcode.RECONNECT) { this.bot.offline() logger.warn('offline: discord request reconnect') this.bot.socket?.close() @@ -112,12 +111,12 @@ export namespace WsClient { export const Config: Schema = Schema.intersect([ Schema.object({ - intents: Schema.bitset(GatewayIntent).description('需要订阅的机器人事件。').default(0 - | GatewayIntent.GUILD_MESSAGES - | GatewayIntent.GUILD_MESSAGE_REACTIONS - | GatewayIntent.DIRECT_MESSAGES - | GatewayIntent.DIRECT_MESSAGE_REACTIONS - | GatewayIntent.MESSAGE_CONTENT), + intents: Schema.bitset(Gateway.Intent).description('需要订阅的机器人事件。').default(0 + | Gateway.Intent.GUILD_MESSAGES + | Gateway.Intent.GUILD_MESSAGE_REACTIONS + | Gateway.Intent.DIRECT_MESSAGES + | Gateway.Intent.DIRECT_MESSAGE_REACTIONS + | Gateway.Intent.MESSAGE_CONTENT), }).description('推送设置'), Adapter.WsClient.Config, ] as const) diff --git a/adapters/kook/.npmignore b/adapters/kook/.npmignore new file mode 100644 index 00000000..7e5fcbc1 --- /dev/null +++ b/adapters/kook/.npmignore @@ -0,0 +1,2 @@ +.DS_Store +tsconfig.tsbuildinfo diff --git a/adapters/kook/package.json b/adapters/kook/package.json index 80859e66..87e687d1 100644 --- a/adapters/kook/package.json +++ b/adapters/kook/package.json @@ -1,7 +1,7 @@ { "name": "@satorijs/adapter-kook", "description": "Kook (Kaiheila) Adapter for Satorijs", - "version": "3.8.2", + "version": "3.10.2", "main": "lib/index.js", "typings": "lib/index.d.ts", "files": [ @@ -26,7 +26,7 @@ "satori" ], "peerDependencies": { - "@satorijs/satori": "^2.3.10" + "@satorijs/satori": "^2.6.1" }, "dependencies": { "form-data": "^4.0.0" diff --git a/adapters/kook/src/bot.ts b/adapters/kook/src/bot.ts index 1a92377f..3b3ac903 100644 --- a/adapters/kook/src/bot.ts +++ b/adapters/kook/src/bot.ts @@ -1,18 +1,20 @@ -import { Bot, Context, Fragment, h, Quester, Schema, SendOptions } from '@satorijs/satori' -import { Method } from 'axios' -import { adaptAuthor, adaptGroup, adaptMessage, adaptUser } from './utils' +import { Bot, Context, Fragment, h, Quester, Schema, SendOptions, Universal } from '@satorijs/satori' +import { adaptAuthor, adaptGroup, adaptMessage, adaptUser, decodeRole, encodeRole } from './utils' import * as Kook from './types' import FormData from 'form-data' import { WsClient } from './ws' import { HttpServer } from './http' -import { KookMessenger } from './message' +import { isDirectChannel, KookMessageEncoder } from './message' export class KookBot extends Bot { + static MessageEncoder = KookMessageEncoder + http: Quester internal: Kook.Internal constructor(ctx: Context, config: T) { super(ctx, config) + this.platform = 'kook' this.http = ctx.http.extend({ headers: { 'Authorization': `Bot ${config.token}`, @@ -28,7 +30,7 @@ export class KookBot extends Bot { } } - async request(method: Method, path: string, data = {}, headers: any = {}): Promise { + async request(method: Quester.Method, path: string, data = {}, headers: any = {}): Promise { if (method === 'GET') { return (await this.http.get(path, { params: data, headers })).data } else { @@ -37,17 +39,8 @@ export class KookBot extends Bot { } } - async sendMessage(channelId: string, content: Fragment, guildId?: string, options?: SendOptions) { - return new KookMessenger(this, channelId, guildId, options).send(content) - } - - async sendPrivateMessage(target_id: string, content: Fragment, options?: SendOptions) { - const { code } = await this.request('POST', '/user-chat/create', { target_id }) - return this.sendMessage(code, content, null, options) - } - async deleteMessage(channelId: string, msg_id: string) { - if (channelId.length > 30) { + if (isDirectChannel(channelId)) { await this.request('POST', '/user-chat/delete-msg', { msg_id }) } else { await this.request('POST', '/message/delete', { msg_id }) @@ -56,7 +49,7 @@ export class KookBot extends Bot { async editMessage(channelId: string, msg_id: string, content: Fragment) { content = h.normalize(content).join('') - if (channelId.length > 30) { + if (isDirectChannel(channelId)) { await this.request('POST', '/user-chat/update-msg', { msg_id, content }) } else { await this.request('POST', '/message/update', { msg_id, content }) @@ -64,7 +57,7 @@ export class KookBot extends Bot { } async getMessage(channelId: string, msg_id: string) { - if (channelId.length > 30) { + if (isDirectChannel(channelId)) { return adaptMessage(await this.request('POST', '/user-chat/view', { msg_id })) } else { return adaptMessage(await this.request('POST', '/message/view', { msg_id })) @@ -72,7 +65,7 @@ export class KookBot extends Bot { } async $createReaction(channelId: string, msg_id: string, emoji: string) { - if (channelId.length > 30) { + if (isDirectChannel(channelId)) { await this.request('POST', '/direct-message/add-reaction', { msg_id, emoji }) } else { await this.request('POST', '/message/add-reaction', { msg_id, emoji }) @@ -80,7 +73,7 @@ export class KookBot extends Bot { } async $deleteReaction(channelId: string, messageId: string, emoji: string, user_id?: string) { - if (channelId.length > 30) { + if (isDirectChannel(channelId)) { await this.request('POST', '/direct-message/delete-reaction', { msg_id: messageId, emoji }) } else { await this.request('POST', '/message/delete-reaction', { msg_id: messageId, emoji, user_id }) @@ -115,10 +108,74 @@ export class KookBot extends Bot { async kickGroup(guild_id: string, user_id: string) { await this.request('POST', '/guild/kickout', { guild_id, user_id }) } + + async sendPrivateMessage(userId: string, content: Fragment, options?: SendOptions) { + const { code } = await this.request('POST', '/user-chat/create', { target_id: userId }) + return this.sendMessage(code, content, null, options) + } + + createReaction(channelId: string, messageId: string, emoji: string) { + if (isDirectChannel(channelId)) { + return this.internal.addDirectMessageReaction({ msg_id: messageId, emoji }) + } else { + return this.internal.addMessageReaction({ msg_id: messageId, emoji }) + } + } + + deleteReaction(channelId: string, messageId: string, emoji: string, userId?: string) { + if (isDirectChannel(channelId)) { + return this.internal.deleteDirectMessageReaction({ msg_id: messageId, emoji, user_id: userId }) + } else { + return this.internal.deleteMessageReaction({ msg_id: messageId, emoji, user_id: userId }) + } + } + + async getReactions(channelId: string, messageId: string, emoji: string): Promise { + let users: Kook.User[] + if (isDirectChannel(channelId)) { + users = await this.internal.getDirectMessageReactionList({ msg_id: messageId, emoji }) + } else { + users = await this.internal.getMessageReactionList({ msg_id: messageId, emoji }) + } + return users.map(adaptUser) + } + + async setGuildMemberRole(guildId: string, userId: string, roleId: string) { + await this.internal.grantGuildRole({ guild_id: guildId, user_id: userId, role_id: +roleId }) + } + + async unsetGuildMemberRole(guildId: string, userId: string, roleId: string) { + await this.internal.revokeGuildRole({ guild_id: guildId, user_id: userId, role_id: +roleId }) + } + + async getGuildRoles(guildId: string): Promise { + const { items } = await this.internal.getGuildRoleList({ guild_id: guildId }) + return items.map(decodeRole) + } + + async createGuildRole(guildId: string, data: Partial) { + const role = await this.internal.createGuildRole({ + guild_id: guildId, + ...data, + }) + return role.role_id.toString() + } + + async modifyGuildRole(guildId: string, roleId: string, data: Partial) { + await this.internal.updateGuildRole({ + guild_id: guildId, + ...encodeRole(data), + role_id: +roleId, + }) + } + + async deleteGuildRole(guildId: string, roleId: string) { + await this.internal.deleteGuildRole({ guild_id: guildId, role_id: +roleId }) + } } export namespace KookBot { - export interface BaseConfig extends Bot.Config, Quester.Config, KookMessenger.Config {} + export interface BaseConfig extends Bot.Config, Quester.Config, KookMessageEncoder.Config {} export type Config = BaseConfig & (HttpServer.Config | WsClient.Config) @@ -132,10 +189,7 @@ export namespace KookBot { WsClient.Config, HttpServer.Config, ]), - KookMessenger.Config, + KookMessageEncoder.Config, Quester.createConfig('https://www.kookapp.cn/api/v3'), ] as const) } - -// for backward compatibility -KookBot.prototype.platform = 'kook' diff --git a/adapters/kook/src/http.ts b/adapters/kook/src/http.ts index e5e2f468..1c29039a 100644 --- a/adapters/kook/src/http.ts +++ b/adapters/kook/src/http.ts @@ -44,9 +44,9 @@ export namespace HttpServer { } export const Config: Schema = Schema.object({ - protocol: Schema.const('http' as const).required(), + protocol: Schema.const('http').required(), + token: Schema.string().description('机器人令牌。').role('secret').required(), + verifyToken: Schema.string().description('验证令牌。').role('secret').required(), path: Schema.string().description('服务器监听的路径。').default('/kook'), - token: Schema.string().description('机器人的用户令牌。').role('secret').required(), - verifyToken: Schema.string().description('机器人的验证令牌。').role('secret').required(), }) } diff --git a/adapters/kook/src/index.ts b/adapters/kook/src/index.ts index f92dce4b..513d1df6 100644 --- a/adapters/kook/src/index.ts +++ b/adapters/kook/src/index.ts @@ -1,5 +1,5 @@ import { KookBot } from './bot' -import * as Kook from './types' +import * as Kook from './utils' export { Kook } @@ -11,14 +11,10 @@ export * from './utils' export default KookBot -declare global { - namespace Satori { - interface Session { - kook?: Kook.Payload & Kook.Internal - } +declare module '@satorijs/core' { + interface Events extends Kook.Events {} - interface Events { - 'kook/message-btn-click': {} - } + interface Session { + kook?: Kook.Payload & Kook.Internal } } diff --git a/adapters/kook/src/message.ts b/adapters/kook/src/message.ts index b2cd5c81..fbf005c2 100644 --- a/adapters/kook/src/message.ts +++ b/adapters/kook/src/message.ts @@ -1,4 +1,4 @@ -import { h, Messenger, Schema, SendOptions } from '@satorijs/satori' +import { h, MessageEncoder, Schema } from '@satorijs/satori' import FormData from 'form-data' import { KookBot } from './bot' import { adaptMessage } from './utils' @@ -7,19 +7,22 @@ import internal from 'stream' const attachmentTypes = ['image', 'video', 'audio', 'file'] -export class KookMessenger extends Messenger { +export function isDirectChannel(channelId: string) { + return channelId.length > 30 +} + +export class KookMessageEncoder extends MessageEncoder { private path: string private params = {} as Partial private additional = {} as Partial private buffer: string = '' - constructor(bot: KookBot, channelId: string, guildId?: string, options?: SendOptions) { - super(bot, channelId, guildId, options) - if (channelId.length > 30) { - this.params.chat_code = channelId + async prepare() { + if (isDirectChannel(this.session.channelId)) { + this.params.chat_code = this.session.channelId this.path = '/user-chat/create-msg' } else { - this.params.target_id = channelId + this.params.target_id = this.session.channelId this.path = '/message/create' } } @@ -196,18 +199,18 @@ export class KookMessenger extends Messenger { } } -export namespace KookMessenger { +export namespace KookMessageEncoder { export type HandleMixedContent = 'card' | 'separate' | 'mixed' export interface Config { handleMixedContent?: HandleMixedContent } - export const Config: Schema = Schema.object({ + export const Config: Schema = Schema.object({ handleMixedContent: Schema.union([ - Schema.const('separate' as const).description('将每个不同形式的内容分开发送'), - Schema.const('card' as const).description('使用卡片发送内容'), - Schema.const('mixed' as const).description('使用混合模式发送内容'), + Schema.const('separate').description('将每个不同形式的内容分开发送'), + Schema.const('card').description('使用卡片发送内容'), + Schema.const('mixed').description('使用混合模式发送内容'), ]).role('radio').description('发送图文等混合内容时采用的方式。').default('separate'), }).description('发送设置') } diff --git a/adapters/kook/src/types.ts b/adapters/kook/src/types.ts index c3ca7ff6..d181fbeb 100644 --- a/adapters/kook/src/types.ts +++ b/adapters/kook/src/types.ts @@ -229,10 +229,18 @@ export interface User { avatar: string online: boolean bot?: boolean + roles: number[] + vip_avatar?: string + is_vip?: boolean + mobile_verified: boolean + joined_at?: number + active_time?: number + status: UserStatus } export enum UserStatus { normal = 0, + normal_1 = 1, banned = 10, } @@ -271,18 +279,23 @@ export interface Channel { name: string user_id: string guild_id: string - is_category: number + is_category: boolean parent_id: string topic: string - type: number + type: 0 | 1 | 2 level: number - slow_mode: number - permission_overwrites: Overwrite - permission_users: any - permission_sync: 0 | 1 -} - -export interface NoticeBody extends Channel, MessageMeta { + slow_mode?: 0 | 5000 | 10000 | 15000 | 30000 | 60000 | 120000 | 300000 | 600000 | 900000 | 1800000 | 3600000 | 7200000 | 21600000 + has_password?: boolean + limit_amount: number + permission_overwrites?: Overwrite[] + permission_users?: any[] + permission_sync?: 0 | 1 + voice_quality?: '1' | '2' | '3' + server_url?: string + children?: string[] +} + +export interface NoticeBody extends Channel, MessageMeta, GuildRole { value: string msg_id: string target_id: string @@ -365,7 +378,6 @@ export interface GuildList extends List {} export interface GuildUser extends User { joined_at: number active_time: number - roles: number[] is_master: boolean abbr: string } @@ -429,8 +441,8 @@ export enum Permissions { CHANNEL_VOICR_SPEAK_FREE = 22, CHANNEL_VOICE_SPEAK = 23, GUILD_USER_DEAFEN = 24, - GUILD_USER_NAME_CHANGE_OTHER = 25, - GUILD_USER_MUTE = 26, + GUILD_USER_MUTEGUILD_USER_NAME_CHANGE_OTHER = 25, + GUILD_USER_NAME_CHANGE_OTHER = 26, CHANNEL_VOICE_BGM = 27, } @@ -595,6 +607,41 @@ export interface Internal { hasPermission(permissions: number, permission: Permissions): boolean } +export interface Events { + 'kook/updated-message'(input: any): void + 'kook/updated-private-message'(input: any): void + 'kook/deleted-message'(input: any): void + 'kook/deleted-private-message'(input: any): void + 'kook/added-reaction'(input: any): void + 'kook/private-added-reaction'(input: any): void + 'kook/deleted-reaction'(input: any): void + 'kook/private-deleted-reaction'(input: any): void + 'kook/updated-channel'(input: any): void + 'kook/deleted-channel'(input: any): void + 'kook/pinned-message'(input: any): void + 'kook/unpinned-message'(input: any): void + 'kook/joined-guild'(input: any): void + 'kook/exited-guild'(input: any): void + 'kook/updated-guild'(input: any): void + 'kook/deleted-guild'(input: any): void + 'kook/self-joined-guild'(input: any): void + 'kook/self-exited-guild'(input: any): void + 'kook/update-guild-member'(input: any): void + 'kook/guild-member-online'(input: any): void + 'kook/guild-member-offline'(input: any): void + 'kook/added-role'(input: any): void + 'kook/deleted-role'(input: any): void + 'kook/updated-role'(input: any): void + 'kook/added-block-list'(input: any): void + 'kook/deleted-block-list'(input: any): void + 'kook/added-emoji'(input: any): void + 'kook/updated-emoji'(input: any): void + 'kook/joined-channel'(input: any): void + 'kook/exited-channel'(input: any): void + 'kook/user-updated'(input: any): void + 'kook/message-btn-click'(input: any): void +} + export class Internal { constructor(private http: Quester) {} diff --git a/adapters/kook/src/utils.ts b/adapters/kook/src/utils.ts index fb38666b..fa553838 100644 --- a/adapters/kook/src/utils.ts +++ b/adapters/kook/src/utils.ts @@ -1,6 +1,8 @@ -import { Bot, defineProperty, h, hyphenate, Session, Universal } from '@satorijs/satori' +import { Bot, defineProperty, h, hyphenate, isNullable, Session, Universal } from '@satorijs/satori' import * as Kook from './types' +export * from './types' + export const adaptGroup = (data: Kook.Guild): Universal.Guild => ({ guildId: data.id, guildName: data.name, @@ -18,13 +20,33 @@ export const adaptAuthor = (author: Kook.Author): Universal.Author => ({ nickname: author.nickname, }) +export const decodeRole = (role: Kook.GuildRole): Universal.Role => ({ + ...role, + id: '' + role.role_id, + permissions: BigInt(role.permissions), + hoist: !!role.hoist, + mentionable: !!role.mentionable, +}) + +function encodeBit(value: boolean) { + return isNullable(value) ? value : value ? 1 : 0 +} + +export const encodeRole = (role: Partial): Partial => ({ + ...role, + role_id: +role.id, + permissions: role.permissions && Number(role.permissions), + hoist: encodeBit(role.hoist), + mentionable: encodeBit(role.mentionable), +}) + function transformCardElement(data: any) { const { type, modules, text, elements, fields, ...attrs } = data const children = modules || elements || fields || (text ? [text] : []) return h(type, attrs, children.map(transformCardElement)) } -function adaptMessageMeta(base: Kook.MessageBase, meta: Kook.MessageMeta, session: Universal.MessageBase = {}) { +function adaptMessageMeta(base: Kook.MessageBase, meta: Kook.MessageMeta, session: Universal.Message = {}) { if (meta.author) { session.author = adaptAuthor(meta.author) session.userId = meta.author.id @@ -78,13 +100,14 @@ function adaptMessageSession(data: Kook.Data, meta: Kook.MessageMeta, session: P adaptMessageMeta(data, meta, session) session.messageId = data.msg_id session.timestamp = data.msg_timestamp - const subtype = data.channel_type === 'GROUP' ? 'group' : 'private' - session.subtype = subtype + session.isDirect = data.channel_type === 'PERSON' + session.subtype = data.channel_type === 'GROUP' ? 'group' : 'private' if (meta.quote) { session.quote = adaptMessageMeta(meta.quote, meta.quote) session.quote.messageId = meta.quote.rong_id session.quote.channelId = session.channelId - session.quote.subtype = subtype + session.quote.subtype = session.subtype + session.quote.isDirect = session.isDirect } return session } @@ -98,6 +121,7 @@ function adaptMessageCreate(data: Kook.Data, meta: Kook.MessageExtra, session: P session.channelId = data.target_id } else { session.subtype = 'private' + session.isDirect = true session.channelId = meta.code } } @@ -117,10 +141,10 @@ function adaptReaction(body: Kook.NoticeBody, session: Partial) { export function adaptSession(bot: Bot, input: any) { const session = bot.session() - defineProperty(session, 'kook', Object.create(bot.internal)) - Object.assign(session.kook, input) + defineProperty(session, 'kook', Object.assign(Object.create(bot.internal), input)) if (input.type === Kook.Type.system) { const { type, body } = input.extra as Kook.Notice + bot.ctx.emit('kook/' + type.replace(/_/g, '-') as any, input.body) switch (type) { case 'updated_message': case 'updated_private_message': @@ -183,6 +207,15 @@ export function adaptSession(bot: Bot, input: any) { case 'added_role': case 'deleted_role': case 'updated_role': + session.type = { + added_role: 'guild-role-added', + deleted_role: 'guild-role-deleted', + updated_role: 'guild-role-updated', + }[type] + session.guildId = input.target_id + session.roleId = '' + body.role_id + session.data.role = decodeRole(body) + break case 'added_block_list': case 'deleted_block_list': case 'added_emoji': @@ -190,7 +223,6 @@ export function adaptSession(bot: Bot, input: any) { session.type = 'kook' session.subtype = hyphenate(type) session.guildId = input.target_id - session.extra = body break case 'joined_channel': case 'exited_channel': @@ -204,7 +236,6 @@ export function adaptSession(bot: Bot, input: any) { session.type = 'kook' session.subtype = hyphenate(type) session.userId = body.user_id - session.extra = body break case 'message_btn_click': session.type = 'kook' @@ -213,7 +244,6 @@ export function adaptSession(bot: Bot, input: any) { session.userId = body.user_id session.content = body.value session.targetId = body.target_id - session.extra = body break default: return } diff --git a/adapters/kook/src/ws.ts b/adapters/kook/src/ws.ts index 425681f4..749b8e77 100644 --- a/adapters/kook/src/ws.ts +++ b/adapters/kook/src/ws.ts @@ -72,7 +72,7 @@ export namespace WsClient { export const Config: Schema = Schema.intersect([ Schema.object({ - protocol: Schema.const('ws' as const).required(process.env.KOISHI_ENV !== 'browser'), + protocol: Schema.const('ws').required(process.env.KOISHI_ENV !== 'browser'), token: Schema.string().description('机器人的用户令牌。').role('secret').required(), }), Adapter.WsClient.Config, diff --git a/adapters/lark/.npmignore b/adapters/lark/.npmignore new file mode 100644 index 00000000..7e5fcbc1 --- /dev/null +++ b/adapters/lark/.npmignore @@ -0,0 +1,2 @@ +.DS_Store +tsconfig.tsbuildinfo diff --git a/adapters/lark/package.json b/adapters/lark/package.json index 57374f14..c1643fa1 100644 --- a/adapters/lark/package.json +++ b/adapters/lark/package.json @@ -1,7 +1,7 @@ { "name": "@satorijs/adapter-lark", "description": "Lark / Feishu Adapter for Satorijs", - "version": "2.0.2", + "version": "2.1.3", "main": "lib/index.js", "typings": "lib/index.d.ts", "files": [ @@ -30,7 +30,7 @@ "satori" ], "peerDependencies": { - "@satorijs/satori": "^2.3.10" + "@satorijs/satori": "^2.6.1" }, "dependencies": { "form-data": "^4.0.0" diff --git a/adapters/lark/src/bot.ts b/adapters/lark/src/bot.ts index c50229cd..cec0e665 100644 --- a/adapters/lark/src/bot.ts +++ b/adapters/lark/src/bot.ts @@ -1,12 +1,14 @@ -import { Bot, Context, Logger, Quester, Schema, SendOptions } from '@satorijs/satori' +import { Bot, Context, h, Logger, Quester, Schema } from '@satorijs/satori' import { HttpServer } from './http' -import { FeishuMessenger } from './message' +import { LarkMessageEncoder } from './message' import { Internal } from './types' const logger = new Logger('lark') export class LarkBot extends Bot { + static MessageEncoder = LarkMessageEncoder + _token?: string _refresher?: NodeJS.Timeout http: Quester @@ -21,6 +23,7 @@ export class LarkBot extends Bot { logger.warn('selfUrl is not set, some features may not work') } + this.platform = 'lark' this.selfId = config.appId this.http = ctx.http.extend({ @@ -36,12 +39,12 @@ export class LarkBot extends Bot { ctx.plugin(HttpServer, this) } - async initialize(): Promise { + async initialize() { await this.refreshToken() this.online() } - private async refreshToken(): Promise { + private async refreshToken() { const { tenant_access_token: token } = await this.internal.getTenantAccessToken({ app_id: this.config.appId, app_secret: this.config.appSecret, @@ -64,15 +67,14 @@ export class LarkBot extends Bot { this.http.config.headers.Authorization = `Bearer ${v}` } - async sendMessage(channelId: string, content: string, guildId?: string, options?: SendOptions): Promise { - return new FeishuMessenger(this, channelId, guildId, options).send(content) - } - - async sendPrivateMessage(userId: string, content: string, options?: SendOptions): Promise { - return this.sendMessage(userId, content, null, options) + async editMessage(channelId: string, messageId: string, content: h.Fragment) { + await this.internal.updateMessage(messageId, { + content: h.normalize(content).join(''), + msg_type: 'text', + }) } - async deleteMessage(channelId: string, messageId: string): Promise { + async deleteMessage(channelId: string, messageId: string) { await this.internal.deleteMessage(messageId) } } diff --git a/adapters/lark/src/http.ts b/adapters/lark/src/http.ts index e1d96a92..818364a1 100644 --- a/adapters/lark/src/http.ts +++ b/adapters/lark/src/http.ts @@ -50,12 +50,12 @@ export class HttpServer extends Adapter.Server { } // compare verification token - const enabledVeirfyTokenVerify = this.bots.filter((bot) => bot.config.verifyToken && bot.config.verificationToken) - if (enabledVeirfyTokenVerify.length) { + const enabledVerifyTokenVerify = this.bots.filter((bot) => bot.config.verifyToken && bot.config.verificationToken) + if (enabledVerifyTokenVerify.length) { const token = ctx.request.body?.token // only compare token if token exists if (token) { - const result = enabledVeirfyTokenVerify.some((bot) => { + const result = enabledVerifyTokenVerify.some((bot) => { if (token === bot.config.verificationToken) return true else return false }) @@ -97,6 +97,7 @@ export class HttpServer extends Adapter.Server { dispatchSession(body: AllEvents): void { const { header } = body + if (!header) return const { app_id, event_type } = header body.type = event_type // add type to body to ease typescript type narrowing const bot = this.bots.find((bot) => bot.selfId === app_id) diff --git a/adapters/lark/src/message.ts b/adapters/lark/src/message.ts index fdff3b3a..ac8307d8 100644 --- a/adapters/lark/src/message.ts +++ b/adapters/lark/src/message.ts @@ -1,10 +1,10 @@ import { createReadStream } from 'fs' import internal from 'stream' -import { h, Messenger, Quester } from '@satorijs/satori' +import { h, MessageEncoder, Quester } from '@satorijs/satori' import FormData from 'form-data' -import { FeishuBot } from './bot' +import { LarkBot } from './bot' import { BaseResponse, Message, MessageContent, MessageType } from './types' import { extractIdType } from './utils' @@ -13,7 +13,7 @@ export interface Addition { type: MessageType } -export class LarkMessenger extends Messenger { +export class LarkMessageEncoder extends MessageEncoder { private quote: string | undefined private content = '' private addition: Addition @@ -39,7 +39,7 @@ export class LarkMessenger extends Messenger { // try to extract error message from Lark API if (Quester.isAxiosError(e)) { if (e.response?.data?.code) { - const generalErrorMsg = `Check error code at https://open.larksuite.com/document/ukTMukTMukTM/ugjM14COyUjL4ITN` + const generalErrorMsg = `Check error code at https://open.larksuite.com/document/server-docs/getting-started/server-error-codes` e.message += ` (Lark error code ${e.response.data.code}: ${e.response.data.msg ?? generalErrorMsg})` } } @@ -75,7 +75,7 @@ export class LarkMessenger extends Messenger { this.richText = undefined } - async sendFile(type: 'image' | 'video' | 'audio' |'file', url: string): Promise { + async sendFile(type: 'image' | 'video' | 'audio' | 'file', url: string): Promise { const payload = new FormData() const assetKey = type === 'image' ? 'image' : 'file' @@ -174,4 +174,4 @@ export class LarkMessenger extends Messenger { } } -export { LarkMessenger as FeishuMessenger } +export { LarkMessageEncoder as FeishuMessageEncoder } diff --git a/adapters/lark/src/types/message/index.ts b/adapters/lark/src/types/message/index.ts index 055b9198..b9126562 100644 --- a/adapters/lark/src/types/message/index.ts +++ b/adapters/lark/src/types/message/index.ts @@ -173,6 +173,8 @@ declare module '../internal' { sendMessage(receive_id_type: Lark.ReceiveIdType, message: MessagePayload): Promise /** @see https://open.larksuite.com/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/reply */ replyMessage(message_id: string, message: MessagePayload): Promise + /** @see https://open.larksuite.com/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/update */ + updateMessage(message_id: string, message: Omit): Promise /** @see https://open.larksuite.com/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/get */ getMessage(message_id: string): Promise /** @see https://open.larksuite.com/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/delete */ @@ -191,6 +193,7 @@ Internal.define({ }, '/im/v1/messages/{message_id}': { GET: 'getMessage', + PUT: 'updateMessage', DELETE: 'deleteMessage', }, '/im/v1/messages/{message_id}/read_users': { diff --git a/adapters/lark/src/utils.ts b/adapters/lark/src/utils.ts index 68bd9c4a..53f6e695 100644 --- a/adapters/lark/src/utils.ts +++ b/adapters/lark/src/utils.ts @@ -74,7 +74,6 @@ export function adaptMessage(bot: FeishuBot, data: Events['im.message.receive_v1 export function adaptSession(bot: FeishuBot, body: AllEvents): Session { const session = bot.session() - session.selfId = bot.selfId const internal = Object.create(bot.internal) Object.assign(internal, body) defineProperty(session, 'feishu', internal) @@ -84,6 +83,8 @@ export function adaptSession(bot: FeishuBot, body: AllEvents): Session { case 'im.message.receive_v1': session.type = 'message' session.subtype = body.event.message.chat_type + if (session.subtype === 'p2p') session.subtype = 'private' + session.isDirect = session.subtype === 'private' adaptSender(body.event.sender, session) adaptMessage(bot, body.event, session) break diff --git a/adapters/line/.npmignore b/adapters/line/.npmignore new file mode 100644 index 00000000..7e5fcbc1 --- /dev/null +++ b/adapters/line/.npmignore @@ -0,0 +1,2 @@ +.DS_Store +tsconfig.tsbuildinfo diff --git a/adapters/line/package.json b/adapters/line/package.json new file mode 100644 index 00000000..3d6a1916 --- /dev/null +++ b/adapters/line/package.json @@ -0,0 +1,31 @@ +{ + "name": "@satorijs/adapter-line", + "description": "Line Adapter for Satorijs", + "version": "1.1.1", + "main": "lib/index.js", + "typings": "lib/index.d.ts", + "files": [ + "lib" + ], + "author": "LittleC ", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/satorijs/satori.git", + "directory": "adapters/line" + }, + "bugs": { + "url": "https://github.com/satorijs/satori/issues" + }, + "homepage": "https://koishi.chat/plugins/adapter/line.html", + "keywords": [ + "bot", + "line", + "adapter", + "chatbot", + "satori" + ], + "peerDependencies": { + "@satorijs/satori": "^2.6.1" + } +} diff --git a/adapters/line/src/bot.ts b/adapters/line/src/bot.ts new file mode 100644 index 00000000..1e101f28 --- /dev/null +++ b/adapters/line/src/bot.ts @@ -0,0 +1,120 @@ +import { Bot, Context, Logger, Quester, Schema, Universal } from '@satorijs/satori' +import { HttpServer } from './http' +import { Internal } from './types' +import { LineMessageEncoder } from './message' + +const logger = new Logger('line') + +export class LineBot extends Bot { + static MessageEncoder = LineMessageEncoder + public http: Quester + public contentHttp: Quester + public internal: Internal + + constructor(ctx: Context, config: LineBot.Config) { + super(ctx, config) + if (!ctx.root.config.selfUrl) { + logger.warn('selfUrl is not set, some features may not work') + } + + this.platform = 'line' + this.http = ctx.http.extend({ + ...config.api, + headers: { + Authorization: `Bearer ${config.token}`, + }, + }) + this.contentHttp = ctx.http.extend({ + ...config.content, + headers: { + Authorization: `Bearer ${config.token}`, + }, + }) + this.internal = new Internal(this.http) + + ctx.plugin(HttpServer, this) + } + + async initialize(callback: (bot: this) => Promise) { + const user = await this.getSelf() + Object.assign(this, user) + await callback(this) + this.online() + } + + // https://developers.line.biz/en/reference/messaging-api/#get-profile + async getSelf(): Promise { + const { userId, displayName, pictureUrl } = await this.internal.getBotInfo() + return { + userId, + nickname: displayName, + avatar: pictureUrl, + } + } + + async getFriendList(): Promise { + let userIds: string[] = [] + let start: string + do { + const res = await this.internal.getFollowers({ + start, + limit: 1000, + }) + userIds = userIds.concat(res.userIds) + start = res.next + } while (start) + + return userIds.map(v => ({ userId: v })) + } + + async getGuild(guildId: string): Promise { + const res = await this.internal.getGroupSummary(guildId) + return { + guildId: res.groupId, + guildName: res.groupName, + } + } + + async getGuildMemberList(guildId: string): Promise { + let userIds: string[] = [] + let start: string + do { + const res = await this.internal.getGroupMembersIds(guildId, { start }) + userIds = userIds.concat(res.memberIds) + start = res.next + } while (start) + + return userIds.map(v => ({ userId: v })) + } + + async getGuildMember(guildId: string, userId: string): Promise { + const res = await this.internal.getGroupMemberProfile(guildId, userId) + return ({ + userId: res.userId, + nickname: res.displayName, + avatar: res.pictureUrl, + }) + } +} + +export namespace LineBot { + export interface Config extends Bot.Config { + token: string + secret: string + api: Quester.Config + content: Quester.Config + } + + export const Config: Schema = Schema.intersect([ + Schema.object({ + token: Schema.string().required().description('机器人令牌。'), + secret: Schema.string().required().description('机器人密钥。'), + }), + Schema.object({ + api: Quester.createConfig('https://api.line.me/'), + }), + Schema.object({ + content: Quester.createConfig('https://api-data.line.me/'), + }), + ]) +} diff --git a/adapters/line/src/http.ts b/adapters/line/src/http.ts new file mode 100644 index 00000000..fe27c35d --- /dev/null +++ b/adapters/line/src/http.ts @@ -0,0 +1,56 @@ +import { Adapter, Context, Logger } from '@satorijs/satori' +import { LineBot } from './bot' +import crypto from 'node:crypto' +import { WebhookRequestBody } from './types' +import { adaptSessions } from './utils' +import internal from 'stream' + +export class HttpServer extends Adapter.Server { + logger = new Logger('line') + + constructor(ctx: Context, bot: LineBot) { + super() + } + + async start(bot: LineBot) { + bot.ctx.router.post('/line', async (ctx) => { + const sign = ctx.headers['x-line-signature']?.toString() + const parsed = ctx.request.body as WebhookRequestBody + const { destination } = parsed + const bot = this.bots.find(bot => bot.selfId === destination) + if (!bot) return ctx.status = 403 + const hash = crypto.createHmac('SHA256', bot?.config?.secret).update(ctx.request.rawBody || '').digest('base64') + if (hash !== sign) { + return ctx.status = 403 + } + this.logger.debug(require('util').inspect(parsed, false, null, true)) + for (const event of parsed.events) { + const sessions = await adaptSessions(bot, event) + if (sessions.length) sessions.forEach(bot.dispatch.bind(bot)) + this.logger.debug(require('util').inspect(sessions, false, null, true)) + } + ctx.status = 200 + ctx.body = 'ok' + }) + bot.ctx.router.get('/line/assets/:self_id/:message_id', async (ctx) => { + const messageId = ctx.params.message_id + const selfId = ctx.params.self_id + const bot = this.bots.find((bot) => bot.selfId === selfId) + if (!bot) return ctx.status = 404 + const resp = await bot.contentHttp.axios(`/v2/bot/message/${messageId}/content`, { + method: 'GET', + responseType: 'stream', + }) + ctx.type = resp.headers['content-type'] + ctx.set('cache-control', resp.headers['cache-control']) + ctx.response.body = resp.data + ctx.status = 200 + }) + bot.initialize(async (bot) => { + await bot.internal.setWebhookEndpoint({ + endpoint: bot.ctx.root.config.selfUrl + '/line', + }) + this.logger.debug('listening updates %c', 'line:' + bot.selfId) + }) + } +} diff --git a/adapters/line/src/index.ts b/adapters/line/src/index.ts new file mode 100644 index 00000000..6499e0f6 --- /dev/null +++ b/adapters/line/src/index.ts @@ -0,0 +1,9 @@ +import { LineBot } from './bot' + +export * from './bot' +export * from './utils' +export * from './types' +export * from './http' +export * from './message' + +export default LineBot diff --git a/adapters/line/src/message.ts b/adapters/line/src/message.ts new file mode 100644 index 00000000..8f4f5ba2 --- /dev/null +++ b/adapters/line/src/message.ts @@ -0,0 +1,103 @@ +import { h, MessageEncoder } from '@satorijs/satori' +import { LineBot } from './bot' +import * as Line from './types' + +export const escape = (val: string) => + val + .replace(/(? + val + .replace(/\u200b([\*_~`])/g, '$1') + +export class LineMessageEncoder extends MessageEncoder { + buffer = '' + blocks: Line.Message[] = [] + block: Line.Message = null + sender: Line.Sender = {} + emojis: Line.Emoji[] = [] + async flush(): Promise { + await this.insertBlock() + // https://developers.line.biz/en/reference/messaging-api/#send-push-message + for (let i = 0; i < this.blocks.length; i += 5) { + await this.bot.internal.pushMessage({ + to: this.channelId, + messages: this.blocks.slice(i, i + 5), + }) + } + } + + async insertBlock() { + if (this.buffer.length) { + this.blocks.push({ + ...{ + type: 'text', + text: escape(this.buffer), + sender: { ...this.sender }, + }, + ...this.emojis.length ? { emojis: this.emojis } : {}, + }) + this.buffer = '' + this.emojis = [] + } + } + + async visit(element: h) { + const { type, attrs, children } = element + + if (type === 'text') { + this.buffer += attrs.content + } else if (type === 'image' && attrs.url) { + await this.insertBlock() + this.blocks.push({ + type: 'image', + originalContentUrl: attrs.url, + previewImageUrl: attrs.url, + }) + } else if (type === 'video' && attrs.url) { + await this.insertBlock() + this.blocks.push({ + type: 'video', + originalContentUrl: attrs.url, + previewImageUrl: attrs.url, + }) + } else if (type === 'audio' && attrs.url) { + await this.insertBlock() + this.blocks.push({ + type: 'audio', + originalContentUrl: attrs.url, + duration: 1145, + }) + } else if (type === 'face' && attrs.id) { + if (attrs.id.startsWith('s')) { + // https://developers.line.biz/en/reference/messaging-api/#sticker-message + await this.insertBlock() + this.blocks.push({ + type: 'sticker', + packageId: attrs.id.split(':')[1], + stickerId: attrs.id.split(':')[2], + }) + } else { + // https://developers.line.biz/en/reference/messaging-api/#text-message + this.emojis.push({ + index: this.buffer.length, + productId: attrs.id.split(':')[1], + emojiId: attrs.id.split(':')[2], + }) + this.buffer += '$' + } + } else if (type === 'author') { + this.sender.name = attrs.nickname + this.sender.iconUrl = attrs.avatar + } else if (type === 'message') { + // let childAuthor = h.select(children, 'author') + const sender = { ...this.sender } + await this.insertBlock() + await this.render(children) + await this.insertBlock() + if (this.sender.iconUrl || this.sender.name) { + this.sender = { ...sender } + } + } + } +} diff --git a/adapters/line/src/types/definition.ts b/adapters/line/src/types/definition.ts new file mode 100644 index 00000000..646183fb --- /dev/null +++ b/adapters/line/src/types/definition.ts @@ -0,0 +1,737 @@ +export type GetWebhookEndpointResponse = { + endpoint: string + active: boolean +} + +export type SetWebhookEndpointRequest = { + endpoint: string +} + +export type TestWebhookEndpointRequest = { + endpoint?: string +} + +export type TestWebhookEndpointResponse = { + success?: boolean + timestamp: string + statusCode: number + reason: string + detail: string +} + +export type GetMessageContentTranscodingResponse = { + status: string +} + +export type ReplyMessageRequest = { + replyToken: string + messages: Message[] + notificationDisabled?: NotificationDisabled +} + +export type PushMessageRequest = { + to: string + messages: Message[] + notificationDisabled?: NotificationDisabled + customAggregationUnits?: string[] +} + +export type NotificationDisabled = boolean + +export type MulticastRequest = { + messages: Message[] + to: string[] + notificationDisabled?: NotificationDisabled + customAggregationUnits?: string[] +} + +export type NarrowcastRequest = { + messages: Message[] + recipient?: Recipient + filter?: Filter + limit?: Limit + notificationDisabled?: NotificationDisabled +} + +export type BaseRecipient = { + type?: string +} + +export type Recipient = OperatorRecipient | AudienceRecipient | RedeliveryRecipient +export type OperatorRecipient = BaseRecipient & { type: 'operator' } & { + and?: Recipient[] + or?: Recipient[] + not?: Recipient +} + +export type AudienceRecipient = BaseRecipient & { type: 'audience' } & { + audienceGroupId?: number +} + +export type RedeliveryRecipient = BaseRecipient & { type: 'redelivery' } & { + requestId?: string +} + +export type Filter = { + demographic?: DemographicFilter +} + +export type BaseDemographicFilter = { + type?: string +} + +export type DemographicFilter = + | AgeDemographicFilter + | AppTypeDemographicFilter + | AreaDemographicFilter + | GenderDemographicFilter + | OperatorDemographicFilter + | SubscriptionPeriodDemographicFilter + +export type AgeDemographicFilter = BaseDemographicFilter & { type: 'age' } & { + gte?: AgeDemographic + lt?: AgeDemographic +} + +export type AgeDemographic = string + +export type AppTypeDemographicFilter = BaseDemographicFilter & { type: 'appType' } & { + oneOf?: AppTypeDemographic[] +} + +export type AppTypeDemographic = string + +export type AreaDemographicFilter = BaseDemographicFilter & { type: 'area' } & { + oneOf?: AreaDemographic[] +} + +export type AreaDemographic = string + +export type GenderDemographicFilter = BaseDemographicFilter & { type: 'gender' } & { + oneOf?: GenderDemographic[] +} + +export type GenderDemographic = string + +export type OperatorDemographicFilter = BaseDemographicFilter & { type: 'operator' } & { + and?: DemographicFilter[] + or?: DemographicFilter[] + not?: DemographicFilter +} + +export type SubscriptionPeriodDemographicFilter = BaseDemographicFilter & { type: 'subscriptionPeriod' } & { + gte?: SubscriptionPeriodDemographic + lt?: SubscriptionPeriodDemographic +} + +export type SubscriptionPeriodDemographic = string + +export type Limit = { + max?: number + upToRemainingQuota?: boolean +} + +export type NarrowcastProgressResponse = { + phase: string + successCount?: number + failureCount?: number + targetCount?: number + failedDescription?: string + errorCode?: number + acceptedTime: string + completedTime?: string +} + +export type BroadcastRequest = { + messages: Message[] + notificationDisabled?: NotificationDisabled +} + +export type MessageQuotaResponse = { + type: QuotaType + value?: number +} + +export type QuotaType = string + +export type QuotaConsumptionResponse = { + totalUsage: number +} + +export type NumberOfMessagesResponse = { + status: string + success?: number +} + +export type ValidateMessageRequest = { + messages: Message[] +} + +export type GetAggregationUnitUsageResponse = { + numOfCustomAggregationUnits: number +} + +export type GetAggregationUnitNameListResponse = { + customAggregationUnits: string[] + next?: string +} + +export type UserProfileResponse = { + displayName: string + userId: string + pictureUrl?: string + statusMessage?: string + language?: string +} + +export type GetFollowersResponse = { + userIds: string[] + next?: string +} + +export type BotInfoResponse = { + userId: string + basicId: string + premiumId?: string + displayName: string + pictureUrl?: string + chatMode: string + markAsReadMode: string +} + +export type GroupUserProfileResponse = { + displayName: string + userId: string + pictureUrl?: string +} + +export type RoomUserProfileResponse = { + displayName: string + userId: string + pictureUrl?: string +} + +export type MembersIdsResponse = { + memberIds: string[] + next?: string +} + +export type GroupSummaryResponse = { + groupId: string + groupName: string + pictureUrl?: string +} + +export type GroupMemberCountResponse = { + count: number +} + +export type RoomMemberCountResponse = { + count: number +} + +export type RichMenuRequest = { + size?: RichMenuSize + selected?: boolean + name?: string + chatBarText?: string + areas?: RichMenuArea[] +} + +export type RichMenuSize = { + width?: number + height?: number +} + +export type RichMenuArea = { + bounds?: RichMenuBounds + action?: Action +} + +export type RichMenuBounds = { + x?: number + y?: number + width?: number + height?: number +} + +export type RichMenuIdResponse = { + richMenuId: string +} + +export type RichMenuResponse = { + richMenuId: string + size: RichMenuSize + selected: boolean + name: string + chatBarText: string + areas: RichMenuArea[] +} + +export type RichMenuListResponse = { + richmenus: RichMenuResponse[] +} + +export type CreateRichMenuAliasRequest = { + richMenuAliasId: string + richMenuId: string +} + +export type RichMenuAliasResponse = { + richMenuAliasId: string + richMenuId: string +} + +export type UpdateRichMenuAliasRequest = { + richMenuId: string +} + +export type RichMenuAliasListResponse = { + aliases: RichMenuAliasResponse[] +} + +export type RichMenuBulkLinkRequest = { + richMenuId: string + userIds: string[] +} + +export type RichMenuBulkUnlinkRequest = { + userIds: string[] +} + +export type RichMenuBatchRequest = { + operations: RichMenuBatchOperation[] + resumeRequestKey?: string +} + +export type BaseRichMenuBatchOperation = { + type: string +} + +export type RichMenuBatchOperation = RichMenuBatchLinkOperation | RichMenuBatchUnlinkOperation | RichMenuBatchUnlinkAllOperation +export type RichMenuBatchLinkOperation = BaseRichMenuBatchOperation & { type: 'link' } & { + from?: string + to?: string +} + +export type RichMenuBatchUnlinkOperation = BaseRichMenuBatchOperation & { type: 'unlink' } & { + from?: string +} + +export type RichMenuBatchUnlinkAllOperation = BaseRichMenuBatchOperation + +export type RichMenuBatchProgressResponse = { + phase: RichMenuBatchProgressPhase + acceptedTime: string + completedTime?: string +} + +export type RichMenuBatchProgressPhase = string + +export type IssueLinkTokenResponse = { + linkToken: string +} + +export type MarkMessagesAsReadRequest = { + chat: ChatReference +} + +export type ChatReference = { + userId: string +} + +export type PnpMessagesRequest = { + messages: Message[] + to: string + notificationDisabled?: NotificationDisabled +} + +export type AudienceMatchMessagesRequest = { + messages: Message[] + to: string[] + notificationDisabled?: NotificationDisabled +} + +export type BaseMessage = { + type: string + quickReply?: QuickReply + sender?: Sender +} + +export type Message = + | TextMessage + | StickerMessage + | ImageMessage + | VideoMessage + | AudioMessage + | LocationMessage + | ImagemapMessage + | TemplateMessage + | FlexMessage + +export type QuickReply = { + items?: QuickReplyItem[] +} + +export type QuickReplyItem = { + imageUrl?: string + action?: Action + type?: string +} + +export type Sender = { + name?: string + iconUrl?: string +} + +export type TextMessage = BaseMessage & { type: 'text' } & { + text?: string + emojis?: Emoji[] +} + +export type Emoji = { + index?: number + productId?: string + emojiId?: string +} + +export type StickerMessage = BaseMessage & { type: 'sticker' } & { + packageId?: string + stickerId?: string +} + +export type ImageMessage = BaseMessage & { type: 'image' } & { + originalContentUrl?: string + previewImageUrl?: string +} + +export type VideoMessage = BaseMessage & { type: 'video' } & { + originalContentUrl?: string + previewImageUrl?: string + trackingId?: string +} + +export type AudioMessage = BaseMessage & { type: 'audio' } & { + originalContentUrl?: string + duration?: number +} + +export type LocationMessage = BaseMessage & { type: 'location' } & { + title?: string + address?: string + latitude?: unknown + longitude?: unknown +} + +export type ImagemapMessage = BaseMessage & { type: 'imagemap' } & { + baseUrl?: string + altText?: string + baseSize?: ImagemapBaseSize + actions?: ImagemapAction[] + video?: ImagemapVideo +} + +export type ImagemapBaseSize = { + height?: number + width?: number +} + +export type BaseImagemapAction = { + type: string + area?: ImagemapArea +} + +export type ImagemapAction = MessageImagemapAction | URIImagemapAction + +export type MessageImagemapAction = BaseImagemapAction & { type: 'message' } & { + text?: string + label?: string +} + +export type URIImagemapAction = BaseImagemapAction & { type: 'uri' } & { + linkUri?: string + label?: string +} + +export type ImagemapArea = { + x?: number + y?: number + width?: number + height?: number +} + +export type ImagemapVideo = { + originalContentUrl?: string + previewImageUrl?: string + area?: ImagemapArea + externalLink?: ImagemapExternalLink +} + +export type ImagemapExternalLink = { + linkUri?: string + label?: string +} + +export type TemplateMessage = BaseMessage & { type: 'template' } & { + altText?: string + template?: Template +} + +export type BaseTemplate = { + type: string +} + +export type Template = ButtonsTemplate | ConfirmTemplate | CarouselTemplate | ImageCarouselTemplate +export type ButtonsTemplate = BaseTemplate & { type: 'buttons' } & { + thumbnailImageUrl?: string + imageAspectRatio?: string + imageSize?: string + imageBackgroundColor?: string + title?: string + text?: string + defaultAction?: Action + actions?: Action[] +} + +export type ConfirmTemplate = BaseTemplate & { type: 'confirm' } & { + text?: string + actions?: Action[] +} + +export type CarouselTemplate = BaseTemplate & { type: 'carousel' } & { + columns?: CarouselColumn[] + imageAspectRatio?: string + imageSize?: string +} + +export type CarouselColumn = { + thumbnailImageUrl?: string + imageBackgroundColor?: string + title?: string + text?: string + defaultAction?: Action + actions?: Action[] +} + +export type ImageCarouselTemplate = BaseTemplate & { type: 'image_carousel' } & { + columns?: ImageCarouselColumn[] +} + +export type ImageCarouselColumn = { + imageUrl?: string + action?: Action +} + +export type FlexMessage = BaseMessage & { type: 'flex' } & { + altText?: string + contents?: FlexContainer +} + +export type BaseFlexContainer = { + type: string +} + +export type FlexContainer = FlexBubble | FlexCarousel +export type FlexBubble = BaseFlexContainer & { type: 'bubble' } & { + direction?: string + styles?: FlexBubbleStyles + header?: FlexBox + hero?: FlexComponent + body?: FlexBox + footer?: FlexBox + size?: string + action?: Action +} + +export type FlexCarousel = BaseFlexContainer & { type: 'carousel' } & { + contents?: FlexBubble[] +} + +export type FlexBubbleStyles = { + header?: FlexBlockStyle + hero?: FlexBlockStyle + body?: FlexBlockStyle + footer?: FlexBlockStyle +} + +export type FlexBlockStyle = { + backgroundColor?: string + separator?: boolean + separatorColor?: string +} + +export type BaseFlexComponent = { + type: string +} + +export type FlexComponent = FlexBox | FlexButton | FlexImage | FlexVideo | FlexIcon | FlexText | FlexSpan | FlexSeparator | FlexFiller +export type FlexBox = BaseFlexComponent & { type: 'box' } & unknown + +export type FlexButton = BaseFlexComponent & { type: 'button' } & { + flex?: number + color?: string + style?: string + action?: Action + gravity?: string + margin?: string + position?: string + offsetTop?: string + offsetBottom?: string + offsetStart?: string + offsetEnd?: string + height?: string + adjustMode?: string + scaling?: boolean +} + +export type FlexImage = BaseFlexComponent & { type: 'image' } & { + url?: string + flex?: number + margin?: string + position?: string + offsetTop?: string + offsetBottom?: string + offsetStart?: string + offsetEnd?: string + align?: string + gravity?: string + size?: string + aspectRatio?: string + aspectMode?: string + backgroundColor?: string + action?: Action + animated?: boolean +} + +export type FlexVideo = BaseFlexComponent & { type: 'video' } & { + url?: string + previewUrl?: string + altContent?: FlexComponent + aspectRatio?: string + action?: Action +} + +export type FlexIcon = BaseFlexComponent & { type: 'icon' } & { + url?: string + size?: string + aspectRatio?: string + margin?: string + position?: string + offsetTop?: string + offsetBottom?: string + offsetStart?: string + offsetEnd?: string + scaling?: boolean +} + +export type FlexText = BaseFlexComponent & { type: 'text' } & { + flex?: number + text?: string + size?: string + align?: string + gravity?: string + color?: string + weight?: string + style?: string + decoration?: string + wrap?: boolean + lineSpacing?: string + margin?: string + position?: string + offsetTop?: string + offsetBottom?: string + offsetStart?: string + offsetEnd?: string + action?: Action + maxLines?: number + contents?: FlexSpan[] + adjustMode?: string + scaling?: boolean +} + +export type FlexSpan = BaseFlexComponent & { type: 'span' } & { + text?: string + size?: string + color?: string + weight?: string + style?: string + decoration?: string +} + +export type FlexSeparator = BaseFlexComponent & { type: 'separator' } & { + margin?: string + color?: string +} + +export type FlexFiller = BaseFlexComponent & { type: 'filler' } & { + flex?: number +} + +export type BaseFlexBoxBackground = { + type: string +} + +export type FlexBoxBackground = FlexBoxLinearGradient +export type FlexBoxLinearGradient = BaseFlexBoxBackground & { type: 'linearGradient' } & { + angle?: string + startColor?: string + endColor?: string + centerColor?: string + centerPosition?: string +} + +export type BaseAction = { + type?: string + label?: string +} + +export type Action = CameraAction | CameraRollAction | DatetimePickerAction | LocationAction | MessageAction | PostbackAction | RichMenuSwitchAction | URIAction +export type CameraAction = BaseAction + +export type CameraRollAction = BaseAction + +export type DatetimePickerAction = BaseAction & { type: 'datetimepicker' } & { + data?: string + mode?: string + initial?: string + max?: string + min?: string +} + +export type LocationAction = BaseAction + +export type MessageAction = BaseAction & { type: 'message' } & { + text?: string +} + +export type PostbackAction = BaseAction & { type: 'postback' } & { + data?: string + displayText?: string + text?: string + inputOption?: string + fillInText?: string +} + +export type RichMenuSwitchAction = BaseAction & { type: 'richmenuswitch' } & { + data?: string + richMenuAliasId?: string +} + +export type URIAction = BaseAction & { type: 'uri' } & { + uri?: string + altUri?: AltUri +} + +export type AltUri = { + desktop?: string +} + +export type ErrorResponse = { + message: string + details?: ErrorDetail[] +} + +export type ErrorDetail = { + message?: string + property?: string +} diff --git a/adapters/line/src/types/index.ts b/adapters/line/src/types/index.ts new file mode 100644 index 00000000..d4572363 --- /dev/null +++ b/adapters/line/src/types/index.ts @@ -0,0 +1,352 @@ +import type {} from './request' +export * from './request' +export * from './internal' +export * from './definition' + +// https://github.com/line/line-bot-sdk-nodejs/blob/next/lib/types.ts + +/** + * Request body which is sent by webhook. + * + * @see [Request body](https://developers.line.biz/en/reference/messaging-api/#request-body) + */ +export type WebhookRequestBody = { + /** + * User ID of a bot that should receive webhook events. The user ID value is a string that matches the regular expression, U[0-9a-f]{32}. + */ + destination: string + + /** + * Information about the event + */ + events: WebhookEvent[] +} + +/** + * JSON objects which contain events generated on the LINE Platform. + * + * @see [Webhook event objects](https://developers.line.biz/en/reference/messaging-api/#webhook-event-objects) + */ +export type WebhookEvent = + | MessageEvent + | UnsendEvent + | FollowEvent + | UnfollowEvent + | JoinEvent + | LeaveEvent + | MemberJoinEvent + | MemberLeaveEvent + +export type EventBase = { + /** + * Channel state. + * + * `active`: The channel is active. You can send a reply message or push message from the bot server that received this webhook event. + * + * `standby`: The channel is waiting. The bot server that received this webhook event shouldn't send any messages. + */ + mode: 'active' | 'standby' + /** + * Time of the event in milliseconds + */ + timestamp: number + /** + * Source user, group, or room object with information about the source of the event. + */ + source: EventSource +} + +export type EventSource = User | Group | Room + +export type User = { type: 'user'; userId: string } + +export type Group = { + type: 'group' + groupId: string + /** + * ID of the source user. + * + * Only included in [message events](https://developers.line.biz/en/reference/messaging-api/#message-event). + * Not included if the user has not agreed to the + * [Official Accounts Terms of Use](https://developers.line.biz/en/docs/messaging-api/user-consent/). + */ + userId?: string +} + +export type Room = { + type: 'room' + roomId: string + /** + * ID of the source user. + * + * Only included in [message events](https://developers.line.biz/en/reference/messaging-api/#message-event). + * Not included if the user has not agreed to the + * [Official Accounts Terms of Use](https://developers.line.biz/en/docs/messaging-api/user-consent/). + */ + userId?: string +} + +export type ReplyableEvent = EventBase & { replyToken: string } + +/** + * Webhook event object which contains the sent message. + * + * The `message` property contains a message object which corresponds with the + * message type. You can reply to message events. + * + * @see [Message event](https://developers.line.biz/en/reference/messaging-api/#message-event) + */ +export type MessageEvent = { + type: 'message' + message: EventMessage +} & ReplyableEvent + +/** + * Event object for when the user unsends a message in a [group](https://developers.line.biz/en/docs/messaging-api/group-chats/#group) + * or [room](https://developers.line.biz/en/docs/messaging-api/group-chats/#room). + * [Unsend event](https://developers.line.biz/en/reference/messaging-api/#unsend-event) + */ +export type UnsendEvent = { + type: 'unsend' + /** + * The message ID of the unsent message + */ + unsend: { messageId: string } +} & EventBase + +/** + * Event object for when your account is added as a friend (or unblocked). + */ +export type FollowEvent = { type: 'follow' } & ReplyableEvent + +/** + * Event object for when your account is blocked. + */ +export type UnfollowEvent = { type: 'unfollow' } & EventBase + +/** + * Event object for when your bot joins a group or room. You can reply to join events. + * + * A join event is triggered at different times for groups and rooms. + * + * - For groups: A join event is sent when a user invites your bot. + * - For rooms: A join event is sent when the first event (for example when a + * user sends a message or is added to the room) occurs after your bot is + * added. + */ +export type JoinEvent = { type: 'join' } & ReplyableEvent + +/** + * Event object for when a user removes your bot from a group or a room. + */ +export type LeaveEvent = { type: 'leave' } & EventBase + +/** + * Event object for when a user joins a [group](https://developers.line.biz/en/docs/messaging-api/group-chats/#group) + * or [room](https://developers.line.biz/en/docs/messaging-api/group-chats/#room) that the bot is in. + */ +export type MemberJoinEvent = { + type: 'memberJoined' + /** + * User ID of users who joined + * Array of [source user](https://developers.line.biz/en/reference/messaging-api/#source-user) objects + */ + joined: { members: User[] } +} & ReplyableEvent + +/** + * Event object for when a user leaves a [group](https://developers.line.biz/en/docs/messaging-api/group-chats/#group) + * or [room](https://developers.line.biz/en/docs/messaging-api/group-chats/#room) that the bot is in. + */ +export type MemberLeaveEvent = { + type: 'memberLeft' + /** + * User ID of users who left + * Array of [source user](https://developers.line.biz/en/reference/messaging-api/#source-user) objects + */ + left: { members: User[] } +} & EventBase + +export type EventMessage = + | TextEventMessage + | ImageEventMessage + | VideoEventMessage + | AudioEventMessage + | LocationEventMessage + | FileEventMessage + | StickerEventMessage + +export type EventMessageBase = { id: string } + +/** + * Message object which contains the text sent from the source. + */ +export type TextEventMessage = { + type: 'text' + text: string + /** + * Sendable LINE emojis + */ + emojis?: { + index: number + length: number + productId: string + emojiId: string + }[] + /** + * Object containing the contents of the mentioned user. + */ + mention?: { + /** + * Mentioned user information. + * Max: 20 mentions + */ + mentionees: { + /** + * Index position of the user mention for a character in `text`, + * with the first character being at position 0. + */ + index: number + /** + * The length of the text of the mentioned user. For a mention `@example`, + * 8 is the length. + */ + length: number + /** + * Mentioned target. + * + * - `user`: User. + * - `all`: Entire group. + */ + type: 'user' | 'all' + /** + * User ID of the mentioned user. Only included if mention.mentions[].type is user + * and the user consents to the LINE Official Account obtaining their user profile information. + */ + userId?: string + }[] + } +} & EventMessageBase + +export type ContentProvider = + | { + /** + * The content is provided by LINE. + * + * The data itself can be retrieved from the content API. + */ + type: 'line' + } + | { + /** + * The content is provided by a provider other than LINE + */ + type: 'external' + /** + * URL of the content. Only included when contentProvider.type is external. + */ + originalContentUrl: string + /** + * URL of the content preview. Only included when contentProvider.type is external. + * + * For contents without preview (e.g. audio), it's undefined. + */ + previewImageUrl: WithPreview extends true ? string : undefined + } + +/** + * Message object which contains the image content sent from the source. + * The binary image data can be retrieved using Client#getMessageContent. + */ +export type ImageEventMessage = { + type: 'image' + contentProvider: ContentProvider + /** + * Object containing the number of images sent simultaneously. + */ + imageSet?: { + /** + * Image set ID. Only included when multiple images are sent simultaneously. + */ + id: string + /** + * An index starting from 1, indicating the image number in a set of images sent simultaneously. + * Only included when multiple images are sent simultaneously. + * However, it won't be included if the sender is using LINE 11.15 or earlier for Android. + */ + index: number + /** + * The total number of images sent simultaneously. + * If two images are sent simultaneously, the number is 2. + * Only included when multiple images are sent simultaneously. + * However, it won't be included if the sender is using LINE 11.15 or earlier for Android. + */ + total: number + } +} & EventMessageBase + +/** + * Message object which contains the video content sent from the source. + * The binary video data can be retrieved using Client#getMessageContent. + */ +export type VideoEventMessage = { + type: 'video' + contentProvider: ContentProvider +} & EventMessageBase + +/** + * Message object which contains the audio content sent from the source. + * The binary audio data can be retrieved using Client#getMessageContent. + */ +export type AudioEventMessage = { + type: 'audio' + duration: number + contentProvider: ContentProvider +} & EventMessageBase + +/** + * Message object which contains the file sent from the source. + * The binary data can be retrieved using Client#getMessageContent. + */ +export type FileEventMessage = { + type: 'file' + fileName: string + fileSize: string +} & EventMessageBase + +/** + * Message object which contains the location data sent from the source. + */ +export type LocationEventMessage = { + type: 'location' + title: string + address: string + latitude: number + longitude: number +} & EventMessageBase + +/** + * Message object which contains the sticker data sent from the source. + * For a list of basic LINE stickers and sticker IDs, see + * [sticker list](https://developers.line.biz/media/messaging-api/sticker_list.pdf). + */ +export type StickerEventMessage = { + type: 'sticker' + packageId: string + stickerId: string + stickerResourceType: + | 'STATIC' + | 'ANIMATION' + | 'SOUND' + | 'ANIMATION_SOUND' + | 'POPUP' + | 'POPUP_SOUND' + | 'CUSTOM' + | 'MESSAGE' + keywords: string[] + /** + * Any text entered by the user. This property is only included for message stickers. + * Max character limit: 100 + */ + text?: string +} & EventMessageBase diff --git a/adapters/line/src/types/internal.ts b/adapters/line/src/types/internal.ts new file mode 100644 index 00000000..976ab4d3 --- /dev/null +++ b/adapters/line/src/types/internal.ts @@ -0,0 +1,228 @@ +import { Dict, makeArray, Quester } from '@satorijs/satori' + +export class Internal { + constructor(private http: Quester) { } + + static define(routes: Dict>>) { + for (const path in routes) { + for (const key in routes[path]) { + const method = key as Quester.Method + for (const name of makeArray(routes[path][method])) { + Internal.prototype[name] = async function (this: Internal, ...args: any[]) { + const raw = args.join(', ') + const url = path.replace(/\{([^}]+)\}/g, () => { + if (!args.length) throw new Error(`too few arguments for ${path}, received ${raw}`) + return args.shift() + }) + const config: Quester.AxiosRequestConfig = {} + if (args.length === 1) { + if (method === 'GET' || method === 'DELETE') { + config.params = args[0] + } else { + config.data = args[0] + } + } else if (args.length === 2 && method !== 'GET' && method !== 'DELETE') { + config.data = args[0] + config.params = args[1] + } else if (args.length > 1) { + throw new Error(`too many arguments for ${path}, received ${raw}`) + } + try { + return await this.http(method, url, config) + } catch (error) { + if (!Quester.isAxiosError(error) || !error.response) throw error + throw new Error(`[${error.response.status}] ${JSON.stringify(error.response.data)}`) + } + } + } + } + } + } +} + +Internal.define({ + '/v2/bot/channel/webhook/endpoint': { + GET: 'getWebhookEndpoint', + PUT: 'setWebhookEndpoint', + }, + '/v2/bot/channel/webhook/test': { + POST: 'testWebhookEndpoint', + }, + '/v2/bot/message/{messageId}/content': { + GET: 'getMessageContent', + }, + '/v2/bot/message/{messageId}/content/preview': { + GET: 'getMessageContentPreview', + }, + '/v2/bot/message/{messageId}/content/transcoding': { + GET: 'getMessageContentTranscodingByMessageId', + }, + '/v2/bot/message/reply': { + POST: 'replyMessage', + }, + '/v2/bot/message/push': { + POST: 'pushMessage', + }, + '/v2/bot/message/multicast': { + POST: 'multicast', + }, + '/v2/bot/message/narrowcast': { + POST: 'narrowcast', + }, + '/v2/bot/message/progress/narrowcast': { + GET: 'getNarrowcastProgress', + }, + '/v2/bot/message/broadcast': { + POST: 'broadcast', + }, + '/v2/bot/message/quota': { + GET: 'getMessageQuota', + }, + '/v2/bot/message/quota/consumption': { + GET: 'getMessageQuotaConsumption', + }, + '/v2/bot/message/delivery/reply': { + GET: 'getNumberOfSentReplyMessages', + }, + '/v2/bot/message/delivery/push': { + GET: 'getNumberOfSentPushMessages', + }, + '/v2/bot/message/delivery/multicast': { + GET: 'getNumberOfSentMulticastMessages', + }, + '/v2/bot/message/delivery/broadcast': { + GET: 'getNumberOfSentBroadcastMessages', + }, + '/v2/bot/message/validate/reply': { + POST: 'validateReply', + }, + '/v2/bot/message/validate/push': { + POST: 'validatePush', + }, + '/v2/bot/message/validate/multicast': { + POST: 'validateMulticast', + }, + '/v2/bot/message/validate/narrowcast': { + POST: 'validateNarrowcast', + }, + '/v2/bot/message/validate/broadcast': { + POST: 'validateBroadcast', + }, + '/v2/bot/message/aggregation/info': { + GET: 'getAggregationUnitUsage', + }, + '/v2/bot/message/aggregation/list': { + GET: 'getAggregationUnitNameList', + }, + '/v2/bot/profile/{userId}': { + GET: 'getProfile', + }, + '/v2/bot/followers/ids': { + GET: 'getFollowers', + }, + '/v2/bot/info': { + GET: 'getBotInfo', + }, + '/v2/bot/group/{groupId}/member/{userId}': { + GET: 'getGroupMemberProfile', + }, + '/v2/bot/room/{roomId}/member/{userId}': { + GET: 'getRoomMemberProfile', + }, + '/v2/bot/group/{groupId}/members/ids': { + GET: 'getGroupMembersIds', + }, + '/v2/bot/room/{roomId}/members/ids': { + GET: 'getRoomMembersIds', + }, + '/v2/bot/group/{groupId}/leave': { + POST: 'leaveGroup', + }, + '/v2/bot/room/{roomId}/leave': { + POST: 'leaveRoom', + }, + '/v2/bot/group/{groupId}/summary': { + GET: 'getGroupSummary', + }, + '/v2/bot/group/{groupId}/members/count': { + GET: 'getGroupMemberCount', + }, + '/v2/bot/room/{roomId}/members/count': { + GET: 'getRoomMemberCount', + }, + '/v2/bot/richmenu': { + POST: 'createRichMenu', + }, + '/v2/bot/richmenu/validate': { + POST: 'validateRichMenuObject', + }, + '/v2/bot/richmenu/{richMenuId}/content': { + GET: 'getRichMenuImage', + POST: 'setRichMenuImage', + }, + '/v2/bot/richmenu/{richMenuId}': { + GET: 'getRichMenu', + DELETE: 'deleteRichMenu', + }, + '/v2/bot/richmenu/list': { + GET: 'getRichMenuList', + }, + '/v2/bot/user/all/richmenu/{richMenuId}': { + POST: 'setDefaultRichMenu', + }, + '/v2/bot/user/all/richmenu': { + GET: 'getDefaultRichMenuId', + DELETE: 'cancelDefaultRichMenu', + }, + '/v2/bot/richmenu/alias': { + POST: 'createRichMenuAlias', + }, + '/v2/bot/richmenu/alias/{richMenuAliasId}': { + GET: 'getRichMenuAlias', + POST: 'updateRichMenuAlias', + DELETE: 'deleteRichMenuAlias', + }, + '/v2/bot/richmenu/alias/list': { + GET: 'getRichMenuAliasList', + }, + '/v2/bot/user/{userId}/richmenu': { + GET: 'getRichMenuIdOfUser', + DELETE: 'unlinkRichMenuIdFromUser', + }, + '/v2/bot/user/{userId}/richmenu/{richMenuId}': { + POST: 'linkRichMenuIdToUser', + }, + '/v2/bot/richmenu/bulk/link': { + POST: 'linkRichMenuIdToUsers', + }, + '/v2/bot/richmenu/bulk/unlink': { + POST: 'unlinkRichMenuIdFromUsers', + }, + '/v2/bot/richmenu/batch': { + POST: 'richMenuBatch', + }, + '/v2/bot/richmenu/validate/batch': { + POST: 'validateRichMenuBatchRequest', + }, + '/v2/bot/richmenu/progress/batch': { + GET: 'getRichMenuBatchProgress', + }, + '/v2/bot/user/{userId}/linkToken': { + POST: 'issueLinkToken', + }, + '/v2/bot/message/markAsRead': { + POST: 'markMessagesAsRead', + }, + '/bot/pnp/push': { + POST: 'pushMessagesByPhone', + }, + '/bot/ad/multicast/phone': { + POST: 'audienceMatch', + }, + '/v2/bot/message/delivery/pnp': { + GET: 'getPNPMessageStatistics', + }, + '/v2/bot/message/delivery/ad_phone': { + GET: 'getAdPhoneMessageStatistics', + }, +}) diff --git a/adapters/line/src/types/request.ts b/adapters/line/src/types/request.ts new file mode 100644 index 00000000..8ca6fd6c --- /dev/null +++ b/adapters/line/src/types/request.ts @@ -0,0 +1,428 @@ +import * as Line from './definition' + +export type GetNarrowcastProgressParams = { + requestId: string +} + +export type GetNumberOfSentReplyMessagesParams = { + date: string +} + +export type GetNumberOfSentPushMessagesParams = { + date: string +} + +export type GetNumberOfSentMulticastMessagesParams = { + date: string +} + +export type GetNumberOfSentBroadcastMessagesParams = { + date: string +} + +export type GetAggregationUnitNameListParams = { + limit?: string + start?: string +} + +export type GetFollowersParams = { + start?: string + limit?: number +} + +export type GetGroupMembersIdsParams = { + start?: string +} + +export type GetRoomMembersIdsParams = { + start?: string +} + +export type GetRichMenuBatchProgressParams = { + requestId: string +} + +export type GetPNPMessageStatisticsParams = { + date: string +} + +export type GetAdPhoneMessageStatisticsParams = { + date: string +} + +declare module './internal' { + interface Internal { + + /** + * Get webhook endpoint information + * @see https://developers.line.biz/en/reference/messaging-api/#get-webhook-endpoint-information + */ + getWebhookEndpoint(): Promise + + /** + * Set webhook endpoint URL + * @see https://developers.line.biz/en/reference/messaging-api/#set-webhook-endpoint-url + */ + setWebhookEndpoint(params: Line.SetWebhookEndpointRequest): Promise + + /** + * Test webhook endpoint + * @see https://developers.line.biz/en/reference/messaging-api/#test-webhook-endpoint + */ + testWebhookEndpoint(params: Line.TestWebhookEndpointRequest): Promise + + /** + * Download image, video, and audio data sent from users. + * @see https://developers.line.biz/en/reference/messaging-api/#get-content + */ + getMessageContent(messageId: string): Promise + + /** + * Get a preview image of the image or video + * @see https://developers.line.biz/en/reference/messaging-api/#get-image-or-video-preview + */ + getMessageContentPreview(messageId: string): Promise + + /** + * Verify the preparation status of a video or audio for getting + * @see https://developers.line.biz/en/reference/messaging-api/#verify-video-or-audio-preparation-status + */ + getMessageContentTranscodingByMessageId(messageId: string): Promise + + /** + * Send reply message + * @see https://developers.line.biz/en/reference/messaging-api/#send-reply-message + */ + replyMessage(params: Line.ReplyMessageRequest): Promise + + /** + * Sends a message to a user, group chat, or multi-person chat at any time. + * @see https://developers.line.biz/en/reference/messaging-api/#send-push-message + */ + pushMessage(params: Line.PushMessageRequest): Promise + + /** + * An API that efficiently sends the same message to multiple user IDs. You can't send messages to group chats or multi-person chats. + * @see https://developers.line.biz/en/reference/messaging-api/#send-multicast-message + */ + multicast(params: Line.MulticastRequest): Promise + + /** + * Gets the status of a narrowcast message. + * @see https://developers.line.biz/en/reference/messaging-api/#get-narrowcast-progress-status + */ + getNarrowcastProgress(params: GetNarrowcastProgressParams): Promise + + /** + * Sends a message to multiple users at any time. + * @see https://developers.line.biz/en/reference/messaging-api/#send-broadcast-message + */ + broadcast(params: Line.BroadcastRequest): Promise + + /** + * Gets the target limit for sending messages in the current month. The total number of the free messages and the additional messages is returned. + * @see https://developers.line.biz/en/reference/messaging-api/#get-quota + */ + getMessageQuota(): Promise + + /** + * Gets the number of messages sent in the current month. + * @see https://developers.line.biz/en/reference/messaging-api/#get-consumption + */ + getMessageQuotaConsumption(): Promise + + /** + * Get number of sent reply messages + * @see https://developers.line.biz/en/reference/messaging-api/#get-number-of-reply-messages + */ + getNumberOfSentReplyMessages(params: GetNumberOfSentReplyMessagesParams): Promise + + /** + * Get number of sent push messages + * @see https://developers.line.biz/en/reference/messaging-api/#get-number-of-push-messages + */ + getNumberOfSentPushMessages(params: GetNumberOfSentPushMessagesParams): Promise + + /** + * Get number of sent multicast messages + * @see https://developers.line.biz/en/reference/messaging-api/#get-number-of-multicast-messages + */ + getNumberOfSentMulticastMessages(params: GetNumberOfSentMulticastMessagesParams): Promise + + /** + * Get number of sent broadcast messages + * @see https://developers.line.biz/en/reference/messaging-api/#get-number-of-broadcast-messages + */ + getNumberOfSentBroadcastMessages(params: GetNumberOfSentBroadcastMessagesParams): Promise + + /** + * Validate message objects of a reply message + * @see https://developers.line.biz/en/reference/messaging-api/#validate-message-objects-of-reply-message + */ + validateReply(params: Line.ValidateMessageRequest): Promise + + /** + * Validate message objects of a push message + * @see https://developers.line.biz/en/reference/messaging-api/#validate-message-objects-of-push-message + */ + validatePush(params: Line.ValidateMessageRequest): Promise + + /** + * Validate message objects of a multicast message + * @see https://developers.line.biz/en/reference/messaging-api/#validate-message-objects-of-multicast-message + */ + validateMulticast(params: Line.ValidateMessageRequest): Promise + + /** + * Validate message objects of a narrowcast message + * @see https://developers.line.biz/en/reference/messaging-api/#validate-message-objects-of-narrowcast-message + */ + validateNarrowcast(params: Line.ValidateMessageRequest): Promise + + /** + * Validate message objects of a broadcast message + * @see https://developers.line.biz/en/reference/messaging-api/#validate-message-objects-of-broadcast-message + */ + validateBroadcast(params: Line.ValidateMessageRequest): Promise + + /** + * Get number of units used this month + * @see https://developers.line.biz/en/reference/messaging-api/#get-number-of-units-used-this-month + */ + getAggregationUnitUsage(): Promise + + /** + * Get name list of units used this month + * @see https://developers.line.biz/en/reference/messaging-api/#get-name-list-of-units-used-this-month + */ + getAggregationUnitNameList(params: GetAggregationUnitNameListParams): Promise + + /** + * Get profile + * @see https://developers.line.biz/en/reference/messaging-api/#get-profile + */ + getProfile(userId: string): Promise + + /** + * Get a list of users who added your LINE Official Account as a friend + * @see https://developers.line.biz/en/reference/messaging-api/#get-follower-ids + */ + getFollowers(params: GetFollowersParams): Promise + + /** + * Get bot info + * @see https://developers.line.biz/en/reference/messaging-api/#get-bot-info + */ + getBotInfo(): Promise + + /** + * Get group chat member profile + * @see https://developers.line.biz/en/reference/messaging-api/#get-group-member-profile + */ + getGroupMemberProfile(groupId: string, userId: string): Promise + + /** + * Get multi-person chat member profile + * @see https://developers.line.biz/en/reference/messaging-api/#get-room-member-profile + */ + getRoomMemberProfile(roomId: string, userId: string): Promise + + /** + * Get group chat member user IDs + * @see https://developers.line.biz/en/reference/messaging-api/#get-group-member-user-ids + */ + getGroupMembersIds(groupId: string, params: GetGroupMembersIdsParams): Promise + + /** + * Get multi-person chat member user IDs + * @see https://developers.line.biz/en/reference/messaging-api/#get-room-member-user-ids + */ + getRoomMembersIds(roomId: string, params: GetRoomMembersIdsParams): Promise + + /** + * Leave group chat + * @see https://developers.line.biz/en/reference/messaging-api/#leave-group + */ + leaveGroup(groupId: string): Promise + + /** + * Leave multi-person chat + * @see https://developers.line.biz/en/reference/messaging-api/#leave-room + */ + leaveRoom(roomId: string): Promise + + /** + * Get group chat summary + * @see https://developers.line.biz/en/reference/messaging-api/#get-group-summary + */ + getGroupSummary(groupId: string): Promise + + /** + * Get number of users in a group chat + * @see https://developers.line.biz/en/reference/messaging-api/#get-members-group-count + */ + getGroupMemberCount(groupId: string): Promise + + /** + * Get number of users in a multi-person chat + * @see https://developers.line.biz/en/reference/messaging-api/#get-members-room-count + */ + getRoomMemberCount(roomId: string): Promise + + /** + * Create rich menu + * @see https://developers.line.biz/en/reference/messaging-api/#create-rich-menu + */ + createRichMenu(params: Line.RichMenuRequest): Promise + + /** + * Validate rich menu object + * @see https://developers.line.biz/en/reference/messaging-api/#validate-rich-menu-object + */ + validateRichMenuObject(params: Line.RichMenuRequest): Promise + + /** + * Download rich menu image. + * @see https://developers.line.biz/en/reference/messaging-api/#download-rich-menu-image + */ + getRichMenuImage(richMenuId: string): Promise + + /** + * Upload rich menu image + * @see https://developers.line.biz/en/reference/messaging-api/#upload-rich-menu-image + */ + setRichMenuImage(richMenuId: string): Promise + + /** + * Gets a rich menu via a rich menu ID. + * @see https://developers.line.biz/en/reference/messaging-api/#get-rich-menu + */ + getRichMenu(richMenuId: string): Promise + + /** + * Deletes a rich menu. + * @see https://developers.line.biz/en/reference/messaging-api/#delete-rich-menu + */ + deleteRichMenu(richMenuId: string): Promise + + /** + * Get rich menu list + * @see https://developers.line.biz/en/reference/messaging-api/#get-rich-menu-list + */ + getRichMenuList(): Promise + + /** + * Set default rich menu + * @see https://developers.line.biz/en/reference/messaging-api/#set-default-rich-menu + */ + setDefaultRichMenu(richMenuId: string): Promise + + /** + * Gets the ID of the default rich menu set with the Messaging API. + * @see https://developers.line.biz/en/reference/messaging-api/#get-default-rich-menu-id + */ + getDefaultRichMenuId(): Promise + + /** + * Cancel default rich menu + * @see https://developers.line.biz/en/reference/messaging-api/#cancel-default-rich-menu + */ + cancelDefaultRichMenu(): Promise + + /** + * Create rich menu alias + * @see https://developers.line.biz/en/reference/messaging-api/#create-rich-menu-alias + */ + createRichMenuAlias(params: Line.CreateRichMenuAliasRequest): Promise + + /** + * Get rich menu alias information + * @see https://developers.line.biz/en/reference/messaging-api/#get-rich-menu-alias-by-id + */ + getRichMenuAlias(richMenuAliasId: string): Promise + + /** + * Update rich menu alias + * @see https://developers.line.biz/en/reference/messaging-api/#update-rich-menu-alias + */ + updateRichMenuAlias(richMenuAliasId: string, params: Line.UpdateRichMenuAliasRequest): Promise + + /** + * Delete rich menu alias + * @see https://developers.line.biz/en/reference/messaging-api/#delete-rich-menu-alias + */ + deleteRichMenuAlias(richMenuAliasId: string): Promise + + /** + * Get list of rich menu alias + * @see https://developers.line.biz/en/reference/messaging-api/#get-rich-menu-alias-list + */ + getRichMenuAliasList(): Promise + + /** + * Get rich menu ID of user + * @see https://developers.line.biz/en/reference/messaging-api/#get-rich-menu-id-of-user + */ + getRichMenuIdOfUser(userId: string): Promise + + /** + * Unlink rich menu from user + * @see https://developers.line.biz/en/reference/messaging-api/#unlink-rich-menu-from-user + */ + unlinkRichMenuIdFromUser(userId: string): Promise + + /** + * Link rich menu to user. + * @see https://developers.line.biz/en/reference/messaging-api/#link-rich-menu-to-user + */ + linkRichMenuIdToUser(userId: string, richMenuId: string): Promise + + /** + * Validate a request body of the Replace or unlink the linked rich menus in batches endpoint. + * @see https://developers.line.biz/en/reference/messaging-api/#validate-batch-control-rich-menus-request + */ + validateRichMenuBatchRequest(params: Line.RichMenuBatchRequest): Promise + + /** + * Get the status of Replace or unlink a linked rich menus in batches. + * @see https://developers.line.biz/en/reference/messaging-api/#get-batch-control-rich-menus-progress-status + */ + getRichMenuBatchProgress(params: GetRichMenuBatchProgressParams): Promise + + /** + * Issue link token + * @see https://developers.line.biz/en/reference/messaging-api/#issue-link-token + */ + issueLinkToken(userId: string): Promise + + /** + * Mark messages from users as read + * @see https://developers.line.biz/en/reference/partner-docs/#mark-messages-from-users-as-read + */ + markMessagesAsRead(params: Line.MarkMessagesAsReadRequest): Promise + + /** + * Send LINE notification message + * @see https://developers.line.biz/en/reference/partner-docs/#send-line-notification-message + */ + pushMessagesByPhone(params: Line.PnpMessagesRequest): Promise + + /** + * Send a message using phone number + * @see https://developers.line.biz/en/reference/partner-docs/#phone-audience-match + */ + audienceMatch(params: Line.AudienceMatchMessagesRequest): Promise + + /** + * Get number of sent LINE notification messages + * @see https://developers.line.biz/en/reference/partner-docs/#get-number-of-sent-line-notification-messages + */ + getPNPMessageStatistics(params: GetPNPMessageStatisticsParams): Promise + + /** + * Get result of message delivery using phone number + * @see https://developers.line.biz/en/reference/partner-docs/#get-phone-audience-match + */ + getAdPhoneMessageStatistics(params: GetAdPhoneMessageStatisticsParams): Promise + } +} diff --git a/adapters/line/src/utils.ts b/adapters/line/src/utils.ts new file mode 100644 index 00000000..713f91d4 --- /dev/null +++ b/adapters/line/src/utils.ts @@ -0,0 +1,135 @@ +import { h, Session } from '@satorijs/satori' +import { LineBot } from './bot' +import { EventMessage, WebhookEvent } from './types' +// import jose from 'jose' + +export async function adaptMessage(bot: LineBot, message: EventMessage) { + const result: h[] = [] + if (message.type === 'text') { + const splits: number[] = [] + let nowPos = 0 + const finalLen = message.text.length + for (const emoji of (message.emojis ?? [])) { + splits.push(emoji.index) + } + for (const mention of (message.mention?.mentionees ?? [])) { + splits.push(mention.index) + } + if (splits.length === 0) return [h.text(message.text)] + do { + const nextPos = splits.shift() ?? finalLen + if (nextPos !== nowPos) { + result.push(h.text(message.text.substring(nowPos, nextPos))) + nowPos = nextPos + } + if (message.emojis) { + const emoji = message.emojis.find(v => v.index === nextPos) + if (emoji) { + result.push(h('face', { id: `e:${emoji.productId}:${emoji.emojiId}`, platform: bot.platform })) + nowPos = nowPos + emoji.length + } + } + if (message.mention) { + const mention = message.mention.mentionees.find(v => v.index === nextPos) + if (mention) { + if (mention.type === 'all') { + result.push(h('at', { type: 'all' })) + } else { + result.push(h('at', { name: message.text.slice(nowPos + 1, nowPos + mention.length) })) + } + nowPos = nowPos + mention.length + } + } + } while (nowPos !== finalLen) + } else if (message.type === 'image') { + if (message.contentProvider.type === 'line') { + return [h.image(`${bot.ctx.root.config.selfUrl}/line/assets/${bot.selfId}/${message.id}`)] + } else { + return [h.image(message.contentProvider.originalContentUrl)] + } + } else if (message.type === 'video') { + if (message.contentProvider.type === 'line') { + return [h.video(`${bot.ctx.root.config.selfUrl}/line/assets/${bot.selfId}/${message.id}`)] + } else { + return [h.video(message.contentProvider.originalContentUrl)] + } + } else if (message.type === 'sticker') { + return [h('face', { type: 'sticker', id: `s:${message.packageId}:${message.stickerId}`, platform: bot.platform })] + } else if (message.type === 'file') { + return [h.file(`${bot.ctx.root.config.selfUrl}/line/assets/${bot.selfId}/${message.id}`)] + } + return result +} + +export async function adaptSessions(bot: LineBot, body: WebhookEvent) { + const result: Partial[] = [] + const session = bot.session() + session.timestamp = +body.timestamp + if (body.source.type === 'user') { + session.userId = body.source.userId + session.channelId = body.source.userId // for message encoder + } else if (body.source.type === 'group') { + session.guildId = body.source.groupId + session.channelId = body.source.groupId + session.userId = body.source.userId + } else if (body.source.type === 'room') { + session.guildId = body.source.roomId + session.channelId = body.source.roomId + session.userId = body.source.userId + } + session.author = { + userId: session.userId, + } + // https://developers.line.biz/en/reference/messaging-api/#webhook-event-objects + if (body.type === 'message') { + session.type = 'message' + session.isDirect = body.source.type === 'user' + session.messageId = body.message.id + session.elements = await adaptMessage(bot, body.message) + session.content = session.elements.join('') + } else if (body.type === 'memberJoined') { + session.type = 'guild-member-added' + for (const user of body.joined.members) { + const tmpSession = Object.assign({}, session) + tmpSession.userId = user.userId + result.push(tmpSession) + } + } else if (body.type === 'memberLeft') { + session.type = 'guild-member-deleted' + for (const user of body.left.members) { + const tmpSession = Object.assign({}, session) + tmpSession.userId = user.userId + result.push(tmpSession) + } + } else if (body.type === 'follow') { + session.type = 'friend-added' + session.userId = body.source.userId + } else if (body.type === 'unfollow') { + session.type = 'friend-deleted' + session.userId = body.source.userId + } else if (body.type === 'unsend') { + session.type = 'message-deleted' + session.messageId = body.unsend.messageId + } else if (body.type === 'join') { + session.type = 'guild-added' + } else if (body.type === 'leave') { + session.type = 'guild-deleted' + } + if (session.type) result.push(session) + return result +} + +// export async function getChannelToken(kid: string, privKey: string, channelId: string) { +// const jws = await new jose.CompactSign( +// new TextEncoder().encode(JSON.stringify({ +// iss: channelId, +// sub: channelId, +// aud: 'https://api.line.me/', +// exp: Math.floor(Date.now() / 1000) + (60 * 60), +// token_exp: 60 * 60 +// })), +// ) +// .setProtectedHeader({ alg: 'RS256', type: 'JWT', kid }) +// .sign(await jose.importJWK(JSON.parse(privKey))) +// return jws +// } diff --git a/adapters/line/tsconfig.json b/adapters/line/tsconfig.json new file mode 100644 index 00000000..a14e38f4 --- /dev/null +++ b/adapters/line/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src", + }, + "include": [ + "src", + ], +} diff --git a/adapters/mail/.npmignore b/adapters/mail/.npmignore new file mode 100644 index 00000000..7e5fcbc1 --- /dev/null +++ b/adapters/mail/.npmignore @@ -0,0 +1,2 @@ +.DS_Store +tsconfig.tsbuildinfo diff --git a/adapters/mail/package.json b/adapters/mail/package.json index 3c70f307..adc4a1b7 100644 --- a/adapters/mail/package.json +++ b/adapters/mail/package.json @@ -1,7 +1,7 @@ { "name": "@satorijs/adapter-mail", "description": "Mail Adapter for Satorijs", - "version": "1.0.5", + "version": "1.1.2", "main": "lib/index.js", "typings": "lib/index.d.ts", "files": [ @@ -25,17 +25,17 @@ "satori" ], "peerDependencies": { - "@satorijs/satori": "^2.3.10" + "@satorijs/satori": "^2.6.1" }, "dependencies": { "@types/mailparser": "^3.4.0", "html5parser": "^2.0.2", - "mailparser": "^3.6.4", + "mailparser": "^3.6.5", "node-imap": "^0.9.6", - "nodemailer": "^6.9.2" + "nodemailer": "^6.9.3" }, "devDependencies": { "@types/node-imap": "^0.9.0", - "@types/nodemailer": "^6.4.7" + "@types/nodemailer": "^6.4.8" } } diff --git a/adapters/mail/src/bot.ts b/adapters/mail/src/bot.ts index ccee5f83..fdd61efc 100644 --- a/adapters/mail/src/bot.ts +++ b/adapters/mail/src/bot.ts @@ -1,15 +1,22 @@ -import { Bot, Fragment, Logger, Schema, SendOptions } from '@satorijs/satori' +import { Bot, Context, Logger, Schema } from '@satorijs/satori' import { ParsedMail } from 'mailparser' import { IMAP, SMTP } from './mail' -import { MailMessenger } from './message' +import { MailMessageEncoder } from './message' import { dispatchSession } from './utils' const logger = new Logger('adapter-mail') export class MailBot extends Bot { + static MessageEncoder = MailMessageEncoder + imap: IMAP smtp: SMTP + constructor(ctx: Context, config: MailBot.Config) { + super(ctx, config) + this.platform = 'mail' + } + async start() { this.username = this.config.username await super.start() @@ -51,14 +58,6 @@ export class MailBot extends Bot { this.imap.connect() }, 3000) } - - async sendMessage(channelId: string, content: Fragment, guildId?: string, options?: SendOptions) { - return await new MailMessenger(this, channelId, guildId, options).send(content) - } - - async sendPrivateMessage(userId: string, content: Fragment, options?: SendOptions) { - return await this.sendMessage(`private:${userId}`, content, null, options) - } } export namespace MailBot { @@ -81,7 +80,7 @@ export namespace MailBot { export const Config = Schema.object({ username: Schema.string().description('用户名。').required(), - password: Schema.string().description('密码。').required(), + password: Schema.string().description('密码或授权码。').required(), selfId: Schema.string().description('邮件地址 (默认与用户名相同)。'), name: Schema.string().description('发送邮件时显示的名称。'), subject: Schema.string().description('机器人发送的邮件主题。').default('Koishi'), @@ -119,5 +118,3 @@ export namespace MailBot { ]), }) } - -MailBot.prototype.platform = 'mail' diff --git a/adapters/mail/src/message.ts b/adapters/mail/src/message.ts index 80e0bf28..3e962e95 100644 --- a/adapters/mail/src/message.ts +++ b/adapters/mail/src/message.ts @@ -1,4 +1,4 @@ -import { Element, Messenger } from '@satorijs/satori' +import { Element, MessageEncoder } from '@satorijs/satori' import { MailBot } from './bot' import { Attachment } from './mail' @@ -8,7 +8,7 @@ export function randomId() { return Array(8).fill(0).map(() => letters[Math.floor(Math.random() * letters.length)]).join('') } -export class MailMessenger extends Messenger { +export class MailMessageEncoder extends MessageEncoder { buffer = '' reply: string attachments: Attachment[] = [] @@ -17,7 +17,7 @@ export class MailMessenger extends Messenger { async flush() { if (!this.buffer && this.attachments.length === 0) return const messageId = await this.bot.smtp.send({ - to: this.channelId.substring(8), + to: this.session.channelId, html: `
${this.buffer}
`, attachments: this.attachments, inReplyTo: this.reply, @@ -39,40 +39,21 @@ export class MailMessenger extends Messenger { const { type, attrs, children } = element if (type === 'text') { this.buffer += attrs.content - } else if (type === 'b' || type === 'strong') { - this.buffer += '' + } else if (['b', 'strong', 'i', 'em', 'u', 'ins', 's', 'del', 'p', 'code', 'li', 'ul', 'ol', 'blockquote'].includes(type)) { + this.buffer += `<${type}>` await this.render(children) - this.buffer += '' - } else if (type === 'i' || type === 'em') { - this.buffer += '' - await this.render(children) - this.buffer += '' - } else if (type === 'u' || type === 'ins') { - this.buffer += '' - await this.render(children) - this.buffer += '' - } else if (type === 's' || type === 'del') { - this.buffer += '' - await this.render(children) - this.buffer += '' - } else if (type === 'code') { - this.buffer += '' - await this.render(children) - this.buffer += '' + this.buffer += `` } else if (type === 'a') { this.buffer += `` await this.render(children) this.buffer += `` - } else if (type === 'p') { - await this.render(children) - this.buffer += `\n` } else if (type === 'at') { if (attrs.id) { this.buffer += `@${attrs.id}` } } else if (type === 'sharp' && attrs.id) { this.buffer += ` #${attrs.id} ` - } else if (type === 'image' && attrs.url) { + } else if (['image', 'audio', 'video', 'file'].includes(type) && attrs.url) { let url: string if (attrs.url.match(/^https?:/)) { url = attrs.url @@ -87,7 +68,13 @@ export class MailMessenger extends Messenger { }) url = `cid:${cid}` } - this.buffer += `` + if (type === 'image') { + this.buffer += `` + } else if (type === 'audio') { + this.buffer += `