美文网首页
蒲公英:平台分发测试等等:使用脚本快速上传app(包含四个种类:

蒲公英:平台分发测试等等:使用脚本快速上传app(包含四个种类:

作者: 阳光下的叶子呵 | 来源:发表于2022-08-21 13:19 被阅读0次
    利用蒲公英提供的接口,第三方开发者可以把蒲公英提供的应用上传托管、安装等功能,接入到自己的应用中,并且可以根据数据接口,获取蒲公英提供的各种应用数据,以方便开发者更容易的进行内测应用的分发。

    [【蒲公英官方文档 API 2.0】:](https://www.pgyer.com/doc/view/api#listMyReleased)

    因为API 1.0即将废弃,2.0 APP上传文档github:

    快速上传 App

    脚本上传app:包含四个种类:demo.shAppUploadDemo.javademo.jsdemo.php

    通过 API 快速上传 App 到蒲公英平台。github.com代码调用示例:https://github.com/PGYER/pgyer_api_example

    1、获取上传的 token

    通过该接口,开发者可以获取预上传 url 和相关的签名参数

    API地址

    POST https://www.pgyer.com/apiv2/app/getCOSToken

    POST参数

    参数 类型 说明
    _api_key String (必填) API Key [点击获取_api_key](javascript:void(0))
    buildType String (必填) 需要上传的应用类型,ios 或 android
    buildInstallType Integer (选填)应用安装方式,值为(1,2,3,默认为1 公开安装)。1:公开安装,2:密码安装,3:邀请安装
    buildPassword String (选填) 设置App安装密码,密码为空时默认公开安装
    buildUpdateDescription String (选填) 版本更新描述,请传空字符串,或不传。
    buildInstallDate Interger (选填)是否设置安装有效期,值为:1 设置有效时间, 2 长期有效,如果不填写不修改上一次的设置
    buildInstallStartDate String (选填)安装有效期开始时间,字符串型,如:2018-01-01
    buildInstallEndDate String (选填)安装有效期结束时间,字符串型,如:2018-12-31
    buildChannelShortcut String (选填)所需更新的指定渠道的下载短链接,只可指定一个渠道,字符串型,如:abcd

    返回数据

    参数 类型 说明
    key String key 上传文件存储标识唯一 key
    endpoint String 上传文件的 URL
    params Object 上传文件需要的参数,包含signature、x-cos-security-token、key

    2、上传文件到第上一步获取的 URL

    在这一步中上传 App 成功后,App 会自动进入服务器后台队列继续后续的发布流程。所以,在这一步中 App 上传完成后,并不代表 App 已经完成发布。一般来说,一般1分钟以内就能完成发布。要检查是否发布完成,请调用下一步中的 API。

    API地址

    POST 上一步响应中 endpoint 的值

    POST参数

    参数 类型 说明
    key String (必填) 从上一步响应中得到
    signature String (必填) 从上一步响应中得到
    x-cos-security-token String (必填) 从上一步响应中得到
    file String (必填) App 文件的本地路径

    返回数据

    如果上传成功:返回的 http 状态码为 204,内容为空;如果上传失败:返回相应错误信息说明。

    Linux下的curl命令上传App示例

    curl -D - --form-string 'key={key}' --form-string 'signature={signature}' --form-string 'x-cos-security-token={x-cos-security-token}' -F 'file=@/tmp/example.ipa' {endpoint}
    
    

    demo示例:

    第一种 demo.sh:

    #!/bin/bash
    #
    # 通过shell脚本来实现将本地app文件通过API上传到蒲公英
    # https://www.pgyer.com/doc/view/api#fastUploadApp
    ##
    # 参数说明:
    # $1: 蒲公英api_key
    # $2: 要上传的文件路径(ipa/apk)
    #
    
    readonly api_key=$1
    readonly file=$2
    
    printHelp() {
        echo "Usage: $0 api_key file"
        echo "Example: $0 <your_api_key> <your_apk_or_ipa_path>"
    }
    
    # check api_key exists
    if [ -z "$api_key" ]; then
        echo "api_key is empty"
        printHelp
        exit 1
    fi
    
    # check file exists
    if [ ! -f "$file" ]; then
        echo "file not exists"
        printHelp
        exit 1
    fi
    
    if [[ $file =~ ipa$ ]]; then
        app_type="ios"
    elif [[ $file =~ apk$ ]]; then
        app_type="android"
    else
        echo "file type not support"
        printHelp
        exit 1
    fi
    
    # ---------------------------------------------------------------
    # functions
    # ---------------------------------------------------------------
    
    log() {
        echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*"
    }
    
    logTitle() {
        log "-------------------------------- $* --------------------------------"
    }
    
    execCommand() {
        log "$@"
        result=$(eval $@)
    }
    
    # ---------------------------------------------------------------
    # 获取上传凭证
    # ---------------------------------------------------------------
    
    logTitle "获取凭证"
    
    execCommand "curl -s -F '_api_key=${api_key}' -F 'buildType=${app_type}' http://www.pgyer.com/apiv2/app/getCOSToken"
    
    [[ "${result}" =~ \"endpoint\":\"([\:\_\.\/\\A-Za-z0-9\-]+)\" ]] && endpoint=`echo ${BASH_REMATCH[1]} | sed 's!\\\/!/!g'`
    [[ "${result}" =~ \"key\":\"([\.a-z0-9]+)\" ]] && key=`echo ${BASH_REMATCH[1]}`
    [[ "${result}" =~ \"signature\":\"([\=\&\_\;A-Za-z0-9\-]+)\" ]] && signature=`echo ${BASH_REMATCH[1]}`
    [[ "${result}" =~ \"x-cos-security-token\":\"([\_A-Za-z0-9\-]+)\" ]] && x_cos_security_token=`echo ${BASH_REMATCH[1]}`
    
    if [ -z "$key" ] || [ -z "$signature" ] || [ -z "$x_cos_security_token" ] || [ -z "$endpoint" ]; then
        log "get upload token failed"
        exit 1
    fi
    
    # ---------------------------------------------------------------
    # 上传文件
    # ---------------------------------------------------------------
    
    logTitle "上传文件"
    
    execCommand "curl -s -o /dev/null -w '%{http_code}' --form-string 'key=${key}' --form-string 'signature=${signature}' --form-string 'x-cos-security-token=${x_cos_security_token}' -F 'file=@${file}' ${endpoint}"
    if [ $result -ne 204 ]; then
        log "Upload failed"
        exit 1
    fi
    
    # ---------------------------------------------------------------
    # 检查结果
    # ---------------------------------------------------------------
    
    logTitle "检查结果"
    
    for i in {1..60}; do
        execCommand "curl -s http://www.pgyer.com/apiv2/app/buildInfo?_api_key=${api_key}\&buildKey=${key}"
        [[ "${result}" =~ \"code\":([0-9]+) ]] && code=`echo ${BASH_REMATCH[1]}`
        if [ $code -eq 0 ]; then
            log $result
            break
        else
            sleep 1
        fi
    done
    
    

    第二种 demo.php:

    <?php
    /**
     * 通过API上传App到蒲公英的示例代码
     *
     * 更多信息请见: https://www.pgyer.com/doc/view/api#fastUploadApp
     */
    
    const API_KEY_DEV = "";
    const API_KEY_PRODUCTION = "";
    const APP_PATH = "";
    
    // 获取上传凭证和上传地址
    $res = sendRequest("http://www.pgyer.com/apiv2/app/getCOSToken", [
        "_api_key" => API_KEY_PRODUCTION,  // 填写您在平台注册的 API Key
        "buildType" => 'ios',  // 填写应用类型,可选值为: ios、android
        "buildInstallType" => 2,  // 填写安装类型,可选值为: 1 公开, 2密码
        "buildPassword" => '123456',  // 填写密码
    ]);
    $res = json_decode($res, true);
    // _log($res);
    
    if ($res['code'] != 0 || empty($res['data'])) {
        exit($res['message']);
    }
    $key = $res['data']['key'];
    
    // 开始上传
    $params = $res['data']['params'];
    $params['file'] = new CURLFile(APP_PATH);  // 填写待上传文件的路径
    $httpcode = 0;
    
    $result = sendRequest($res['data']['endpoint'], $params, $httpcode);
    if ($httpcode == 204) {
        _log("upload success");
    } else {
        _log("upload failed");
        _log($result);
        exit;
    }
    
    // 获取版本信息
    getBuildInfo("http://www.pgyer.com/apiv2/app/buildInfo?_api_key=" . API_KEY_PRODUCTION . "&buildKey=$key");
    
    // functions
    function sendRequest($url, $params = [], &$httpcode = 0)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
        if (!empty($params)) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        }
    
        $result = curl_exec($ch);
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
        curl_close($ch);
        return $result;
    }
    
    function getBuildInfo($url)
    {
        _log($url);
        for ($i = 0; $i < 60; $i++) {
            $res = json_decode(sendRequest($url), true);
            if ($res['code'] == 0) {
                _log($res['data']);
                break;
            } else {
                _log("[$i] get app build info...");
                sleep(1);
            }
        }
    }
    
    function _log($message) {
        if (is_array($message) || is_object($message)) {
            $message = var_export($message, true);
        }
        echo date("Y-m-d H:i:s") . " " . $message . "\n";
    }
    
    

    第三种 AppUploadDemo.java:

    package com.pgyer.app_upload_demo;
    
    import org.json.JSONObject;
    
    import java.io.File;
    import java.io.FilterOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.nio.charset.Charset;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Timer;
    
    /**
     * @describe
     * @author: Caoxy
     * @date: 2022/8/19
     */
    public class AppUploadDemo implements AppUploadDemo.ProgressHttpEntityWrapper.ProgressCallback{
        public static final String API_KEY_DEV = "";//测试环境apikey
        public static final String API_KEY_PRODUCTION = "";//线上环境apikey
        public static final String APP_PATH = "";//文件地址
        public static final String  GET_TOKEN_URL = "https://www.pgyer.com/apiv2/app/getCOSToken";
        public static final int FILE_UPLOAD_SUCCESSFUL = 1001;
    
        private UploadFileToServiceCallback uploadFileToServiceCallback;
        Timer timers = null;
    
    
        //接口方法调用例子开始
        /**
         * 例子
         */
        public void uploadApk(){
            Map<String, String> params = new HashMap<>();
            params.put("_api_key", API_KEY_DEV);
            int buildInstallType = 1;
            params.put("buildInstallType", buildInstallType+"");//buildInstallType 1,2,3,默认为1 公开安装 1:公开安装,2:密码安装,3:邀请安装
            if (buildInstallType == 2) {
                params.put("buildPassword", "");//需要安装密码
            }
            params.put("buildUpdateDescription", "");//版本更新日志
    
            File uploadFile = new File(APP_PATH);//apk文件路径
            params.put("buildType", "android");
            String url = GET_TOKEN_URL;//
            getToken(params, url, new HttpCallback() {
                @java.lang.Override
                public void onSuccess(int code, String data) {
                    JSONObject backData = new JSONObject(responseString);
                    int code = backData.getInt("code");
                    JSONObject jsonObject = backData.getJSONObject("data");
                    if(code == 0 && jsonObject != null){//获取成功
                        JSONObject jsonObjectparams = jsonObject.getJSONObject("params");
                        Map<String, String> params = new HashMap<>();
                        String key = jsonObjectparams.getString("key");
                        params.put("key",key);
                        params.put("signature",jsonObjectparams.getString("signature"));
                        params.put("x-cos-security-token",jsonObjectparams.getString("x-cos-security-token"));
                        String url = jsonObject.getString("endpoint");
                        uploadFilr(params, url, uploadFile, API_KEY_DEV, key);
                    } else {//获取失败
    
                    }
                }
    
                @java.lang.Override
                public void onError(int code, String data) {
    
                }
            })
        }
        /**
         * 例子 上传文件
         * @param url
         */
        public void uploadFilr(Map<String, String> params, String url ,File files, String apikey, String buildKey){
            uploadFileToServer(params, url, files, new UploadFileToServiceCallback() {
                @java.lang.Override
                public void onUploadBack(int code, String msg) {
                    if(code == FILE_UPLOAD_SUCCESSFUL){
                        //数据同步需要时间延时5秒请求同步结果
                        timers = new Timer(5000, new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                if(timers != null){
                                    timers.stop();
                                    timers = null;
                                    String url = "https://www.pgyer.com/apiv2/app/buildInfo?_api_key="+apikey+"&buildKey="+buildKey;
                                    uploadResult(url,uploadFileToServiceCallback);
                                }
                            }
                        });
                        timers.start();
                    }
                }
    
                @java.lang.Override
                public void onPackageSizeComputed(long param1Long) {//上传文件的大小 去做度更新UI
    
                }
    
                @java.lang.Override
                public void onProgressChanged(float param1Long) {//上传文件的进  去做度更新UI
    
                }
    
                @java.lang.Override
                public void onUploadError(int code, String error) {//文件上传失败返回
    
                }
            });
        }
    
        /**
         * 例子 获取同步结果
         * @param url
         */
        public void dataSynchronous(String url){
            uploadResult(url, new HttpCallback() {
                @java.lang.Override
                public void onSuccess(int code, String data) {
                    JSONObject backDatas = new JSONObject(responseString);
                    int code = backDatas.getInt("code");
                    if(code == 0){//上传成功
                        backData = responseString;
                        JSONObject data = backDatas.getJSONObject("data");
                        //返回成功后相关文件信息
                        if (uploadFileToServiceCallback != null) {
                            uploadFileToServiceCallback.onUploadBack(code,responseString);
                        }
                    } else if(code == 1246){//等待同步
                        //数据同步需要时间延时已经延时5秒还在同步中,再2秒后请求同步结果
                        timers = new Timer(2000, new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                if(timers != null){
                                    timers.stop();
                                    timers = null;
                                    dataSynchronous(url);
                                }
                            }
                        });
                        timers.start();
                    } else {//上传失败
                        if (uploadFileToServiceCallback != null) {
                            uploadFileToServiceCallback.onUploadError(code,"上传失败");
                        }
                    }
                }
    
                @java.lang.Override
                public void onError(int code, String data) {
    
                }
            });
        }
        //接口方法调用例子结束
    
        /**
         * 获取文件相关参数
         * @param params
         * @param url
         * @param httpCallback
         */
        public void getToken(Map<String, String> params, String url, HttpCallback httpCallback){
            sendRequest("POST",url, params ,httpCallback);
        }
    
        /**
         * 上传文件
         * @param params
         * @param url
         * @param files
         * @param apikey
         * @param buildKey
         * @param uploadFileToServiceCallback
         */
        public void uploadFileToServer(final Map<String, String> params, String url ,final File files, UploadFileToServiceCallback uploadFileToServiceCallback) {
            this.uploadFileToServiceCallback = uploadFileToServiceCallback;
            // TODO Auto-generated method stub
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        uploadFiles(params, url, files, uploadFileToServiceCallback);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        uploadFileToServiceCallback.onUploadError(-1,e.getMessage());
                    }
                }
            }).start();
        }
    
        /**
         * 上传文件实现
         * @param params
         * @param url
         * @param files
         * @param uploadFileToServiceCallback
         */
        public void uploadFiles(final Map<String, String> params, String url ,final File files, UploadFileToServiceCallback uploadFileToServiceCallback,) {
            // TODO Auto-generated method stub
            HttpClient client = HttpClientBuilder.create().build();// 开启一个客户端 HTTP 请求
            HttpPost post = new HttpPost(url);//创建 HTTP POST 请求
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式
            for(Map.Entry<String, String> entry:params.entrySet()){
                builder.addTextBody(entry.getKey(), entry.getValue());//设置请求参数
            }
            builder.addBinaryBody("file", files);
            if (this.uploadFileToServiceCallback != null)
                this.uploadFileToServiceCallback.onPackageSizeComputed(100);
            HttpEntity entity = builder.build();// 生成 HTTP POST 实体
            post.setEntity(new ProgressHttpEntityWrapper(entity,this));//设置请求参数
            HttpResponse response = client.execute(post);// 发起请求 并返回请求的响应
            int httpCode = response.getStatusLine().getStatusCode();
            if (httpCode == 204) {
                if(uploadFileToServiceCallback != null) {
                    uploadFileToServiceCallback.onUploadBack(FILE_UPLOAD_SUCCESSFUL, "文件上传成功等待同步数据");
                }
            } else {
                if(uploadFileToServiceCallback != null){
                    uploadFileToServiceCallback.onUploadError(httpCode,"上传失败!");
                }
            }
    
        }
    
        /**
         * 获取上传文件后同步信息
         * @param url
         */
        public void uploadResult(String url,HttpCallback httpCallback){
            sendRequest("GET",url, null ,httpCallback);
        }
    
        /**
         * 发起http 请求
         * @param httpModle
         * @param url
         * @param params
         * @param httpCallback
         */
        public void sendRequest(String httpModle, String url, Map<String, String> params, HttpCallback httpCallback){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        HttpClient client = HttpClientBuilder.create().build();// 开启一个客户端 HTTP 请求
                        if(httpModle.equals("GET")){
                            HttpGet httpClient = new HttpGet(url);//创建 HTTP POST 请求
                        } else if(httpModle.equals("POST")){
                            HttpPost httpClient = new HttpPost(url);//创建 HTTP POST 请求
                            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
                            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式
                            for(Map.Entry<String, String> entry:params.entrySet()){
                                builder.addTextBody(entry.getKey(), entry.getValue());//设置请求参数
                                if(entry.getKey().equals("buildUpdateDescription")){
                                    builder.addTextBody(entry.getKey(), entry.getValue(), ContentType.create(entry.getValue(), Charset.forName("UTF-8")));
                                }
                            }
                            HttpEntity entity = builder.build();// 生成 HTTP POST 实体
                            httpClient.setEntity(new HttpEntityWrapper(entity));//设置请求参数
                        }
                        HttpResponse response = client.execute(httpClient);// 发起请求 并返回请求的响应
                        if (response.getStatusLine().getStatusCode() == 200) {
                            String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
                            JSONObject backDatas = new JSONObject(responseString);
                            int code = backDatas.getInt("code");
                            if(httpCallback != null){
                                httpCallback.onSuccess(code,responseString);
                            }
                        }
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        httpCallback.onError(-1,e.getMessage());
                    }
                }
            }).start();
        }
    
        @Override
        public void progress(float progress) {
            uploadFileToServiceCallback.onProgressChanged(progress);
        }
    
        /**
         * 上传文件封装监听
         */
        public class ProgressHttpEntityWrapper extends HttpEntityWrapper {
    
            private final ProgressCallback progressCallback;
    
            public static interface ProgressCallback {
                public void progress(float progress);
            }
    
            public ProgressHttpEntityWrapper(final HttpEntity entity, final ProgressCallback progressCallback) {
                super(entity);
                this.progressCallback = progressCallback;
            }
    
            @Override
            public void writeTo(final OutputStream out) throws IOException {
                this.wrappedEntity.writeTo(out instanceof ProgressFilterOutputStream ? out : new ProgressFilterOutputStream(out, this.progressCallback, getContentLength()));
            }
    
            public static class ProgressFilterOutputStream extends FilterOutputStream {
    
                private final ProgressCallback progressCallback;
                private long transferred;
                private long totalBytes;
    
                ProgressFilterOutputStream(final OutputStream out, final ProgressCallback progressCallback, final long totalBytes) {
                    super(out);
                    this.progressCallback = progressCallback;
                    this.transferred = 0;
                    this.totalBytes = totalBytes;
                }
    
                @Override
                public void write(final byte[] b, final int off, final int len) throws IOException {
                    //super.write(byte b[], int off, int len) calls write(int b)
                    out.write(b, off, len);
                    this.transferred += len;
                    this.progressCallback.progress(getCurrentProgress());
                }
    
                @Override
                public void write(final int b) throws IOException {
                    out.write(b);
                    this.transferred++;
                    this.progressCallback.progress(getCurrentProgress());
                }
    
                private float getCurrentProgress() {
                    return ((float) this.transferred / this.totalBytes) * 100;
                }
    
            }
        }
    
        /**
         * 上传文件监听回调
         */
        public interface UploadFileToServiceCallback {
            //上传成功 或者 同步数据接口成功返回
            void onUploadBack(int code,String msg);
            //上传文件大小
            void onPackageSizeComputed(long param1Long);
            //上传文件进度
            void onProgressChanged(float param1Long);
            //上传失败返回
            void onUploadError(int code,String error);
        }
    
        /**
         * http 请求回调
         */
        public interface HttpCallback{
            void onSuccess(int code, String data){
    
            }
            void onError(int code, String data){
    
            }
        }
    }
    
    

    第四种 demo.js:

    // 此 Demo 用演示如何使用 PGYER API 上传 App
    // 详细文档参照 https://www.pgyer.com/doc/view/api#fastUploadApp
    // 适用于 nodejs 项目
    // 本代码需要 npm 包 form-data 支持 运行 npm install --save form-data 即可
    
    const https = require('https');
    const fs = require('fs');
    const querystring = require('querystring');
    const FormData = require('form-data');
    
    const API_KEY_PRODUCTION = '<your api key>';
    const APP_PATH = '<your app path>';
    
    function upload (apiKey, appPath, callback) {
      function getUploadResult (uploadData) {
        const uploadResultRequest = https.request({
          hostname: 'www.pgyer.com',
          path: '/apiv2/app/buildInfo?_api_key=' + apiKey + '&buildKey=' + uploadData.data.key,
          method: 'POST',
          headers: {
            'Content-Type' : 'application/x-www-form-urlencoded',
            'Content-Length' : 0
          }
        }, response => {
          if (response.statusCode !== 200) {
            throw new Error('PGYER Service is down.');
          }
        
          let responseData = '';
          response.on('data', data => {
            responseData += data.toString();
          })
        
          response.on('end', () => {
            const responseText = responseData.toString();
            try {
              const responseInfo = JSON.parse(responseText);
              if (responseInfo.code === 1247) {
                console.log('Parsing App Data ... Please Wait ... \n');
                setTimeout(() => getUploadResult(uploadData), 1000);
              } else if (responseInfo.code) {
                throw new Error('PGYER Service Error > ' + responseInfo.code + ': ' + responseInfo.message);
              }
              callback(responseInfo);
            } catch (error) {
              throw error;
            }
          })
        
        })
      
        uploadResultRequest.write(uploadTokenRequestData);
        uploadResultRequest.end();
      }
    
      function uploadApp(uploadData) {
        const uploadAppRequestData = new FormData()
        uploadAppRequestData.append('signature', uploadData.data.params.signature);
        uploadAppRequestData.append('x-cos-security-token', uploadData.data.params['x-cos-security-token']);
        uploadAppRequestData.append('key', uploadData.data.params.key);
        uploadAppRequestData.append('file', fs.createReadStream(appPath))
        
        uploadAppRequestData.submit(uploadData.data.endpoint, function (error, response) {
          if (response.statusCode === 204) {
            setTimeout(() => getUploadResult(uploadData), 1000);
          } else {
            throw new Error('Upload Error!')
          }
        });
      }
    
      const uploadTokenRequestData = querystring.stringify({
        _api_key: apiKey,  // 填写您在平台注册的 API Key (具体参照文档)
        buildType: 'ios',  // 填写应用类型,可选值为: ios、android (具体参照文档)
        buildInstallType: 2,  // 填写安装类型,可选值为: 1 公开, 2密码 (具体参照文档)
        buildPassword: '123456',  // 填写密码安装时的密码 (具体参照文档)
      });
      
      const uploadTokenRequest = https.request({
        hostname: 'www.pgyer.com',
        path: '/apiv2/app/getCOSToken',
        method: 'POST',
        headers: {
          'Content-Type' : 'application/x-www-form-urlencoded',
          'Content-Length' : uploadTokenRequestData.length
        }
      }, response => {
        if (response.statusCode !== 200) {
          throw new Error('PGYER Service is down.');
        }
      
        let responseData = '';
        response.on('data', data => {
          responseData += data.toString();
        })
      
        response.on('end', () => {
          const responseText = responseData.toString();
          try {
            const responseInfo = JSON.parse(responseText);
            if (responseInfo.code) {
              throw new Error('PGYER Service Error > ' + responseInfo.code + ': ' + responseInfo.message);
            }
            uploadApp(responseInfo);
          } catch (error) {
            throw error;
          }
        })
      
      })
    
      uploadTokenRequest.write(uploadTokenRequestData);
      uploadTokenRequest.end();
    }
    
    // 调用说明:
    // upload(apikey, appPath, successCallback): void
    // apikey: 你的 API Key
    // appPath: 你的 app 路径,绝对路径相对路径均可
    // successCallback: 成功后的回调函数, 传入一个参数为 App 信息 类似如下对象描述
    // {
    //   code: 0,
    //   message: '',
    //   data: {
    //     buildKey: 'xxx',
    //     buildType: '1',
    //     buildIsFirst: '0',
    //     buildIsLastest: '1',
    //     buildFileKey: 'xxx.ipa',
    //     buildFileName: '',
    //     buildFileSize: '40095060',
    //     buildName: 'xxx',
    //     buildVersion: '2.2.0',
    //     buildVersionNo: '1.0.1',
    //     buildBuildVersion: '9',
    //     buildIdentifier: 'xxx.xxx.xxx.xxx',
    //     buildIcon: 'xxx',
    //     buildDescription: '',
    //     buildUpdateDescription: '',
    //     buildScreenshots: '',
    //     buildShortcutUrl: 'xxxx',
    //     buildCreated: 'xxxx-xx-xx xx:xx:xx',
    //     buildUpdated: 'xxxx-xx-xx xx:xx:xx',
    //     buildQRCodeURL: 'https://www.pgyer.com/app/qrcodeHistory/xxxx'
    //   }
    // }
    
    upload(API_KEY_PRODUCTION, APP_PATH, console.log);
    
    结合第四种js:package-lock.json:
    {
      "requires": true,
      "lockfileVersion": 1,
      "dependencies": {
        "asynckit": {
          "version": "0.4.0",
          "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
          "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
        },
        "combined-stream": {
          "version": "1.0.8",
          "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
          "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
          "requires": {
            "delayed-stream": "~1.0.0"
          }
        },
        "delayed-stream": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
          "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
        },
        "form-data": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
          "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
          "requires": {
            "asynckit": "^0.4.0",
            "combined-stream": "^1.0.8",
            "mime-types": "^2.1.12"
          }
        },
        "mime-db": {
          "version": "1.52.0",
          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
          "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
        },
        "mime-types": {
          "version": "2.1.35",
          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
          "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
          "requires": {
            "mime-db": "1.52.0"
          }
        }
      }
    }
    
    

    相关文章

      网友评论

          本文标题:蒲公英:平台分发测试等等:使用脚本快速上传app(包含四个种类:

          本文链接:https://www.haomeiwen.com/subject/tpyvgrtx.html