20251002 devops notifier

更新 發佈閱讀 38 分鐘

好的,使用 VB.NET 來實現這個自動化需求完全沒有問題。核心邏輯與 PowerShell 版本相同,但我們會使用 .NET 的 HttpClient 來呼叫 REST API,並用 Newtonsoft.Json 來解析回傳的 JSON 資料。 這將是一個主控台應用程式 (Console Application),編譯後產生的 .exe 檔案可以被 Windows 工作排程器每日呼叫。 核心步驟 * 專案設定:建立一個 VB.NET 主控台應用程式,並安裝 Newtonsoft.Json 套件。 * 程式碼實作:編寫程式碼來執行查詢、獲取資料、分組並發送郵件。 * 編譯與排程:將專案編譯成 .exe,並設定工作排程器。 1. 專案設定 * 建立專案: * 打開 Visual Studio。 * 建立一個新的專案 (Create a new project)。 * 選擇 Console App (.NET Framework) 並確定語言是 Visual Basic。 * 為專案命名,例如 DevOpsNotifier。 * 安裝 Newtonsoft.Json 套件: * 在方案總管 (Solution Explorer) 中,對您的專案按右鍵,選擇 管理 NuGet 套件 (Manage NuGet Packages...)。 * 在 瀏覽 (Browse) 標籤頁中,搜尋 Newtonsoft.Json。 * 找到 Newtonsoft.Json 並點擊 安裝 (Install)。 2. 程式碼 將以下所有程式碼複製並貼到您的 Module1.vb 檔案中,完全覆蓋原有內容。 Imports System.Net.Http Imports System.Net.Http.Headers Imports System.Text Imports Newtonsoft.Json Imports System.Net.Mail Module Module1 ' ========================【請修改以下設定】======================== ' 你的 Azure DevOps Server URL 和專案名稱 Private Const organizationUrl As String = "https://tfs.yourcompany.com/DefaultCollection" Private Const projectName As String = "YourProjectName" ' 你的個人存取權杖 (PAT) Private Const pat As String = "YOUR_PERSONAL_ACCESS_TOKEN" ' 你已經建立好的查詢 ID Private Const queryId As String = "YOUR_QUERY_ID" ' SMTP 伺服器設定 (用於發送郵件) Private Const smtpServer As String = "smtp.yourcompany.com" Private Const smtpPort As Integer = 25 ' 或 587 等 Private Const emailFrom As String = "devops-no-reply@yourcompany.com" ' ================================================================= ' 建立一個靜態的 HttpClient 實例以供重複使用 Private ReadOnly httpClient As New HttpClient() Async Function Main() As Task ' 設定 HttpClient 的基礎驗證標頭 httpClient.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($":{pat}"))) Console.WriteLine("開始執行 Azure DevOps 工作項目到期通知...") Try ' 步驟 1: 執行查詢以獲取 ID Console.WriteLine("正在執行查詢...") Dim workItemRefs = Await GetWorkItemIdsAsync() If workItemRefs Is Nothing OrElse workItemRefs.Count = 0 Then Console.WriteLine("沒有找到 30 天內即將到期的工作項目。") Return End If Console.WriteLine($"找到 {workItemRefs.Count} 個工作項目。") ' 步驟 2: 根據 ID 獲取詳細資訊 Console.WriteLine("正在批次獲取工作項目詳細資訊...") Dim workItemDetails = Await GetWorkItemDetailsAsync(workItemRefs.Select(Function(wi) wi.id).ToList()) ' 步驟 3: 按負責人分組 Console.WriteLine("正在按負責人分組...") Dim notifications = GroupItemsByUser(workItemDetails) ' 步驟 4: 發送通知郵件 Console.WriteLine("正在發送通知郵件...") For Each entry In notifications SendNotificationEmail(entry.Key, entry.Value) Next Console.WriteLine("所有通知已處理完畢。") Catch ex As Exception Console.ForegroundColor = ConsoleColor.Red Console.WriteLine($"發生錯誤: {ex.Message}") Console.ResetColor() End Try End Function ' 執行查詢並返回工作項目 ID 列表 Private Async Function GetWorkItemIdsAsync() As Task(Of List(Of WorkItemReference)) Dim queryUrl = $"{organizationUrl}/{projectName}/_apis/wit/wiql/{queryId}?api-version=7.0" Using response = Await httpClient.PostAsync(queryUrl, Nothing) response.EnsureSuccessStatusCode() Dim jsonString = Await response.Content.ReadAsStringAsync() Dim result = JsonConvert.DeserializeObject(Of QueryResult)(jsonString) Return result.workItems End Using End Function ' 批次獲取工作項目的詳細資訊 Private Async Function GetWorkItemDetailsAsync(ids As List(Of Integer)) As Task(Of List(Of WorkItemDetail)) Dim idsString = String.Join(",", ids) Dim fields = "System.Id,System.Title,System.State,System.AssignedTo,Microsoft.VSTS.Scheduling.TargetDate" Dim detailsUrl = $"{organizationUrl}/_apis/wit/workitems?ids={idsString}&fields={fields}&$expand=all&api-version=7.0" Using response = Await httpClient.GetAsync(detailsUrl) response.EnsureSuccessStatusCode() Dim jsonString = Await response.Content.ReadAsStringAsync() Dim result = JsonConvert.DeserializeObject(Of WorkItemDetailList)(jsonString) Return result.value End Using End Function ' 將工作項目按負責人 Email 分組 Private Function GroupItemsByUser(details As List(Of WorkItemDetail)) As Dictionary(Of String, List(Of NotificationItem)) Dim groupedItems = New Dictionary(Of String, List(Of NotificationItem))() For Each item In details ' 檢查是否有指派負責人 If item.fields.AssignedTo IsNot Nothing AndAlso Not String.IsNullOrEmpty(item.fields.AssignedTo.uniqueName) Then Dim userEmail = item.fields.AssignedTo.uniqueName Dim dueDate = item.fields.TargetDate Dim notificationItem = New NotificationItem With { .Id = item.id, .Title = item.fields.Title, .Url = item.url.Replace("_apis/wit/workItems", "_workitems/edit"), ' 轉換為網頁連結 .DueDate = dueDate.ToString("yyyy-MM-dd") } If Not groupedItems.ContainsKey(userEmail) Then groupedItems(userEmail) = New List(Of NotificationItem)() End If groupedItems(userEmail).Add(notificationItem) End If Next Return groupedItems End Function ' 發送單一郵件給指定使用者 Private Sub SendNotificationEmail(emailTo As String, items As List(Of NotificationItem)) Try Dim mailMessage As New MailMessage(emailFrom, emailTo) mailMessage.Subject = $"【Azure DevOps 通知】您有 {items.Count} 個工作項目即將到期" mailMessage.IsBodyHtml = True Dim bodyBuilder As New StringBuilder() bodyBuilder.AppendLine("<html><head><style>body { font-family: 'Segoe UI', sans-serif; } table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid #dddddd; text-align: left; padding: 8px; } th { background-color: #f2f2f2; }</style></head><body>") bodyBuilder.AppendLine("<h2>您好,</h2>") bodyBuilder.AppendLine("<p>系統提醒您,以下工作項目將在 30 天內到期,請及時處理:</p>") bodyBuilder.AppendLine("<table><tr><th>ID</th><th>標題</th><th>到期日</th></tr>") For Each item In items bodyBuilder.AppendLine($"<tr><td><a href='{item.Url}'>{item.Id}</a></td><td>{item.Title}</td><td>{item.DueDate}</td></tr>") Next bodyBuilder.AppendLine("</table><br><p>此為系統自動發送的郵件,請勿直接回覆。</p></body></html>") mailMessage.Body = bodyBuilder.ToString() Dim smtpClient As New SmtpClient(smtpServer, smtpPort) ' 如果你的 SMTP 伺服器需要帳號密碼驗證,請取消註解並填入以下程式碼 ' smtpClient.Credentials = New System.Net.NetworkCredential("username", "password") ' smtpClient.EnableSsl = True smtpClient.Send(mailMessage) Console.WriteLine($"已成功發送通知郵件至: {emailTo}") Catch ex As Exception Console.ForegroundColor = ConsoleColor.Yellow Console.WriteLine($"發送郵件至 {emailTo} 失敗: {ex.Message}") Console.ResetColor() End Try End Sub End Module ' --- 以下是用於解析 JSON 回應的資料模型 --- Public Class QueryResult Public Property workItems As List(Of WorkItemReference) End Class Public Class WorkItemReference Public Property id As Integer End Class Public Class WorkItemDetailList Public Property value As List(Of WorkItemDetail) End Class Public Class WorkItemDetail Public Property id As Integer Public Property url As String Public Property fields As WorkItemFields End Class Public Class WorkItemFields <JsonProperty("System.Title")> Public Property Title As String <JsonProperty("System.AssignedTo")> Public Property AssignedTo As AssignedToUser <JsonProperty("Microsoft.VSTS.Scheduling.TargetDate")> Public Property TargetDate As DateTime End Class Public Class AssignedToUser Public Property uniqueName As String End Class ' --- 用於組織通知內容的輔助類別 --- Public Class NotificationItem Public Property Id As Integer Public Property Title As String Public Property Url As String Public Property DueDate As String End Class 3. 編譯與排程 * 修改設定: * 在程式碼頂端的設定區塊,填入您自己的 organizationUrl, projectName, pat, queryId, 和 SMTP 伺服器資訊。 * 編譯專案: * 在 Visual Studio 的頂端選單,選擇 建置 (Build) -> 建置方案 (Build Solution)。 * 建置成功後,到您的專案資料夾底下 bin/Debug (或 bin/Release) 中,找到產生的 .exe 檔案 (例如 DevOpsNotifier.exe)。 * 設定工作排程器: * 開啟 Windows 工作排程器 (Task Scheduler)。 * 建立工作 (Create Task)... * 一般 (General):填寫名稱,例如 "Azure DevOps Due Date Notifier"。 * 觸發程序 (Triggers):新增一個觸發程序,設定為 每日 (Daily),並選擇一個執行時間。 * 動作 (Actions):新增一個動作。 * 動作:啟動程式 (Start a program)。 * 程式/指令碼:點擊 瀏覽 (Browse...) 並選擇您剛剛編譯好的 .exe 檔案路徑。 * 儲存工作排程。 現在,這個 VB.NET 程式就會在您指定的時間自動運行,完成通知任務。


