import { request, RequestConfig } from './request' import { createHmac, randomBytes } from 'crypto' export interface IdsConfig { endpoint: string accessKeyId: string accessKeySecret: string } export enum IdsChannel { Csdn = 1, Wechat = 2, Zhihu = 3, Juejin = 4 } export type IdsCrawlRule = 'fulldata' | 'extdata' export interface IdsArticle { code: IdsChannel author_id: string | number cover_url?: string title: string author_name?: string sn_code: string original_url?: string source_address: string is_headline?: 0 | 1 is_original: 0 | 1 body: string label?: string published_at: Date external_read_num?: number external_see_num?: number external_like_num?: number external_comment_num?: number } export enum IdsSource { Manual = 0, User = 1, AliyunMarket = 2, TencentCloudMarket = 3, HuaweiCloudMarket = 4, Xiniu = 6, Website = 7, } export interface IdsProvider { name: string short_name?: string tel?: string email?: string logo?: string description?: string service_time?: string source: IdsSource source_pid: string | number source_url?: string } export interface IdsSolutionExtra { api_gateway: { service_id: string api_id: string dep_api_id?: string[] } icon_padding?: number } export interface IdsSolution { uid: number title: string description: string images: string details: string plain_text?: string service_type?: string[] dimension: 1 | 2 status: number source: IdsSource source_id: string source_pid: string source_dt?: string source_url: string source_tags?: string[] source_labels?: string ext_sold?: number ext_score?: number skus?: any[] api?: any[] doc_path?: string is_signed?: 1 | 0 type?: 'gateway' min_price?: number max_price?: number extra?: IdsSolutionExtra | string } export interface IdsUser { uid?: string password: string mobile?: string email?: string nickname: string introduction?: string icon_url?: string source: string } const genNonceString = () => randomBytes(8).toString('hex') export const randomtail = () => `_=${genNonceString()}` export class Ids { config: IdsConfig constructor(config: IdsConfig) { this.config = config } private async request(config: RequestConfig) { const { endpoint, accessKeyId, accessKeySecret } = this.config config.baseURL = endpoint config.url = config.url || '/' config.params = config.params || {} config.params.nonce = genNonceString() const timestamp = Math.floor(Date.now() / 1000) const data = config.url.toLowerCase() + timestamp const signature = createHmac('sha256', accessKeySecret).update(data).digest('base64') config.headers = config.headers || {} config.headers['Authorization'] = `IDS-HMAC-SHA256 Credential=${accessKeyId}/${timestamp},Signature=${signature}` const res = await request(config) if (res.data.status != 1) { console.error(res.data) throw new Error(`[${res.data.status}] ${res.data.info}`) } return res.data } getCrawlAuthors(channel: IdsChannel) { return this.request({ method: 'POST', url: '/api/ids/getCrawlAuthors', data: { code: channel } }) } getCrawlArticleRules(params: { ids: string[]; channel: IdsChannel }) { const { ids, channel } = params return this.request({ method: 'POST', url: '/api/ids/getCrawlArticleRules', data: { code: channel, sn_codes: ids } }) } putArticle(data: IdsArticle, rule: IdsCrawlRule) { data.external_read_num = data.external_read_num || 0 data.external_see_num = data.external_see_num || 0 data.external_like_num = data.external_like_num || 0 data.external_comment_num = data.external_comment_num || 0 return this.request({ method: 'POST', url: `/api/ids/putArticleData`, params: { crawl: rule }, data }) } putProvider(data: IdsProvider) { return this.request({ method: 'POST', url: `/api/ids/putSourceData`, data }) } putSolution(data: IdsSolution) { data.ext_sold = data.ext_sold || 0 data.ext_score = data.ext_score || 0 if (data.extra && typeof data.extra === 'object') { data.extra = JSON.stringify(data.extra) } return this.request({ method: 'POST', url: `/api/ids/putSolutionData`, data }) } createUser(data: IdsUser) { return this.request({ method: 'POST', url: `/api/ids/createUser`, data }) } }