Docker最全教程之使用.NET Core推送钉钉消息(十九)
<h1><strong>前言</strong></h1><p>上一篇我们通过实战分享了使用Go推送钉钉消息,由于技痒,笔者现在也编写了一个.NET Core的Demo,作为简单的对照和说明。</p>
<p><strong>最后,由于精力有限,笔者希望有兴趣的朋友可以分享下使用CoreRT将.NET Core编译成机器代码这块的实践。</strong></p>
<p> </p>
<h1><strong>目录</strong></h1>
<ul class="list-paddingleft-2">
<li>
<h3>使用.NET Core推送钉钉消息</h3>
</li>
<li>
<p>获取参数</p>
</li>
<li>
<p>设置消息数据格式</p>
</li>
<li>
<p>发送请求</p>
</li>
<li>
<p>设置Dockerfile</p>
</li>
<li>
<p>运行并设置环境变量推送消息</p>
</li>
</ul>
<p> </p>
<h1>使用.NET Core推送钉钉消息</h1>
<p>这里我们使用.NET Core来完成相关需求,注意,这里是.NET Core,而不是ASP.NET Core。需求和上面类似,工程相关依赖如下所示:</p>
<p> </p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:false;"><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"/>
</pre>
</div>
<p> </p>
<p>以下是相关的主体代码:</p>
<p> </p>
<h2>获取参数</h2>
<p> </p>
<p>从环境变量或者命令行参数获取配置:</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)">环境变量列表
</span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 0, 1)">
privatestaticreadonlystring[] EnvList </span>=<span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">钉钉机器人地址</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WEBHOOK</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">@的手机号码</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AT_MOBILES</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">@所有人</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">IS_AT_ALL</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">消息内容</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MESSAGE</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">消息类型(仅支持文本和markdown)</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MSG_TYPE</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
};
privatestaticvoid Main(</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">[] args)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> config =<span style="color: rgba(0, 0, 0, 1)"> newConfigurationBuilder()
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">支持命令行参数</span>
<span style="color: rgba(0, 0, 0, 1)">
.AddCommandLine(args)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">支持环境变量</span>
<span style="color: rgba(0, 0, 0, 1)">
.AddEnvironmentVariables()
.Build();
#region参数检查
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> envName <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> EnvList)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> value =<span style="color: rgba(0, 0, 0, 1)">config;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">string</span>.IsNullOrWhiteSpace(value)&& envName != <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AT_MOBILES</span><span style="color: rgba(128, 0, 0, 1)">"</span> && envName !=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">IS_AT_ALL</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
{
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{envName}不能为空!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">string</span>.IsNullOrWhiteSpace(config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AT_MOBILES</span><span style="color: rgba(128, 0, 0, 1)">"</span>]) &&<span style="color: rgba(0, 0, 255, 1)">string</span>.IsNullOrWhiteSpace(config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">IS_AT_ALL</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]))
{
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">必须设置参数 AT_MOBILES 和 IS_AT_ALL 两者之一!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>
<span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">推送消息</span>
<span style="color: rgba(0, 0, 0, 1)">
SetDataAndSendWebhooks(config).Wait();
}
</span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}</span></pre>
</div>
<p> </p>
<h1>设置消息数据格式</h1>
<p>设置消息格式,为了简单,这里我们使用匿名类:</p>
<p> </p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)">设置消息并调用Webhook
</span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><param name="config"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 0, 1)">
privatestaticasync Task SetDataAndSendWebhooks(IConfigurationRoot config)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> at = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">
{
AtMobiles </span>= config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AT_MOBILES</span><span style="color: rgba(128, 0, 0, 1)">"</span>]?.Split(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">,</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
IsAtAll </span>= Convert.ToBoolean(config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">IS_AT_ALL</span><span style="color: rgba(128, 0, 0, 1)">"</span>] ?? <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">false</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
};
</span><span style="color: rgba(0, 0, 255, 1)">switch</span> (config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MSG_TYPE</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">])
{
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> data = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">
{
Msgtype </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
Text </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">
{
Content </span>=config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MESSAGE</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]
},
At </span>=<span style="color: rgba(0, 0, 0, 1)"> at
};
awaitSendWebhooks(config[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WEBHOOK</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">], data);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">markdown</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> data = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">
{
Msgtype </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">markdown</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
Markdown </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">
{
Title </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">钉钉通知</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
Text </span>= config[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MESSAGE</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]
},
At </span>=<span style="color: rgba(0, 0, 0, 1)"> at
};
awaitSendWebhooks(config[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WEBHOOK</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">], data);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
{
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">不支持的格式:{config[</span><span style="color: rgba(128, 0, 0, 1)">"</span>MSG_TYPE<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">]}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
}</span></pre>
</div>
<p> </p>
<h2>发送请求</h2>
<p>此处代码使用Newtonsoft.Json做JSON序列化,然后使用Microsoft.Extensions.Http的HttpClient库来发送Post请求。</p>
<p>在数据格式这块,我们通过配置做了以下设置:</p>
<ul class="list-paddingleft-2">
<li>
<p>忽略Null值。也就是为null的属性不做JSON序列化。</p>
</li>
<li>
<p>设置属性命名规则为Camel-Case驼峰式命名法,首字母小写。</p>
</li>
</ul>
<p> </p>
<p>主体代码如下所示:</p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)">调用webhook
</span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><typeparamname="T"></typeparam></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><param name="url"></span><span style="color: rgba(0, 128, 0, 1)">webhook地址</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><param name="data"></span><span style="color: rgba(0, 128, 0, 1)">消息</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 0, 1)">
privatestaticasync Task SendWebhooks</span><T>(<span style="color: rgba(0, 0, 255, 1)">string</span> url, T data) <span style="color: rgba(0, 0, 255, 1)">where</span> T : <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">
{
JsonConvert.DefaultSettings </span>= newFunc<JsonSerializerSettings>(() =><span style="color: rgba(0, 0, 0, 1)">newJsonSerializerSettings()
{
NullValueHandling </span>=<span style="color: rgba(0, 0, 0, 1)">NullValueHandling.Ignore,
ContractResolver </span>=<span style="color: rgba(0, 0, 0, 1)"> newCamelCasePropertyNamesContractResolver()
});
</span><span style="color: rgba(0, 0, 255, 1)">var</span> jsonData =<span style="color: rgba(0, 0, 0, 1)">JsonConvert.SerializeObject(data);
Console.WriteLine(jsonData);
</span><span style="color: rgba(0, 0, 255, 1)">using</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> httpClient = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> HttpClient())
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> content =<span style="color: rgba(0, 0, 0, 1)"> newStringContent(jsonData);
content.Headers.ContentType </span>= newMediaTypeHeaderValue(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">application/json</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result =<span style="color: rgba(0, 0, 0, 1)"> awaithttpClient.PostAsync(url, content);
result.EnsureSuccessStatusCode();
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Send webhook succeed. StatusCode:{result.StatusCode}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
}
}</span></pre>
</div>
<p> </p>
<h2>设置Dockerfile</h2>
<p>在之前我们已经讲述过,使用了分阶段构建。整个Dockerfile基本上使用VS Docker tool生成:</p>
<div class="cnblogs_code">
<pre>FROMmicrosoft/dotnet:<span style="color: rgba(128, 0, 128, 1)">2.2</span>-runtime AS <span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">
WORKDIR </span>/<span style="color: rgba(0, 0, 0, 1)">app
FROMmicrosoft</span>/dotnet:<span style="color: rgba(128, 0, 128, 1)">2.2</span>-<span style="color: rgba(0, 0, 0, 1)">sdk AS build
WORKDIR </span>/<span style="color: rgba(0, 0, 0, 1)">src
COPY DingTalk.NET</span>/DingTalk.NET.csprojDingTalk.NET/<span style="color: rgba(0, 0, 0, 1)">
RUN dotnet restoreDingTalk.NET</span>/<span style="color: rgba(0, 0, 0, 1)">DingTalk.NET.csproj
COPY . .
WORKDIR </span>/src/<span style="color: rgba(0, 0, 0, 1)">DingTalk.NET
RUN dotnet buildDingTalk.NET.csproj </span>-c Release -o /<span style="color: rgba(0, 0, 0, 1)">app
FROM build AS publish
RUN dotnet publish DingTalk.NET.csproj</span>-c Release -o /<span style="color: rgba(0, 0, 0, 1)">app
FROM </span><span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)"> AS final
WORKDIR </span>/<span style="color: rgba(0, 0, 0, 1)">app
COPY </span>--<span style="color: rgba(0, 0, 255, 1)">from</span>=publish/<span style="color: rgba(0, 0, 0, 1)">app .
ENTRYPOINT [</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dotnet</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">DingTalk.NET.dll</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]
# 注意不要单独使用 MAINTAINER 指令,MAINTAINER已被Label标签代替
LABEL MAINTAINER </span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">xinlai@xin-lai.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
# LABEL指令用于将元数据添加到镜像,支持键值对和JSON,我们可以使用 docker inspect 命令来查看
LABELDingtalkComponent</span>=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">{\</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">description</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">使用钉钉发送通知消息.</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,\
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">input</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: [\
{</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WEBHOOK</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">desc</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">必填, 钉钉机器人Webhook地址</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">},\
{</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AT_MOBILES</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">desc</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">非必填,被@人的手机号</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">},\
{</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">IS_AT_ALL</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">desc</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">非必填,@所有人时:true, 否则为:false</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">},\
{</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MESSAGE</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">desc</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">必填,自定义发送的消息内容</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">},\
{</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MSG_TYPE</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">desc</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">必填,自定义发送的消息类型,目前仅支持text和markdown</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}\
]\
}</span><span style="color: rgba(128, 0, 0, 1)">'</span></pre>
</div>
<p> </p>
<p>编译完成后,我们来查看下镜像大小:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201903/70544-20190322093205086-1345813661.png" alt=""></p>
<p><span style="color: rgba(0, 0, 255, 1)"><em>注意:</em></span><br><span style="color: rgba(0, 0, 255, 1)"><em>通过上图我们可以看到,镜像大小不到200M,相比GO体重大了许多,但是相比其他语言却轻了不少。<strong>不过,我们可以通过官方开源库CoreRT将.NET Core编译成机器代码,也就是.NET Core也可以做到编译完成后只有几M大小。有兴趣的朋友可以分享下这块的实践。</strong></em></span></p>
<p> </p>
<h2>
运行并设置环境变量推送消息</h2>
<p>我们使用PowerShell编写简单脚本如下所示:</p>
<div class="cnblogs_code">
<pre>docker build --rm-f <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Dockerfile</span><span style="color: rgba(128, 0, 0, 1)">"</span> -<span style="color: rgba(0, 0, 0, 1)">t dingtalk.net:latest .
docker run </span>--rm -e<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WEBHOOK=https://oapi.dingtalk.com/robot/send?access_token={yourAccess Token}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> `
</span>-e <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MESSAGE=*使用.NET Core发送钉钉消息。*</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> `
</span>-e <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">IS_AT_ALL=true</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> `
</span>-e <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MSG_TYPE=markdown</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> `
</span>-d dingtalk.net</pre>
</div>
<p> </p>
<p>效果如图:</p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201903/70544-20190322093314963-585832983.png" alt=""></p>
<p><img src="https://img2018.cnblogs.com/blog/70544/201903/70544-20190322093323767-1621047112.png" alt=""></p>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
作者:雪雁<br>出处:http://www.cnblogs.com/codelove/
<br>如果喜欢作者的文章,请关注【CodeSpirit-码灵】公众号以便第一时间获得最新内容。本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。<br><b>静听鸟语花香,漫赏云卷云舒。</b>
<br>
<img src="https://images.cnblogs.com/cnblogs_com/codelove/315887/o_251224070213_%E5%85%AC%E4%BC%97%E5%8F%B7.jpg" width="100" height="100"><br><br>
来源:https://www.cnblogs.com/codelove/p/10576322.html
頁:
[1]