好的,收到。既然 TLS 1.2 也不是問題所在,代表我們已經排除了最常見的環境設定錯誤。現在我們需要進入更深層的偵錯。 400 錯誤依然指向我們的程式送出的請求「格式有問題」。既然 URL 沒錯、PAT 權限也夠,問題很可能出在 HTTP 標頭 (Headers) 或 請求主體 (Body) 的細微之處,這些是瀏覽器會自動處理,但 HttpClient 需要我們明確設定的地方。 核心診斷:捕獲伺服器真正的錯誤訊息 目前我們的程式碼只知道「失敗了 (400)」,但不知道伺服器為什麼認為這個請求是錯的。400 錯誤的回應中,通常會包含一個 JSON 物件,裡面有更詳細的錯誤說明。 我們現在修改程式碼,目標是無論成功或失敗,都把伺服器回傳的內容印出來,這樣就能看到最關鍵的線索。 同時,我們會模擬瀏覽器的行為,加上一些 HttpClient 預設不會加上的標頭。 解決方案:升級偵錯程式碼 請用以下完整更新的 Module1.vb 程式碼替換掉您現有的版本。這個版本做了幾項關鍵修改: * 新增 User-Agent 標頭:讓請求看起來更像一個合法的用戶端。 * 明確指定 Content-Type:在 POST 請求中,明確告知伺服器我們發送的是 JSON 格式。 * 捕獲並印出詳細錯誤:這是最重要的,在請求失敗時,讀取並印出伺服器的錯誤訊息內文。 <!-- end list --> Imports System.Net.Http Imports System.Net.Http.Headers Imports System.Text Imports Newtonsoft.Json Imports System.Net.Mail Module Module1 ' ========================【請修改以下設定】======================== Private Const organizationUrl As String = "https://tfs.yourcompany.com/DefaultCollection" Private Const projectName As String = "YourProjectName" Private Const pat As String = "YOUR_PERSONAL_ACCESS_TOKEN" Private Const queryId As String = "YOUR_QUERY_ID" Private Const smtpServer As String = "smtp.yourcompany.com" Private Const smtpPort As Integer = 25 Private Const emailFrom As String = "devops-no-reply@yourcompany.com" ' ================================================================= Private ReadOnly httpClient As New HttpClient() Sub Main() ' 強制使用 TLS 1.2 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 ' 設定基礎驗證標頭 httpClient.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($":{pat}"))) ' 【修改】新增通用標頭,模擬瀏覽器行為 httpClient.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json")) httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36") RunAsync().Wait() End Sub Async Function RunAsync() As Task Console.WriteLine("開始執行 Azure DevOps 工作項目到期通知...") Try Dim workItemRefs = Await GetWorkItemIdsAsync() If workItemRefs Is Nothing OrElse workItemRefs.Count = 0 Then Console.WriteLine("沒有找到 30 天內即將到期的工作項目。") Return End If Console.WriteLine($"找到 {workItemRefs.Count} 個工作項目。") Dim workItemDetails = Await GetWorkItemDetailsAsync(workItemRefs.Select(Function(wi) wi.id).ToList()) Dim notifications = GroupItemsByUser(workItemDetails) ' ... (發送郵件的邏輯不變) Catch ex As Exception Console.ForegroundColor = ConsoleColor.Red Console.WriteLine($"[執行階段捕捉到例外] 錯誤: {ex.Message}") Console.ResetColor() End Try Console.WriteLine("按任意鍵結束...") Console.ReadKey() End Function ' 【修改】徹底改寫此函式以進行深度偵錯 Private Async Function GetWorkItemIdsAsync() As Task(Of List(Of WorkItemReference)) Dim queryUrl = $"{organizationUrl}/{projectName}/_apis/wit/wiql/{queryId}?api-version=7.0" Console.WriteLine($"[DEBUG] 正在 POST 請求 Query URL: {queryUrl}") ' 【修改】明確設定 POST 請求的內容和標頭 Dim request As New HttpRequestMessage(HttpMethod.Post, queryUrl) request.Content = New StringContent("", Encoding.UTF8, "application/json") ' Body 為空,但明確指定 Content-Type Using response = Await httpClient.SendAsync(request) Dim responseBody = Await response.Content.ReadAsStringAsync() If Not response.IsSuccessStatusCode Then Console.ForegroundColor = ConsoleColor.Red Console.WriteLine($"請求失敗! 狀態碼: {response.StatusCode} ({(Int32)response.StatusCode})") Console.WriteLine("==== 伺服器回應內容 ====") Console.WriteLine(responseBody) Console.WriteLine("========================") Throw New Exception("查詢工作項目ID失敗。") End If Console.WriteLine("查詢 ID 成功。") Dim result = JsonConvert.DeserializeObject(Of QueryResult)(responseBody) Return result.workItems End Using End Function ' 【修改】徹底改寫此函式以進行深度偵錯 Private Async Function GetWorkItemDetailsAsync(ids As List(Of Integer)) As Task(Of List(Of WorkItemDetail)) Dim idsString = String.Join(",", ids) Dim fields = "System.Id,System.Title,System.State,System.AssignedTo,Microsoft.VSTS.Scheduling.TargetDate" Dim detailsUrl = $"{organizationUrl}/_apis/wit/workitems?ids={idsString}&fields={fields}&$expand=all&api-version=7.0" Console.WriteLine($"[DEBUG] 正在 GET 請求 Details URL: {detailsUrl}") Using response = Await httpClient.GetAsync(detailsUrl) Dim responseBody = Await response.Content.ReadAsStringAsync() If Not response.IsSuccessStatusCode Then Console.ForegroundColor = ConsoleColor.Red Console.WriteLine($"請求失敗! 狀態碼: {response.StatusCode} ({(Int32)response.StatusCode})") Console.WriteLine("==== 伺服器回應內容 ====") Console.WriteLine(responseBody) Console.WriteLine("========================") Throw New Exception("獲取工作項目詳情失敗。") End If Console.WriteLine("獲取詳情成功。") Dim result = JsonConvert.DeserializeObject(Of WorkItemDetailList)(responseBody) Return result.value End Using End Function ' (GroupItemsByUser 和 SendNotificationEmail 函式保持不變) '... End Module 執行步驟 * 用上面的程式碼完整替換您的 Module1.vb。 * 重新建置並執行。 * 現在,當 400 錯誤發生時,程式不會立刻崩潰,而是會印出一個區塊,標題是 ==== 伺服器回應內容 ====。 * 請將這個區塊裡的完整內容貼給我。這就是伺服器告訴我們的、最直接的錯誤原因,通常會包含像 "Invalid query id" 或 "VS402327: The value for parameter '...' is not supported." 這樣的關鍵訊息。 有了這個訊息,我們就能 100% 確定問題的根源並解決它。



