[RPA] Call Automation 360 IQ Bot API

使用Microsoft.AspNet.WebApi呼叫Automation 360 IQ Bot的API語法

帳號需要權限: AAE_Basic, AAE_IQ Bot Admin

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Web;

namespace xxx
{
    static class IQBotTool
    {
        private static List<Instance> instances;//實例清單
        private static string Server;//server url
        private static string InstancesPath;//Instance儲存位置
        private static int RetryGet;//server url
        private static int WaitTranning;//Instance儲存位置
        /// <summary>
        /// 先初始化參數才能使用本Tool
        /// </summary>
        /// <param name="server">server url</param>
        /// <param name="instancePath">Instance儲存位置</param>
        /// <param name="retryGet">重下載幾次</param>
        /// <param name="tranningSec">等待解析秒數</param>
        public static void Init(string server, string instancePath, int retryGet, int tranningSec)
        {
            Server = server;
            InstancesPath = instancePath;
            RetryGet = retryGet;
            WaitTranning = tranningSec * 1000;
        }

        /// <summary>
        /// 產生IQ BOT的api元件
        /// </summary>
        /// <param name="Token">認證用(有時效性)</param>
        /// <returns></returns>
        private static HttpClient CreateClient(string Token = null)
        {
            HttpClient client = new HttpClient
            {
                BaseAddress = new Uri(Server)
            };
            if (Token != null)
                client.DefaultRequestHeaders.Add("x-authorization", Token);
            return client;
        }

        /// <summary>
        /// 取得Token
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="PW"></param>
        /// <returns></returns>
        public static string GetToken(string ID, string PW)
        {
            using (var client = CreateClient())
            {
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                var user = new
                {
                    username = ID,
                    password = PW
                };
                HttpResponseMessage response = client.PostAsJsonAsync("v1/authentication", user).Result;
                if (response.IsSuccessStatusCode)
                {
                    dynamic rslt = response.Content.ReadAsAsync<dynamic>().Result;
                    return rslt["token"];
                }
                throw new Exception(response.StatusCode.ToString());
            }
        }

        /// <summary>
        /// 取得已存儲在本機的實例ID
        /// </summary>
        /// <param name="InstanceName">實例名稱</param>
        /// <returns></returns>
        private static string GetInstanceID(string InstanceName)
        {
            string prjId = (from Instance data in GetInstancets()
                            where data.name == InstanceName
                            select data.id).First();
            return prjId;
        }

        /// <summary>
        /// 取得實例ID
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="PW"></param>
        /// <param name="InstanceName">實例名稱</param>
        /// <param name="GetNew">true:從Web重新下載</param>
        /// <returns></returns> 
        public static string GetInstanceID(string ID, string PW, string InstanceName, bool GetNew = false)
        {
            if (!GetNew && GetInstancets() != null)
                return GetInstanceID(InstanceName);
            return GetInstanceID(GetToken(ID, PW), InstanceName, GetNew);
        }

        /// <summary>
        /// 取得實例ID
        /// </summary>
        /// <param name="Token">認證用(有時效性)</param>
        /// <param name="InstanceName">實例名稱</param>
        /// <param name="GetNew">true:從Web重新下載</param>
        /// <returns></returns>
        public static string GetInstanceID(string Token, string InstanceName, bool GetNew = false)
        {
            GetInstances(Token, GetNew);
            return GetInstanceID(InstanceName);
        }

        /// <summary>
        /// 取得已存儲在本機的實例清單
        /// </summary>
        /// <returns></returns>
        private static List<Instance> GetInstancets()
        {
            //暫存檔沒有的話讀檔
            if (instances == null)
            {
                string json = File.ReadAllText(InstancesPath);
                instances = JsonConvert.DeserializeObject<List<Instance>>(json);
            }
            return instances;
        }

        /// <summary>
        /// 取得實例清單
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="PW"></param>
        /// <param name="GetNew">true:重新抓最新的清單</param>
        /// <returns></returns>
        public static List<Instance> GetInstances(string ID, string PW, bool GetNew = false)
        {
            if (!GetNew && GetInstancets() != null)
                return GetInstancets();
            return GetInstances(GetToken(ID, PW), GetNew);
        }

        /// <summary>
        /// 取得實例清單
        /// </summary>
        /// <param name="Token">認證用(有時效性)</param>
        /// <param name="GetNew">true:重新抓最新的清單</param>
        /// <returns></returns>
        public static List<Instance> GetInstances(string Token, bool GetNew = false)
        {
            if (instances == null && !File.Exists(InstancesPath))
                GetNew = true;
            //抓清單
            if (GetNew)
                using (var client = CreateClient(Token))
                {
                    instances = null;
                    HttpResponseMessage response = client.GetAsync("IQBot/api/reporting/projects").Result;
                    if (response.IsSuccessStatusCode)
                    {
                        Instances prj = response.Content.ReadAsAsync<Instances>().Result;
                        string json = JsonConvert.SerializeObject(prj.data);
                        File.WriteAllText(InstancesPath, json);
                    }
                    else
                        throw new Exception(response.StatusCode.ToString());
                }
            return GetInstancets();
        }

