简体   繁体   English

手动开始Xcode Bot的集成?

[英]Start Integration of Xcode Bot manually?

I was watching WWDC 2014 "Continuous Integration with Xcode" Video and it looks great how the bots can be used to run test. 我正在观看WWDC 2014“与Xcode持续集成”视频,它看起来很棒,如何使用机器人进行测试。 But my question is to anyone who has seen the video, when he sends message to Jeeves saying " integrate CoffeeBoard ".Bot starts to integrate. 但我的问题是任何看过该视频的人,当他向Jeeves发送信息说“整合CoffeeBoard”时。开始整合。 I want to know how he did that. 我想知道他是怎么做到的。

I want to add post-receive hook on github which on receiving any commit should start Xcode bot on my OS X Server. 我想在github上添加post-receive hook,在接收任何提交时应该在我的OS X Server上启动Xcode bot。 Most of my team members use SourceTree or GitHub to manage their git and they don't want to use Xcode Source Control. 我的大多数团队成员使用SourceTree或GitHub来管理他们的git,他们不想使用Xcode Source Control。 I thought creating a bot and setting its option to start manually will do the trick. 我认为创建一个机器人并设置其手动启动的选项将成功。 I need to know, "Does OS X Server gives you option like some sort of url which will start a bot? " 我需要知道,“OS X Server是否会为您提供类似于启动机器人的URL的选项?”

Sorry, If I am not clear enough. 对不起,如果我不够清楚的话。 But it is too confusing for me as they have very less documentation on triggers. 但这对我来说太混乱了,因为他们对触发器的文档很少。 And though he mention it as cool new feature, they have included no information to achieve that 虽然他提到它是很酷的新功能,但他们没有包含任何信息来实现这一目标

The prior two answers don't exactly answer the original question of "how they did that" to kick off bots from within Messages app. 之前的两个答案并没有完全回答“如何做到这一点”的原始问题,从“消息”应用程序中启动机器人。

I've recreated the exact workflow and scripts required to mimic the Jeeves virtual assistant for interacting with bots (and for getting the weather). 我重新创建了模仿Jeeves虚拟助手与机器人交互(以及获取天气)所需的确切工作流程和脚本。

See the linked PDF document for the complete details: 有关完整的详细信息,请参阅链接的PDF文档:

https://s3.amazonaws.com/icefield/IntegratingXcodeBotsWithMessages.pdf https://s3.amazonaws.com/icefield/IntegratingXcodeBotsWithMessages.pdf

Edit: original answer was deleted due, I believe, to the fact that I referenced via a link to the full answer. 编辑:原始答案已被删除,我相信,因为我通过链接引用了完整的答案。 This edit adds the full implementation details as part of this answer. 此编辑添加了完整的实现细节作为此答案的一部分。 I hope it is not too long for a SO answer. 我希望SO答案不会太久。

Integrating Xcode Bots with Messages 将Xcode机器人与消息集成

During WWDC 2014 Session 415, Continuous Integration with Xcode 6, Apple demonstrated integrating Xcode bots with the Messages app via custom integration triggers. 在WWDC 2014 Session 415,与Xcode 6的持续集成期间,Apple展示了通过自定义集成触发器将Xcode机器人与Messages应用程序集成。 More specifically, starting at the 23 minute mark of that session's video ( https://developer.apple.com/videos/play/wwdc2014-415/ ), Apple demonstrates the use of integration triggers in conjunction with Messages to receive the status of integrations on a build server. 更具体地说,从该会话的视频( https://developer.apple.com/videos/play/wwdc2014-415/ )的23分钟开始,Apple演示了如何使用集成触发器与Messages一起接收状态构建服务器上的集成。 Furthermore, through the use of a virtual chat room member, Jeeves, they demonstrate the ability to start integrations directly from within the Messages app. 此外,通过使用虚拟聊天室成员Jeeves,他们展示了直接从Messages应用程序中启动集成的能力。 The following article provides step-by-step instructions to reproduce that functionality. 以下文章提供了重现该功能的逐步说明。

Client and Server Configurations 客户端和服务器配置

