diff --git a/conversation/conversation.go b/conversation/conversation.go
index f0ee48f..c041900 100644
--- a/conversation/conversation.go
+++ b/conversation/conversation.go
@@ -51,6 +51,11 @@ func (c *Conversation) Start(ctx context.Context) {
 func (c *Conversation) LaunchEngine(ctx context.Context) {
 	ctx, cancel := context.WithCancel(ctx)
 	defer cancel()
+	defer func() {
+		logrus.Debug("Closing engine queues")
+		close(c.engineQueues.ReadQ)
+		close(c.engineQueues.WriteQ)
+	}()
 
 	stdin, stdout, stderr, err := c.engine.Setup(ctx)
 	if err != nil {
@@ -108,10 +113,6 @@ func (c *Conversation) LaunchEngine(ctx context.Context) {
 		logrus.Error("Engine failed:", err)
 		return
 	}
-
-	// Close engine queues
-	close(c.engineQueues.ReadQ)
-	close(c.engineQueues.WriteQ)
 }
 
 func (c *Conversation) Post(m *message.Message) {
diff --git a/conversation/manager.go b/conversation/manager.go
index dc8ef82..631c0e0 100644
--- a/conversation/manager.go
+++ b/conversation/manager.go
@@ -294,8 +294,8 @@ func (cm *Manager) GetConversations(ctx context.Context, m *message.Message) []*
 						conversations = append(conversations, &c)
 						logrus.Debugf("New channel conversation with %s: %+v", config.Name, c)
 					} else {
-						logrus.Debugf("Ignoring trigger as bot already active: channel='%s' msg='%s' trigger='%s'",
-							c.channelName, m.Text, re.String())
+						logrus.Debugf("Ignoring trigger as bot already active: %s: channel='%s' msg='%s' trigger='%s'",
+							config.Name, c.channelName, m.Text, re.String())
 					}
 				}
 
diff --git a/examples/cuckoobot/Makefile b/examples/cuckoobot/Makefile
new file mode 100644
index 0000000..fe59861
--- /dev/null
+++ b/examples/cuckoobot/Makefile
@@ -0,0 +1,16 @@
+CONFIG_DIR = $(HOME)/teabot-engines
+
+all:
+	@echo Run \"make install\" to install the cuckoobot engine
+
+install: $(CONFIG_DIR) $(CONFIG_DIR)/cuckoobot.yaml $(CONFIG_DIR)/cuckoobot.sh
+
+$(CONFIG_DIR)/cuckoobot.yaml: cuckoobot.yaml.tmpl
+	sed -e 's|@CONFIG_DIR@|$(CONFIG_DIR)|' $< > $@
+
+$(CONFIG_DIR)/cuckoobot.sh: cuckoobot.sh
+	cp $< $@
+	chmod 755 $@
+
+$(CONFIG_DIR):
+	mkdir -p $@
diff --git a/examples/cuckoobot/README.md b/examples/cuckoobot/README.md
new file mode 100644
index 0000000..7f4bba5
--- /dev/null
+++ b/examples/cuckoobot/README.md
@@ -0,0 +1,19 @@
+## Basic bot engine
+
+A simple bot which prints the message "cuckoo" on the hour every hour in any
+channel it is invited into.
+
+### Installation
+
+```
+make install
+```
+
+This copies the bot's config as well as the bot script to the
+default config directory: `~/teabot-engines`.
+
+If `teabot` is already running, make it reload its engines:
+
+```
+pkill -HUP teabot
+```
diff --git a/examples/cuckoobot/cuckoobot.sh b/examples/cuckoobot/cuckoobot.sh
new file mode 100755
index 0000000..8aa61d5
--- /dev/null
+++ b/examples/cuckoobot/cuckoobot.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+while :; do
+	# Say cuckoo every hour
+	if ! (( `date +'%M'` % 60 )); then
+		echo "cuckoo"
+	fi
+	sleep 60
+done
diff --git a/examples/cuckoobot/cuckoobot.yaml.tmpl b/examples/cuckoobot/cuckoobot.yaml.tmpl
new file mode 100644
index 0000000..72159cd
--- /dev/null
+++ b/examples/cuckoobot/cuckoobot.yaml.tmpl
@@ -0,0 +1,3 @@
+handler: @CONFIG_DIR@/cuckoobot.sh
+threaded: false
+direct-messages-only: false