slacknimate

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2020 License: MPL-2.0 Imports: 7 Imported by: 0

README

slacknimate

Realtime text animation for Slack messages 👯

Primary use case: ChatOps

deployinator-example

Alternative uses

While slacknimate is primarily intended for ChatOps, it has become popular for... other use cases.

...Such as comedy:

thisisfine-example

...Or maybe art:

nyancat-example

Installation

Simply download a binary for your OS/architecture from the Releases Page and put it somewhere on your $PATH.

Homebrew users, you can also just brew install slacknimate.

Authentication

Generate your Slack app and generate an API token. Note that the app will need appropriate OAuth scopes to post messages to your desired destination.

You'll need to either pass it to the program via the --api-token flag or store it as SLACK_TOKEN environment variable.

Usage

NAME:
   slacknimate - text animation for Slack messages

USAGE:
   slacknimate [options]

VERSION:
   1.1.0-development

GLOBAL OPTIONS:
   --token value, -a value    Slack API token* [$SLACK_TOKEN]
   --channel value, -c value  Slack channel* [$SLACK_CHANNEL]
   --username value           Slack username [$SLACK_USERNAME]
   --icon-url value           Slack icon from url [$SLACK_ICON_URL]
   --icon-emoji value         Slack icon from emoji [$SLACK_ICON_EMOJI]
   --delay value, -d value    minimum delay between frames (default: 1)
   --loop, -l                 loop content upon reaching EOF (default: false)
   --preview                  preview on terminal only (default: false)
   --help, -h                 show help (default: false)
   --version, -v              print the version (default: false)

You can also use Slacknimate directly via the Go package.

Simple animation loops
$ slacknimate -c "#general" --loop < examples/emoji.txt

slacknimate1

Realtime process monitoring

Why spam a chatroom with periodic monitoring messages when you can have realtime status updates so that a message is never out of date?

See for example this example:

$ ./examples/process.sh 5 | slacknimate -c "#devops"
2016/02/23 19:03:14 initial frame G07AJU0SH/1456272194.000086: Processing items: 0/5
2016/02/23 19:03:15 updated frame G07AJU0SH/1456272194.000086: Processing items: 1/5
2016/02/23 19:03:16 updated frame G07AJU0SH/1456272194.000086: Processing items: 2/5
2016/02/23 19:03:17 updated frame G07AJU0SH/1456272194.000086: Processing items: 3/5
2016/02/23 19:03:18 updated frame G07AJU0SH/1456272194.000086: Processing items: 4/5
2016/02/23 19:03:19 updated frame G07AJU0SH/1456272194.000086: Processing items: 5/5

Done!

slacknimate2

Preview in terminal

If you aren't certain about your source, you can preview what the animation would look like in the terminal via the --preview flag.

$ slacknimate --preview --loop -d 0.25 < examples/sample.txt

slacknimate3

Documentation

Overview

Package slacknimate provides facilities for posting continuous realtime status updates to a single Slack message.

Index

Constants

This section is empty.

Variables

View Source
var ErrMaxFramesExceeded = errors.New("maximum number of frames exceeded")

ErrMaxFramesExceeded is returned by (*LoopingLineScanner).Err() if its underlying io.Reader provides more lines of input than its specified maximum number of frames.

Functions

func Updater added in v1.1.0

func Updater(ctx context.Context,
	api *slack.Client,
	channelID string,
	frames <-chan string,
	opts UpdaterOptions) error

Updater posts and updates the "animated" message via the Slack API. It consumes the required frames chan, posting the initial frame as a Slack message to the provided destination Slack channel, and using each subsequent frame to update the text of the posted message.

The Slack channel can be an encoded ID, or a name.

The Slack api client should be configured using an authentication token that is bearing appropriate OAuth scopes for its destination and options.

Results

This function blocks until the provided frame chan is closed, or it encounters a fatal condition. This fatal condition will be returned as a non-nil error, an example would be not being able to make the initial post to Slack. Subsequent message update errors may be transient and thus are not considered fatal errors, and can be monitored or handled via the UpdaterOptions.UpdateFunc callback.

Monitoring Realtime Updates

