Skip to content

Commit

Permalink
Merge pull request #5240 from irwinsun/issue_notify_1.5
Browse files Browse the repository at this point in the history
feat: 提供企业微信“蓝盾bot”,用于推送蓝盾相关信息 #3797  [1.5]
  • Loading branch information
irwinsun authored Sep 27, 2021
2 parents 494f3f1 + 75a1224 commit 0a0568b
Show file tree
Hide file tree
Showing 49 changed files with 1,930 additions and 41 deletions.
11 changes: 10 additions & 1 deletion scripts/bkenv.properties
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ BK_SSM_PORT=
BK_TURBO_PRIVATE_URL=http://bk-turbo.service.consul
# BK_TURBO_PUBLIC_URL默认为http://turbo.$BK_DOMAIN. 按需修改. turbo网关
BK_TURBO_PUBLIC_URL=http://turbo.$BK_DOMAIN
# BK_CI_WEWORK_HOST 默认值为:https://qyapi.weixin.qq.com, 企业微信服务端host,用于调用企业微信api接口
BK_CI_WEWORK_HOST=https://qyapi.weixin.qq.com
# BK_CI_WEWORK_API_URL 默认值为:https://qyapi.weixin.qq.com, 企业微信服务端host,用于调用企业微信api接口
BK_CI_WEWORK_API_URL=

##########
# 1-基础配置
Expand Down Expand Up @@ -199,7 +203,12 @@ BK_CI_REPOSITORY_SVN_API_URL=
BK_CI_REPOSITORY_SVN_WEBHOOK_URL=
# BK_CI_STORE_USER_AVATARS_URL默认为$BK_PAAS_PUBLIC_URL/console/static/img/getheadimg.jpg?. 无需修改. PaaS用户头像, 目前仅显示默认头像.
BK_CI_STORE_USER_AVATARS_URL=$BK_PAAS_PUBLIC_URL/console/static/img/getheadimg.jpg?

