Shell 技巧 - 解析您的 Twitter 流

作者:Dave Taylor

上个月,我们再次关注 Twitter,并开始开发一个 shell 脚本,让您能够实际解析和响应通过 Twitter 发送的查询。我们的想法是,如果您是一家商店,例如,一条关于“营业时间?”的推文可以自动回复一条包含商店营业时间的推文——简单,但仍然很有趣。

上个月末,我们完成了一个用几行代码就能完成很多工作的脚本

#!/bin/sh

curl="/usr/bin/curl -s"
inurl="http://www.twitter.com/statuses/mentions.xml"
pw='PasswordGoesHere'
temp="/tmp/$(basename $0).$$"

trap "/bin/rm -f $temp" 0 1 9 15 # axe our temp file

$curl -u "davetaylor:$pw" $inurl | \
    grep -E '(<screen_name>|<text>)' | \
    sed 's/@DaveTaylor //;s/  <text>//;s/<\/text>//' | \
    sed 's/    <screen_name>//;s/<\/screen_name>//' | \
    awk '{if (NR % 2 == 1) { printf ("msg=\"%s\"; ",$0) }
          else             { print "id="$0 }}' > $temp

while read buffer
do
    eval $buffer
    echo Twitter user @$id sent message $msg
done < $temp

exit 0

(遗憾的是,它必须硬编码 Twitter 帐户密码,我在这里显然已经删节了。您可以看到我出现“davetaylor”的地方,并可以调整它以匹配您自己的 Twitter 帐户。)

如果我自我评价的话,这是一个相当棘手的脚本。在这里您可以看到,我们解开 Twitter 发送的 XML,并使用复杂的 grep/sed/awk 序列将其转换为两个名称=值对,实例化 msg 和 id。

当我运行脚本时,我看到

Twitter user @TedWahler sent message That sounds like a
very interesting article. When and where can I read
&quot;When Not To Identify your Group Memberships&quot; Dave?

Twitter user @naomimimi sent message i will send you some
of my amazing restedness after sleeping for 20 hours
yesterday. *bzzzt* feel better? :)

Twitter user @GaryBloomer sent message RE: Song. Dave,
don't know if you have an answer yet, but: Supertramp:
If Everyone Was Listening

一个小小的调整可以显示是谁给您发送推文(这些实际上是 @ 回复,这正是它工作的原因):只需更改echo在最终循环中改为echo $id.

想要找到那些缩短的 URL 并编译一个列表吗?这有点棘手,但是您可以使用 tr 和 grep 来完成繁重的工作

$ sh tweet-listen.sh | tr ' ' '\
> ' | grep 'http://'

http://twurl.nl/bco8tq
http://twurl.nl/bco8tq
http://bit.ly/12PvjV

嘿,一定是有人转发了或者什么,同一个 URL 才会出现两次!

不过,我们想要做的是在流中查找特定的模式,所以让我们这样做。

查找模式

简单的方法是更改while read buffer循环来进行解析

while read buffer
do
  eval $buffer
  if [ "$msg" == "hours" ] ; then
    echo "Twitter user @$id asked what our hours are"

  elif [ "$msg" = "address" ] ; then
    echo "Twitter user @$id asked for our address"

  # else
  #   echo Twitter user @$id sent message $msg
  fi
done < $temp

有了这些(以及一些配合的 Twitter 朋友),我现在可以运行脚本并发现

Twitter user @MommyBrain asked for our address
Twitter user @lizhamilton asked what our hours are
Twitter user @valdezign asked what our hours are
Twitter user @bgindra asked what our hours are
Twitter user @MommyBrain asked what our hours are

酷吧,嗯?现在,让我们回复。

回复推文查询

在 2008 年 11 月号的 LJ 中一篇早期的专栏文章“将您的消息推送到 Twitter”(www.linuxjournal.com/article/10222)中,我们已经有一个现成的脚本,可以让您指定您想在 Twitter 上发送什么消息,所以现在只是正确地组装它的问题。

while read buffer
do
  eval $buffer
  if [ "$msg" == "hours" ] ; then
    echo "Twitter user @$id asked what our hours are"
    $tweet "@$id our hours are Mon-Fri 9-5, Sat 10-4."

  elif [ "$msg" = "address" ] ; then
    echo "Twitter user @$id asked for our address"
    $tweet "@$id we're at 123 University Avenue, Anywhere USA"
  fi
done < $temp

在这种情况下,我将重复之前的推文脚本,因为它既简洁又非常有用

#!/bin/sh
# Twitter command line interface

user="DaveTaylor" ; pass='PasswordGoesHere'

curl="/usr/bin/curl"
$curl --silent --user "$user:$pass" --data-ascii \
    "status=$(echo $@ | tr ' ' '+')" \
    "http://twitter.com/statuses/update.json" > /dev/null

echo "(sent tweet $@)"
exit 0

问题比我们目前解决的要复杂一些,因为当我要求人们发送一个词的查询时,我还收到了诸如“directions”和 directions! 之类的东西,而不是仅仅是这个词本身,没有标点符号、引号等等的修饰。

这是我们需要在脚本中处理的事情,所以我们希望清理 msg 值,使其仅为字母数字(或者仅为字母,如果我们的预设响应查询集永远不包含数字)。这可以使用 tr 再次完成,紧接在eval $buffer语句

msg="$(echo $msg | tr -cd '[:alpha:]')"

那不太对。当我们收到“directions”时,实际上引号被 HTML 转义了,所以它们是 &quot; 而不是仅仅是 " 符号。结果呢?quotdirectionsquot。不好。

就像编程世界中的许多事情一样,事情并不像您希望的那么容易。相反,我们将不得不手动剥离引号,作为清理过程的一部分。现在它看起来像这样

msg="$(echo $msg | sed 's/\&quot;//g' | tr -cd '[:alpha:]')"

这有点复杂,但也没那么糟糕。

更大的问题是识别我们何时已经回复了机器人对 Twitter 查询。我确信没有人会喜欢如果对“营业时间?”的查询在接下来的两周内每十分钟得到一个答案!

有两种方法可以解决这个特殊问题,其中一种方法是为每条推文添加时间戳,并弄清楚我们上次自动回复的时间,但这听起来很像工作。相反,我们可以简单地记住我们回复的最新推文,包括用户 ID,并将其用作后续自动回复解析工作的起点。

我本月无法挤出时间,但请放心,下个月我们将添加第三部分,然后讨论如何将其放入 cron 作业中,以便我们的 Twitter 响应机器人每 N 分钟回复来自 Twitter 世界的任何待处理查询。

Ask Dave Taylor iPhone 应用

Dave Taylor 的 Ask Dave Taylor 技术支持 iPhone 应用现在可以通过 Apple iPhone 应用商店以 0.99 美元的价格购买。

它有 2,500 多个技术支持问题和大量的 Linux 和 shell 脚本答案——尽在您的掌握之中。该应用还包括关于拍卖、博客、建立网站流量等等的问答文章。此外,“它是 iPhone 以及地球上任何移动设备的第一个真正的交互式技术支持应用程序”。

请务必访问 www.askdavetaylor.com/app 查看。

Dave Taylor 编写 shell 脚本已经很长时间了。他是流行的 Wicked Cool Shell Scripts 的作者,您可以在 Twitter 上找到他 @DaveTaylor,或者更广泛地访问 www.DaveTaylorOnline.com

加载 Disqus 评论