Skip to content

Commit

Permalink
Auto Format
Browse files Browse the repository at this point in the history
  • Loading branch information
adaex committed Jun 1, 2021
1 parent 53574c0 commit f42f1ef
Show file tree
Hide file tree
Showing 14 changed files with 288 additions and 290 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
[![npm downloads](https://img.shields.io/npm/dm/coa-wx-work.svg?style=flat-square)](http://npm-stat.com/charts.html?package=coa-wx-work)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/coajs/coa-wx-work/pulls)

简洁的企业微信SDK for Node.js
简洁的企业微信 SDK for Node.js

## 特点

根据日常实际项目使用情况:

- 覆盖了绝大多数使用场景
- 统一了异步表现形式,全部返回 Promise
- 内置类型引用,无需额外查看文档,开箱即用,IDE友好
- 内置类型引用,无需额外查看文档,开箱即用,IDE 友好

## 快速开始

Expand All @@ -35,7 +35,7 @@ const bin = new WxWorkBin()
const agent = {
corpId: 'wwc2bf51eeeeeee825b1',
agentId: '1000001',
secret: 'J1jxD5X3eXXXXXXXXXXXXIAHvawDRU4'
secret: 'J1jxD5X3eXXXXXXXXXXXXIAHvawDRU4',
}

// 成员类服务实例
Expand Down Expand Up @@ -81,8 +81,6 @@ await botService.text('文本消息')
await botService.image('data of base64')

// 发送markdown消息
const content = new WxWorkMarkdown()
.header3('主题')
.text('主体内容')
const content = new WxWorkMarkdown().header3('主题').text('主体内容')
await botService.markdown(content)
```
19 changes: 8 additions & 11 deletions src/libs/WxWorkBin.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
import { CoaError } from 'coa-error'
import { $, _, axios, Axios } from 'coa-helper'
import { $, axios, Axios, _ } from 'coa-helper'
import { WxWork } from '../typings'
import { WxWorkStorage } from './WxWorkStorage'

const baseURL = 'https://qyapi.weixin.qq.com'

export class WxWorkBin {

readonly storage: WxWorkStorage

constructor (storage?: WxWorkStorage) {
this.storage = storage || new WxWorkStorage()
constructor(storage?: WxWorkStorage) {
this.storage = storage ?? new WxWorkStorage()
}

async get (url: string, params: WxWork.Dic = {}, allow: number[] = []) {
async get(url: string, params: WxWork.Dic = {}, allow: number[] = []) {
const res = await axios(url, { params, baseURL })
return this.wxResponseResult(res, allow)
}

async post (url: string, data: WxWork.Dic, params: WxWork.Dic = {}, config: Axios.AxiosRequestConfig = {}, allow: number[] = []) {
async post(url: string, data: WxWork.Dic, params: WxWork.Dic = {}, config: Axios.AxiosRequestConfig = {}, allow: number[] = []) {
const res = await axios(url, { params, data, baseURL, method: 'POST', ...config })
return this.wxResponseResult(res, allow)
}

protected wxResponseResult (res: Axios.AxiosResponse, allow: number[]) {
protected wxResponseResult(res: Axios.AxiosResponse, allow: number[]) {
const info: WxWork.Dic = res.data || {}
if (info.errcode) {
const message = _.toString(info.errmsg) || '企业微信服务返回错误'
const code = _.toNumber(info.errcode) || 0
if (!allow.includes(code))
CoaError.throw('WxWork.Error.' + info.errcode, message)
if (!allow.includes(code)) CoaError.throw('WxWork.Error.' + info.errcode, message)
}
return $.camelCaseKeys(info)
}

}
}
11 changes: 5 additions & 6 deletions src/libs/WxWorkStorage.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
export class WxWorkStorage {
private DATA: { [index: string]: { value: any; expire: number } } = {}

private DATA = {} as { [index: string]: { value: any, expire: number } }

async get<T> (key: string) {
async get<T>(key: string) {
const { value, expire } = this.DATA[key] || { value: null, expire: 0 }
if (expire < Date.now()) return null
return value
return value as T
}

async set (key: string, value: any, ms: number) {
async set(key: string, value: any, ms: number) {
const expire = Date.now() + ms
this.DATA[key] = { value, expire }
}
}
}
16 changes: 7 additions & 9 deletions src/services-bot/WxWorkBotService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,39 @@ import { WxWorkMarkdown } from './WxWorkMarkdown'

// https://work.weixin.qq.com/api/doc/90000/90136/91770
export class WxWorkBotService {

readonly bin: WxWorkBin
readonly key: string

constructor (bin: WxWorkBin, key: string) {
constructor(bin: WxWorkBin, key: string) {
this.bin = bin
this.key = key
}

async text (content: string, mentioned_list: string[] = [], mentioned_mobile_list: string[] = []) {
async text(content: string, mentioned_list: string[] = [], mentioned_mobile_list: string[] = []) {
const data = { msgtype: 'text', text: { content, mentioned_list, mentioned_mobile_list } }
return await this.send(data)
}

async json (title: string, env: string, data: any) {
async json(title: string, env: string, data: any) {
return await this.text(`${title} ${env} ${dayjs().format('YYYY-MM-DD HH:mm:ss')} \n${JSON.stringify(data, undefined, 2)}`)
}

async markdown (markdown: WxWorkMarkdown) {
async markdown(markdown: WxWorkMarkdown) {
const data = { msgtype: 'markdown', markdown: { content: markdown.value() } }
return await this.send(data)
}

async image (base64: string, md5: string) {
async image(base64: string, md5: string) {
const data = { msgtype: 'image', image: { base64, md5 } }
return await this.send(data)
}

async news (articles: { title: string, description?: string, url: string, picurl?: string }[]) {
async news(articles: Array<{ title: string; description?: string; url: string; picurl?: string }>) {
const data = { msgtype: 'news', news: { articles } }
return await this.send(data)
}

protected async send (data: any) {
protected async send(data: any) {
return await this.bin.post('/cgi-bin/webhook/send', data, { key: this.key })
}

}
40 changes: 19 additions & 21 deletions src/services-bot/WxWorkMarkdown.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,71 @@
export class WxWorkMarkdown {
private data = ''

text (text: string, color?: 'info' | 'comment' | 'warning') {
if (!color)
this.data += text
else
this.data += `<font color="${color}">${text}</font>`
text(text: string, color?: 'info' | 'comment' | 'warning') {
if (!color) this.data += text
else this.data += `<font color="${color}">${text}</font>`
return this
}

header3 (text: string) {
header3(text: string) {
return this.text(`### ${text}`)
}

header4 (text: string) {
header4(text: string) {
return this.text(`#### ${text}`)
}

header5 (text: string) {
header5(text: string) {
return this.text(`##### ${text}`)
}

header6 (text: string) {
header6(text: string) {
return this.text(`###### ${text}`)
}

red (text: string) {
red(text: string) {
return this.text(text, 'warning')
}

green (text: string) {
green(text: string) {
return this.text(text, 'info')
}

gray (text: string) {
gray(text: string) {
return this.text(text, 'comment')
}

bold (text: string) {
bold(text: string) {
return this.text(`**${text}**`)
}

link (title: string, url: string) {
link(title: string, url: string) {
return this.text(`[${title}](${url})`)
}

commentText (text: string) {
commentText(text: string) {
return this.text(text, 'comment')
}

warningText (text: string) {
warningText(text: string) {
return this.text(text, 'warning')
}

infoText (text: string) {
infoText(text: string) {
return this.text(text, 'info')
}

br () {
br() {
this.data += '\n'
return this
}

quote () {
quote() {
this.data += '> '
return this
}

value () {
value() {
return this.data
}
}
}
22 changes: 10 additions & 12 deletions src/services/WxWorkAuthServiceBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,54 @@ import { WxWorkBin } from '../libs/WxWorkBin'
import { WxWork } from '../typings'

export class WxWorkAuthServiceBase {

readonly bin: WxWorkBin
readonly agent: WxWork.Agent

constructor (bin: WxWorkBin, agent: WxWork.Agent) {
constructor(bin: WxWorkBin, agent: WxWork.Agent) {
this.bin = bin
this.agent = agent
}

// 获取Token
async getToken () {
async getToken() {
const cacheName = `WxWorkToken:${this.agent.corpId}:${this.agent.agentId}`
let result = await this.bin.storage.get<WxWork.Token>(cacheName) || { token: '', expire: 1 }
let result = (await this.bin.storage.get<WxWork.Token>(cacheName)) ?? { token: '', expire: 1 }
if (!result.token) {
const param = { corpid: this.agent.corpId, corpsecret: this.agent.secret }
const data = await this.bin.get('/cgi-bin/gettoken', param)
const ms = _.toInteger(data.expiresIn) * 1e3 - 200 * 1e3
const expire = _.now() + ms
const token = data.accessToken as string || ''
const token = (data.accessToken as string) || ''
result = { expire, token }
await this.bin.storage.set(cacheName, result, ms)
}
return result.token
}

// 获取Ticket
async getTicket () {
async getTicket() {
const { ticket } = await this.gain()
return ticket
}

// 获取Ticket对象
async gainTicket () {
async gainTicket() {
return await this.gain()
}

// 获取Ticket
private async gain () {
private async gain() {
const cacheName = `WxWorkJsapiTicket:${this.agent.corpId}:${this.agent.agentId}`
let result = await this.bin.storage.get<WxWork.JsapiTicket>(cacheName) || { ticket: '', expire: 1 }
let result = (await this.bin.storage.get<WxWork.JsapiTicket>(cacheName)) ?? { ticket: '', expire: 1 }
if (!result.ticket) {
const access_token = await this.getToken()
const data = await this.bin.get('/cgi-bin/get_jsapi_ticket', { access_token })
const ms = _.toInteger(data.expiresIn) * 1e3 - 200 * 1e3
const expire = _.now() + ms
const ticket = data.ticket as string || ''
const ticket = (data.ticket as string) || ''
result = { expire, ticket }
await this.bin.storage.set(cacheName, result, ms)
}
return result
}

}
}
22 changes: 11 additions & 11 deletions src/services/WxWorkDepartmentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@ import { WxWork } from '../typings'
import { WxWorkAuthServiceBase } from './WxWorkAuthServiceBase'

export class WxWorkDepartmentService extends WxWorkAuthServiceBase {

// 创建部门 https://work.weixin.qq.com/api/doc/90000/90135/90205
async create ({ id = 0, name = '', nameEn = '', parentid = 0, order = 0 } = {}) {
async create({ id = 0, name = '', nameEn = '', parentid = 0, order = 0 } = {}) {
const params = _.pickBy({ id, name, name_en: nameEn, parentid, order })
return await this.bin.post('/cgi-bin/department/create', $.snakeCaseKeys(params), { access_token: await this.getToken() }, {}, [60008]) as WxWork.CreateDepartmentResponse
return (await this.bin.post('/cgi-bin/department/create', $.snakeCaseKeys(params), { access_token: await this.getToken() }, {}, [
60008,
])) as WxWork.CreateDepartmentResponse
}

// 更新部门 https://work.weixin.qq.com/api/doc/90000/90135/90206
async update (id: number, { name, nameEn, parentid, order }: { name?: string, nameEn?: string, parentid?: number, order?: number }) {
async update(id: number, { name, nameEn, parentid, order }: { name?: string; nameEn?: string; parentid?: number; order?: number }) {
const access_token = await this.getToken()
const params = { id, name, name_en: nameEn, parentid, order }
return await this.bin.post('/cgi-bin/department/update', _.pickBy(params), { access_token }) as WxWork.NormalResponse
return (await this.bin.post('/cgi-bin/department/update', _.pickBy(params), { access_token })) as WxWork.NormalResponse
}

// 删除部门 https://work.weixin.qq.com/api/doc/90000/90135/90207
async delete (id: number) {
return await this.bin.get('cgi-bin/department/delete', { access_token: await this.getToken(), id }) as WxWork.NormalResponse
async delete(id: number) {
return (await this.bin.get('cgi-bin/department/delete', { access_token: await this.getToken(), id })) as WxWork.NormalResponse
}

// 获取部门列表 https://work.weixin.qq.com/api/doc/90000/90135/90208
async getList (id?: number) {
async getList(id?: number) {
const params = id ? { id } : {}
return await this.bin.get('cgi-bin/department/list', { access_token: await this.getToken(), ...params }) as WxWork.DepartmentList
return (await this.bin.get('cgi-bin/department/list', { access_token: await this.getToken(), ...params })) as WxWork.DepartmentList
}

}
}
Loading

0 comments on commit f42f1ef

Please sign in to comment.