func (q *Queue) ChangeMessageVisibility(msg *Message, timeoutInSeconds int) error {
	_, err := q.service.client.ChangeMessageVisibility(&SDK.ChangeMessageVisibilityInput{
		QueueUrl:          q.url,
		VisibilityTimeout: pointers.Long(timeoutInSeconds),
		ReceiptHandle:     msg.GetReceiptHandle(),
	})
	if err != nil {
		q.service.Errorf("error on `ChangeMessageVisibility`; queue=%s; error=%s;", q.nameWithPrefix, err.Error())
	}
	return err
}
ChangeMessageVisibility sends the request to AWS api to change visibility of the message.
package sqs
import (
	"encoding/json"
	"fmt"
	"sync"
	SDK "github.com/aws/aws-sdk-go/service/sqs"
	"github.com/evalphobia/aws-sdk-go-wrapper/private/pointers"
)
const (
	defaultMessageIDPrefix = "msg_"
	defaultExpireSecond    = 180
	defaultWaitTimeSeconds = 0
)
type Queue struct {
	service *SQS
	name           string
	nameWithPrefix string
	url            *string
	sendSpoolMu sync.Mutex
	sendSpool   []*SDK.SendMessageBatchRequestEntry
	deleteSpoolMu sync.Mutex
	deleteSpool   []*SDK.DeleteMessageBatchRequestEntry
	failedMu     sync.Mutex
	failedSend   []*SDK.BatchResultErrorEntry
	failedDelete []*SDK.BatchResultErrorEntry
	autoDel         bool
	expire          int
	waitTimeSeconds int
}
func NewQueue(svc *SQS, name string, url string) *Queue {
	queueName := svc.prefix + name
	return &Queue{
		service:         svc,
		name:            name,
		nameWithPrefix:  queueName,
		url:             pointers.String(url),
		autoDel:         false,
		expire:          defaultExpireSecond,
		waitTimeSeconds: defaultWaitTimeSeconds,
	}
}
func (q *Queue) AutoDelete(b bool) {
	q.autoDel = b
}
func (q *Queue) SetExpire(sec int) {
	q.expire = sec
}
func (q *Queue) SetWaitTimeSeconds(sec int) {
	q.waitTimeSeconds = sec
}
func (q *Queue) AddMessage(message string) {
	q.sendSpoolMu.Lock()
	defer q.sendSpoolMu.Unlock()
	num := fmt.Sprint(len(q.sendSpool) + 1)
	m := &SDK.SendMessageBatchRequestEntry{
		MessageBody: pointers.String(message),
		Id:          pointers.String(defaultMessageIDPrefix + num),  
	}
	q.sendSpool = append(q.sendSpool, m)
}
func (q *Queue) AddMessageWithGroupID(message string, messageGroupID string) {
	q.sendSpoolMu.Lock()
	defer q.sendSpoolMu.Unlock()
	num := fmt.Sprint(len(q.sendSpool) + 1)
	m := &SDK.SendMessageBatchRequestEntry{
		MessageBody:    pointers.String(message),
		Id:             pointers.String(defaultMessageIDPrefix + num),  
		MessageGroupId: pointers.String(messageGroupID),
	}
	q.sendSpool = append(q.sendSpool, m)
}
func (q *Queue) AddMessageJSONMarshal(message interface{}) error {
	msg, err := json.Marshal(message)
	if err != nil {
		q.service.Errorf("error on Queue.AddMessageJSONMarshal `json.Marshal` message=%s; error=%s;", fmt.Sprint(msg), err.Error())
		return err
	}
	q.AddMessage(string(msg))
	return nil
}
func (q *Queue) AddMessageMap(message map[string]interface{}) error {
	return q.AddMessageJSONMarshal(message)
}
func (q *Queue) Send() error {
	q.sendSpoolMu.Lock()
	defer q.sendSpoolMu.Unlock()
	messages := make(map[int][]*SDK.SendMessageBatchRequestEntry)
	spool := q.sendSpool
	switch {
	case len(spool) > 10:
		for i, msg := range spool {
			v := (i + 1) / 10
			messages[v] = append(messages[v], msg)
		}
	default:
		messages[0] = append(messages[0], spool...)
	}
	errList := newErrors()
	for i := 0; i < len(messages); i++ {
		err := q.send(messages[i])
		if err != nil {
			q.service.Errorf("error on `SendMessageBatch` operation; queue=%s; error=%s;", q.nameWithPrefix, err.Error())
			errList.Add(err)
		}
	}
	q.sendSpool = nil
	if errList.HasError() {
		return errList
	}
	return nil
}
func (q *Queue) send(msg []*SDK.SendMessageBatchRequestEntry) error {
	res, err := q.service.client.SendMessageBatch(&SDK.SendMessageBatchInput{
		Entries:  msg,
		QueueUrl: q.url,
	})
	if len(res.Failed) != 0 {
		q.failedMu.Lock()
		defer q.failedMu.Unlock()
		q.failedSend = append(q.failedSend, res.Failed...)
	}
	return err
}
func (q *Queue) SendSingleMessage(message string) (string, error) {
	res, err := q.service.client.SendMessage(&SDK.SendMessageInput{
		MessageBody: pointers.String(message),
		QueueUrl:    q.url,
	})
	return res.GoString(), err
}
func (q *Queue) Fetch(num int) ([]*Message, error) {
	wait := q.waitTimeSeconds
	if wait == 0 && num > 1 {
		wait = 1  
	}
	resp, err := q.service.client.ReceiveMessage(&SDK.ReceiveMessageInput{
		QueueUrl:            q.url,
		WaitTimeSeconds:     pointers.Long(wait),
		MaxNumberOfMessages: pointers.Long(num),
		VisibilityTimeout:   pointers.Long(q.expire),
	})
	if err != nil {
		q.service.Errorf("error on `ReceiveMessage` operation; queue=%s; error=%s;", q.nameWithPrefix, err.Error())
	}
	if resp == nil || len(resp.Messages) == 0 {
		return nil, err
	}
	if q.autoDel {
		q.AddDeleteList(resp.Messages)
		defer q.DeleteListItems()
	}
	list := make([]*Message, len(resp.Messages))
	for i, msg := range resp.Messages {
		list[i] = NewMessage(msg)
	}
	return list, err
}
func (q *Queue) FetchOne() (*Message, error) {
	msgList, err := q.Fetch(1)
	switch {
	case err != nil:
		return nil, err
	case len(msgList) == 0:
		return nil, nil
	}
	return msgList[0], nil
}
func (q *Queue) FetchBody(num int) []string {
	msgList, err := q.Fetch(num)
	switch {
	case err != nil:
		return nil
	case len(msgList) == 0:
		return nil
	}
	bodies := make([]string, len(msgList))
	for i, msg := range msgList {
		bodies[i] = msg.Body()
	}
	q.AddDeleteList(msgList)
	if q.autoDel {
		defer q.DeleteListItems()
	}
	return bodies
}
func (q *Queue) FetchBodyOne() string {
	bodies := q.FetchBody(1)
	if len(bodies) == 0 {
		return ""
	}
	return bodies[0]
}
func (q *Queue) AddDeleteList(msg interface{}) {
	switch v := msg.(type) {
	case *SDK.Message:
		q.deleteSpoolMu.Lock()
		defer q.deleteSpoolMu.Unlock()
		q.deleteSpool = append(q.deleteSpool, &SDK.DeleteMessageBatchRequestEntry{
			Id:            v.MessageId,
			ReceiptHandle: v.ReceiptHandle,
		})
	case *Message:
		q.deleteSpoolMu.Lock()
		defer q.deleteSpoolMu.Unlock()
		q.deleteSpool = append(q.deleteSpool, &SDK.DeleteMessageBatchRequestEntry{
			Id:            v.GetMessageID(),
			ReceiptHandle: v.GetReceiptHandle(),
		})
	case []*SDK.Message:
		for _, m := range v {
			q.AddDeleteList(m)
		}
	case []*Message:
		for _, m := range v {
			q.AddDeleteList(m.message)
		}
	}
}