To get started, here are the configurations of the client and server I used to mimic the Jeeves functionality: 首先,以下是我用来模仿Jeeves功能的客户端和服务器的配置:

Client OS X Version 10.11 (El Capitan), Xcode 7.0.1 客户端 OS X版本10.11(El Capitan),Xcode 7.0.1

Server OS X Version 10.11 (El Capitan), OS X Server 5.0.4, Xcode 7.0.1, Ruby 2.0.0p645 Server OS X版本10.11(El Capitan),OS X Server 5.0.4,Xcode 7.0.1,Ruby 2.0.0p645

Network For my development and continuous integrations, I use an internal network. 网络对于我的开发和持续集成,我使用内部网络。 My OS X Server is at domain.local, and my development machine is another node on the same internal network. 我的OS X服务器位于domain.local,我的开发机器是同一内部网络上的另一个节点。 The instructions below should work regardless if you're using an internal or external server. 无论您使用的是内部服务器还是外部服务器,下面的说明都可以使用。

Jabber – The foundation of Messages Jabber - 消息的基础

Jabber is the original name of an open source protocol for instance messaging. Jabber是用于实例消息传递的开源协议的原始名称。 Jabber was renamed the Extensible Messaging and Presence Protocol (XMPP). Jabber更名为可扩展消息传递和在线协议(XMPP)。 The OS X Messages app is built using Jabber at its core. OS X Messages应用程序是以Jabber为核心构建的。

We'll use Jabber (Messages) extensively in this effort, so let's ensure it is on. 我们将在这项工作中广泛使用Jabber(消息),所以让我们确保它已经开启。 From the OS X Server App, select the Services > Messages view, and toggle on Messages in the upper right corner. 从OS X Server应用程序中,选择“服务”>“消息”视图,然后在右上角切换消息。 For Jeeves, the Messages service settings I used are as follows: 对于Jeeves,我使用的消息服务设置如下:

消息服务设置

From a terminal window on your server, if you want to check the specific settings for Jabber, use 从服务器上的终端窗口,如果要检查Jabber的特定设置,请使用

$ sudo serveradmin settings jabber

Note in particular the jabberClientPortTLS (5222) and jabberClientPortSSL (5223) values. 请特别注意jabberClientPortTLS(5222)和jabberClientPortSSL(5223)值。 These are the ports on your server that you will use to communicate with the Jabber service. 这些是服务器上用于与Jabber服务通信的端口。

We'll be writing most of the scripts for Jeeves using Ruby, and we'll need a XMPP/Jabber library to accomplish this. 我们将使用Ruby为Jeeves编写大部分脚本,我们需要一个XMPP / Jabber库来实现这一目标。 From a terminal window on your server, install XMPP4R (an XMPP/Jabber library for Ruby) using 从服务器上的终端窗口,使用安装XMPP4R(Ruby的XMPP / Jabber库)

$ gem install xmpp4r

Create Users for Jabber Service 为Jabber服务创建用户

Because my Server is a local server without any developer accounts on it, I needed to create accounts for various developers to login to Jabber. 因为我的服务器是一个没有任何开发人员帐户的本地服务器,所以我需要为各种开发人员创建帐户以登录Jabber。 You may or may not need this step depending if your server already has user accounts defined. 您可能需要或可能不需要此步骤,具体取决于您的服务器是否已定义用户帐户。

From the OS X Server App on your server, go to the Accounts > Users list, and add new user for each client that will be utilizing the virtual Jeeves assistant. 从服务器上的OS X Server应用程序,转到帐户>用户列表,并为将使用虚拟Jeeves助手的每个客户端添加新用户。 Be sure to create a new user for Jeeves. 务必为Jeeves创建一个新用户。 For user 'Tom', here are the settings that were used. 对于用户'Tom',以下是使用的设置。 Be sure to create an email address for each user, but the Mail service does not need to be running. 请务必为每个用户创建一个电子邮件地址,但不需要运行Mail服务。 These email addresses will be used to log into the Jabber service from the Messages App on your client. 这些电子邮件地址将用于从客户端上的消息应用程序登录Jabber服务。

