12 Commits

Author SHA1 Message Date
lizheming b511b81acc 2.0.0 2018-03-23 09:53:35 +08:00
lizheming e38559fd09 remove server chan service 2018-03-23 09:53:12 +08:00
lizheming 3d2f8941f1 rm unnecessary word 2018-01-09 10:26:26 +08:00
lizheming 4dbc0654a7 update dockerfile version 2018-01-09 09:18:28 +08:00
lizheming 7d12e3185c fix readme mistake 2018-01-09 09:08:49 +08:00
lizheming 1ad073309e 1.1.0 2018-01-08 22:42:23 +08:00
lizheming 996d01cbcc update docs.md 2018-01-08 22:42:13 +08:00
lizheming 2533b5f5cd update docs.md 2018-01-08 22:40:16 +08:00
lizheming ab8de5c343 update test 2018-01-08 22:27:15 +08:00
lizheming 734dc3f63a rm camelcase lint 2018-01-08 21:55:51 +08:00
lizheming d60ee90f42 add wechat corp id support raw 2018-01-08 21:51:53 +08:00
lizheming a449906a10 update plugin info 2018-01-07 18:09:30 +08:00
8 changed files with 319 additions and 39 deletions
+4 -1
View File
@@ -1,3 +1,6 @@
{
"extends": "think"
"extends": "think",
"rules": {
"camelcase": "off"
}
}
+80 -4
View File
@@ -5,16 +5,17 @@ author: lizheming
tags: [ notifications, chat ]
repo: lizheming/drone-wechat
logo: wechat.svg
image: lizheming/drone-wechat
---
The Wechat plugin posts build status messages to your account. The below pipeline configuration demonstrates simple usage:
```yaml
```diff
pipline:
wechat:
image: lizheming/drone-wechat
sckey: xxxxxx
title: "plugin notification"
+ sckey: xxxxxx
title: ${DRONE_REPO_NAME}
message: >
{%if success %}
build {{build.number}} succeeded. Good job.
@@ -23,16 +24,91 @@ pipline:
{% endif %}
```
# Praameter Reference
If you want push notification with your own wechat corp id, you can config like this:
```diff
pipeline:
wechat:
image: lizheming/drone-wechat
+ corpid: corpid
+ corp_secret: secret
+ agent_id: 1234567
+ to_user: 111
+ to_party: 112
+ to_tag: ${DRONE_REPO_NAME}
+ msg_url: ${DRONE_BUILD_LINK}
+ safe: 1
+ btn_txt: more
title: ${DRONE_REPO_NAME}
message: >
{%if success %}
build {{build.number}} succeeded. Good job.
{% else %}
build {{build.number}} failed. Fix me please.
{% endif %}
```
# Parameter Reference
corpid
: The corpid for authorization
corp_secret
: The corp secret for authorization
agent_id:
: The agent id to send the message
to_party
: The party ids to send message
to_user
: The user ids to send the message to
to_tag
: The tag ids to send the message to
safe
: encrypt message, default is false
msg_url
: The link for the text card click
btn_text
: The text for the button on the card
sckey
: SCKEY get from [ServerChan](http://sc.ftqq.com)
title
: Notification title
message
: Notification body message, support markdown
# Secret Reference
wechat_corpid
: The corpid for authorization
wechat\_corp\_secret
: The corp secret for authorization
wechat\_agent\_id
: The agent id to send the message
wechat\_to\_party
: The party ids to send message
wechat\_to\_user
: The user ids to send the message to
wechat\_to\_tag
: The tag ids to send the message to
wechat_sckey
: SCKEY get from [ServerChan](http://sc.ftqq.com)
# Template Reference
repo.owner
+2 -2
View File
@@ -1,9 +1,9 @@
FROM mhart/alpine-node:8.9.3
LABEL maintainer="lizheming <i@imnerd.org>" \
org.label-schema.name="Drone Telegram Node" \
org.label-schema.name="Drone Wechat Notification" \
org.label-schema.vendor="lizheming" \
org.label-schema.schema-version="1.0"
org.label-schema.schema-version="1.1.0"
WORKDIR /wechat
COPY package.json /wechat/package.json
+29 -7
View File
@@ -7,17 +7,31 @@
[![](https://images.microbadger.com/badges/image/lizheming/drone-wechat.svg)](https://microbadger.com/images/lizheming/drone-wechat)
[![GitHub release](https://img.shields.io/github/release/lizheming/drone-wechat.svg)]()
Drone plugin for sending telegram notifications.
Drone plugin for sending wechat notifications.
## Description
This drone wechat notification plugin builds base on [ServerChan](http://sc.ftqq.com). Before using you should login to [ServerChan](http://sc.ftqq.com) to get `SCKEY`. After login with Github account you can get `SCKEY` at http://sc.ftqq.com/?c=code.
This drone wechat notification plugin builds base on Wechat for Work.
Read this in other languages: [English](README.md), [简体中文](README.zh-cn.md).
## Environment
- `PLUGIN_SCKEY`: SCKEY get from [ServerChan](http://sc.ftqq.com)
- `PLUGIN_CORPID`: The corpid for authorization
- `WECHAT_CORPID`: alias for `PLUGIN_CORPID`
- `PLUGIN_CORP_SECRET`: The corp secret for authorization
- `WECHAT_CORP_SECRET`: alias for `PLUGIN_CORP_SECRET`
- `PLUGIN_AGENT_ID`: The agent id to send the message
- `WECHAT_AGENT_ID`: alias for `PLUGIN_AGENT_ID`
- `PLUGIN_TO_PARTY`: The party ids to send the message
- `WECHAT_TO_PARTY`: alias for `PLUGIN_TO_PARTY`
- `PLUGIN_TO_USER`: The user ids to send the message to
- `WECHAT_TO_USER`: alias for `PLUGIN_TO_USER`
- `PLUGIN_TO_TAG`: The tag ids to send the message to
- `WECHAT_TO_TAG`: alias for `PLUGIN_TO_TAG`
- `PLUGIN_SAFE`: encrypt message, default is false
- `PLUGIN_MSG_URL`: The link for the text card click
- `PLUGIN_BTN_TEXT`: The text for the button on the card
- `PLUGIN_TITLE`: Notification title
- `PLUGIN_MESSAGE`: Notification body message, support markdown.
@@ -25,9 +39,17 @@ Read this in other languages: [English](README.md), [简体中文](README.zh-cn.
```
docker run --rm \
-e PLUGIN_SCKEY=xxxx \
-e PLUGIN_TITLE=xxxx \
-e PLUGIN_MESSAGE=xxx \
-e PLUGIN_CORPID=corpid \
-e PLUGIN_CORP_SECRET=corpsecret \
-e PLUGIN_AGENT_ID=agentid \
-e PLUGIN_TO_USER=userId \
-e PLUGIN_TO_TAG=tagId \
-e PLUGIN_TO_PARTY=toParty \
-e PLUGIN_SAFE=1 \
-e PLUGIN_MSG_URL=url \
-e PLUGIN_BTN_TXT=true \
-e PLUGIN_TITLE=title \
-e PLUGIN_MESSAGE=description \
-e DRONE_REPO_OWNER=lizheming \
-e DRONE_REPO_NAME=drone-wechat \
-e DRONE_COMMIT_SHA=e5e82b5eb3737205c25955dcc3dcacc839b7be52 \
@@ -42,4 +64,4 @@ docker run --rm \
-e DRONE_JOB_STARTED=1477550550 \
-e DRONE_JOB_FINISHED=1477550750 \
lizheming/drone-wechat
```
```
+29 -7
View File
@@ -13,21 +13,43 @@ drone 微信消息通知插件。
## 简介
基于 http://sc.ftqq.com/ 封装的 drone 微信消息通知插件。使用前需要去 [Server酱]( http://sc.ftqq.com/) 获取密钥。Github 登录后即可在 [发送消息](http://sc.ftqq.com/?c=code) 页面查看
基于微信企业号封装的 drone 微信消息通知插件
## 配置说明
- `PLUGIN_SCKEY`: SCKEY get from [ServerChan](http://sc.ftqq.com)
- `PLUGIN_TITLE`: Notification title
- `PLUGIN_MESSAGE`: Notification body message, support markdown.
- `PLUGIN_CORPID`: 企业Id
- `WECHAT_CORPID`: `PLUGIN_CORPID` 别名
- `PLUGIN_CORP_SECRET`: 管理组的凭证密钥
- `WECHAT_CORP_SECRET`: `PLUGIN_CORP_SECRET` 别名
- `PLUGIN_AGENT_ID`: 企业应用的id,整型。可在应用的设置页面查看
- `WECHAT_AGENT_ID`: `PLUGIN_AGENT_ID` 别名
- `PLUGIN_TO_PARTY`: 部门ID列表,多个接收者用‘|’分隔,最多支持100个。
- `WECHAT_TO_PARTY`: `PLUGIN_TO_PARTY` 别名
- `PLUGIN_TO_USER`: 成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向该企业应用的全部成员发送
- `WECHAT_TO_USER`: `PLUGIN_TO_USER` 别名
- `PLUGIN_TO_TAG`: 标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
- `WECHAT_TO_TAG`: `PLUGIN_TO_TAG` 别名
- `PLUGIN_SAFE`: 表示是否是保密消息,0表示否,1表示是,默认0
- `PLUGIN_MSG_URL`: 点击后跳转的链接。
- `PLUGIN_BTN_TEXT`: 按钮文字。 默认为“详情”, 不超过4个文字,超过自动截断。
- `PLUGIN_TITLE`: 消息卡片标题
- `PLUGIN_MESSAGE`: 消息卡片正文,支持 Markdown。
## 如何使用
```
docker run --rm \
-e PLUGIN_SCKEY=xxxx \
-e PLUGIN_TITLE=xxxx \
-e PLUGIN_MESSAGE=xxx \
-e PLUGIN_CORPID=corpid \
-e PLUGIN_CORP_SECRET=corpsecret \
-e PLUGIN_AGENT_ID=agentid \
-e PLUGIN_TO_USER=userId \
-e PLUGIN_TO_TAG=tagId \
-e PLUGIN_TO_PARTY=toParty \
-e PLUGIN_SAFE=1 \
-e PLUGIN_MSG_URL=url \
-e PLUGIN_BTN_TXT=true \
-e PLUGIN_TITLE=title \
-e PLUGIN_MESSAGE=description \
-e DRONE_REPO_OWNER=lizheming \
-e DRONE_REPO_NAME=drone-wechat \
-e DRONE_COMMIT_SHA=e5e82b5eb3737205c25955dcc3dcacc839b7be52 \
+88 -11
View File
@@ -3,18 +3,95 @@ const render = require('drone-render');
const request = require('request-promise-native');
const {
PLUGIN_SCKEY,
PLUGIN_CORPID,
WECHAT_CORPID,
PLUGIN_CORP_SECRET,
WECHAT_CORP_SECRET,
PLUGIN_AGENT_ID,
WECHAT_AGENT_ID,
PLUGIN_TO_PARTY,
WECHAT_TO_PARTY,
PLUGIN_TO_USER,
WECHAT_TO_USER,
PLUGIN_TO_TAG,
WECHAT_TO_TAG,
PLUGIN_MSG_TYPE,
PLUGIN_SAFE,
PLUGIN_MSG_URL,
PLUGIN_BTN_TEXT,
PLUGIN_TITLE,
PLUGIN_MESSAGE,
SERVER_CHAN_KEY
PLUGIN_MESSAGE
} = process.env;
const SCKEY = PLUGIN_SCKEY || SERVER_CHAN_KEY;
function getAccessToken() {
const CORPID = PLUGIN_CORPID || WECHAT_CORPID;
const CORP_SECRET = PLUGIN_CORP_SECRET || WECHAT_CORP_SECRET;
request({
url: `https://sc.ftqq.com/${SCKEY}.send`,
qs: {
text: PLUGIN_TITLE,
desp: render(PLUGIN_MESSAGE)
}
});
return request({
url: 'https://qyapi.weixin.qq.com/cgi-bin/gettoken',
qs: {
corpid: CORPID,
corpsecret: CORP_SECRET
},
json: true
}).then(resp => {
if (!resp.access_token) {
throw new Error(resp);
}
return resp.access_token;
});
}
function sendMsgFromWork(access_token) {
const TO_USER = PLUGIN_TO_USER || WECHAT_TO_USER || '@all';
const TO_PARTY = PLUGIN_TO_PARTY || WECHAT_TO_PARTY;
const TO_TAG = PLUGIN_TO_TAG || WECHAT_TO_TAG;
const AGENT_ID = PLUGIN_AGENT_ID || WECHAT_AGENT_ID;
const MSG_TYPE = PLUGIN_MSG_TYPE || 'textcard';
const SAFE = PLUGIN_SAFE || 0;
const TITLE = PLUGIN_TITLE;
const DESCRIPTION = render(PLUGIN_MESSAGE);
const MSG_URL = PLUGIN_MSG_URL;
const BTN_TEXT = PLUGIN_BTN_TEXT;
return request({
method: 'POST',
url: 'https://qyapi.weixin.qq.com/cgi-bin/message/send',
qs: {
access_token
},
body: {
touser: TO_USER,
toparty: TO_PARTY,
tag: TO_TAG,
msgtype: MSG_TYPE,
agentid: AGENT_ID,
safe: SAFE,
textcard: {
title: TITLE,
description: DESCRIPTION,
url: MSG_URL,
btntext: BTN_TEXT
}
},
json: true
});
}
function sendMsgFromWechat() {
return getAccessToken()
.then(sendMsgFromWork)
.catch(err => {
console.error(err);
});
}
sendMsgFromWechat();
module.exports = {
getAccessToken,
sendMsgFromWork,
sendMsgFromWechat
};
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "drone-wechat",
"version": "1.0.0",
"version": "2.0.0",
"description": "drone wechat notification plugin",
"main": "index.js",
"scripts": {
+86 -6
View File
@@ -6,7 +6,7 @@ const SCKEY2 = 'testsckey2';
const TITLE = 'test for title';
const MESSAGE = 'test for message';
test('send wechat', async t => {
test('send wechat with serverchan', async t => {
t.plan(2);
mock('process', {
@@ -34,18 +34,98 @@ test('send wechat', async t => {
mock.stopAll();
});
test('send wechat with SERVER_CHAN_KEY', async t => {
test('get wechat corp access token', async t => {
t.plan(3);
mock('process', {
env: {
SERVER_CHAN_KEY: SCKEY2,
PLUGIN_CORPID: 111,
PLUGIN_CORP_SECRET: 222,
PLUGIN_TITLE: TITLE,
PLUGIN_MESSAGE: MESSAGE
}
});
mock('request-promise-native', obj => {
t.is(obj.url, `https://sc.ftqq.com/${SCKEY2}.send`);
});
if (obj.url.includes('gettoken')) {
t.deepEqual(obj, {
url: 'https://qyapi.weixin.qq.com/cgi-bin/gettoken',
qs: {
corpid: 111,
corpsecret: 222
},
json: true
});
}
mock.reRequire('./index.js');
return Promise.resolve({access_token: 1234});
});
const wechat = mock.reRequire('./index');
t.is(1234, await wechat.getAccessToken());
mock.stopAll();
});
test('send wechat with corp id', async t => {
mock('process', {
env: {
PLUGIN_TITLE: TITLE,
PLUGIN_MESSAGE: MESSAGE,
PLUGIN_TO_PARTY: 'party',
PLUGIN_TO_TAG: 'tag',
PLUGIN_MSG_URL: '',
PLUGIN_BTN_TEXT: 'more',
PLUGIN_AGENT_ID: 1122
}
});
mock('request-promise-native', obj => {
if (obj.url.includes('gettoken')) {
return Promise.resolve({access_token: 1234});
}
if (obj.url.includes('send')) {
t.deepEqual(obj, {
method: 'POST',
url: 'https://qyapi.weixin.qq.com/cgi-bin/message/send',
qs: {
access_token: 1234
},
body: {
touser: '@all',
toparty: 'party',
tag: 'tag',
msgtype: 'textcard',
agentid: 1122,
safe: 0,
textcard: {
title: TITLE,
description: MESSAGE,
url: '',
btntext: 'more'
}
},
json: true
});
}
});
mock.reRequire('./index');
mock.stopAll();
});
test('send wechat', async t => {
mock('process', {
env: {
PLUGIN_TITLE: TITLE,
PLUGIN_MESSAGE: MESSAGE
}
});
mock('request-promise-native', obj => {
if (obj.url.includes('gettoken')) {
return Promise.resolve({errcode: 1, errmsg: 123});
}
if (obj.url.includes('send')) {
t.fail();
}
});
mock.reRequire('./index');
await new Promise(resolve => setTimeout(resolve, 2000)).then(() => t.pass());
mock.stopAll();
});