Пример #1
0
func Animate() command.Command {
	usage := "animate [text]"
	desc := "Returns an animation"

	type Meta struct {
		Status int    `json:"status"`
		Msg    string `json:"msg"`
	}

	type Image struct {
		Url string `json:"url"`
	}

	type Images struct {
		FixedHeight Image `json:"fixed_height"`
	}

	type Result struct {
		Images Images `json:"images"`
	}

	type Results struct {
		Data []Result `json:"data"`
		Meta Meta     `json:"meta"`
	}

	return command.NewCommand("animate", usage, desc, func(args ...string) ([]byte, error) {
		if len(args) < 2 {
			return []byte("animate what?"), nil
		}
		u := url.Values{}
		u.Set("q", strings.Join(args[1:], " "))
		u.Set("limit", "1")
		u.Set("api_key", key)

		rsp, err := http.Get("http://api.giphy.com/v1/gifs/search?" + u.Encode())
		if err != nil {
			return nil, err
		}
		defer rsp.Body.Close()

		var res Results
		if err := json.NewDecoder(rsp.Body).Decode(&res); err != nil {
			return nil, err
		}

		if res.Meta.Status != 200 {
			return nil, fmt.Errorf("returned status: %d %s", res.Meta.Status, res.Meta.Msg)
		}

		if len(res.Data) == 0 {
			return nil, nil
		}

		return []byte(res.Data[0].Images.FixedHeight.Url), nil
	})
}
Пример #2
0
func TestBot(t *testing.T) {
	flagSet := flag.NewFlagSet("test", flag.ExitOnError)
	app := cli.NewApp()
	ctx := cli.NewContext(app, flagSet, nil)

	io := &testInput{
		send: make(chan *input.Event),
		recv: make(chan *input.Event),
		exit: make(chan bool),
	}

	inputs := map[string]input.Input{
		"test": io,
	}

	commands := map[string]command.Command{
		"^echo ": command.NewCommand("echo", "test usage", "test description", func(args ...string) ([]byte, error) {
			return []byte(strings.Join(args[1:], " ")), nil
		}),
	}

	bot := newBot(ctx, inputs, commands)

	if err := bot.start(); err != nil {
		t.Fatal(err)
	}

	// send command
	select {
	case io.recv <- &input.Event{
		Meta: map[string]interface{}{},
		Type: input.TextEvent,
		Data: []byte("echo test"),
	}:
	case <-time.After(time.Second):
		t.Fatal("timed out sending event")
	}

	// recv output
	select {
	case ev := <-io.send:
		if string(ev.Data) != "test" {
			t.Fatal("expected 'test', got: ", string(ev.Data))
		}
	case <-time.After(time.Second):
		t.Fatal("timed out receiving event")
	}

	if err := bot.stop(); err != nil {
		t.Fatal(err)
	}
}
Пример #3
0
func Geocode() command.Command {
	usage := "geocode [address]"
	desc := "Returns the geocoded address; lat,lng"

	type Location struct {
		Lat float64 `json:"lat"`
		Lng float64 `json:"lng"`
	}

	type Geometry struct {
		Location Location `json:"location"`
	}

	type Result struct {
		Geometry Geometry `json:"geometry"`
	}

	type Results struct {
		Results []Result `json:"results"`
		Status  string   `json:"status"`
	}

	return command.NewCommand("geocode", usage, desc, func(args ...string) ([]byte, error) {
		if len(args) < 2 {
			return []byte("geocode what?"), nil
		}
		u := url.Values{}
		u.Set("address", strings.Join(args[1:], " "))

		rsp, err := http.Get("https://maps.googleapis.com/maps/api/geocode/json?" + u.Encode())
		if err != nil {
			return nil, err
		}
		defer rsp.Body.Close()

		var res Results
		if err := json.NewDecoder(rsp.Body).Decode(&res); err != nil {
			return nil, err
		}

		if res.Status != "OK" {
			return nil, fmt.Errorf("returned status: %s", res.Status)
		}

		lat := res.Results[0].Geometry.Location.Lat
		lng := res.Results[0].Geometry.Location.Lng
		val := fmt.Sprintf("%.6f,%.6f", lat, lng)

		return []byte(val), nil
	})
}
Пример #4
0
func WhereAreYou() command.Command {
	usage := "where are you?"
	desc := "Returns the location of the bot"

	getIp := func() string {
		ifaces, _ := net.Interfaces()

		for _, i := range ifaces {
			addrs, _ := i.Addrs()

			for _, addr := range addrs {
				if ip, ok := addr.(*net.IPNet); ok && ip.IP.IsLoopback() {
					continue
				}

				switch v := addr.(type) {
				case *net.IPNet:
					return v.IP.String()
				case *net.IPAddr:
					return v.IP.String()
				}
			}
		}

		return "127.0.0.1"
	}

	return command.NewCommand("whereareyou", usage, desc, func(args ...string) ([]byte, error) {
		rsp, err := http.Get("http://myexternalip.com/raw")
		if err != nil {
			return nil, err
		}
		defer rsp.Body.Close()

		b, err := ioutil.ReadAll(rsp.Body)
		if err != nil {
			return nil, err
		}

		host, _ := os.Hostname()
		exIp := string(b)
		inIp := getIp()

		val := fmt.Sprintf("hostname: %s\ninternal ip: %s\nexternal ip: %s", host, inIp, exIp)
		return []byte(val), nil
	})
}
Пример #5
0
func help(commands map[string]command.Command) command.Command {
	usage := "help"
	desc := "Displays help for all known commands"

	var cmds []command.Command

	for _, cmd := range commands {
		cmds = append(cmds, cmd)
	}

	sort.Sort(sortedCommands{cmds})

	return command.NewCommand("help", usage, desc, func(args ...string) ([]byte, error) {
		response := []string{"\n"}
		for _, cmd := range cmds {
			response = append(response, fmt.Sprintf("%s - %s", cmd.Usage(), cmd.Description()))
		}
		return []byte(strings.Join(response, "\n")), nil
	})
}