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