您的位置:首页 > 其它

钉钉开发系列(十三)SVN机器人通知

2017-06-14 17:19 411 查看
在《钉钉开发系列-机器人》中已经介绍了钉钉机器人的创建与通知,那SVN提交时是否也可以自动发出通知呢?我们来思考一下原理,钉钉机器人的通知,本质上就是调用一个URL,然后POST数据,如果SVN中能够调起该URL并POST,那么理论上就应可以的。现在我们来开始实践。

我们用的是VisualSVN-Server作为SVN的服务器,SVN客户端用TortoiseSVN。在VisualSVN-Server是免费的,新版的要求在WIN2008以上安装,所以只要在虚拟机中装WIN2008,然后装VisualSVN-Server就可以了。安装时一路默认即可。安装后创建一个DDRobotTest的库。



在Users文件夹下右键,然后创建用户,比如test.

VisualSVN-Server有钩子来实现客制化的方式,所以我们利用钩子hook来发起钉钉机器人的通知请求。在DDRobotTest上右键,如下图





我们要用到的是Pre-commit hook和Post-commit hook,Pre-commit hook是提交代码前的钩子,Post-commit hook是提交完成后的钩子。为了能够在通知时更规范,我们有必要对提交代码作一些要求,比如必须输入日志内容,为此我们先在Pre-commit hook中实现一个控制提交代码日志的钩子。代码如下

@echo off
::
:: Stops commits that have empty log messages.
::
@echo off

setlocal

rem Subversion sends through the path to the repository and transaction id
set REPOS=%1
set TXN=%2

rem check for an empty log message
svnlook log %REPOS% -t %TXN% | findstr "..." > nul
if %errorlevel% gtr 0  (goto err) else exit 0

:err
echo 1>&2
echo 抱歉,由于您没有正确填写Log或者Log字数过少(必须大于3),系统拒绝提交! 1>&2
echo Log格式: 新增/修改/删除: 提交内容 1>&2
echo 请详细描述提交内容,然后再提交. -- 谢谢! 1>&2
exit 1
将上面的代码直接贴到Pre-commit hook中就可以了。其中findstr中的"..."是控制日志内容的文字个数,几个点就是几个字。



测试一下



如果输入的日志符合长度,则提交成功。



SVN日志已经规范,接下来就是在Post-commit hook发出通知。由于Post-commit hook中没有办法直接发起https请求,但是可以调用相关的应用程序,所以如果我们能够写一个控制台程序供其调用,然后将通知的内容传入,那通知也就应该可以成功发出了。下面是控制台的代码

class Program
{
static void Main(string[] args)
{
if (args == null || args.Length < 2)
{
Console.WriteLine("请输入机器人票据和通知内容");
return;
}

var token = args[0];
var msg = args[1];
var result = Notify(token, msg);
Console.WriteLine(result);
}

#region Notify
public static string Notify(string token, string msg)
{
var robotUrl = $"https://oapi.dingtalk.com/robot/send?access_token={token}";
String textMsg = "{ \"msgtype\": \"text\", \"text\": {\"content\": \"" + msg + "\"}}";
string s = Post(robotUrl, textMsg, null);
return s;
}
#endregion

#region Post
/// <summary>
/// 以Post方式提交命令
/// </summary>
/// <param name="apiurl">请求的URL</param>
/// <param name="jsonString">请求的json参数</param>
/// <param name="headers">请求头的key-value字典</param>
private static String Post(string apiurl, string jsonString, Dictionary<String, String> headers = null)
{
WebRequest request = WebRequest.Create(@apiurl);
request.Method = "POST";
request.ContentType = "application/json";
if (headers != null)
{
foreach (var keyValue in headers)
{
if (keyValue.Key == "Content-Type")
{
request.ContentType = keyValue.Value;
continue;
}
request.Headers.Add(keyValue.Key, keyValue.Value);
}
}

if (String.IsNullOrEmpty(jsonString))
{
request.ContentLength = 0;
}
else
{
byte[] bs = Encoding.UTF8.GetBytes(jsonString);
request.ContentLength = bs.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(bs, 0, bs.Length);
newStream.Close();
}

WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
Encoding encode = Encoding.UTF8;
StreamReader reader = new StreamReader(stream, encode);
string resultJson = reader.ReadToEnd();
return resultJson;
}
#endregion
}
编译生成控制台程序 DingDingRobotNotify.exe,我们可以对该程序用cmd测试一下。



现在我们将DingDingRobotNotify.exe放到VisualSVN-Server所在的服务器上,比如放到C盘,然后在Post-commit hook中调用,hook的代码如下

@echo off
set REPOS=%1
set REV=%2
set tttt=%date:~0,10% %time:~0,8%
for /f "tokens=1,2 delims=:" %%a in ('svnlook author -r %REV% %REPOS%') do (
if not defined AUTHOR set AUTHOR=%%a
)
for /f "tokens=1,2 delims=:" %%a in ('svnlook dirs-changed %REPOS%') do (
if not defined CHANGEDDIRS set CHANGEDDIRS=%%a
)
for /f "tokens=1,2 delims=:" %%a in ('svnlook log -r %REV% %REPOS%') do (
if not defined MESSAGE set MESSAGE=%%a
)
set CONTENT="提交时间:%tttt% \n提交版本:%REV% \n作者:%AUTHOR%\n提交备注:%MESSAGE%\n修改目录:%CHANGEDDIRS% "
"C:\DingDingRobotNotify.exe" XXX %CONTENT%
其中XXX是钉钉机器人的access_token。

现在我们要SVN的客户端提交修改,如下图



欢迎打描左侧二维码打赏。

转载请注明出处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息