public static async void SendHeartbeat(string reason)
        {
            string jwt    = FileManager.getItemAsString("jwt");
            bool   online = await IsOnlineAsync();

            if (online && jwt != null)
            {
                string version = Constants.EditorVersion;

                JsonObject jsonObj = new JsonObject();
                jsonObj.Add("version", SoftwareCoPackage.GetVersion());
                jsonObj.Add("os", SoftwareCoPackage.GetOs());
                jsonObj.Add("pluginId", Constants.PluginId);
                jsonObj.Add("start", SoftwareCoUtil.GetNowInSeconds());
                jsonObj.Add("trigger_annotation", reason);
                jsonObj.Add("hostname", SoftwareCoUtil.getHostname());

                string api      = "/data/heartbeat";
                string jsonData = jsonObj.ToString();
                HttpResponseMessage response = await SoftwareHttpManager.SendRequestAsync(HttpMethod.Post, api, jsonData, jwt);

                if (!SoftwareHttpManager.IsOk(response))
                {
                    Logger.Warning("Code Time: Unable to send heartbeat");
                }
            }
        }
        public static async Task <string> GetAppJwtAsync(bool online)
        {
            try
            {
                if (online)
                {
                    long seconds = SoftwareCoUtil.GetNowInSeconds();
                    HttpResponseMessage response = await SoftwareHttpManager.SendRequestAsync(
                        HttpMethod.Get, "/data/apptoken?token=" + seconds, null);

                    if (SoftwareHttpManager.IsOk(response))
                    {
                        string responseBody = await response.Content.ReadAsStringAsync();

                        IDictionary <string, object> jsonObj = (IDictionary <string, object>)SimpleJson.DeserializeObject(responseBody, new Dictionary <string, object>());
                        jsonObj.TryGetValue("jwt", out object jwtObj);
                        string app_jwt = (jwtObj == null) ? null : Convert.ToString(jwtObj);
                        return(app_jwt);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("GetAppJwtAsync, error: " + ex.Message, ex);
            }

            return(null);
        }
        public static async Task <bool> IsOnlineAsync()
        {
            long nowInSec         = SoftwareCoUtil.GetNowInSeconds();
            long thresholdSeconds = nowInSec - lastOnlineCheck;

            if (thresholdSeconds > 60)
            {
                // 3 second timeout
                HttpResponseMessage response = await SoftwareHttpManager.SendRequestAsync(HttpMethod.Get, "/ping", null, 3, null, true /*isOnlineCheck*/);

                isOnline        = SoftwareHttpManager.IsOk(response);
                lastOnlineCheck = nowInSec;
            }

            return(isOnline);
        }