        /// <summary>
        /// 上傳解析文件, 並下載到指定位置
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="PW"></param>
        /// <param name="InstanceName">實例名稱</param>
        /// <param name="Upload">上傳完整路徑</param>
        /// <param name="Download">下載完整路徑</param>
        /// <returns>true:成功</returns>
        public static bool Training(string ID, string PW, string InstanceName, string Upload, string Download)
        {
            string token = GetToken(ID, PW);
            string prjId = (from Instance data in GetInstances(token)
                            where data.name == InstanceName
                            select data.id).First();
            return Training(token, prjId, Upload, Download, out string file);
        }

        /// <summary>
        /// 上傳解析文件, 並下載到指定位置
        /// </summary>
        /// <param name="Token">認證用(有時效性)</param>
        /// <param name="InstanceId">實例ID</param>
        /// <param name="Upload">上傳完整路徑</param>
        /// <param name="Download">下載完整路徑</param>
        /// <param name="FileId">下載ID</param>
        /// <returns>true:成功</returns>
        public static bool Training(string Token, string InstanceId, string Upload, string Download, out string FileId)
        {
            using (var client = CreateClient(Token))
            {
                using (var content = new MultipartFormDataContent())
                {
                    var fileStreamContent = new StreamContent(File.OpenRead(Upload));
                    string contentType = MimeMapping.GetMimeMapping(Path.GetFileName(Upload));
                    fileStreamContent.Headers.Add("Content-Type", contentType);
                    content.Add(fileStreamContent, "files", Path.GetFileName(Upload));
                    HttpResponseMessage response = client.PostAsync($"IQBot/gateway/organizations/1/projects/{InstanceId}/files/upload/1", content).Result;
                    if (response.IsSuccessStatusCode)
                    {
                        dynamic rslt = response.Content.ReadAsAsync<dynamic>().Result;
                        FileId = rslt["data"]["uploadedFiles"][0]["fileId"];
                        return GetTraining(Token, InstanceId, FileId, Download);
                    }
                    throw new Exception("上傳錯誤:" + response.StatusCode.ToString());
                }
            }
        }

        /// <summary>
        /// 下載解析結果
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="PW"></param>
        /// <param name="InstanceId">實例ID</param>
        /// <param name="FileId">下載的ID</param>
        /// <param name="Download">下載完整路徑</param>
        /// <returns>true:成功</returns>
        public static bool GetTraining(string ID, string PW, string InstanceId, string FileId, string Download)
        {
            return GetTraining(GetToken(ID, PW), InstanceId, FileId, Download);
        }

        /// <summary>
        /// 下載解析結果
        /// </summary>
        /// <param name="Token">認證用(有時效性)</param>
        /// <param name="InstanceId">實例ID</param>
        /// <param name="FileId">下載的ID</param>
        /// <param name="Download">下載完整路徑</param>
        /// <returns>true:成功;false:沒取到;失敗:丟exception</returns>
        public static bool GetTraining(string Token, string InstanceId, string FileId, string Download)
        {
            using (var client = CreateClient(Token))
            {
                string err = string.Empty;
                for (int i = RetryGet; i > 0; i--)
                {
                    Thread.Sleep(WaitTranning);
                    #region 抓狀態
                    HttpResponseMessage response = client.GetAsync($"IQBot/gateway/learning-instances/{InstanceId}/filestatus/fileid/{FileId}").Result;
                    if (response.IsSuccessStatusCode)
                    {
                        dynamic rslt = response.Content.ReadAsAsync<dynamic>().Result;
                        string success = rslt["success"];
                        if (success.ToLower() == "true")
                        {
                            string status = rslt["data"]["status"];
                            switch (status.ToUpper())
                            {
                                case "IN_VALIDATOR"://需登入control-room人工解析檔案
                                    return false;
                                case "INVALID":
                                    throw new FormatException($"無法解析檔案");
                                case "SUCCESS"://完成
                                    break;
                                default://處理中: YET_TO_BE_CLASSIFIED, CLASSIFIED
                                    continue;
                            }
                        }
                        else
                            throw new FormatException($"解析檔案失敗:{rslt["errors"]}");
                    }
                    else
                        throw new FormatException($"抓取檔案狀態失敗:{response.StatusCode}");
                    #endregion

                    #region 抓檔案
                    response = client.GetAsync($"IQBot/api/backups/{FileId}/download").Result;
                    if (response.IsSuccessStatusCode)
                    {
                        if (response.Content.Headers.ContentType.MediaType != "text/plain")
                            throw new FormatException($"下載檔案為{response.Content.Headers.ContentType.MediaType}檔");
                        string data = response.Content.ReadAsStringAsync().Result;
                        Directory.CreateDirectory(Path.GetDirectoryName(Download));
                        File.WriteAllText(Download, data, Encoding.GetEncoding(950));
                        return true;
                    }
                    #endregion
                }
                return false;
            }
        }
    }
}

實例欄位多, 只用到2欄, 故直接作class來用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace xxx
{
    public class Projects
    {
        public List<Project> data { get; set; }
    }
    public class Project
    {
        public string name { get; set; }
        public string id { get; set; }
    }
}

Taiwan is a country. 臺灣是我的國家