If you wish to monitor or act upon individual updates to the Updater completing, you can set an UpdateFunc callback in the opts. For example, to simply log intermediate errors:

opts.UpdateFunc = func(u Update) {
    if u.Err != nil {
        log.Println(err)
    }
}

Or to get the updates sent back to you on a buffered channel:

updateChan := make(chan Update, 50)
opts.UpdateFunc = func(u Update) {
    updateChan <- res
}

This allows the consumer the most flexibility in how to consume these updates.

Types

type LineScanner added in v1.1.0

type LineScanner struct {
	// contains filtered or unexported fields
}

LineScanner will scan over an io.Reader line by line, broadcasting each line as a string over its Frames() channel. Once the io.Reader reaches EOF, the output channel will be closed.

func NewLineScanner added in v1.1.0

func NewLineScanner(ctx context.Context, in io.Reader) *LineScanner

NewLineScanner starts and returns a new LineScanner for a given io.Reader.

func (*LineScanner) Err added in v1.1.0

func (s *LineScanner) Err() error

Err returns the underlying error which was the cause of the LineScanner closing its Frames channel. If the reason was the underlying io.Reader encountered io.EOF, then Err will be nil.

func (*LineScanner) Frames added in v1.1.0

func (s *LineScanner) Frames() <-chan string

Frames returns a channel which will broadcast a string with the contents of every line scanned from the underlying io.Reader.

type LoopingLineScanner added in v1.1.0

type LoopingLineScanner struct {
	// contains filtered or unexported fields
}

LoopingLineScanner will first consume an entire underlying io.Reader until EOF, and then continuously loop its lines on the Frames channel and never close, unless its internal context is cancelled.

A LoopingLineScanner has little practical usage (known to the author anyhow) outside of creating animations that loop continulously, e.g. art and memes!

func NewLoopingLineScanner added in v1.1.0

func NewLoopingLineScanner(ctx context.Context, in io.Reader, maxFrames int) *LoopingLineScanner

NewLoopingLineScanner generates a LoopingLineScanner which will first consume an entire io.Reader until EOF, and then continuously loop its lines on the Frames() channel and never close unless its underlying context is canceled.

As a result, it is only suitable for an input value that will have an EOF, as otherwise it will continue consuming memory while never sending anything. You can mitigate this risk by providing the required maxFrames parameter: if the underlying io.Reader in exceeds this many lines of input, the Scanner will be halted with an error and the output channel closed. If maxFrames is 0, no checking will occur.

func (*LoopingLineScanner) Err added in v1.1.0

func (s *LoopingLineScanner) Err() error

Err returns the underlying error which was the cause of the LoopingLineScanner closing its Frames channel.

The likely scenarios where this would occur are either an IO error during the initial consumption of the underlying io.Reader (in which case, this error will occur prior to any values being sent over the Frames channel), an io.Reader that provides more lines than the configured maxFrames for the scanner, or the completion of the scanner's context.

func (*LoopingLineScanner) Frames added in v1.1.0

func (s *LoopingLineScanner) Frames() <-chan string

Frames returns a channel which will loop over the scanner's frames forever.

The Frames channel will not begin sending data until the LoopingLineScanner has finished consuming the underlying io.Reader to EOF.

type Update added in v1.1.0

type Update struct {
	Dst   string // target message destination channel ID
	TS    string // target message timestamp in Slack API format
	Frame string // text sent as message payload
	Err   error
}

Update represents the status returned from the Slack API for a specific frame message post or update.

type UpdaterOptions added in v1.1.0

type UpdaterOptions struct {
	MinDelay   time.Duration // minimum delay between frames
	UpdateFunc func(Update)  // callback to perform upon each update result

	Username  string // override bot username
	IconEmoji string // override bot icon with Emoji
	IconURL   string // override bot icon with URL
}

UpdaterOptions contains optional configuration for the Update function.

Directories

Path Synopsis
cmd
slacknimate
Command slacknimate is a basic CLI client for the slacknimate library that posts each line from os.Stdin.
Command slacknimate is a basic CLI client for the slacknimate library that posts each line from os.Stdin.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL