前言
上一篇我們通過(guò)實(shí)戰(zhàn)分享了使用Go推送釘釘消息,由于技癢,筆者現(xiàn)在也編寫(xiě)了一個(gè).NET Core的Demo誓焦,作為簡(jiǎn)單的對(duì)照和說(shuō)明。
最后着帽,由于精力有限杂伟,筆者希望有興趣的朋友可以分享下使用CoreRT將.NET Core編譯成機(jī)器代碼這塊的實(shí)踐。
目錄
使用.NET Core推送釘釘消息
獲取參數(shù)
設(shè)置消息數(shù)據(jù)格式
發(fā)送請(qǐng)求
設(shè)置Dockerfile
運(yùn)行并設(shè)置環(huán)境變量推送消息
使用.NET Core推送釘釘消息
這里我們使用.NET Core來(lái)完成相關(guān)需求仍翰,注意赫粥,這里是.NET Core,而不是ASP.NET Core予借。需求和上面類似越平,工程相關(guān)依賴如下所示:
<PackageReferenceInclude="Microsoft.Extensions.Configuration"Version="2.2.0"/>
???<PackageReferenceInclude="Microsoft.Extensions.Configuration.CommandLine"Version="2.2.0"/>
???<PackageReferenceInclude="Microsoft.Extensions.Configuration.EnvironmentVariables"Version="2.2.0"/>
????<PackageReferenceInclude="Microsoft.Extensions.Http"Version="2.2.0"/>
????<PackageReferenceInclude="Newtonsoft.Json"Version="12.0.1"/>
以下是相關(guān)的主體代碼:
獲取參數(shù)
從環(huán)境變量或者命令行參數(shù)獲取配置:
///<summary>///環(huán)境變量列表
? ? ? ///</summary>? ? ? privatestaticreadonlystring[] EnvList =? ? ? {
? ? ? ? ? ? //釘釘機(jī)器人地址"WEBHOOK",
? ? ? ? ? ? //@的手機(jī)號(hào)碼"AT_MOBILES",
? ? ? ? ? ? //@所有人"IS_AT_ALL",
? ? ? ? ? //消息內(nèi)容"MESSAGE",
? ? ? ? ? ? //消息類型(僅支持文本和markdown)"MSG_TYPE"? ? ? };
? ? ? privatestaticvoid Main(string[] args)
? ? ? {
? ? ? ? ? ? varconfig = newConfigurationBuilder()
? ? ? ? ? ? ? ? ? ? ? ? //支持命令行參數(shù)? ? ? ? ? ? ? ? ? ? ? ? .AddCommandLine(args)
? ? ? ? ? ? ? ? ? ? ? ? //支持環(huán)境變量? ? ? ? ? ? ? ? ? ? ? .AddEnvironmentVariables()
? ? ? ? ? ? ? ? ? ? ? ? .Build();
? ? ? ? ? ? #region參數(shù)檢查
? ? ? ? ? ? foreach(varenvNamein EnvList)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? varvalue =config[envName];
? ? ? ? ? ? ? ? if(string.IsNullOrWhiteSpace(value)&& envName !="AT_MOBILES"&& envName !="IS_AT_ALL")
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? Console.WriteLine($"{envName}不能為空!");
? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if(string.IsNullOrWhiteSpace(config["AT_MOBILES"]) &&string.IsNullOrWhiteSpace(config["IS_AT_ALL"]))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Console.WriteLine("必須設(shè)置參數(shù) AT_MOBILES 和 IS_AT_ALL 兩者之一蕾羊!");
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? #endregiontry? ? ? ? ? ? {
? ? ? ? ? ? ? ? //推送消息? ? ? ? ? ? ? SetDataAndSendWebhooks(config).Wait();
? ? ? ? ? ? }
? ? ? ? ? ? catch (Exception ex)
? ? ? ? ? {
? ? ? ? ? ? ? Console.WriteLine(ex.ToString());
? ? ? ? ? ? }
? ? ? }
設(shè)置消息數(shù)據(jù)格式
設(shè)置消息格式喧笔,為了簡(jiǎn)單,這里我們使用匿名類:
///<summary>///設(shè)置消息并調(diào)用Webhook
? ? ? ///</summary>///<param name="config"></param>///<returns></returns>? ? ? privatestaticasync Task SetDataAndSendWebhooks(IConfigurationRoot config)
? ? ? {
? ? ? ? ? ? varat =new? ? ? ? ? ? {
? ? ? ? ? ? ? ? AtMobiles = config["AT_MOBILES"]?.Split(','),
? ? ? ? ? ? ? ? IsAtAll = Convert.ToBoolean(config["IS_AT_ALL"] ??"false")
? ? ? ? ? ? };
? ? ? ? ? ? switch(config["MSG_TYPE"])
? ? ? ? ? ? {
? ? ? ? ? ? ? ? case"text":
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? vardata =new? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? Msgtype ="text",
? ? ? ? ? ? ? ? ? ? ? ? ? ? Text =new? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Content =config["MESSAGE"]
? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? At = at
? ? ? ? ? ? ? ? ? ? ? ? };
? ? ? ? ? ? ? ? ? ? ? ? awaitSendWebhooks(config["WEBHOOK"], data);
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? case"markdown":
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? vardata =new? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? Msgtype ="markdown",
? ? ? ? ? ? ? ? ? ? ? ? ? ? Markdown =new? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Title ="釘釘通知",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Text = config["MESSAGE"]
? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? At = at
? ? ? ? ? ? ? ? ? ? ? ? };
? ? ? ? ? ? ? ? ? ? ? ? awaitSendWebhooks(config["WEBHOOK"], data);
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? Console.WriteLine($"不支持的格式:{config["MSG_TYPE"]}");
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? }
發(fā)送請(qǐng)求
此處代碼使用Newtonsoft.Json做JSON序列化龟再,然后使用Microsoft.Extensions.Http的HttpClient庫(kù)來(lái)發(fā)送Post請(qǐng)求。
在數(shù)據(jù)格式這塊尼变,我們通過(guò)配置做了以下設(shè)置:
忽略Null值利凑。也就是為null的屬性不做JSON序列化浆劲。
設(shè)置屬性命名規(guī)則為Camel-Case駝峰式命名法,首字母小寫(xiě)哀澈。
主體代碼如下所示:
///<summary>///調(diào)用webhook
? ? ? ///</summary>///<typeparamname="T"></typeparam>///<param name="url">webhook地址</param>///<param name="data">消息</param>///<returns></returns>? ? ? privatestaticasync Task SendWebhooks(stringurl, T data)whereT :class? ? ? {
? ? ? ? ? ? JsonConvert.DefaultSettings = newFunc(() =>newJsonSerializerSettings()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? NullValueHandling =NullValueHandling.Ignore,
? ? ? ? ? ? ? ? ContractResolver = newCamelCasePropertyNamesContractResolver()
? ? ? ? ? ? });
? ? ? ? ? ? varjsonData =JsonConvert.SerializeObject(data);
? ? ? ? ? ? Console.WriteLine(jsonData);
? ? ? ? ? ? using(varhttpClient =new HttpClient())
? ? ? ? ? ? {
? ? ? ? ? ? ? ? varcontent = newStringContent(jsonData);
? ? ? ? ? ? ? ? content.Headers.ContentType = newMediaTypeHeaderValue("application/json");
? ? ? ? ? ? ? ? varresult = awaithttpClient.PostAsync(url, content);
? ? ? ? ? ? ? result.EnsureSuccessStatusCode();
? ? ? ? ? ? ? ? Console.WriteLine($"Send webhook succeed. StatusCode:{result.StatusCode}");
? ? ? ? ? ? }
? ? ? }
設(shè)置Dockerfile
在之前我們已經(jīng)講述過(guò)牌借,使用了分階段構(gòu)建。整個(gè)Dockerfile基本上使用VS Docker tool生成:
FROMmicrosoft/dotnet:2.2-runtime ASbaseWORKDIR /app
FROMmicrosoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY DingTalk.NET/DingTalk.NET.csprojDingTalk.NET/RUN dotnet restoreDingTalk.NET/DingTalk.NET.csproj
COPY . .
WORKDIR /src/DingTalk.NET
RUN dotnet buildDingTalk.NET.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish DingTalk.NET.csproj-c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish/app .
ENTRYPOINT ["dotnet","DingTalk.NET.dll"]
# 注意不要單獨(dú)使用 MAINTAINER 指令割按,MAINTAINER已被Label標(biāo)簽代替
LABEL MAINTAINER ="xinlai@xin-lai.com"# LABEL指令用于將元數(shù)據(jù)添加到鏡像膨报,支持鍵值對(duì)和JSON,我們可以使用 docker inspect 命令來(lái)查看
LABELDingtalkComponent='{\"description":"使用釘釘發(fā)送通知消息.",\
? ? "input": [\
? ? ? ? {"name":"WEBHOOK","desc":"必填, 釘釘機(jī)器人Webhook地址"},\
? ? ? ? {"name":"AT_MOBILES","desc":"非必填适荣,被@人的手機(jī)號(hào)"},\
? ? ? ? {"name":"IS_AT_ALL","desc":"非必填现柠,@所有人時(shí):true, 否則為:false"},\
? ? ? ? {"name":"MESSAGE","desc":"必填,自定義發(fā)送的消息內(nèi)容"}弛矛,\
? ? ? ? {"name":"MSG_TYPE","desc":"必填够吩,自定義發(fā)送的消息類型,目前僅支持text和markdown"}\
? ? ? ? ]\
? ? }'
編譯完成后丈氓,我們來(lái)查看下鏡像大兄苎:
注意:
通過(guò)上圖我們可以看到,鏡像大小不到200M万俗,相比GO體重大了許多湾笛,但是相比其他語(yǔ)言卻輕了不少。不過(guò)闰歪,我們可以通過(guò)官方開(kāi)源庫(kù)CoreRT將.NET Core編譯成機(jī)器代碼迄本,也就是.NET Core也可以做到編譯完成后只有幾M大小。有興趣的朋友可以分享下這塊的實(shí)踐课竣。
運(yùn)行并設(shè)置環(huán)境變量推送消息
我們使用PowerShell編寫(xiě)簡(jiǎn)單腳本如下所示:
docker build --rm-f"Dockerfile"-t dingtalk.net:latest .
docker run --rm -e"WEBHOOK=https://oapi.dingtalk.com/robot/send?access_token={yourAccess Token}" `
? ? -e"MESSAGE=*使用.NET Core發(fā)送釘釘消息嘉赎。*" `
? ? -e"IS_AT_ALL=true" `
? ? -e"MSG_TYPE=markdown" `
? ? -d dingtalk.net
效果如圖: