专栏首页huginn创建一个新的 Huginn Agent

创建一个新的 Huginn Agent

创建一个新的 Huginn Agent

请注意:Huginn API 一直在改进,因此一些无用的 Agent 或将被放弃。我们非常希望您能将您的使用方法以及 API 应该更改什么告诉我们。查看 #60#293

Huginn Agent 能创建和接受事件,并且能按照预定的安排在特定的时间或时间间隔运行代码。创建一个 Agent 并不难,你可以很轻松的从一个已存在的 Agent 创建一个子 Agent。

Agent 保存在 app/models/agents,RSpec 保存在 spec/models/agents

描述

使用 description 类方法描述你的 Agent。例如:

description <<-MD The WeatherAgent creates an event for the following day's weather at `zipcode`. You must setup an API key for Wunderground in order to use this Agent. MD

123456

description <<-MD  The WeatherAgent creates an event for the following day's weather at `zipcode`.   You must setup an API key for Wunderground in order to use this Agent.MD

选项

Agent 是用户使用 JSON 结构进行配置的,options(选项)非常容易使用,同时还可以使用 Liquid 模板引擎进行更改。你应该定义一个 default_options方法,该方法用来定义默认配置,另外,你还应该定义一个validate_options 方法,该方法会验证 options 的内容,确保一些必填选项已经填写,通常情况下,你是不希望用户更改这些必填选项的,下面是一个具体的例子:

def default_options { 'zipcode' => '94103' } end def validate_options errors.add(:base, 'zipcode is required') unless options['zipcode'].present? end

12345678

def default_options  { 'zipcode' => '94103' }end def validate_options  errors.add(:base, 'zipcode is required') unless options['zipcode'].present?end

时间表

Agent 可以被设定在特定的时间或一定的时间间隔运行,当设定的时间被触发,Agent 内的 check 方法将会被调用。如果你的 Agent 是可调度的,需要定义 default_schedule 方法定义默认值,否则会调用 cannot_be_scheduled!方法。可用的设定时间如下:every_1mevery_2mevery_5mevery_10mevery_30mevery_1hevery_2hevery_5hevery_12hevery_1devery_2devery_7dmidnight1am2am3am4am5am6am7am8am9am10am11amnoon1pm2pm3pm4pm5pm6pm7pm8pm9pm10pm11pm

default_schedule "8pm" def check wunderground.forecast_for(interpolated['zipcode'])['forecast']['simpleforecast']['forecastday'].each do |day| if is_tomorrow?(day) create_event :payload => day.merge('zipcode' => interpolated['zipcode']) end end end

12345678910

default_schedule "8pm" def check  wunderground.forecast_for(interpolated['zipcode'])['forecast']['simpleforecast']['forecastday'].each do |day|    if is_tomorrow?(day)      create_event :payload => day.merge('zipcode' => interpolated['zipcode'])    end  endend

如果你的Agent创建了事件,比如像 WeatherAgent 这样,你应该使用event_description 类方法描述这些事件包含哪些数据。

event_description <<-MD Events look like this: { 'zipcode' => 12345, ... 'maxhumidity' => 93, 'minhumidity' => 63 } MD

1234567891011

event_description <<-MD  Events look like this:       {        'zipcode' => 12345,        ...        'maxhumidity' => 93,        'minhumidity' => 63      }MD

接受事件

如果你的 Agent 能接受事件,定义 receive 方法,该方法接受事件的 array,否则调用 cannot_receive_events! 注释掉它。

创建事件

在代码中,你的 Agent 可以通过 create_event :payload => { ... } 创建事件,否则调用 cannot_create_events! 注释掉它。

内存

Agent 拥有内存池,可以用在时间间隔内或接受事件之间维持状态。它会被自动加载并保存,可通过 memory 获得。

日志

你的 Agent 应该创建日志,尤其是错误发生的时候。通过调用 logerror打印日志信息,还可以使用 :outbound_event:inbound_event 监测事件有关的日志信息。

正在工作吗?

最好将 Agent 实例的运行状态反馈给用户。你需要定义 working? 方法,当一切正常的时候,该方法返回 true。下面的例子中,Agent 创建事件并有一个expected_update_period_in_days 选项:

def working? event_created_within?(interpolated['expected_update_period_in_days']) && !recent_error_logs? end

1234

def working?  event_created_within?(interpolated['expected_update_period_in_days']) && !recent_error_logs?end

当然,你也可以写一些特殊的代码在 working? 方法中。

UI

Agent 的 UI 文件保存在 app/views/agents/agent_views/<agent name>/_show.html.erb 中。如果你需要一些服务器端的功能,你可以 POST 数据到 handle_details_post_agent_path,使用 handle_details_post 方法进行处理。查看示例: ManualEventAgentdetails view

接收web请求

通过 receive_web_request,你的 Agent 可以接收 web 请求。你的 Agent URL 像这样http://yourserver.com/users/:user_id/web_requests/:agent_id/:secret:user_id是用户的 ID, :agent_id 是 Agent 的 ID,secret 是用户的特殊 token,通过receive_web_request 验证。推荐每次调用 receive_web_request 时都要验证 token。例如,你的 Agent 有一个 secret 的选项,每次调用receive_web_request 时,都将其与 params[:secret] 进行比较,从而过滤掉那些无效的请求,

