Re: [Zotonic-Usr] Realtime twitter updates

105 views
Skip to first unread message

Arjan Scherpenisse

unread,
Oct 29, 2012, 10:03:36 AM10/29/12
to zotoni...@googlegroups.com
What exactly do you want to update?

You could create a function observe_rsc_update_done/2 in your module, which is fired every time a rsc is updated (so also when tweets arrive).

You could then look at the action attribute of the #rsc_update_done record to determine it's an insert, and look at the post_is_a attribute to see if it's a tweet. If so, you can decide to do something...

Arjan

On Mon, Oct 29, 2012 at 2:57 PM, tpbradley <t...@71squared.com> wrote:
Hi all,

I have a zotonic site up and running and have successfully configured the twitter module to receive tweets as they are posted. What I would like to do now is update the website in realtime as the tweets are created, much like Disqus comments. Can someone give me some guidance on how to achieve this?

Thanks

tpbradley

unread,
Oct 29, 2012, 10:40:07 AM10/29/12
to zotoni...@googlegroups.com
Hi Arjan,

Thanks got getting back to me. I think the observe_rsc_update_done/2 function is what I need to implement. I want to show a realtime twitter feed on my site but I'm unsure of how to achieve this. Am I right in thinking I should a new module that implements the observe_rsc_update_done/2 function and enable it in the module admin. Each user on the site would then be observing resource updates. To push an update out to the browser, do I call something like z_session_page:add_script/2 in the observe_rsc_update_done/2 function?

Thanks

Arjan Scherpenisse

unread,
Oct 29, 2012, 2:47:52 PM10/29/12
to zotoni...@googlegroups.com
Hi,

I think the easiest route is to use mod_signal for this: http://zotonic.com/docs/ref/modules/mod_signal.html

You could use mod_signal to do a mod_signal:emit/2 inside the rsc_update_done function, and then connect a wire to the signal on the page (or in the template) where you want the live stream to be.

{% wire action={connect signal={twitter_update} action={growl text="example"}} %}
That should do the trick...
In the arguments of the emit you can even pass in the id of the newly created tweet so your template can show it.

Let us know if this works for you!

Arjan

tpbradley

unread,
Oct 29, 2012, 4:07:26 PM10/29/12
to zotoni...@googlegroups.com
Hi Arjan,

mod_signal looks like just what I need, thanks! I've had a little play and now have my own module thats observing resource changes and calling off to mod_signal:emit/2 however, my web page is not receiving the events. I've found that the admin pages inject some javascript that hooks up the event  