用户设置

Login to Jabber from Client Development Machine 从Client Development Machine登录Jabber

With the user account(s) defined on your server, it's now time to login to the Jabber account from your client machine. 使用服务器上定义的用户帐户,现在可以从客户端计算机登录Jabber帐户了。 In the Messages app on your client, go to Messages > Preferences > Accounts. 在客户端的“消息”应用程序中,转至“消息”>“首选项”>“帐户” Select the + sign in the lower left, select “Other Messages Account...” and press Continue. 选择左下方的+号,选择“其他消息帐户...”,然后按继续。 In the Add a Messages account dialog, select Jabber for the Account Type, and fill in the credential information for your user(s). 在“添加消息”帐户对话框中,为“帐户类型”选择“Jabber”,然后填写用户的凭据信息。 Here were the settings I used: 以下是我使用的设置:

在此输入图像描述

(Note with SSL toggled on, the Port (5223) matches the jabberClientPortSSL value you listed earlier when checking the settings of the Jabber service on your server.) (注意,当SSL切换为开启时,端口(5223)与您在检查服务器上的Jabber服务设置时列出的jabberClientPortSSL值匹配。)

After successfully logging in to the Jabber service, you can optionally change your account nickname under the “Chat Settings” page of the Jabber account. 成功登录Jabber服务后,您可以选择在Jabber帐户的“聊天设置”页面下更改您的帐户昵称。 All other default settings are okay to leave as is. 所有其他默认设置都可以保持原样。

Create Chat Room 创建聊天室

We want all bot integration statuses and communication to our virtual assistant, Jeeves, to be through a Messages chat room. 我们希望所有僵尸程序集成状态和与我们的虚拟助手Jeeves的通信都通过消息聊天室。 Chat rooms allow group communication but you don't need an invitation to join. 聊天室允许群组通信,但您不需要加入邀请。 To create the chat room, do the following. 要创建聊天室,请执行以下操作。

From Messages, choose File > Go to Chat Room. 在消息中,选择“文件”>“转到聊天室”。 You should see the account you logged into the Jabber service listed. 您应该会看到登录到Jabber服务的帐户。 Key in integration@rooms..local for the Room Name, and select Go. 键入@ Room..local的房间名称,然后选择Go。 (Note that I found that chat room needed to be 'rooms..local' .com'>. Using a word other than 'rooms' would not create the chat room.) (请注意,我发现聊天室必须是'rooms..local'.com'>。使用'rooms'以外的单词不会创建聊天室。)

创建聊天室

Configure the Server Websites Service 配置服务器网站服务

When an integration is started from Xcode running on your client machine, the pre- and post- integration scripts communicate with the Jabber service by making an http call to a file on the OS X Server Website Service. 当从客户端计算机上运行的Xcode开始集成时,集成前和集成后脚本通过对OS X Server网站服务上的文件进行http调用来与Jabber服务进行通信。 You must configure the OS X Server Websites service to handle these calls. 您必须配置OS X Server网站服务才能处理这些调用。

You'll need to modify the settings for the non-SSL http (port 80) site. 您需要修改非SSL http(端口80)站点的设置。 Here are the settings I used. 这是我使用的设置。

Web服务器设置

Select the Port 80 Website, and select the pencil icon underneath to make your settings match these. 选择端口80网站,然后选择下面的铅笔图标以使您的设置与这些设置相匹配。

Web服务器设置

Select the “Edit Advanced Settings...” and make your settings match these. 选择“编辑高级设置...”并使您的设置与这些设置相匹配。 (Enabling “Allow CGI execution...” enables Ruby script execution.) (启用“允许CGI执行...”启用Ruby脚本执行。)

Web服务器设置

Finally, you'll need to enable a particular file (message_room – we'll discuss later) to be configured to run as a Ruby script. 最后,您需要启用一个特定的文件(message_room - 我们将在后面讨论)配置为作为Ruby脚本运行。 To do that, place the following .htaccess file in your web server's default home folder (typically /Library/Server/Web/Data/Sites/Default). 为此,请将以下.htaccess文件放在Web服务器的默认主文件夹中(通常为/ Library / Server / Web / Data / Sites / Default)。