你的 Agent 的 receive_web_request 方法应该返回一个数组 (status, MiME type) 作为响应,示例如下:

[{ status: "success" }, 200]

12

[{ status: "success" }, 200]

["not found", 404, 'text/plain']

12

["not found", 404, 'text/plain']

这里有一个 receive_web_request 例子,如下所示:

<span class="k">def</span> <span class="nf">receive_web_request</span><span class="p">(</span><span class="n">params</span><span class="err">,</span> <span class="nb">method</span><span class="err">,</span> <span class="nb">format</span><span class="p">)</span> <span class="n">secret</span> <span class="o">=</span> <span class="n">params</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="s1">'secret'</span><span class="p">)</span> <span class="k">return</span> <span class="p">[</span><span class="s2">"Please use POST requests only"</span><span class="err">,</span> <span class="mi">401</span><span class="p">]</span> <span class="k">unless</span> <span class="nb">method</span> <span class="o">==</span> <span class="s2">"post"</span> <span class="k">return</span> <span class="p">[</span><span class="s2">"Not Authorized"</span><span class="err">,</span> <span class="mi">401</span><span class="p">]</span> <span class="k">unless</span> <span class="n">secret</span> <span class="o">==</span> <span class="n">interpolated</span><span class="p">[</span><span class="s1">'secret'</span><span class="p">]</span> <span class="c1"># do something with params here</span> <span class="p">[</span><span class="s1">'Done!'</span><span class="err">,</span> <span class="mi">200</span><span class="err">,</span> <span class="s1">'text/plain'</span><span class="p">]</span> <span class="k">end</span>

12345678910

<span class="k">def</span> <span class="nf">receive_web_request</span><span class="p">(</span><span class="n">params</span><span class="err">,</span> <span class="nb">method</span><span class="err">,</span> <span class="nb">format</span><span class="p">)</span>  <span class="n">secret</span> <span class="o">=</span> <span class="n">params</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="s1">'secret'</span><span class="p">)</span>  <span class="k">return</span> <span class="p">[</span><span class="s2">"Please use POST requests only"</span><span class="err">,</span> <span class="mi">401</span><span class="p">]</span> <span class="k">unless</span> <span class="nb">method</span> <span class="o">==</span> <span class="s2">"post"</span>  <span class="k">return</span> <span class="p">[</span><span class="s2">"Not Authorized"</span><span class="err">,</span> <span class="mi">401</span><span class="p">]</span> <span class="k">unless</span> <span class="n">secret</span> <span class="o">==</span> <span class="n">interpolated</span><span class="p">[</span><span class="s1">'secret'</span><span class="p">]</span>   <span class="c1"># do something with params here</span>   <span class="p">[</span><span class="s1">'Done!'</span><span class="err">,</span> <span class="mi">200</span><span class="err">,</span> <span class="s1">'text/plain'</span><span class="p">]</span><span class="k">end</span>

如果你需要从请求中获得更多的参数,也可以定义 receive_web_request 方法如下:

def receive_web_request(request) end

123

def receive_web_request(request)end

WebRequestsController 查看更多详细信息,可参考 WebhookAgentDataOutputAgent 中的 receive_web_request

本文由 Huginn 中文网 翻译,已经获得项目作者授权,项目原文访问Creating a new agent

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • linux 定时任务 Crontab 使用方法

    用户所建立的 crontab 文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式...

    huginn 中文网
  • 利用 Cloudmailin 服务解析邮件

    Cloudmailin 服务可以将邮件转化成 HTTP POST,这与 Webhook Agent 结合使用的话,可以实现很多有趣的功能,具体的设置步骤如下:

    huginn 中文网
  • 筛选 RSS 源,制作新的全文 RSS 源

    问题:假如你喜欢的网站只提供摘要型的 RSS 源,但是你希望能在 RSS 阅读器中阅读全文 RSS,同时还希望它只推送某些特定的文章 解决方法:利用 Hugin...

    huginn 中文网
  • CSS 使用 Flex 布局来制作一个骰子

    我在上一篇博文 CSS 布局_2 Flex弹性盒中,对 Flex 弹性盒有着详细的介绍,在这里,我们使用 Flex 弹性盒布局,来实现骰子的布局,一个面可以设置...

    Nian糕
  • 筛选 RSS 源,制作新的全文 RSS 源

    问题:假如你喜欢的网站只提供摘要型的 RSS 源,但是你希望能在 RSS 阅读器中阅读全文 RSS,同时还希望它只推送某些特定的文章 解决方法:利用 Hugin...

    huginn 中文网
  • 利用 Cloudmailin 服务解析邮件

    Cloudmailin 服务可以将邮件转化成 HTTP POST,这与 Webhook Agent 结合使用的话,可以实现很多有趣的功能,具体的设置步骤如下:

    huginn 中文网
  • CSS3

    天天_哥
  • 在Mac下配置PHP开发环境:Apache+php+MySql

    <span class="pln">sudo apachectl start</span>

    慕白
  • 对libevent+多线程服务器模型的C++封装类

    最近在看memcached的源码,觉得它那种libevent+多线程的服务器模型真的很不错,我将这个模型封装成一个C++类,根据我的简单测试,这个模型的效率真...

    bear_fish
  • linux 定时任务 Crontab 使用方法

    用户所建立的 crontab 文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式...

    huginn 中文网

扫码关注云+社区

领取腾讯云代金券