func (c *Client) TriggerBatch(batch []Event) (*TriggerBatchChannelsList, error) {
	hasEncryptedChannel := false
	for _, event := range batch {
		if !validChannel(event.Channel) {
			return nil, fmt.Errorf("The channel named %s has a non-valid name", event.Channel)
		}
		if err := validateSocketID(event.SocketID); err != nil {
			return nil, err
		}
		if isEncryptedChannel(event.Channel) {
			hasEncryptedChannel = true
		}
	}
	masterKey, keyErr := c.encryptionMasterKey()
	if hasEncryptedChannel && keyErr != nil {
		return nil, keyErr
	}
	payload, err := encodeTriggerBatchBody(batch, masterKey, c.OverrideMaxMessagePayloadKB)
	if err != nil {
		return nil, err
	}
	path := fmt.Sprintf("/apps/%s/batch_events", c.AppID)
	triggerURL, err := createRequestURL("POST", c.Host, path, c.Key, c.Secret, authTimestamp(), c.Secure, payload, nil, c.Cluster)
	if err != nil {
		return nil, err
	}
	response, err := c.request("POST", triggerURL, payload)
	if err != nil {
		return nil, err
	}
	return unmarshalledTriggerBatchChannelsList(response)
}
/*
TriggerBatch triggers multiple events on multiple channels in a single call:

info := "subscription_count"
socketID := "1234.12"
client.TriggerBatch([]pusher.Event{
{ Channel: "donut-1", Name: "ev1", Data: "d1", SocketID: socketID, Info: &info },
{ Channel: "private-encrypted-secretdonut", Name: "ev2", Data: "d2", SocketID: socketID, Info: &info },
})
package pusher
import (
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"regexp"
	"strings"
	"time"
)
var pusherPathRegex = regexp.MustCompile("^/apps/([0-9]+)$")
var maxTriggerableChannels = 100
const (
	libraryVersion = "5.0.0"
	libraryName    = "pusher-http-go"
)
type Client struct {
	AppID                        string
	Key                          string
	Secret                       string
	Host                         string  
	Secure                       bool    
	Cluster                      string
	HTTPClient                   *http.Client
	EncryptionMasterKey          string   
	EncryptionMasterKeyBase64    string   
	OverrideMaxMessagePayloadKB  int      
	validatedEncryptionMasterKey *[]byte  
}
func ClientFromURL(serverURL string) (*Client, error) {
	url2, err := url.Parse(serverURL)
	if err != nil {
		return nil, err
	}
	c := Client{
		Host: url2.Host,
	}
	matches := pusherPathRegex.FindStringSubmatch(url2.Path)
	if len(matches) == 0 {
		return nil, errors.New("No app ID found")
	}
	c.AppID = matches[1]
	if url2.User == nil {
		return nil, errors.New("Missing <key>:<secret>")
	}
	c.Key = url2.User.Username()
	var isSet bool
	c.Secret, isSet = url2.User.Password()
	if !isSet {
		return nil, errors.New("Missing <secret>")
	}
	if url2.Scheme == "https" {
		c.Secure = true
	}
	return &c, nil
}
func ClientFromEnv(key string) (*Client, error) {
	url := os.Getenv(key)
	return ClientFromURL(url)
}
func (c *Client) requestClient() *http.Client {
	if c.HTTPClient == nil {
		c.HTTPClient = &http.Client{Timeout: time.Second * 5}
	}
	return c.HTTPClient
}
func (c *Client) request(method, url string, body []byte) ([]byte, error) {
	return request(c.requestClient(), method, url, body)
}
func (c *Client) Trigger(channel string, eventName string, data interface{}) error {
	_, err := c.trigger([]string{channel}, eventName, data, TriggerParams{})
	return err
}
type TriggerParams struct {
	SocketID *string
	Info *string
}
func (params TriggerParams) toMap() map[string]string {
	m := make(map[string]string)
	if params.SocketID != nil {
		m["socket_id"] = *params.SocketID
	}
	if params.Info != nil {
		m["info"] = *params.Info
	}
	return m
}
func (c *Client) TriggerWithParams(
	channel string,
	eventName string,
	data interface{},
	params TriggerParams,
) (*TriggerChannelsList, error) {
	return c.trigger([]string{channel}, eventName, data, params)
}
func (c *Client) TriggerMulti(channels []string, eventName string, data interface{}) error {
	_, err := c.trigger(channels, eventName, data, TriggerParams{})
	return err
}
func (c *Client) TriggerMultiWithParams(
	channels []string,
	eventName string,
	data interface{},
	params TriggerParams,
) (*TriggerChannelsList, error) {
	return c.trigger(channels, eventName, data, params)
}
func (c *Client) TriggerExclusive(channel string, eventName string, data interface{}, socketID string) error {
	params := TriggerParams{SocketID: &socketID}
	_, err := c.trigger([]string{channel}, eventName, data, params)
	return err
}
func (c *Client) TriggerMultiExclusive(channels []string, eventName string, data interface{}, socketID string) error {
	params := TriggerParams{SocketID: &socketID}
	_, err := c.trigger(channels, eventName, data, params)
	return err
}
func (c *Client) trigger(channels []string, eventName string, data interface{}, params TriggerParams) (*TriggerChannelsList, error) {
	if len(channels) > maxTriggerableChannels {
		return nil, fmt.Errorf("You cannot trigger on more than %d channels at once", maxTriggerableChannels)
	}
	if !channelsAreValid(channels) {
		return nil, errors.New("At least one of your channels' names are invalid")
	}
	hasEncryptedChannel := false
	for _, channel := range channels {
		if isEncryptedChannel(channel) {
			hasEncryptedChannel = true
		}
	}
	if hasEncryptedChannel && len(channels) > 1 {
		return nil, errors.New("You cannot trigger to multiple channels when using encrypted channels")
	}
	masterKey, keyErr := c.encryptionMasterKey()
	if hasEncryptedChannel && keyErr != nil {
		return nil, keyErr
	}
	if err := validateSocketID(params.SocketID); err != nil {
		return nil, err
	}
	payload, err := encodeTriggerBody(channels, eventName, data, params.toMap(), masterKey, c.OverrideMaxMessagePayloadKB)
	if err != nil {
		return nil, err
	}
	path := fmt.Sprintf("/apps/%s/events", c.AppID)
	triggerURL, err := createRequestURL("POST", c.Host, path, c.Key, c.Secret, authTimestamp(), c.Secure, payload, nil, c.Cluster)
	if err != nil {
		return nil, err
	}
	response, err := c.request("POST", triggerURL, payload)
	if err != nil {
		return nil, err
	}
	return unmarshalledTriggerChannelsList(response)
}
type Event struct {
	Channel  string
	Name     string
	Data     interface{}
	SocketID *string
	Info *string
}