z_event_register("adminwidget_toggle", function(zEvtArgs) {z_queue_postback('window',....

For some reason, my site doesn't inject any javascript registering for the twitter_update event. The following is the JS generated at the bottom of my site page.

<script type='text/javascript'>
$(function() {
z_pageid="LHoOAM4hQzUEZ1JpuUgZ";z_language="en";z_init_postback_forms();
z_default_form_postback = "crWsxAQUWxXHFcho8M0qvrZchu-DaAVrAAZzdWJtaXRkAAl1bmRlZmluZWRkAAl1bmRlZmluZWRqZAAPY29udHJvbGxlcl9wYWdl";
z_stream_start('www.71squared.com:8000');
z_queue_postback('window', 'eLGD-D6_JqKsr-dM83BZ7EkRgFGDaAVkAAVjbGlja2QABndpbmRvd2QABndpbmRvd2gCZAAHY29ubmVjdGwAAAADaAJkAAZzaWduYWxoAmQADnR3aXR0ZXJfdXBkYXRlamgCZAAEbmFtZWQACXVuZGVmaW5lZGgCZAAHYWN0aW9uc2wAAAABaAJkAAVncm93bGwAAAABaAJkAAR0ZXh0awAHZXhhbXBsZWpqamQAFWFjdGlvbl9zaWduYWxfY29ubmVjdA', typeof(zEvtArgs) != 'undefined' ? zEvtArgs : undefined);
});
</script>

Any ideas why this would be? I can't see any major differences between my templates and the mod_base / mod_base_site templates

Cheers
Tom

Arjan Scherpenisse

unread,
Oct 30, 2012, 3:17:41 AM10/30/12
to zotoni...@googlegroups.com
Do you add the {% wire %} in your template with the action={connect...} attribute?
That should be enough.

And of course your template should include the "usual" scripts like in the base template, a lib with zotonic-1.0.js, {% stream %} and {% script %}, iirc

Arjan

tpbradley

unread,
Oct 30, 2012, 8:04:48 AM10/30/12
to zotoni...@googlegroups.com
Yea thats the weird thing, I do have a {% wire %} along with the {% stream %} and {% script %} commands and all the JS. I've tried adding html around the scomps to verify the template is updating correctly. I've also cleared the cache and rescanned all modules just in case ;)

If you examine the page at http://71squared.com:8000 you can see the js files are being included

Below is the contents of my base.tpl file 
Cheers

<!DOCTYPE html>
{# Base TEXT template #}
<html lang="{{ z_language|default:"en"|escape }}">
<head>
<meta charset="utf-8" />
<title>{{ m.config.site.title.value }}: {{ m.rsc[id].pagetitle }}{% block title %}{% endblock %}</title>

<link rel="icon" href="/lib/images/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="/lib/images/favicon.ico" type="image/x-icon" />

<meta name="author" content="71 Squared LTD &copy; 2012" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="text/javascript" src="//use.typekit.net/wab5beo.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
{% all include "_html_head.tpl" %}
    {% lib "bootstrap/css/bootstrap.css" "bootstrap/css/bootstrap-responsive.css" %}
{% block html_head_extra %}{% endblock %}
</head>
<body class="{% block page_class %}{% endblock %}">
{% wire action={connect signal={twitter_update} action={growl text="example"}} %}
    {% block navbar %}
    {% include "_navbar.tpl" %}
    {% endblock %}

<div class="ss-main-poster"> 
{% block pagebanner %}
{% endblock %}
</div>

    <div class="container ss-container" style="">
<div class="row-fluid">
<div class="ss-content ss-rounded-corners">
<div class="ss-padding10">
{% block content_area %}
{% block chapeau %}{% endblock %}
{% block content %}
{% endblock %}
{% endblock %}
</div>
</div>
</div>


      <footer>
  <p style="color:rgba(200,200,200,0.5);">© 71 Squared 2012</p>
      </footer>

    </div> <!-- /container -->

{% include "_js_include.tpl" %}

{% stream %}
{% script %}

    {% all include "_html_body.tpl" %}    
</body>
</html>

Arjan Scherpenisse

unread,
Oct 30, 2012, 12:14:01 PM10/30/12
to zotoni...@googlegroups.com
That seems to be all in order... the websockets connection is also there.
Strange.. it should "just" work...

maybe you can try on the zotonic shell to emit a signal by hand and see if the templates pick it up?

I'll do a small test myself here.

Arjan

Arjan Scherpenisse

unread,
Oct 30, 2012, 12:19:25 PM10/30/12
to zotoni...@googlegroups.com
I just copy-pasted the examples from mod_signal, and they seem to work fine....?

note that the arguments in the connect action function as filters: so in the example, only a growl is triggered when the signal is example and the argument has a {session, 123} tuple.


On 10/30/2012 01:04 PM, tpbradley wrote:

tpbradley

unread,
Oct 30, 2012, 2:16:30 PM10/30/12
to zotoni...@googlegroups.com
Ahhhh, looks like it is all working as expected.... I've just noticed that the growl notifications are displaying at the bottom of the page, so you have to scroll down to see them. I must have a CSS issue somewhere! Thanks for all the help! This signal stuff is awesome!!

A couple of quick questions...

1. How would I go about calling emit from the zotonic shell? I've tried copying in the erlang code as follows but Context is undefined.

mod_signal:emit({example, [{test, "a"}, {session, 123}]}, Context)

2. While I was in the zotonic shell, I noticed some error messages being emitted from the twitter module, which I've just realised is because I have multiple sites pointing at the same database. I will remove these soon which should fix the problem, but thought it was worth mentioning in case a fix could be put in, or better logging of the errors.

17:56:42.322 [info] Twitter: (blogtest) Username = "71squared"
17:56:42.369 [info] Twitter: (admin) Username = "71squared"
17:56:43.061 [info] Twitter: (ssquared) Username = "71squared"
17:56:52.414 [error] Twitter: unknown stream result ({{"HTTP/1.1",420,"Client Error (420)"},[{"content-length","67"},{"content-type","text/html"}],<<"Easy there, Turbo. Too many requests recently. Enhance your calm.\r\n">>})
17:56:52.482 [error] Twitter: unknown stream result ({{"HTTP/1.1",420,"Client Error (420)"},[{"content-length","67"},{"content-type","text/html"}],<<"Easy there, Turbo. Too many requests recently. Enhance your calm.\r\n">>})
17:56:53.149 [error] Twitter: unknown stream result ({{"HTTP/1.1",420,"Client Error (420)"},[{"content-length","67"},{"content-type","text/html"}],<<"Easy there, Turbo. Too many requests recently. Enhance your calm.\r\n">>})

Cheers

Andreas Stenius

unread,
Oct 30, 2012, 3:20:35 PM10/30/12
to zotoni...@googlegroups.com
1. How would I go about calling emit from the zotonic shell? I've tried copying in the erlang code as follows but Context is undefined.
mod_signal:emit({example, [{test, "a"}, {session, 123}]}, Context)

 
Context = z:c(blogtest).

will give you a fresh context to use (replace blogtest with the name of the site for which you want the context).

//Andreas

Arjan Scherpenisse

unread,
Oct 30, 2012, 4:26:36 PM10/30/12
to zotoni...@googlegroups.com

On 10/30/2012 07:16 PM, tpbradley wrote:
17:56:53.149 [error] Twitter: unknown stream result ({{"HTTP/1.1",420,"Client Error (420)"},[{"content-length","67"},{"content-type","text/html"}],<<"Easy there, Turbo. Too many requests recently. Enhance your calm.\r\n">>})

Twitter allows only one connection per user on the streaming API. It will disconnect the previous connection in case of multiple connections per user.

When you have multiple sites on a single DB, then the twitter module is started for each of those sites, using the same credentials, so that means that the twitter modules start fighting for the connections because they keep reconnecting, resulting in the Easy there, Turbo message... Not much to fix there, I'd just make a separate DB for each site. Or try using a single db with multiple schemas per site...

cheers, Arjan


tpbradley

unread,
Oct 30, 2012, 5:12:51 PM10/30/12
to zotoni...@googlegroups.com
Excellent! Thats just what I was looking for thanks!

tpbradley

unread,
Oct 30, 2012, 5:13:37 PM10/30/12
to zotoni...@googlegroups.com
Yea, that makes perfect sense! I thought it was worth mentioning just in case ;)

Cheers!
Reply all
Reply to author
Forward
0 new messages