With reference to article www.jianshu.com/p/4aa01c35b… , slightly modified, completed the packet to the pin group code. Add git log. Without further ado. Mainly because dandelion Chinese processing is not very good, directly in the notification to Dingding, add git log.

import groovy.json.JsonSlurper import groovy.json.JsonOutput class ContentModel{ String text String title String picUrl String messageUrl} /** * uploadApk(def path, def apiKey, defpwdDef apkDir = new File(path) def apkDir = new File(path)if(! apkDir.exists()) { throw new RuntimeException("apk output path not exists!")
    }

    def apk = null
    for (int i = apkDir.listFiles().length - 1; i >= 0; i--) {
        File file = apkDir.listFiles()[i]
        if (file.name.endsWith(".apk")) {
            apk = file
            break}}if (apk == null) {
        throw new RuntimeException("apk file not exists!")
    }

    println "*************** start upload file ***************"

    def twoHyphens = "--"
    def boundary = "* * * * * * * * *"
    def end = "\r\n"Def conn = new URL("https://www.pgyer.com/apiv2/app/upload").openConnection()
    conn.setRequestMethod('POST')
    conn.setRequestProperty("Connection"."Keep-Alive")
    conn.setRequestProperty("Charset"."UTF-8")
    conn.setRequestProperty("Content-Type"."multipart/form-data; boundary=" + boundary)
    conn.setDoInput(true)
    conn.setDoOutput(true_api_key def sb = new StringBuilder() sb.append(twoEnd).appEnd (boundary).append(end) s.append (登 记 记)"Content-Disposition: form-data; name=_api_key")
    sb.append(end).append(end)
    sb.append(apiKey).append(end)


//    def desc = "${proc.in.text}"// Add parameters: BuildUpdateDescription Update log, BUILD_NOTES sb. Append (twoanimate).append(boundary).append(end) sb. Append (animate animate)"Content-Disposition: form-data; name=buildUpdateDescription")
    sb.append(end).append(end)
    sb.append("This is Test"(登 记 记).appEnd (end) // To get moving to sb. Append (twoEnd).append(boundary).append(end) sb. Append (登 记 记)"Content-Disposition: form-data; name=buildInstallType")
    sb.append(end).append(end)
    sb.append("2").appEnd (end) // Get moving to the password sb. Append (twoEnd).append(boundary).append(end) sb. Append (登 记 记)"Content-Disposition: form-data; name=buildPassword")
    sb.append(end).append(end)
    sb.append(pwdSb.append (twoEnd).append(boundary).append(end) sb.append(登 记 记)"Content-Disposition: form-data; name=file; filename=").append(apk.getName())
    sb.append(end).append(end)



    def dos = new DataOutputStream(conn.getOutputStream())
    dos.writeBytes(sb.toString())
    dos.flush()
    sb.delete(0, sb.length())

    def fis = new FileInputStream(apk)
    byte[] bf = new byte[8192]
    int len
    while((len = fis.read(bf)) ! = -1) { dos.write(bf, 0, len) } sb.append(end) sb.append(twoHyphens).append(boundary).append(end) dos.writeBytes(sb.toString()) dos.flush() fis.close() dos.close() conn.connect() def text = conn.getContent().text def resp = new JsonSlurper().parseText(text) println text println"*************** upload finish ***************"

    if(resp.code ! = 0) {throw new RuntimeException(resp.message)} println resp // // open short connection // def url ="https://www.pgyer.com/" + resp.data.buildShortcutUrl
//    exec {
//        commandLine "bash"."start", url
//    }

    sendMsgToDing(resp.data, apiKey, pwdTask packageDingTalk {def apkDir = new File() task packageDingTalk {def apkDir = new File()"./build/outputs/apk/debug")
    if(apkDir.exists() && apkDir.isDirectory()){
        apkDir.deleteDir()
    }
    dependsOn("assembleDebug")

    doLast {
        uploadApk("./build/outputs/apk/debug"."Dandelion apikey"."Dandelion Installation Password")
    }
}

task packageReleaseDingTalk {
    def apkDir = new File("./release")
    if(apkDir.exists() && apkDir.isDirectory()){
        apkDir.deleteDir()
    }
    dependsOn("assembleRelease")

    doLast {
        uploadApk("./release"."Dandelion apikey"."Dandelion Installation Password")
    }
}



def sendMsgToDing(def data, def apiKey, def pwd){
    def conn = new URL("Nail robot address").openConnection()
    conn.setRequestMethod('POST')
    conn.setRequestProperty("Connection"."Keep-Alive")
    conn.setRequestProperty("Content-type"."application/json; charset=UTF-8")
    conn.setConnectTimeout(30000)
    conn.setReadTimeout(30000)
    conn.setDoInput(true)
    conn.setDoOutput(true)
    def dos = new DataOutputStream(conn.getOutputStream())
    HashMap<String,Object> map = new HashMap<>()
    map.put("msgtype"."link")
    ContentModel contentModel = new ContentModel()
    def command = """git log -3 --pretty=format:'%s' --abbrev-commit"""// Create the String
    def proc = command.execute()                 // Call *execute* on the string
    proc.waitFor()                               // Wait for the command to finish
// Obtain status and output
    println "return code: ${ proc.exitValue()}"
    println "stderr: ${proc.err.text}"
    def k = proc.in.text.replaceAll("'"."").replaceAll("\n".";")
    println "stdout: ${k}" // *out* from the external program is *in* for groovy
    contentModel.text = k
    contentModel.title= "Your title"
    contentModel.picUrl = data.buildQRCodeURL
    contentModel.messageUrl= "https://www.pgyer.com/apiv2/app/install?_api_key=" + apiKey + "&buildKey="+data.buildKey+"&buildPassword="+pwd
    map.put("link",contentModel)
    def json = JsonOutput.toJson(map)
    println(json)
    dos.writeBytes(json)
    def input = new BufferedReader(new InputStreamReader(conn.getInputStream()))
    String line =""
    String result=""
    while((line = input.readLine()) ! = null) { result += line } dos.flush() dos.close() input.close() conn.connect() println(result) }Copy the code