- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们公司使用 Skype 进行通信,我希望能够在 Jenkins 构建失败(以及恢复时)时向 Skype 聊天室发送警报。
我该怎么做?
最佳答案
我已经使用 Skype Public API 完成了此操作
我所做的是编写一个 Perl 脚本,它使用 SkypeAPI CPAN模块处理与Skype的通信。它有点笨重,因为该脚本需要在运行 Skype 的桌面上运行。我在自己的桌面上运行它,该桌面始终处于开启状态,但这确实意味着该机器人对于我们团队的其他成员来说似乎就是“我”。
最终结果非常棒 - 每当 jenkins 构建更改状态时,机器人都会向任何通过输入 *alert 注册了兴趣的 Skype 聊天发送消息。此外,任何开发人员都可以通过输入 *jenkins
查看并共享最新的构建状态现在,SkypeAPI 模块非常基本。它的listen()方法中有一个消息循环,用于检查来自Skype客户端的新事件,如果没有,则休眠一会儿。
我希望我的脚本能够挂接到这个循环中,以便我的机器人能够定期检查 Jenkins RSS 提要,因此在使用 ActiveState 包管理器安装 SkypeAPI.pm 后,我对它进行了以下修改:
我声明了新属性“idler”以及现有属性...
__PACKAGE__->mk_accessors(
qw/api handler_list stop_listen idler/
);
我添加了一个方法来设置“idler”回调,模块将调用该回调而不是休眠
sub register_idler {
my $self = shift;
my $ref_sub = shift;
$self->idler($ref_sub);
}
最后我修改了消息循环以调用空闲程序(如果已设置)
sub listen {
my $self = shift;
my $idler=$self->idler();
$self->stop_listen(0);
while (!$self->stop_listen) {
my $message;
{
lock @message_list;
$message = shift @message_list;
}
if (not defined $message) {
if ($idler)
{
$self->idler->($self);
}
else
{
sleep 0.1;
}
next;
}
for my $id (sort keys %{$self->handler_list}) {
$self->handler_list->{$id}->($self, $message);
}
}
}
现在该模块的功能更强了,只需编写一个脚本来充当机器人即可。这是我的 - 我对原始版本进行了一些编辑,因为它包含其他不相关的功能,但它应该为您提供一个起点。
所有依赖模块都可以使用 ActiveState 包管理器安装。
use strict;
use SkypeAPI;
use LWP::Simple;
use Data::Dumper;
use dirtyRSS;
use Time::Local 'timegm';
use Math::Round;
use Storable;
#CHANGE THIS - where to get jenkins status from
my $jenkinsRss='http://username:password@jenkins.example.com/rssLatest';
my %commands=(
'jenkins' =>\&cmdJenkins,
'alert' =>\&cmdAlert,
'noalert' =>\&cmdNoAlert,
'help' =>\&cmdHelp,
);
my $helpMessage=<<HELP;
Who asked for help? Here's all the other special commands I know...
*jenkins - show status of our platform tests
*alert - add this room to get automatic notification of build status
*noalert - cancel notifcations
*help - displays this message
HELP
#status for jenkins tracking
my %builds;
my $lastJenkinsCheck=0;
my $alertRoomsFile='alert.rooms';
my $alertRooms={};
#store jenkins state
checkJenkins();
#because that was our first fetch, we'll have flagged everything as changed
#but it hasn't really, so we reset those flags
resetJenkinsChangeFlags();
#remember rooms we're supposed to alert
loadAlertRooms();
#attach to skype and enter message loop
my $skype = SkypeAPI->new();
my $attached=$skype->attach();
$skype->register_handler(\&onEvent);
$skype->register_idler(\&onIdle);
$skype->listen();
exit;
#here are the command handlers
sub cmdJenkins
{
my ($chatId, $args)=@_;
my $message="";
foreach my $build (keys(%builds))
{
$message.=formatBuildMessage($build)."\n";
#reset changed flag - we've just show the status
$builds{$build}->{'changed'}=0;
}
chatmessage($chatId, $message);
}
sub cmdAlert
{
my ($chatId, $args)=@_;
addChatroomToAlerts($chatId,1);
}
sub cmdNoAlert
{
my ($chatId, $args)=@_;
addChatroomToAlerts($chatId,0);
}
sub cmdHelp
{
my ($chatId, $args)=@_;
chatmessage($chatId, $helpMessage);
}
#simple helper to transmit a message to a specific chatroom
sub chatmessage
{
my ($chatId, $message)=@_;
my $commandstr="CHATMESSAGE $chatId $message";
my $command = $skype->create_command( { string => $commandstr} );
$skype->send_command($command);
}
#refreshes our copy of jenkins state, and will flag any builds
#which have changed state since the last check
sub checkJenkins{
my $xml = get($jenkinsRss);
my $tree = parse($xml);
my $items=$tree->{'channel'}->[0]->{'item'};
foreach my $item (@{$items})
{
my $title=$item->{'title'};
my $link=$item->{'link'};
my $built=$item->{'lastbuilddate'};
#print Dumper($item);
if ($title=~m/^(.*?) #(\d+)\s*(.*)$/)
{
my $build=$1;
my $buildnumber=$2;
my $status=$3;
#print "$build\n$buildnumber\n$status\n$link\n$built\n\n";
#build in progress, ignore
if (!exists($builds{$build}))
{
$builds{$build}={};
$builds{$build}->{'status'}='';
$builds{$build}->{'changed'}=0;
}
$builds{$build}->{'name'}=$build;
if ($status eq '(?)')
{
$builds{$build}->{'in_progress'}=1;
next; #don't update until complete
}
else
{
$builds{$build}->{'in_progress'}=0;
}
#is this status different to last status?
if ($builds{$build}->{'status'} ne $status)
{
$builds{$build}->{'changed'}=1;
}
$builds{$build}->{'status'}=$status;
$builds{$build}->{'build_number'}=$buildnumber;
$builds{$build}->{'link'}=$link;
$builds{$build}->{'built'}=$built;
}
}
#print Dumper(\%builds);
}
#generates a string suitable for displaying build status in skype
sub formatBuildMessage
{
my ($build)=@_;
my $status=$builds{$build}->{'status'};
my $smiley=":)";
if ($status=~m/broken/)
{
$smiley="(devil)";
}
elsif ($status=~m/\?/)
{
#this means the build is being retested, we should skip it
$smiley=":|";
}
my $message='';
if ($builds{$build}->{'in_progress'})
{
$message=":| $build - rebuild in progress..."
}
else
{
my ($y,$mon,$d,$h,$m,$s) = $builds{$build}->{'built'} =~ m/(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z/;
my $time = timegm($s,$m,$h,$d,$mon-1,$y);
my $age=time()-$time;
my $mins=round($age/60);
my $hrs=round($age/3600);
my $days=round($age/86400);
my $niceage;
if ($mins<=2)
{
$niceage="a few moments ago";
}
elsif ($mins<120)
{
$niceage="$mins minutes ago";
}
elsif ($hrs<48)
{
$niceage="$hrs hours ago";
}
else
{
$niceage="$days days ago";
}
$message="$smiley $build last built $niceage $status";
}
return $message;
}
#forget any changes we've flagged
sub resetJenkinsChangeFlags
{
foreach my $build (keys(%builds))
{
$builds{$build}->{'changed'}=0;
}
}
#checks for builds which have changed state. Can be called
#often, it will only kick in if 60 seconds have elapsed since
#last check
sub checkForJenkinsChanges
{
my $now=time();
if (($now-$lastJenkinsCheck) < 60)
{
#no need, we fetched it recently
return;
}
checkJenkins();
my $message='';
foreach my $build (keys(%builds))
{
if ($builds{$build}->{'changed'})
{
$builds{$build}->{'changed'}=0;
$message.=formatBuildMessage($build)."\n";
}
}
if (length($message))
{
foreach my $chatId (keys(%$alertRooms))
{
chatmessage($chatId, $message);
}
}
$lastJenkinsCheck=$now;
}
#adds or removes a room from the alerts
sub addChatroomToAlerts
{
my($chatId, $add)=@_;
if ($add)
{
if (exists($alertRooms->{$chatId}))
{
chatmessage($chatId, "/me says this room is already getting alerts");
}
else
{
$alertRooms->{$chatId}=1;
chatmessage($chatId, "/me added this chatroom to jenkins alerts");
}
}
else
{
delete($alertRooms->{$chatId});
chatmessage($chatId, "/me removed this chatroom from jenkins alerts");
}
store $alertRooms, $alertRoomsFile;
}
sub loadAlertRooms
{
if (-e $alertRoomsFile)
{
$alertRooms = retrieve( $alertRoomsFile);
}
}
# Skype event handler
sub onEvent {
my $skype = shift;
my $msg = shift;
#my $command = $skype->create_command( { string => "GET USERSTATUS"} );
#print $skype->send_command($command) , "\n";
#print "handler: $msg\n";
#an inbound chat message is either
#MESSAGE 13021257 STATUS RECEIVED (from others)
#MESSAGE 13021257 STATUS SENT (from us)
if ($msg =~ m/MESSAGE (\d+) STATUS (SEND|RECEIVED)/)
{
my $msgId=$1;
#get message body
my $commandstr="GET CHATMESSAGE $msgId BODY";
my $command = $skype->create_command( { string => $commandstr} );
my $output=$skype->send_command($command);
#if its a message for us...
if ($output =~ m/MESSAGE $msgId BODY \*([^\s]*)\s*(.*)/i)
{
my $botcmd=$1;
my $botargs=$2;
$commandstr="GET CHATMESSAGE $msgId CHATNAME";
$command = $skype->create_command( { string => $commandstr} );
$output=$skype->send_command($command);
if ($output =~ m/MESSAGE $msgId CHATNAME (.*)/)
{
my $chatId=$1;
if (exists($commands{$botcmd}))
{
$commands{$botcmd}->($chatId, $botargs);
}
else
{
chatmessage($chatId, "/me suggests trying *help as the robot didn't understand *$botcmd");
}
}
}
}
}
#skype idle handler
#Note - SkypeAPI.pm was modified to support this
sub onIdle {
my $skype = shift;
checkForJenkinsChanges();
sleep 0.1;
}
如果您已将其另存为 robots.pl,只需打开一个控制台窗口,perl robots.pl
就可以运行它。 Skype 会询问您是否允许 perl.exe 与其通信,一旦您确认,就可以开始了!
进入团队聊天室并输入 *jenkins
以获取最新构建的摘要,并使用 *alert
注册房间以获取构建更改警报
完美:)
关于api - 如何向 Skype 聊天室发出 Jenkins 构建状态警报?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6746081/
我正在尝试向网页添加链接或按钮,以便用户可以在安装了 Skype 后直接调用号码。似乎链接就像 skyp:....?打电话.... 但找不到任何样本或文件。谢谢你的帮助。 最佳答案 这是链接的格式:
是否可以在 Skype 聊天窗口中显示图像? (Windows 7 Skype 客户端) 最佳答案 您可以使用 Windows 桌面客户端(而非 Windows Modern)共享您的桌面,或将图像(
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
是否可以在 Skype 聊天窗口中显示图像? (Windows 7 Skype 客户端) 最佳答案 您可以使用 Windows 桌面客户端(而非 Windows Modern)共享您的桌面,或将图像(
我们能否在网站中集成 Skype API,以便用户可以使用 Skype 与网站管理员交谈?用户为此需要 Skype 用户名吗?有没有网站已经有这样的功能? 最佳答案 你可以放一个Skype butto
我需要制作一个能够调用地面电话(显然是通过 Skype)并记录对话的 Web 应用程序...任何想法,我从哪里开始? (是的,已经尝试过 google :) )可以用 php 完成吗? 谢谢! 最佳答
是否可以对网站进行编程,使其禁止 Skype 在电话号码旁边添加它的图标? 谢谢,斯蒂芬 最佳答案 您可以在页眉中添加: 详情在skype forum 关于skype - 禁止 Skype 在电话号
有没有办法让所有用户 friend 都使用 C# 使用 Skype?还有我怎样才能活跃起来(在线 friend )。 最佳答案 首先,您必须在项目的 COM 引用选项卡中添加对 SKYPE4COMLi
我正在使用 Skype 应用程序的开放 URL 从我的 iOS 应用程序调用特定用户。但是下面的代码只是打开 Skype 但不会调用指定的用户名。 任何人都可以指导我为什么它不调用。 - (IBAct
我正在尝试运行随新 SKYPE SDK 分发的 Web 示例。我没有本地 Lync 服务器,所以我使用站点提供的域和 token 登录。 Domain=metio.net Token= Bearer
根据这个 Skype 开发者页面: https://dev.skype.com/skype-uri/skype-uri-tutorial-webpages看来我可以从我的网页启动 Skype 聊天对话
我知道使用 https://www.skype.com/en/developer/create-contactme-buttons/ 添加 Skype 链接很容易.但是可以为 SkypeForBusi
因为我们可以选择通过提供 URI 在 Skype 中打开链接: skype:xyz?call 我们可以做一些类似的事情来实现相同的功能,但它会在 Skype for Business 中打开吗?请告诉
我们使用一个持久的 Skype for Business 聊天室,并用它来广播每天在特定项目上完成的工作。我想在每个工作日早上启动 Skype for Business 并将其打开到这个聊天室。我想使
全部, 如果您安装了 Webex 生产力工具并安装了 Skype,它会添加一个窗口装饰,您可以从中单击一个按钮,它会自动将一个新的 Webex session 链接粘贴到对话框中。 我想为我的应用程序
我在单击按钮时使用 Skype 从我的 Android 应用调用。下面是启动 Skype Intent 的代码: Uri skypeUri = Uri.parse(uri.toString()); I
每个人, 在网上搜索,但没有找到任何描述信息的文章。谁能告诉我是否可以使用 Skype For Web SDK 录制电话、视频和消息? 抱歉,我没有演示任何代码,因为我没有找到任何东西,所以保持简短。
我需要找到一种无需 API 即可从 Skype 读取所有联系人和聊天消息的方法。 Microsoft 将不再支持 Skype API。这就是我需要它的原因。在 C:\Documents and Set
Skype 如何在 imo.im 和 im+ 服务中工作?有什么猜测吗? 我认为只有3种方式: 为服务器上的每个连接客户端运行多个 Skype 客户端副本 为服务器上的每个客户端从 SkypeKit
我见过使用“Skype”进行机器人编程的例子。是否可以使用 Microsoft 的机器人/认知服务工具/框架开发在“Skype for Business”上运行的企业机器人? 最佳答案 Bot Fra
我是一名优秀的程序员,十分优秀!