Options +ExecCGI 
<FilesMatch message_room$>
    SetHandler cgi-script 
</FilesMatch>

NOTE: in all of the following ruby scripts, you'll need to modify the variables just under the “credentials” comment in each script to match your domain, and login credentials. 注意:在以下所有ruby脚本中,您需要修改每个脚本中“凭据”注释下的变量,以匹配您的域和登录凭据。

Pre- and Post-Integration Scripts When we start an integration from Xcode on our client machine, we want to send a message to the Jabber Integration chat room so that all members of the chat room can be notified the integration has started (and finished). 集成前和集成后脚本当我们从客户端计算机上的Xcode开始集成时,我们希望向Jabber Integration聊天室发送消息,以便可以通知聊天室的所有成员集成已经开始(并已完成) 。 Add the following pre- and post-integration scripts to your project's bot on the bot Triggers page within Xcode. 在Xcode中的bot Triggers页面上将以下集成前和集成后脚本添加到项目的bot中。

This is the pre-integration Trigger script: 这是预集成触发器脚本:

#!/usr/bin/env ruby 
require 'json' 
require 'net/http' 
require 'uri'

# ------------------------------------------------------------------------------------- 
# credentials and such
domain = "<yourDomain>.local"

# ------------------------------------------------------------------------------------- 
# our messaging endpoint
uri = URI.parse("http://#{domain}:80/message_room")

# ------------------------------------------------------------------------------------- 
# what we want to say
message = "#{ENV['XCS_BOT_NAME']} integration #{ENV['XCS_INTEGRATION_NUMBER']} is now starting."

# ------------------------------------------------------------------------------------- 
# build up the request body
reqBody = {:message => message}
body = JSON.generate(reqBody)

# ------------------------------------------------------------------------------------- 
# the connect type
http = Net::HTTP.new(uri.host, uri.port)

# ------------------------------------------------------------------------------------- 
# build up the request
request = Net::HTTP::Post.new(uri.request_uri)
request.add_field('Content-type', 'application/json')
request.body = body

# ------------------------------------------------------------------------------------- 
# send the request and get the response
response = http.request(request)

This is the post-integration Trigger script: 这是集成后的Trigger脚本:

#!/usr/bin/env ruby 
require 'json' 
require 'net/http' 
require 'uri'

# ------------------------------------------------------------------------------------- 
# credentials and such
domain = "<yourDomain>.local"

# ------------------------------------------------------------------------------------- 
# our messaging endpoint
uri = URI.parse("http://#{domain}:80/message_room")

# ------------------------------------------------------------------------------------- 
# what we want to say
integrationResult = case ENV['XCS_INTEGRATION_RESULT']
    when "succeeded"
        "has completed successfully."
    when "test-failures"
        tc = ENV['XCS_TEST_FAILURE_COUNT'].to_i
        "completed with #{tc} failing #{(tc ==1 ) ? 'test' : 'tests'}."
    when "build-errors"
        ec = ENV['XCS_ERROR_COUNT'].to_i
        "failed with #{ec} build #{(ec == 1) ? 'error' : 'errors'}."
    when "warnings"
        wc = ENV['XCS_WARNING_COUNT'].to_i
        "completed with #{wc} #{(wc == 1) ? 'warning' : 'warnings'}."
    when "analyzer-warnings"
        ic = ENV['XCS_ANALYZER_WARNING_COUNT'].to_i
        "completed with #{ic} static analysis #{(ic == 1) ? 'issue' : 'issues'}."
    when "trigger-error"
        "failed running trigger script."
    when "checkout-error"
        "failed to checkout from source control."
    else
        "failed with unexpected errors."
    end

message = "#{ENV['XCS_BOT_NAME']} integration #{ENV['XCS_INTEGRATION_NUMBER']} #{integrationResult}"

# ------------------------------------------------------------------------------------- 
# build up the request body
reqBody = {:message => message}
body = JSON.generate(reqBody)

# ------------------------------------------------------------------------------------- 
# the connect type
http = Net::HTTP.new(uri.host, uri.port)

