增加钉钉通知
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package com.pomelotea.hoperun.sign.notify
|
||||
|
||||
import com.alibaba.fastjson.JSON
|
||||
import com.alibaba.fastjson.JSONObject
|
||||
import com.pomelotea.hoperun.sign.api.model.DingTalkMarkdownRequest
|
||||
import com.pomelotea.hoperun.sign.api.model.DingTalkNotifyRequest
|
||||
import com.pomelotea.hoperun.sign.api.model.DingTalkNotifyResponse
|
||||
import com.pomelotea.hoperun.sign.api.model.MarkdownContent
|
||||
import com.pomelotea.hoperun.sign.common.client
|
||||
import com.pomelotea.hoperun.sign.config.DingTalkConfig
|
||||
import com.pomelotea.hoperun.sign.scheduler.AutoDakaScheduler.Companion.logger
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import org.springframework.stereotype.Service
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.Base64
|
||||
import javax.crypto.Mac
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
import kotlin.experimental.and
|
||||
|
||||
@Service
|
||||
open class DingTalkNotifyHelper(
|
||||
private val dingTalkConfig: DingTalkConfig
|
||||
) {
|
||||
|
||||
fun sendText(content: String): DingTalkNotifyResponse {
|
||||
if (!dingTalkConfig.enabled) {
|
||||
logger.info("钉钉通知未启用,跳过发送消息")
|
||||
return DingTalkNotifyResponse(0, "钉钉通知未启用")
|
||||
}
|
||||
|
||||
val request = DingTalkNotifyRequest(
|
||||
text = com.pomelotea.hoperun.sign.api.model.TextContent(content)
|
||||
)
|
||||
|
||||
return sendRequest(request)
|
||||
}
|
||||
|
||||
fun sendMarkdown(title: String, content: String): DingTalkNotifyResponse {
|
||||
if (!dingTalkConfig.enabled) {
|
||||
logger.info("钉钉通知未启用,跳过发送消息")
|
||||
return DingTalkNotifyResponse(0, "钉钉通知未启用")
|
||||
}
|
||||
|
||||
val request = DingTalkMarkdownRequest(
|
||||
markdown = MarkdownContent(title, content)
|
||||
)
|
||||
|
||||
return sendRequest(request)
|
||||
}
|
||||
|
||||
private fun sendRequest(request: Any): DingTalkNotifyResponse {
|
||||
try {
|
||||
val url = generateSignedUrl()
|
||||
val jsonBody = JSON.toJSONString(request)
|
||||
|
||||
logger.info("发送钉钉消息: $jsonBody")
|
||||
|
||||
val httpRequest = Request.Builder()
|
||||
.url(url)
|
||||
.post(jsonBody.toRequestBody("application/json;charset=utf-8".toMediaTypeOrNull()))
|
||||
.build()
|
||||
|
||||
val response = client.newCall(httpRequest).execute()
|
||||
val responseBody = response.body?.string()
|
||||
|
||||
logger.info("钉钉响应: $responseBody")
|
||||
|
||||
return JSONObject.parseObject(responseBody, DingTalkNotifyResponse::class.java)
|
||||
} catch (e: Exception) {
|
||||
logger.error("发送钉钉消息失败", e)
|
||||
return DingTalkNotifyResponse(-1, "发送钉钉消息失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateSignedUrl(): String {
|
||||
val webhook = dingTalkConfig.webhook
|
||||
val secret = dingTalkConfig.secret
|
||||
|
||||
if (secret.isEmpty()) {
|
||||
return webhook
|
||||
}
|
||||
|
||||
val timestamp = System.currentTimeMillis()
|
||||
val sign = generateSign(timestamp.toString(), secret)
|
||||
|
||||
return "$webhook×tamp=$timestamp&sign=$sign"
|
||||
}
|
||||
|
||||
private fun generateSign(timestamp: String, secret: String): String {
|
||||
val stringToSign = "$timestamp\n$secret"
|
||||
val mac = Mac.getInstance("HmacSHA256")
|
||||
mac.init(SecretKeySpec(secret.toByteArray(StandardCharsets.UTF_8), "HmacSHA256"))
|
||||
val signData = mac.doFinal(stringToSign.toByteArray(StandardCharsets.UTF_8))
|
||||
val sign = Base64.getEncoder().encodeToString(signData)
|
||||
return URLEncoder.encode(sign, StandardCharsets.UTF_8.name())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user