# BK_CI_FQDN_CERT BKCI站点的HTTPS证书存储位置, 默认值为空表示没有开启HTTPS,用于Agent与BKCI走HTTPS通信使用
BK_CI_FQDN_CERT=
# BK_CI_NOTIFY_WEWORK_API_URL 默认值为:https://qyapi.weixin.qq.com, 企业微信服务端host,用于调用企业微信api接口.
BK_CI_NOTIFY_WEWORK_API_URL=https://qyapi.weixin.qq.com
# BK_CI_NOTIFY_WEWORK_SEND_CHANNEL 发送rtx的通道: weworkAgent 企业微信应用,blueking 蓝鲸消息
BK_CI_NOTIFY_WEWORK_SEND_CHANNEL=weworkAgent
##########
# 4-微服务依赖
##########
Expand Down
1 change: 1 addition & 0 deletions src/backend/ci/boot-assembly/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dependencies {
implementation(project(":core:log:biz-log-sample"))
implementation(project(":core:misc:biz-misc-sample"))
implementation(project(":core:notify:biz-notify-blueking"))
implementation(project(":core:notify:biz-notify-wework"))
implementation(project(":core:openapi:biz-openapi"))
implementation(project(":core:plugin:biz-plugin"))
implementation(project(":core:process:plugin-load"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,13 @@ object OkhttpUtils {
url: String,
uploadFile: File,
headers: Map<String, String?>? = null,
fileFieldName: String = "file"
fileFieldName: String = "file",
fileName: String = uploadFile.name
): Response {
val fileBody = RequestBody.create(octetStream, uploadFile)
val requestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(fileFieldName, uploadFile.name, fileBody)
.addFormDataPart(fileFieldName, fileName, fileBody)
.build()
val requestBuilder = Request.Builder()
.url(url)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ object MQ {
const val QUEUE_PIPELINE_BUILD_FINISH_LOG = "q.engine.pipeline.build.log"
const val QUEUE_PIPELINE_BUILD_FINISH_SUBPIPEINE = "q.engine.pipeline.build.subpipeline"
const val QUEUE_PIPELINE_BUILD_FINISH_WEBHOOK_QUEUE = "q.engine.pipeline.build.finish.webhook.queue"
const val QUEUE_PIPELINE_BUILD_FINISH_NOTIFY_QUEUE = "q.engine.pipeline.build.finish.notify.queue"

const val QUEUE_PIPELINE_BUILD_FINISH_EXT = "q.engine.pipeline.build.finish.ext"
const val QUEUE_PIPELINE_BUILD_FINISH_DISPATCHER = "q.engine.pipeline.build.dispatcher"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ enum class NotifyType {
RTX,
EMAIL,
WECHAT,
SMS
SMS,
WEWORK
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ const val QUEUE_NOTIFY_RTX = "queue_notify_rtx"
const val QUEUE_NOTIFY_WECHAT = "queue_notify_wechat"
const val QUEUE_NOTIFY_EMAIL = "queue_notify_email"
const val QUEUE_NOTIFY_SMS = "queue_notify_sms"
const val QUEUE_NOTIFY_WEWORK = "queue_notify_wework"
const val EXCHANGE_NOTIFY = "exchange_notify"
const val ROUTE_RTX = "rtx"
const val ROUTE_WECHAT = "wechat"
const val ROUTE_EMAIL = "email"
const val ROUTE_SMS = "sms"
const val ROUTE_WEWORK = "wework"

const val PIPELINE_QUALITY_AUDIT_NOTIFY_TEMPLATE = "QUALITY_AUDIT_NOTIFY_TEMPLATE"
const val PIPELINE_QUALITY_END_NOTIFY_TEMPLATE = "QUALITY_END_NOTIFY_TEMPLATE"
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import java.io.InputStream
@ApiModel("企业微信文本消息")
data class WeworkNotifyMediaMessage(
@ApiModelProperty("接收人Id", required = true)
val receivers: List<String>,
val receivers: Collection<String>,
@ApiModelProperty("接收人类型", required = true)
val receiverType: WeworkReceiverType,
@ApiModelProperty("媒体内容", required = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import io.swagger.annotations.ApiModelProperty
@ApiModel("企业微信多媒体消息")
data class WeworkNotifyTextMessage(
@ApiModelProperty("接收人Id", required = true)
val receivers: List<String>,
val receivers: Collection<String>,
@ApiModelProperty("接收人类型", required = true)
val receiverType: WeworkReceiverType,
@ApiModelProperty("文本内容类型", required = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ import com.tencent.devops.notify.pojo.WeworkNotifyMediaMessage
import com.tencent.devops.notify.pojo.WeworkNotifyTextMessage
import com.tencent.devops.notify.service.WeworkService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.context.annotation.Configuration

@Service
@Suppress("ALL")
class WeworkServiceImpl @Autowired constructor() : WeworkService {
@Configuration
@ConditionalOnProperty(prefix = "notify", name = ["weworkChannel"], havingValue = "blueking")
class BlueKingWeworkServiceImpl @Autowired constructor() : WeworkService {

override fun sendMediaMessage(weworkNotifyMediaMessage: WeworkNotifyMediaMessage) {
TODO("Not yet implemented")
Expand Down
34 changes: 34 additions & 0 deletions src/backend/ci/core/notify/biz-notify-wework/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
*
* A copy of the MIT License is included in this file.
*
*
* Terms of the MIT License:
* ---------------------------------------------------
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
* the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

dependencies {
implementation(project(":core:notify:api-notify"))
implementation(project(":core:notify:biz-notify"))
implementation(project(":core:notify:model-notify"))
implementation(project(":core:common:common-db"))
implementation(project(":core:common:common-notify"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.tencent.devops.notify.wework.config

import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Configuration

@Configuration
class WeworkConfiguration {

@Value("\${wework.corpId:}")
lateinit var corpId: String

@Value("\${wework.corpSecret:}")
lateinit var corpSecret: String

@Value("\${wework.apiUrl:https://qyapi.weixin.qq.com}")
lateinit var apiUrl: String

@Value("\${wework.agentId:}")
lateinit var agentId: String

@Value("\${wework.tempDirectory:}")
lateinit var tempDirectory: String

/**
* 表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0
*/
@Value("\${wework.safe:#{null}}")
val safe: String? = null

/**
* 表示是否开启重复消息检查,0表示否,1表示是,默认0
*/
@Value("\${wework.enableDuplicateCheck:#{null}}")
val enableDuplicateCheck: String? = null

/**
* 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
*/
@Value("\${wework.duplicateCheckInterval:#{null}}")
val duplicateCheckInterval: String? = null

/**
* 表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。
*/
@Value("\${wework.enableIdTrans:#{null}}")
val enableIdTrans: String? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.tencent.devops.notify.wework.pojo

import com.fasterxml.jackson.annotation.JsonProperty

@Suppress("UnnecessaryAbstractClass")
abstract class AbstractSendMessageRequest(
/**
* 企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
*/
@JsonProperty("agentid")
@get:JsonProperty("agentid")
open val agentId: Int,
@JsonProperty("duplicate_check_interval")
/**
* 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
*/
open val duplicateCheckInterval: Int? = null,
/**
* 表示是否开启重复消息检查,0表示否,1表示是,默认0
*/
@JsonProperty("enable_duplicate_check")
@get:JsonProperty("enable_duplicate_check")
open val enableDuplicateCheck: Int? = null,
@JsonProperty("msgtype")
@get:JsonProperty("msgtype")
open val msgType: String,
/**
* 表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0
*/
@JsonProperty("safe")
@get:JsonProperty("safe")
open val safe: Int? = null,
/**
* 指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。
* 当touser为”@all”时忽略本参数
*/
@JsonProperty("toparty")
@get:JsonProperty("toparty")
open val toParty: String = "",
/**
* 指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。
* 当touser为”@all”时忽略本参数
*/
@JsonProperty("totag")
@get:JsonProperty("totag")
open val toTag: String = "",
/**
* 指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。
* 特殊情况:指定为”@all”,则向该企业应用的全部成员发送
*/
@JsonProperty("touser")
@get:JsonProperty("touser")
open val toUser: String = ""
) {
data class MediaMessageContent(
/**
* 媒体文件id,可以调用上传临时素材接口获取
*/
@JsonProperty("media_id")
@get:JsonProperty("media_id")
val mediaId: String,
/**
* 视频消息的标题,不超过128个字节,超过会自动截断,视频才有
*/
@JsonProperty("description")
@get:JsonProperty("description")
var description: String? = null,
/**
* 视频消息的描述,不超过512个字节,超过会自动截断,视频才有
*/
@JsonProperty("title")
@get:JsonProperty("title")
var title: String? = null
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.tencent.devops.notify.wework.pojo

import com.fasterxml.jackson.annotation.JsonProperty

data class AccessTokenResp(
@JsonProperty("access_token")
val accessToken: String?,
@JsonProperty("errcode")
val errCode: Int?,
@JsonProperty("errmsg")
val errMsg: String?,
@JsonProperty("expires_in")
val expiresIn: Int?
) {
fun isOk(): Boolean {
return errCode == 0 && accessToken != null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.tencent.devops.notify.wework.pojo

data class FileSendMessageRequest(
override val agentId: Int,
override val duplicateCheckInterval: Int?,
override val enableDuplicateCheck: Int?,
override val safe: Int?,
override val toParty: String,
override val toTag: String,
override val toUser: String,
val file: MediaMessageContent
) : AbstractSendMessageRequest(
agentId = agentId,
duplicateCheckInterval = duplicateCheckInterval,
enableDuplicateCheck = enableDuplicateCheck,
msgType = "file",
safe = safe,
toParty = toParty,
toTag = toTag,
toUser = toUser
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.tencent.devops.notify.wework.pojo

data class ImageSendMessageRequest(
override val agentId: Int,
override val duplicateCheckInterval: Int?,
override val enableDuplicateCheck: Int?,
override val safe: Int?,
override val toParty: String,
override val toTag: String,
override val toUser: String,
val image: MediaMessageContent
) : AbstractSendMessageRequest(
agentId = agentId,
duplicateCheckInterval = duplicateCheckInterval,
enableDuplicateCheck = enableDuplicateCheck,
msgType = "image",
safe = safe,
toParty = toParty,
toTag = toTag,
toUser = toUser
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.tencent.devops.notify.wework.pojo

data class MarkdownSendMessageRequest(
override val agentId: Int,
override val duplicateCheckInterval: Int?,
override val enableDuplicateCheck: Int?,
override val safe: Int?,
override val toParty: String,
override val toTag: String,
override val toUser: String,
val markdown: TextMessageContent
) : AbstractSendMessageRequest(
agentId = agentId,
duplicateCheckInterval = duplicateCheckInterval,
enableDuplicateCheck = enableDuplicateCheck,
msgType = "markdown",
safe = safe,
toParty = toParty,
toTag = toTag,
toUser = toUser
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.tencent.devops.notify.wework.pojo

import com.fasterxml.jackson.annotation.JsonProperty

data class SendMessageResp(
@JsonProperty("errcode")
val errCode: Int?,
@JsonProperty("errmsg")
val errMsg: String?,
@JsonProperty("invalidparty")
val invalidParty: String?,
@JsonProperty("invalidtag")
val invalidTag: String?,
@JsonProperty("invaliduser")
val invalidUser: String?
)
Loading

0 comments on commit 0a0568b

Please sign in to comment.