# ------------------------------------------------------------------------------------- 
# build up the request
request = Net::HTTP::Post.new(uri.request_uri)
request.add_field('Content-type', 'application/json')
request.body = body

# -------------------------------------------------------------------------------------
# send the request and get the response
response = http.request(request)

The prior two Ruby scripts make a call to the message_room file residing in your OS X Server Website home folder (typically /Library/Server/Web/Data/Sites/Default). 前两个Ruby脚本调用驻留在OS X Server Website主文件夹中的message_room文件(通常为/ Library / Server / Web / Data / Sites / Default)。 Place the following message_room file into that folder. 将以下message_room文件放入该文件夹。

#!/usr/bin/env ruby
require 'cgi' 
require 'json' 
require 'xmpp4r' 
require 'xmpp4r/muc'

# ------------------------------------------------------------------------------------- 
# credentials and such
domain = "<domain>.local"
userId = "jeeves@#{domain}"
userPw = "<jeevesAccountPassword>"
roomName = "integration@rooms.#{domain}"

# ------------------------------------------------------------------------------------- 
# header sent back
cgi = CGI.new
puts cgi.header( "type" => "text/html", "status" => "OK")

# ------------------------------------------------------------------------------------- 
# get the message out of the json formatted text
keyValue = JSON.parse(cgi.params.keys.first)
key = "message"
value = keyValue[key] puts value

# ------------------------------------------------------------------------------------- 
# create the message to the iChat (jabber) room
fromJID = Jabber::JID.new(userId)
jabberClient = Jabber::Client.new(fromJID)
jabberClient.connect
jabberClient.auth(userPw)
jabberClient.send(Jabber::Presence.new.set_type(:available))

# ------------------------------------------------------------------------------------- 
# send the message to a chat room
roomID = roomName + "/" + jabberClient.jid.node
roomJID = Jabber::JID::new(roomID)
room = Jabber::MUC::MUCClient.new(jabberClient) room.join(roomJID)
roomMessage = Jabber::Message.new(roomJID, value) room.send(roomMessage)

Starting Integrations from the Messages App 从消息应用程序启动集成

We want to be able to issue instructions to our virtual assistant Jeeves from within the Messages App. 我们希望能够从消息应用程序中向我们的虚拟助手Jeeves发出指令。 We're going to support three instructions: 我们将支持三条指令:

  1. Jeeves, weather # gets the current weather (w/o zip defaults to Cupertino) Jeeves,天气#获取当前天气(没有zip默认为Cupertino)

  2. Jeeves, integration (Bot Name) # starts an integration for the given Bot Jeeves,集成(Bot Name)#开始为给定的Bot集成

  3. Jeeves, exit # shutdown Jeeves on your OS X Server Jeeves,退出#关闭你的OS X服务器上的Jeeves

The following files will be placed in your OS X Server website's default folder (typically /Library/Server/Web/Data/Sites/Default). 以下文件将放置在OS X Server网站的默认文件夹中(通常为/ Library / Server / Web / Data / Sites / Default)。

The main file that handles the virtual assistant, Jeeves, is jeevesManager.rb. 处理虚拟助手Jeeves的主文件是jeevesManager.rb。 Start this file to wake Jeeves up by entering 启动此文件以通过输入唤醒Jeeves

$ ruby ./jeevesManager.rb

from the website's default folder on your server. 从网站上的服务器默认文件夹。

#!/usr/bin/env ruby
require 'xmpp4r'
require 'xmpp4r/muc'
require 'xmpp4r/delay'
require './jeevesWeather.rb' 
require './jeevesIntegration.rb'

# ------------------------------------------------------------------------------------- 
# credentials and such
domain = "<domain>.local"
userId = "jeeves@#{domain}"
userPw = "<jeevesAccountPassword>"
roomName = "integration@rooms.#{domain}" 
defaultWeatherZipCode = "95015"

# ------------------------------------------------------------------------------------- 
# create the client we'll use
fromJID = Jabber::JID.new(userId)
jabberClient = Jabber::Client.new(fromJID)
jabberClient.connect
jabberClient.auth(userPw)
jabberClient.send(Jabber::Presence.new.set_type(:available))

