mirror of
https://github.com/lizheming/drone-wechat.git
synced 2026-06-16 14:50:39 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ad073309e | |||
| 996d01cbcc | |||
| 2533b5f5cd | |||
| ab8de5c343 | |||
| 734dc3f63a | |||
| d60ee90f42 | |||
| a449906a10 |
@@ -1,3 +1,6 @@
|
||||
{
|
||||
"extends": "think"
|
||||
"extends": "think",
|
||||
"rules": {
|
||||
"camelcase": "off"
|
||||
}
|
||||
}
|
||||
@@ -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,92 @@ 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
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
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"
|
||||
|
||||
|
||||
@@ -11,18 +11,67 @@ Drone plugin for sending telegram 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. You can config your own wechat corp id, or you can get wechat notification quickly with key from [ServerChan](http://sc.ftqq.com). If you use [ServerChan](http://sc.ftqq.com) you need get `SCKEY` before using. After login with Github account you can get `SCKEY` at http://sc.ftqq.com/?c=code.
|
||||
|
||||
Read this in other languages: [English](README.md), [简体中文](README.zh-cn.md).
|
||||
|
||||
## Environment
|
||||
|
||||
- `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_SCKEY`: SCKEY get from [ServerChan](http://sc.ftqq.com)
|
||||
- `WECHAT_SCKEY`: alias for `PLUGIN_SCKEY`
|
||||
- `PLUGIN_TITLE`: Notification title
|
||||
- `PLUGIN_MESSAGE`: Notification body message, support markdown.
|
||||
|
||||
## Usage
|
||||
|
||||
### With wechat corp id
|
||||
|
||||
```
|
||||
docker run --rm \
|
||||
-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 \
|
||||
-e DRONE_COMMIT_BRANCH=master \
|
||||
-e DRONE_COMMIT_LINK=https://github.com/lizheming/drone-wechat/compare/master... \
|
||||
-e DRONE_COMMIT_AUTHOR=lizheming \
|
||||
-e DRONE_COMMIT_AUTHOR_EMAIL=secretlzm007@gmail.com \
|
||||
-e DRONE_BUILD_NUMBER=1 \
|
||||
-e DRONE_BUILD_STATUS=success \
|
||||
-e DRONE_BUILD_LINK=http://github.com/lizheming/drone-wechat \
|
||||
-e DRONE_TAG=1.0.0 \
|
||||
-e DRONE_JOB_STARTED=1477550550 \
|
||||
-e DRONE_JOB_FINISHED=1477550750 \
|
||||
lizheming/drone-wechat
|
||||
```
|
||||
|
||||
### With server chan key
|
||||
|
||||
```
|
||||
docker run --rm \
|
||||
-e PLUGIN_SCKEY=xxxx \
|
||||
|
||||
+53
-4
@@ -13,16 +13,65 @@ drone 微信消息通知插件。
|
||||
|
||||
## 简介
|
||||
|
||||
基于 http://sc.ftqq.com/ 封装的 drone 微信消息通知插件。使用前需要去 [Server酱]( http://sc.ftqq.com/) 获取密钥。Github 登录后即可在 [发送消息](http://sc.ftqq.com/?c=code) 页面查看。
|
||||
基于微信企业号封装的 drone 微信消息通知插件。你可以设置自己的企业号,也可以使用 [Server酱]( http://sc.ftqq.com/) 来快速配置微信消息通知功能。如果使用 [Server酱]( http://sc.ftqq.com/) 需要在使用前获取密钥。Github 登录后即可在 [发送消息](http://sc.ftqq.com/?c=code) 页面查看。
|
||||
|
||||
## 配置说明
|
||||
|
||||
- `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_SCKEY`: [Server酱](http://sc.ftqq.com) 申请的密钥
|
||||
- `WECHAT_SCKEY`: `PLUGIN_SCKEY` 别名
|
||||
- `PLUGIN_TITLE`: 消息卡片标题
|
||||
- `PLUGIN_MESSAGE`: 消息卡片正文,支持 Markdown。
|
||||
|
||||
## 如何使用
|
||||
|
||||
### 自行配置微信企业号
|
||||
|
||||
```
|
||||
docker run --rm \
|
||||
-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 \
|
||||
-e DRONE_COMMIT_BRANCH=master \
|
||||
-e DRONE_COMMIT_LINK=https://github.com/lizheming/drone-wechat/compare/master... \
|
||||
-e DRONE_COMMIT_AUTHOR=lizheming \
|
||||
-e DRONE_COMMIT_AUTHOR_EMAIL=secretlzm007@gmail.com \
|
||||
-e DRONE_BUILD_NUMBER=1 \
|
||||
-e DRONE_BUILD_STATUS=success \
|
||||
-e DRONE_BUILD_LINK=http://github.com/lizheming/drone-wechat \
|
||||
-e DRONE_TAG=1.0.0 \
|
||||
-e DRONE_JOB_STARTED=1477550550 \
|
||||
-e DRONE_JOB_FINISHED=1477550750 \
|
||||
lizheming/drone-wechat
|
||||
```
|
||||
|
||||
### 使用Server酱快速集成
|
||||
|
||||
```
|
||||
docker run --rm \
|
||||
-e PLUGIN_SCKEY=xxxx \
|
||||
|
||||
@@ -3,18 +3,116 @@ const render = require('drone-render');
|
||||
const request = require('request-promise-native');
|
||||
|
||||
const {
|
||||
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_SCKEY,
|
||||
WECHAT_SERVER_CHAN_KEY,
|
||||
|
||||
PLUGIN_TITLE,
|
||||
PLUGIN_MESSAGE,
|
||||
SERVER_CHAN_KEY
|
||||
PLUGIN_MESSAGE
|
||||
} = process.env;
|
||||
|
||||
const SCKEY = PLUGIN_SCKEY || SERVER_CHAN_KEY;
|
||||
|
||||
request({
|
||||
url: `https://sc.ftqq.com/${SCKEY}.send`,
|
||||
qs: {
|
||||
text: PLUGIN_TITLE,
|
||||
desp: render(PLUGIN_MESSAGE)
|
||||
function sendMsgFromServerChan() {
|
||||
const SCKEY = PLUGIN_SCKEY || WECHAT_SERVER_CHAN_KEY;
|
||||
if (!SCKEY) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
request({
|
||||
url: `https://sc.ftqq.com/${SCKEY}.send`,
|
||||
qs: {
|
||||
text: PLUGIN_TITLE,
|
||||
desp: render(PLUGIN_MESSAGE)
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getAccessToken() {
|
||||
const CORPID = PLUGIN_CORPID || WECHAT_CORPID;
|
||||
const CORP_SECRET = PLUGIN_CORP_SECRET || WECHAT_CORP_SECRET;
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
sendMsgFromServerChan() || sendMsgFromWechat();
|
||||
module.exports = {
|
||||
sendMsgFromServerChan,
|
||||
getAccessToken,
|
||||
sendMsgFromWork,
|
||||
sendMsgFromWechat
|
||||
};
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "drone-wechat",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"description": "drone wechat notification plugin",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user