# Hubot Adapter for Discourse

**URL:** https://meta.discourse.org/t/hubot-adapter-for-discourse/63419
**Category:** Extras
**Created:** [May 26, 2017, 5:03am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419 "2017-05-26T05:03:55Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [May 26, 2017, 5:03am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/1 "2017-05-26T05:03:55Z")

</div>

I built a [Hubot](https://hubot.github.com/) adapter for Discourse.

[https://github.com/featheredtoast/hubot-discourse-adapter](https://github.com/featheredtoast/hubot-discourse-adapter)

This should work moderately well for communities that desire bot integrations. There are a few gotchas (see the readme) but for the most part it has been pretty incredible to tinker with so far.

Something my community desired was a dice roller, which I knew existed as a hubot plugin. While there have been other attempts at [integrating dice rollers into discourse](https://meta.discourse.org/t/simple-dice-roller-plugin/9958/15), if I was going to run a bot against my Discourse instance, I wanted the full power of hubot plugins at my disposal. My aim here was to have there be an easy way to integrate such reply features into a Discourse community using an existing and well known bot.

This adapter is about adding a bot that directly listens in to topics and replies in Discourse itself. It differs from a [previous Hubot integration topic](https://meta.discourse.org/t/hubot-integration/26271) as that seemed to be aimed at querying a discourse community in an existing integration (irc, slack, etc) to get discourse stats, and possibly post to a remote Discourse instance.

The bot now polls for messages over Discourse’s message bus.

I created the repository as `hubot-discourse-integration`, as `hubot-discourse` was already taken… Sadly this also had no documentation, code, or announcements here. I wasn’t inclined to trust it, so I built this.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [May 26, 2017, 2:13pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/2 "2017-05-26T14:13:21Z")

</div>

> [@awole20](#):
>
> simply polling /notifications.json every 10 seconds, processing unread notifications, and marking everything as read

You really should use the message bus here, its both faster and significantly less resource intensive.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [May 26, 2017, 2:35pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/3 "2017-05-26T14:35:06Z")

</div>

Ah right, thanks for the tip! I’ll look into that today – I’ve been putting off learning more about the message bus in general, just to get things working.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [May 26, 2017, 9:50pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/4 "2017-05-26T21:50:11Z")

</div>

Alright, I have practically torn apart your message-bus javascript client and adapted it for node and it’s working great! Polling is now done over message bus, so it should be a lot more responsive now! 👍

One more question - Is there any way for me to get the current user, given a user API key? It would be great if a 3rd party app could figure out their own username + id without having to configure it separately.

---

<div class="post-metadata">

### Author: ![Sujan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sujan/32/70979_2.png) [@Sujan](https://meta.discourse.org/u/Sujan)
#### Post date: [October 12, 2017, 6:34pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/5 "2017-10-12T18:34:35Z")

</div>

So, hey, hi, you sent me here in my topic asking for bots.

This bot can jump in if he is @ mentioned in a topic and then do \*\*\* magic \*\*\* which can then ouput in a post in that topic. Correct?

(Thank god for [http://js2.coffee/](http://js2.coffee/) by the way: [https://github.com/janpio/hubot-discourse-adapter/blob/master/src/discourse.js](https://github.com/janpio/hubot-discourse-adapter/blob/master/src/discourse.js) [my terrible JS is better than my non-existant Coffescript])

Some absolute newbie questions:

- Can you show how you for example would configure it to do the dice rolling thing you mentioned above?
- Is the adapter also able to receive/read _all_ new topics being created? (or would I have to modify it to do this?)
- Is there a diagram/flowchart/list online somewhere which methods of your adapter are called in which order when?

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [October 12, 2017, 7:38pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/6 "2017-10-12T19:38:50Z")

</div>

> [@Sujan](#):
>
> Can you show how you for example would configure it to do the dice rolling thing you mentioned above?

Hubot can be configured with both pre-written plug-in scrips, as well as ad-hoc scripts. You can get started with hubot pretty quickly over commandline for local barebones testing of responses. This adapter is only here to allow it to “speak” and respond over discourse.

I ended up splitting up [my bot](https://github.com/featheredtoast/wotcher-docker) from [my custom configuration](https://github.com/featheredtoast/wotcher), so that I could run tests against my custom scripts.

The dice roller can be seen [here](https://github.com/featheredtoast/wotcher/blob/master/src/dice-roller.coffee) and I have an additional (and much simpler) [“if you here anything about ‘the deals’ respond in kind” script](https://github.com/featheredtoast/wotcher/blob/master/src/wotcher.coffee) for fun.

> [@Sujan](#):
>
> Is the adapter also able to receive/read all new topics being created? (or would I have to modify it to do this?)

You can set it up that way - The adapter responds via discourse’s native notifications. Basically, if there’s a discourse notification of a message, the bot will see it. In the bot’s Discourse profile, you can edit and add to the watched categories to allow it to automatically see new topics/replies/etc without a direct @.

EG: for your use case, you would probably want to add your interested categories to “watching first post” and set the “when I post in a topic set that topic to” normal. That way, the bot gets notified on new topics, but does not continue to monitor/reply afterwards.

> [@Sujan](#):
>
> Is there a diagram/flowchart/list online somewhere which methods of your adapter are called in which order when?

Not currently - It follows the same patterns from other hubot adapters - aside from setting up what hubot “hears” in discourse, you really shouldn’t have to mind much about the internals. Mostly you’d be interested in the API, and the difference between function hooks like `robot.hear` vs `robot.respond`. [See the docs for examples!](https://hubot.github.com/docs/scripting/)

---

<div class="post-metadata">

### Author: ![Sujan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sujan/32/70979_2.png) [@Sujan](https://meta.discourse.org/u/Sujan)
#### Post date: [October 13, 2017, 9:22am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/7 "2017-10-13T09:22:31Z")

</div>

Thanks for replying, will take a deeper look later.

While reading I got an idea: Can your adapter already send private messages instead of post to topics? “Moderating in private” might be an interesting concept to have to call out the people in public but nudge them to add the information in private.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [October 13, 2017, 2:56pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/8 "2017-10-13T14:56:51Z")

</div>

Not currently; it was out of my use case, but it would be possible to extend/ modify how the bot replies to send private messages rather than replying inline.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [October 14, 2017, 12:21am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/9 "2017-10-14T00:21:05Z")

</div>

Little bit of work on this tonight –

It’s admittedly a little bit of a custom workaround as hubot doesn’t currently have a concept of PM replying, so I’m relying on a “pm” attribute to be set in `res.envelope` to imply that we want the bot to respond privately.

Here’s an example:

```plaintext
robot.hear /private hello/i, (res) ->
    res.envelope.pm = true
    res.send "I will reply hello privately!"

```

The new PM is titled “About your post in {topic title}”, and has the first line as the URL to the topic in question.

If the bot is already hearing a message within a PM, it replies as normal.

It would be nice if Hubot had the concept of a whisper, but that’s unfortunately out of my hands at the moment.

I also added the ability to arbitrarily add messages to other topics, or trigger sending of messages by way of the `robot.messageRoom` action to be able to generate PMs or reply to arbitrary topics by topic number.

Hope this helps!

---

<div class="post-metadata">

### Author: ![Timothy\_Vail](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/timothy_vail/32/90872_2.png) [@Timothy\_Vail](https://meta.discourse.org/u/Timothy_Vail)
#### Post date: [March 5, 2018, 9:08pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/10 "2018-03-05T21:08:50Z")

</div>

Hi @awole20, I got everything set up, thanks a million for this adapter! It works great, but my hubot can’t respond or operate in the chat box made possible by the Babble plugin. [https://meta.discourse.org/t/babble-a-chat-plugin/31753](https://meta.discourse.org/t/babble-a-chat-plugin/31753)

Is there a way to get it working in there? I set the bot to the room but it doesn’t hear/ pick up anything from the chat channel.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [March 6, 2018, 12:03am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/11 "2018-03-06T00:03:56Z")

</div>

I’m assuming you are expecting the bot to respond to an unprompted reply. You need to “become” the bot (admin → users) and add that topic to “watching” as stated above:

> [@awole20](#):
>
> The adapter responds via discourse’s native notifications. Basically, if there’s a discourse notification of a message, the bot will see it. In the bot’s Discourse profile, you can edit and add to the watched categories to allow it to automatically see new topics/replies/etc without a direct @.

---

<div class="post-metadata">

### Author: ![Timothy\_Vail](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/timothy_vail/32/90872_2.png) [@Timothy\_Vail](https://meta.discourse.org/u/Timothy_Vail)
#### Post date: [March 6, 2018, 12:18am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/12 "2018-03-06T00:18:51Z")

</div>

I understand that, and I think it sees it but can’t send a message somehow. The problem is that it doesn’t operate like a regular topic, because you can’t “watch” it. Maybe @gdpelican , the plugin creator, could provide some insight.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [March 6, 2018, 12:28am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/13 "2018-03-06T00:28:23Z")

</div>

Oh I understand now - sorry, I don’t have much experience with the ins and outs of babble, and have not attempted to set up a Hubot to listen in on a Babble install. If Babble’s notification flow is outside of the normal Discourse notifications, that would block your bot from seeing those messages.

---

<div class="post-metadata">

### Author: ![Timothy\_Vail](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/timothy_vail/32/90872_2.png) [@Timothy\_Vail](https://meta.discourse.org/u/Timothy_Vail)
#### Post date: [March 6, 2018, 12:51am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/14 "2018-03-06T00:51:01Z")

</div>

It seems it sees it somehow, but can’t send back, in my console, this is what I get

```
[Tue Mar 06 2018 00:51:58 GMT+0000 (UTC)] INFO Constructor
[Tue Mar 06 2018 00:51:58 GMT+0000 (UTC)] INFO Run
[Tue Mar 06 2018 00:51:58 GMT+0000 (UTC)] INFO /var/discourse/hubot/scripts/test.js is using deprecated documentation syntax
[Tue Mar 06 2018 00:51:59 GMT+0000 (UTC)] INFO hubot-redis-brain: Using default redis on localhost:6379
[Tue Mar 06 2018 00:52:11 GMT+0000 (UTC)] INFO got notification: { notification_type: 1,
  post_number: 6,
  topic_title: 'Test',
  topic_id: 38,
  excerpt: '@hubot hi',
  username: 'TimothyVail',
  post_url: '/t/test/38/6' }
[Tue Mar 06 2018 00:52:12 GMT+0000 (UTC)] INFO Emitting robot action: greeting, {}
[Tue Mar 06 2018 00:52:12 GMT+0000 (UTC)] INFO Reply { topic_id: 38,
  reply_to_post_number: 6,
  message: 'How\'s it going?' }
[Tue Mar 06 2018 00:52:12 GMT+0000 (UTC)] INFO Reply { topic_id: 38, reply_to_post_number: 6, message: 'Hi there!' }

```

---

<div class="post-metadata">

### Author: ![gdpelican](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gdpelican/32/81308_2.png) [@gdpelican](https://meta.discourse.org/u/gdpelican)
#### Post date: [March 6, 2018, 8:04am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/15 "2018-03-06T08:04:28Z")

</div>

I think this is pretty close to working out of the box, but I’m missing some bit of context or code here to get a fix.

This line:

```plaintext
[Tue Mar 06 2018 00:52:11 GMT+0000 (UTC)] INFO got notification: { notification_type: 1,

```

gets called in hubot-discourse-adapter/discourse.coffee#100, which then calls `this.emit` with some info.  
That info then goes… somewhere (to the script you’ve written for your bot?), which is then seemingly creating a post, but not emitting properly to the server (babble operates on a separate message bus channel from regular topics). So the bit that I’m missing is 'where is the code which generates the lines beginning with ‘Emitting robot action: greeting’?

```plaintext
[Tue Mar 06 2018 00:52:12 GMT+0000 (UTC)] INFO Emitting robot action: greeting, {}
[Tue Mar 06 2018 00:52:12 GMT+0000 (UTC)] INFO Reply { topic_id: 38,
  reply_to_post_number: 6,
  message: 'How\'s it going?' }
[Tue Mar 06 2018 00:52:12 GMT+0000 (UTC)] INFO Reply { topic_id: 38, reply_to_post_number: 6, message: 'Hi there!' }

```

Disclaimer: I’m not familiar with hubot at all 😅

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [March 6, 2018, 5:51pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/16 "2018-03-06T17:51:00Z")

</div>

So something strange is going on with babble’s handling of replying via the API. Here’s a rundown:

The “emitting robot action” log there is in his script. Hubot adapters work by “hearing” messages that emit messages to a user’s script to handle them (Containing such logic as hearing “hello” I want to reply with “oh hi there”). The script has hooks to “reply” or “respond” again using the adapter’s `say` or `reply` method.

Those methods in my adapter simply hook into the Discourse `posts.json` API endpoint here:

[https://github.com/featheredtoast/hubot-discourse-adapter/blob/master/src/discourse.coffee#L142](https://github.com/featheredtoast/hubot-discourse-adapter/blob/master/src/discourse.coffee#L142)

“reply” uses the `reply_to_post_number` parameter, which works great for standard topics, but appears to not get handled well in Babble land.

---

<div class="post-metadata">

### Author: ![gdpelican](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gdpelican/32/81308_2.png) [@gdpelican](https://meta.discourse.org/u/gdpelican)
#### Post date: [March 6, 2018, 7:15pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/18 "2018-03-06T19:15:13Z")

</div>

What is the result of that post? It seems to me like the most likely thing that’s happening is that the `/posts.json` call is creating the post just fine, but that the core Discourse code isn’t able to broadcast to the babble message channel. @Timothy_Vail are you able to figure out whether that `/posts.json` call actually creates a post or not, and if not, what the response to that request is?

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [March 6, 2018, 7:43pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/19 "2018-03-06T19:43:50Z")

</div>

I don’t currently log that… 🤐

I’ll spin up a babble dev instance soon to dig into the cause of this, and make the bot and plugin be a little more friendly - I think it would be excellent if Babble and Hubot – both intending to be used as “chat” like features – played well together.

---

<div class="post-metadata">

### Author: ![Timothy\_Vail](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/timothy_vail/32/90872_2.png) [@Timothy\_Vail](https://meta.discourse.org/u/Timothy_Vail)
#### Post date: [March 6, 2018, 8:32pm UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/20 "2018-03-06T20:32:17Z")

</div>

Sometimes it responds in the chat, but most of the time not. It responded two or three times, but like an hour or more later. In the private messages it was immediate.

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [March 12, 2018, 7:35am UTC](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419/21 "2018-03-12T07:35:03Z")

</div>

So after some testing, it definitely appears that Babble’s message channel doesn’t expect post replies via the API. The response to the /post.json is that it’s fine, 200 OK, with the body containing the details of the new post as expected.

I went ahead and installed a test Discourse env with Babble, and wired up a Hubot to communicate with. The Hubot reply posts will show up in the correct order, but only after a refresh. Before that, it’s like the bot isn’t saying anything. After refreshing the page, all of Hubot’s messages show up in the correct order.

Willing to work with you if I’m able to in order to get this resolved - I’m on the opposite side, where I’m not familiar with Babble’s message notification systems at all.

[Next page](https://meta.discourse.org/t/hubot-adapter-for-discourse/63419.md?page=2)