# ------------------------------------------------------------------------------------- 
# connect to the chatroom
roomID = roomName + "/" + jabberClient.jid.node
roomJID = Jabber::JID::new(roomID)
room = Jabber::MUC::MUCClient.new(jabberClient) room.join(roomJID)

# ------------------------------------------------------------------------------------- 
# weather
def getWeather(m)
    begin
        words = m.body.downcase.split("weather") 
        where = defaultWeatherZipCode
        if (words.length == 2)
            where = words[1].strip 
        end
        weather = get_weather_for_city(where,'f') 
    rescue
        weather = "Couldn't get weather for that location - try zip code" 
    end
    return weather 
end

# ------------------------------------------------------------------------------------- 
# integration
def startIntegration(m)
    begin
        words = m.body.split("integrate") 
        botName = "Invalid BOT Name"
        if (words.length == 2)
            botName = words[1].strip 
        end
        integrationMessage = jeevesIntegration(botName) 
    rescue
        integrationMessage = "Failed integrating #{botName}" 
    end
    return integrationMessage 
end

# ------------------------------------------------------------------------------------- 
# listen for messages in chatroom (this callback will run in a separate thread) 
room.add_message_callback do |m|
    if (m.x.nil?) # the msg is current 
        if m.type != :error
            body = m.body;
            if (body.downcase.include? "jeeves")

                # assume Jeeves does not understand command
                understood = 0

                # exit Jeeves
                if (body.downcase.include? "exit") 
                    understood = 1
                    message = "Good-bye"
                    mainthread.wakeup
                end

                # Weather
                if (body.downcase.include? "weather") 
                    understood = 1
                    message = getWeather(m) 
                end

                # Integrate BOT
                if (body.downcase.include? "integrate") 
                    understood = 1
                    message = startIntegration(m) 
                end

                # Jeeves doesn't understand command
                if (understood == 0)
                    message = "I don't understand that command!"
                end

                # let user know what has happened
                roomMessage = Jabber::Message.new(roomJID, message)
                room.send(roomMessage)
            end
        end
    end
end


# ------------------------------------------------------------------------------------- 
# add the callback to respond to server ping (to keep the connect alive)
jabberClient.add_iq_callback do |iq_received|
    if iq_received.type == :get
        if iq_received.queryns.to_s != 'http://jabber.org/protocol/disco#info'
            iq = Jabber::Iq.new(:result, jabberClient.jid.node) 
            iq.id = iq_received.id
            iq.from = iq_received.to
            iq.to = iq_received.from
            jabberClient.send(iq) 
        end
    end 
end

# ------------------------------------------------------------------------------------- 
# stop the main thread (the call back will still be alive this way)
print "Connected to chat room...\n"
Thread.stop
print "Disconnected from chat room...\n"

# leave chat room and log out of Jabber
room.exit 
jabberClient.close

Two other supplemental files are utilized by the Jeeves manager file above. 上面的Jeeves经理文件使用了另外两个补充文件。 The first one below handles getting the weather forecast and formatting it, and the second handles starting an integration. 下面的第一个处理天气预报和格式化,第二个处理开始集成。

######### Weather #########
require 'rexml/document' 
require 'open-uri' 
require 'net/smtp'

# ------------------------------------------------------------------------------------- 
# yahoo weather url info
# http://developer.yahoo.net/weather/#examples

