github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/docs/blog/_posts/2016-04-25-the-micro-bot.md (about) 1 --- 2 layout: post 3 title: The Micro Bot - ChatOps for microservices 4 date: 2016-04-25 00:00:00 5 --- 6 <br> 7 Today I want to talk to you about bots. 8 9 ###### Bots? Really... 10 11 Now I know what you're thinking. There's a lot of hype around bots at the moment. If you're familiar with 12 chatterbots you'll know it's not a new concept and in fact goes way back to the days of [Eliza](https://en.wikipedia.org/wiki/ELIZA). 13 The renewed fascination with bots has really emerged because we've found more useful functions for them now beyond sheer amusement. They've also 14 shined a light on what may become the next dominant interface for interaction beyond apps, the conversational UI. 15 16 In the engineering world though, bots are not just for conversational purposes, they can be incredibly useful for operational tasks. 17 So much so that most of us techies have become familiar with the term ChatOps. GitHub have been credited with the origins of this term 18 since publicising the creation and use of [Hubot](https://hubot.github.com/), a chatbot for managing technical and business 19 operation tasks. 20 21 Check out this presentation by Jesse Newland on [ChatOpts at GitHub](https://www.youtube.com/watch?v=NST3u-GjjFw) to learn more about it. 22 23 Hubot and bots like it have proven to be incredibly useful in technical organisations and become a staple in the world of ops and automation. 24 The ability to instruct a bot to perform task through HipChat or Slack which you would otherwise perform manually or cron a script for is 25 rather powerful. There's immediate value in the visibility it offers to the entire team. Everyone can see what you're doing and 26 what the effects are. 27 28 ###### What does this have to do with micro services? 29 30 [**Micro**](https://github.com/tickoalcantara12/micro), the microservice toolkit, includes a number of services which provide entry points into your 31 running systems. The API, Web Dashboard, CLI, etc. These are all fixed points of entry to interact and observe your microservices environment. 32 Over the past few months it became clear that the Bot is another form of entry point to interact and observe and that it should be a first 33 class citizen in the Micro world. 34 35 So with that... 36 37 ###### <center>Introducing The Micro Bot<center> 38 <p align="center"> 39 <img src="{{ site.baseurl }}/blog/images/micro_bot.png" /> 40 </p> 41 42 Let me start by saying, The Micro Bot is a VERY early stage prototype and is currently focused on providing feature parity with the CLI. 43 We're not boasting AI based ChatOps here... but maybe someday... 44 45 The Micro Bot includes hubot like semantics for scripting as [Commands](#commands) and a way of implementing new [Inputs](#inputs) like Slack and 46 Hipchat. It's a rough version 1 but I'm a big believer in shipping as soon as something works and think that by doing so it will open us up to a more rapid 47 paced effort to improve the bot. Hopefully with community contributions! 48 49 The Bot includes all the CLI commands and Inputs for Slack and HipChat. Our community Bot currently runs in the [demo](http://web.micro.pm) 50 environment and is in the Micro Slack right now! Join us [here](http://slack.m3o.com) if you want to check it out. 51 52 In the near term we'll look to add more Input plugins like IRC, XMPP and Commands that simplify managing micro services in a running 53 environment. If you have ideas for other Inputs or Commands or would like to submit a PR for something please do, contributions are 54 more than welcome. 55 Additional plugins can be found in [github.com/micro/go-plugins/bot](https://github.com/micro/go-plugins/tree/master/bot). 56 57 This is really the foundational framework for a programmable bot for the Micro ecosystem. Given the pluggable nature of the entire toolkit it 58 only makes sense to provide something similar in bot form. 59 60 Let's move on to discussing how Inputs and Commands work. 61 62 ###### Inputs 63 64 Inputs are how the micro bot connects to hipchat, slack, irc, xmpp, etc. We've currently got implementations for 65 HipChat and Slack as mentioned above, which seem to cover a significant number of users. 66 67 68 Here's the Input interface. 69 70 ``` 71 type Input interface { 72 // Provide cli flags 73 Flags() []cli.Flag 74 // Initialise input using cli context 75 Init(*cli.Context) error 76 // Stream events from the input 77 Stream() (Conn, error) 78 // Start the input 79 Start() error 80 // Stop the input 81 Stop() error 82 // name of the input 83 String() string 84 } 85 ``` 86 87 The input provides a convenient feature for adding your own command line flags and processing the arguments. 88 The Flags() method is used before initialisation and any flags specified will be added to the global flags list. 89 90 After the flags have been parsed, Init() will be called next so that any context for the Input can be initialised. 91 Once everything is setup, the Bot will call Start() and then Stream() method to create a connection to the Input. 92 93 94 Here's Conn interface returned by Stream method. 95 96 97 ``` 98 type Conn interface { 99 Close() error 100 Recv(*Event) error 101 Send(*Event) error 102 } 103 ``` 104 105 The bot will continuously call Recv() waiting for events. Recv() should essentially be a blocking call otherwise 106 we'll end up in a spin loop that will chew up the CPU. Once the Bot has processed the event it will return 107 some resulting event using the Send() method. 108 109 110 An Event is the common type sent back and forth between the bot and inputs. It allows us to translate various message types 111 of the inputs into a common format. There's currently only a TextEvent type but in the future we have more. 112 113 The bot knows nothing about whether something is from Slack, HipChat or anywhere else. It just knows it's received an event and 114 has to do something with it. It's a great way of separating responsibility of the bot from the input. 115 116 117 Here's the Event type. 118 119 ``` 120 type Event struct { 121 Type EventType 122 From string 123 To string 124 Data []byte 125 Meta map[string]interface{} 126 } 127 ``` 128 129 ###### Commands 130 131 Commands are functions that can be executed by the bot. It's that simple. They're stored in a map, keyed by regex, that will be matched 132 against text events received from the inputs. If a regex matches the event, the associated function will be executed. The command response 133 is then sent back to the input from which the Event originated. If the From field of the originating Event is not blank it will be sent 134 as the To field for the response. You can see how this would then allow the bot to directly communicate with someone or something. 135 136 The current interface for the Command is fairly straight forward but could potentially change in the future if more complex use cases 137 arise. 138 139 The command interface 140 141 ``` 142 type Command interface { 143 // Executes the command with args passed in 144 Exec(args ...string) ([]byte, error) 145 // Usage of the command 146 Usage() string 147 // Description of the command 148 Description() string 149 // Name of the command 150 String() string 151 } 152 ``` 153 154 Here's an example Echo command 155 156 ``` 157 // Echo returns the same message 158 func Echo(ctx *cli.Context) Command { 159 usage := "echo [text]" 160 desc := "Returns the [text]" 161 162 return NewCommand("echo", usage, desc, func(args ...string) ([]byte, error) { 163 if len(args) < 2 { 164 return []byte("echo what?"), nil 165 } 166 return []byte(strings.Join(args[1:], " ")), nil 167 }) 168 } 169 ``` 170 171 And that's the initial building blocks of the bot required to create a conversational interface for Micro services. 172 173 ###### What else? 174 175 It's not enough to just have Inputs and Commands. What if we want to defer some process to a later date? What if 176 we want to persist some state in the bots memory? What about real two way dialog rather than just canned responses? 177 178 It must be built! 179 180 We're still in the early phases of developing the bot framework and it's an opportunity to contribute to what the 181 foundational interface should look like. 182 183 The next step is to provide an interface for <i>streams of consciousness</i>. Sounds...abstract. Being a little more serious, 184 we need a `Stream` interface or something similar, which overlays `Input.Conn` so that we can write plugins for processing 185 all input event streams. 186 187 This should potentially allow the ability to use multiple input streams at the same time. So that we may take events from 188 one stream, process, and then respond elsewhere. 189 190 An example would be receiving a message on Slack, querying a micro service in the platform and sending a summary email. 191 192 ###### Where does it run? 193 194 The micro bot runs in your environment alongside other services. In a way it's just like any other service. It will register 195 with service discovery and leverage it to see everything that's running. 196 197 <p align="center"> 198 <img src="{{ site.baseurl }}/blog/images/bot.png" style="width: 100%; height: auto;" /> 199 </p> 200 201 ###### How do I run it? 202 203 Because the bot behaves like any other service you'll need to be running a service discovery mechanism. The default is consul. 204 205 Using it with Slack is as simple as 206 207 ``` 208 micro bot --inputs=slack --slack_token=SLACK_TOKEN 209 ``` 210 211 And with HipChat 212 213 ``` 214 micro bot --inputs=hipchat --hipchat_username=XMPP_USERNAME --hipchat_password=XMPP_PASSWORD 215 ``` 216 217 ###### The bot in action 218 219 Here's some screengrabs to give you an idea of what it looks like in action. As you can see, it replicates the features of the 220 micro CLI. We've got some extra commands like animate and geocode in the Micro Slack just for kicks. They're 221 in [github.com/micro/go-plugins](https://github.com/micro/go-plugins) if you want to add them yourself. 222 223 <p align="center"> 224 <img src="{{ site.baseurl }}/blog/images/slack.png" style="width: 90%; height: auto;" /> 225 </p> 226 227 <p align="center"> 228 <img src="{{ site.baseurl }}/blog/images/hipchat.png" style="width: 90%; height: auto;" /> 229 </p> 230 231 ###### Adding new Commands 232 233 Commands are functions executed by the bot using text based pattern matching, similar to Hubot or any other ChatOps bot. 234 235 Here's how to write a simple ping command. 236 237 ###### 1. Write a Command 238 239 Firstly create a command using the NewCommand helper. It's basically a quick start for creating commands. 240 You can implement the Command interface yourself too if you like. 241 242 ```go 243 import "github.com/tickoalcantara12/micro/bot/command" 244 245 func Ping() command.Command { 246 usage := "ping" 247 description := "Returns pong" 248 249 return command.NewCommand("ping", usage, desc, func(args ...string) ([]byte, error) { 250 return []byte("pong"), nil 251 }) 252 } 253 ``` 254 255 ###### 2. Register the command 256 257 Add the command to the Commands map with a pattern key that can be matched by [golang/regexp.Match](https://golang.org/pkg/regexp/#Match). 258 259 Here we're saying that we'll only respond to the word "ping". 260 261 ```go 262 import "github.com/tickoalcantara12/micro/bot/command" 263 264 func init() { 265 command.Commands["^ping$"] = Ping() 266 } 267 ``` 268 269 ###### 3. Link the Command 270 271 Create a link with an import for your command. 272 273 link_command.go: 274 275 ```go 276 import _ "path/to/import" 277 ``` 278 279 Build micro with your command 280 281 ```go 282 cd github.com/tickoalcantara12/micro 283 go build -o micro main.go link_command.go 284 ``` 285 286 And that's all there is to creating a command. 287 288 ###### Adding new Inputs 289 290 Inputs are plugins for communication e.g Slack, HipChat, XMPP, IRC, SMTP, etc, etc. 291 292 New inputs can be added in the following way. 293 294 ###### 1. Write an Input 295 296 Write an input that satisfies the Input interface. 297 298 ```go 299 type Input interface { 300 // Provide cli flags 301 Flags() []cli.Flag 302 // Initialise input using cli context 303 Init(*cli.Context) error 304 // Stream events from the input 305 Stream() (Conn, error) 306 // Start the input 307 Start() error 308 // Stop the input 309 Stop() error 310 // name of the input 311 String() string 312 } 313 ``` 314 315 ###### 2. Register the input 316 317 Add the input to the Inputs map. 318 319 ```go 320 import "github.com/tickoalcantara12/micro/bot/input" 321 322 func init() { 323 input.Inputs["name"] = MyInput 324 } 325 ``` 326 327 ###### 3. Link the input 328 329 Create a link with an import for your input plugin. 330 331 link_input.go: 332 333 ```go 334 import _ "path/to/import" 335 ``` 336 337 Build micro with your input 338 339 ```go 340 cd github.com/tickoalcantara12/micro 341 go build -o micro main.go link_input.go 342 ``` 343 344 Inputs are a little tricker to implement than Commands but that's the gist of it. 345 346 ###### What next? 347 348 Making sense of a microservices world isn't easy. It requires a different set of tools and a focus on observability. 349 Monitoring, distributed tracing, structured logging and metrics all play a role but even then it can be difficult. 350 351 Imagine a world in which bots are capable of making sense of distributed systems. Providing 352 feedback when we really need it rather than having to stare at dashboards and deal with false alerts. 353 You've heard of NoOps right? Well what if it was BotOps? What if you never had to be on-call ever again? 354 What if they could be used as 1st point of call or run through a set of procedures to rule out common issues during 355 outages. Just some food for thought. 356 357 Some outlandish ideas and definitely some ways off. At the very least, look for future integrations into Kubernetes, 358 Mesos, etc for managing your services directly from HipChat or Slack and automation of other common tasks. 359 360 ###### Summary 361 362 The bot revolution is upon is. The landscape of infrastructure and automation is changing. We believe bots can play a 363 vital role, initially in a classic ChatOps form but longer term achieving much more. 364 365 Bots should be treated as first class citizens along side configuration management, command line interfaces and APIs. 366 We're doing just that in the Micro ecosystem by including a bot as part of the [Micro toolkit](https://github.com/tickoalcantara12/micro). 367 368 It's still early days but looking very promising thus far. 369 370 If you want to learn more about the services we offer or microservices, check out the [blog](/), the website 371 [micro.mu](https://m3o.com) or the github [repo](https://github.com/tickoalcantara12/micro). 372 373 Follow us on Twitter at [@MicroHQ](https://twitter.com/m3ocloud) or join the [Slack](https://slack.m3o.com) 374 community [here](http://slack.m3o.com). 375