太好了!這是最有價值的一條線索!這則錯誤訊息非常精準。


留言
avatar-img
Pocheng Chiu的沙龍
0會員
24內容數
Pocheng Chiu的沙龍的其他內容
2025/10/01
好的,直接從 Azure DevOps Server 資料庫中抓取各專案的管理者權限使用者,需要查詢您的專案集合 (Project Collection) 資料庫。 核心原則 使用者權限是透過成為特定群組(例如 "Project Administrators")的成員來賦予的。因此,查詢的邏輯是:
2025/10/01
好的,直接從 Azure DevOps Server 資料庫中抓取各專案的管理者權限使用者,需要查詢您的專案集合 (Project Collection) 資料庫。 核心原則 使用者權限是透過成為特定群組(例如 "Project Administrators")的成員來賦予的。因此,查詢的邏輯是:
2025/10/01
好的,這是一個非常核心的開發問題。要看到 VB 與 SQL 之間更詳細的紀錄,可以從「SQL Server 端」、「VB 應用程式端」以及「中間攔截」三個層面切入。 核心策略 * 從 SQL Server 下手:看資料庫實際收到了什麼 這是最直接、最準確的方式,能看到任何應用程式(不只你的
2025/10/01
好的,這是一個非常核心的開發問題。要看到 VB 與 SQL 之間更詳細的紀錄,可以從「SQL Server 端」、「VB 應用程式端」以及「中間攔截」三個層面切入。 核心策略 * 從 SQL Server 下手:看資料庫實際收到了什麼 這是最直接、最準確的方式,能看到任何應用程式(不只你的
2025/10/01
了解,你的重點是「如何用 VB.NET 動態產生包含訂單資訊的信件內文 (HTML Body)」,以便寄給業務。 核心是使用 StringBuilder 來有效率地組合 HTML 字串,並將解析後的 EDI 資料填入其中。 最佳實踐:使用 StringBuilder 當需要組合複雜或多行字串時,Sy
2025/10/01
了解,你的重點是「如何用 VB.NET 動態產生包含訂單資訊的信件內文 (HTML Body)」,以便寄給業務。 核心是使用 StringBuilder 來有效率地組合 HTML 字串,並將解析後的 EDI 資料填入其中。 最佳實踐:使用 StringBuilder 當需要組合複雜或多行字串時,Sy
看更多
你可能也想看
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
前面已經安裝好IIS後,並且也新建站台了,那麼接下來這篇就會分享如何使用它
Thumbnail
前面已經安裝好IIS後,並且也新建站台了,那麼接下來這篇就會分享如何使用它
Thumbnail
Node.js是一個JavaScript運行環境。它使用了一個非阻塞、事件驅動的I/O模型,使其非常適合用於數據密集型的即時應用程序。簡單來說,Node.js允許你使用JavaScript來編寫伺服器端代碼。 nvm 安裝nvm Windows : 點擊 Releases · coreybut
Thumbnail
Node.js是一個JavaScript運行環境。它使用了一個非阻塞、事件驅動的I/O模型,使其非常適合用於數據密集型的即時應用程序。簡單來說,Node.js允許你使用JavaScript來編寫伺服器端代碼。 nvm 安裝nvm Windows : 點擊 Releases · coreybut
Thumbnail
接續上一篇 Step2:VC#專案建立 Step3:IIS新建站台 Step4:VC#架設到IIS中
Thumbnail
接續上一篇 Step2:VC#專案建立 Step3:IIS新建站台 Step4:VC#架設到IIS中
Thumbnail
ServiceNow 是一間協助企業提升自動化的公司,我們可以將它想像成一個超級助手,企業許多例行工作,如入離職、請假申請或處理客戶問題等,都需要填寫表格與審核,ServiceNow 提供的服務可以協助自動化…
Thumbnail
ServiceNow 是一間協助企業提升自動化的公司,我們可以將它想像成一個超級助手,企業許多例行工作,如入離職、請假申請或處理客戶問題等,都需要填寫表格與審核,ServiceNow 提供的服務可以協助自動化…
Thumbnail
👨‍💻簡介 最近因為憑證越來越多,需要監控什麼時候到期,當到期時發送到期通知,因此撰寫一個簡單的小程式來完成。 這次使用Python和Telegram Bot來監控SSL證書的到期時間並發送通知。並使用GCP工具,如CloudFunction和CloudScheduler做部署平台。
Thumbnail
👨‍💻簡介 最近因為憑證越來越多,需要監控什麼時候到期,當到期時發送到期通知,因此撰寫一個簡單的小程式來完成。 這次使用Python和Telegram Bot來監控SSL證書的到期時間並發送通知。並使用GCP工具,如CloudFunction和CloudScheduler做部署平台。
Thumbnail
當我們在撰寫一套系統的時候, 總是會提供一個介面讓使用者來觸發功能模組並回傳使用者所需的請求, 而傳統的安裝包模式總是太侷限, 需要個別主機獨立安裝, 相當繁瑣, 但隨著時代的演進與互聯網的崛起, 大部分的工作都可以藉由網頁端、裝置端來觸發, 而伺服端則是負責接收指令、運算與回傳結果, 雲端
Thumbnail
當我們在撰寫一套系統的時候, 總是會提供一個介面讓使用者來觸發功能模組並回傳使用者所需的請求, 而傳統的安裝包模式總是太侷限, 需要個別主機獨立安裝, 相當繁瑣, 但隨著時代的演進與互聯網的崛起, 大部分的工作都可以藉由網頁端、裝置端來觸發, 而伺服端則是負責接收指令、運算與回傳結果, 雲端
Thumbnail
用 Powershell 的 IDE ,寫一個在剪貼簿裡存 Timestamp 的無聊小程式。
Thumbnail
用 Powershell 的 IDE ,寫一個在剪貼簿裡存 Timestamp 的無聊小程式。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News