# ------------------------------------------------------------------------------------- 
#Returns a hash containing the location and temperature information
#Accepts US zip codes or Yahoo location id's
def yahoo_weather_query(loc_id, units)
    h = {}
    open("http://xml.weather.yahoo.com/forecastrss?p=#{loc_id}&u=#{units}") do |http|
    response = http.read
    doc = REXML::Document.new(response)
    root = doc.root
    channel = root.elements['channel']
    location = channel.elements['yweather:location']
    h[:city] = location.attributes["city"]
    h[:region] = location.attributes["region"]
    h[:country] = location.attributes["country"]
    h[:temp] = channel.elements["item"].elements["yweather:condition"].attributes["temp"]         
    h[:text] = channel.elements["item"].elements["yweather:condition"].attributes["text"] 
    h[:wind_speed] = channel.elements['yweather:wind'].attributes['speed']
    h[:humidity] = channel.elements['yweather:atmosphere'].attributes['humidity'] 
    h[:sunrise] = channel.elements['yweather:astronomy'].attributes['sunrise']
    h[:sunset] = channel.elements['yweather:astronomy'].attributes['sunset']
    h[:forecast_low] = channel.elements["item"].elements['yweather:forecast'].attributes['low']
    h[:forecast_high] = channel.elements["item"].elements['yweather:forecast'].attributes['high'] end
    return h
end

# -------------------------------------------------------------------------------------
def get_weather_for_city(city_code,units)
    weather_info = yahoo_weather_query(city_code, units)
    city = weather_info[:city]
    region = weather_info[:region]
    country = weather_info[:country]
    temp = weather_info[:temp]
    wind_speed = weather_info[:wind_speed]
    humidity = weather_info[:humidity]
    text = weather_info[:text]
    sunrise = weather_info[:sunrise]
    sunset = weather_info[:sunset]
    forecast_low = weather_info[:forecast_low] 
    forecast_high = weather_info[:forecast_high]

    return "#{city}, #{region}:\n" + " Currently #{temp} degrees, #{humidity}% humidity, #{wind_speed} mph winds, #{text}.\n" + " Forecast: #{forecast_low} low, #{forecast_high} high.\n" + " Sunrise: #{sunrise}, sunset: #{sunset}.\n"
end

Finally, this is the script that kicks off an integration from Messages app 最后,这是启动Messages应用程序集成的脚本

require 'json' 
require 'open-uri' 
require 'openssl'

# -------------------------------------------------------------------------------------
def jeevesIntegration(botToIntegrate)

    # credentials
    domain = "<domain>.local"
    endpoint = "https://#{domain}:20343"
    user = "your-integration-username (not Jeeves)" 
    password = "password"

    # return message
    message = "Bot '#{botToIntegrate}' does not exist on server #{domain}"

    # request JSON construct with all the BOTS
    botsRequestURI = URI.parse("#{endpoint}/api/bots")
    output = open(botsRequestURI, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}) 
    bots = JSON.parse(output.readlines.join(""))

    # loop through full list of BOTS for the one we're interested in
    bots['results'].each do |bot| 
        botName = bot['name']
        if (botName.downcase == botToIntegrate.downcase) 
            botID = bot['_id']

            # curl -k -X POST -u "#{user}:#{password}" "#{endpoint}/api/bots/#{botid}/integrations" -i

            # ------------------------------------------------------------------- 
            # kickoff integration
            uri = URI.parse(endpoint)
            http = Net::HTTP.new(uri.host, uri.port)
            http.use_ssl = true
            http.verify_mode = OpenSSL::SSL::VERIFY_NONE
            request = Net::HTTP::Post.new("/api/bots/#{botID}/integrations")
            request.basic_auth(user, password)
            response = http.request(request)
            message = "Integrating #{botName} on server #{domain}" 
        end
    end

    return message 
end

Yes, as I answered here , you first need to find out the bot _id and then send a POST request to the bot's endpoint. 是的,正如我在这里回答的那样 ,您首先需要找出bot _id ,然后向机器人的端点发送POST请求。 See the link for details. 请参阅链接了解详细信息。

I want to add post-receive hook on github which on receiving any commit should start Xcode bot on my OS X Server. 我想在github上添加post-receive hook,在接收任何提交时应该在我的OS X Server上启动Xcode bot。

If you want to 'build on commit' then just select that option when you create the bot. 如果您想“构建提交”,那么只需在创建机器人时选择该选项。 You have the option to run the bot Manually , Periodically or On Commit . 您可以选择手动定期在提交时运行机器人。 The latter does what you describe. 后者做你所描述的。 As soon as one of your team members commits a change to your github repo, Xcode server will do a build. 只要您的一个团队成员对您的github仓库进行更改,Xcode服务器就会进行构建。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM