// Code generated by smithy-go-codegen DO NOT EDIT.

package connect

import (
	"context"
	"fmt"
	"github.com/aws/aws-sdk-go-v2/service/connect/types"
	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
)

// Places an outbound call to a contact, and then initiates the flow. It performs
// the actions in the flow that's specified (in ContactFlowId ).
//
// Agents do not initiate the outbound API, which means that they do not dial the
// contact. If the flow places an outbound call to a contact, and then puts the
// contact in queue, the call is then routed to the agent, like any other inbound
// case.
//
// Dialing timeout for this operation can be configured with the
// “RingTimeoutInSeconds” parameter. If not specified, the default dialing timeout
// will be 60 seconds which means if the call is not connected within 60 seconds,
// it fails.
//
// UK numbers with a 447 prefix are not allowed by default. Before you can dial
// these UK mobile numbers, you must submit a service quota increase request. For
// more information, see [Connect Customer Service Quotas]in the Connect Customer Administrator Guide.
//
// Campaign calls are not allowed by default. Before you can make a call with
// TrafficType = CAMPAIGN , you must submit a service quota increase request to the
// quota [Connect Customer campaigns].
//
// For Preview dialing mode, only the Amazon Connect outbound campaigns service
// principal is allowed to assume a role in your account and call this API with
// OutboundStrategy.
//
// [Connect Customer Service Quotas]: https://docs.aws.amazon.com/connect/latest/adminguide/amazon-connect-service-limits.html
// [Connect Customer campaigns]: https://docs.aws.amazon.com/connect/latest/adminguide/amazon-connect-service-limits.html#outbound-communications-quotas
func (c *Client) StartOutboundVoiceContact(ctx context.Context, params *StartOutboundVoiceContactInput, optFns ...func(*Options)) (*StartOutboundVoiceContactOutput, error) {
	if params == nil {
		params = &StartOutboundVoiceContactInput{}
	}

	result, metadata, err := c.invokeOperation(ctx, "StartOutboundVoiceContact", params, optFns, c.addOperationStartOutboundVoiceContactMiddlewares)
	if err != nil {
		return nil, err
	}

	out := result.(*StartOutboundVoiceContactOutput)
	out.ResultMetadata = metadata
	return out, nil
}

type StartOutboundVoiceContactInput struct {

	// The identifier of the flow for the outbound call. To see the ContactFlowId in
	// the Connect Customer admin website, on the navigation menu go to Routing,
	// Contact Flows. Choose the flow. On the flow page, under the name of the flow,
	// choose Show additional flow information. The ContactFlowId is the last part of
	// the ARN, shown here in bold:
	//
	// arn:aws:connect:us-west-2:xxxxxxxxxxxx:instance/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/contact-flow/846ec553-a005-41c0-8341-xxxxxxxxxxxx
	//
	// This member is required.
	ContactFlowId *string

	// The phone number of the customer, in E.164 format.
	//
	// This member is required.
	DestinationPhoneNumber *string

	// The identifier of the Connect Customer instance. You can [find the instance ID] in the Amazon
	// Resource Name (ARN) of the instance.
	//
	// [find the instance ID]: https://docs.aws.amazon.com/connect/latest/adminguide/find-instance-arn.html
	//
	// This member is required.
	InstanceId *string

	// Configuration of the answering machine detection for this outbound call.
	AnswerMachineDetectionConfig *types.AnswerMachineDetectionConfig

	// A custom key-value pair using an attribute map. The attributes are standard
	// Connect Customer attributes, and can be accessed in flows just like any other
	// contact attributes.
	//
	// There can be up to 32,768 UTF-8 bytes across all key-value pairs per contact.
	// Attribute keys can include only alphanumeric, dash, and underscore characters.
	Attributes map[string]string

	// The campaign identifier of the outbound communication.
	CampaignId *string

	// A unique, case-sensitive identifier that you provide to ensure the idempotency
	// of the request. If not provided, the Amazon Web Services SDK populates this
	// field. For more information about idempotency, see [Making retries safe with idempotent APIs]. The token is valid for 7
	// days after creation. If a contact is already started, the contact ID is
	// returned.
	//
	// [Making retries safe with idempotent APIs]: https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/
	ClientToken *string

	// A description of the voice contact that appears in the agent's snapshot in the
	// CCP logs. For more information about CCP logs, see [Download and review CCP logs]in the Connect Customer
	// Administrator Guide.
	//
	// [Download and review CCP logs]: https://docs.aws.amazon.com/connect/latest/adminguide/download-ccp-logs.html
	Description *string

	// The name of a voice contact that is shown to an agent in the Contact Control
	// Panel (CCP).
	Name *string

	// Information about the outbound strategy.
	OutboundStrategy *types.OutboundStrategy

	// The queue for the call. If you specify a queue, the phone displayed for caller
	// ID is the phone number specified in the queue. If you do not specify a queue,
	// the queue defined in the flow is used. If you do not specify a queue, you must
	// specify a source phone number.
	QueueId *string

	// A formatted URL that is shown to an agent in the Contact Control Panel (CCP).
	// Contacts can have the following reference types at the time of creation: URL |
	// NUMBER | STRING | DATE | EMAIL . ATTACHMENT is not a supported reference type
	// during voice contact creation.
	References map[string]types.Reference

	// The contactId that is related to this contact. Linking voice, task, or chat by
	// using RelatedContactID copies over contact attributes from the related contact
	// to the new contact. All updates to user-defined attributes in the new contact
	// are limited to the individual contact ID. There are no limits to the number of
	// contacts that can be linked by using RelatedContactId .
	RelatedContactId *string

	// The maximum time the outbound call will wait for the destination to answer the
	// call, in seconds
	RingTimeoutInSeconds *int32

	// The phone number associated with the Connect Customer instance, in E.164
	// format. If you do not specify a source phone number, you must specify a queue.
	SourcePhoneNumber *string

	// Denotes the class of traffic. Calls with different traffic types are handled
	// differently by Connect Customer. The default value is GENERAL . Use CAMPAIGN if
	// EnableAnswerMachineDetection is set to true . For all other cases, use GENERAL .
	TrafficType types.TrafficType

	noSmithyDocumentSerde
}

type StartOutboundVoiceContactOutput struct {

	// The identifier of this contact within the Connect Customer instance.
	ContactId *string

	// Metadata pertaining to the operation's result.
	ResultMetadata middleware.Metadata

	noSmithyDocumentSerde
}

func (c *Client) addOperationStartOutboundVoiceContactMiddlewares(stack *middleware.Stack, options Options) (err error) {
	err = stack.Serialize.Add(&awsRestjson1_serializeOpStartOutboundVoiceContact{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsRestjson1_deserializeOpStartOutboundVoiceContact{}, middleware.After)
	if err != nil {
		return err
	}

	if err = addlegacyEndpointContextSetter(stack, options); err != nil {
		return err
	}
	if err = addComputeContentLength(stack); err != nil {
		return err
	}
	if err = addResolveEndpointMiddleware(stack, options); err != nil {
		return err
	}
	if err = addComputePayloadSHA256(stack); err != nil {
		return err
	}
	if err = addRecordResponseTiming(stack, options); err != nil {
		return err
	}
	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = addCredentialSource(stack, options); err != nil {
		return err
	}
	if err = addIdempotencyToken_opStartOutboundVoiceContactMiddleware(stack, options); err != nil {
		return err
	}
	if err = addOpStartOutboundVoiceContactValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "StartOutboundVoiceContact"), middleware.Before); err != nil {
		return err
	}
	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
		return err
	}
	if err = addResponseErrorMiddleware(stack); err != nil {
		return err
	}
	if err = addRequestResponseLogging(stack, options); err != nil {
		return err
	}
	if err = addDisableHTTPSMiddleware(stack, options); err != nil {
		return err
	}
	if err = addInterceptors(stack, options); err != nil {
		return err
	}
	return nil
}

type idempotencyToken_initializeOpStartOutboundVoiceContact struct {
	tokenProvider IdempotencyTokenProvider
}

func (*idempotencyToken_initializeOpStartOutboundVoiceContact) ID() string {
	return "OperationIdempotencyTokenAutoFill"
}

func (m *idempotencyToken_initializeOpStartOutboundVoiceContact) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
	out middleware.InitializeOutput, metadata middleware.Metadata, err error,
) {
	if m.tokenProvider == nil {
		return next.HandleInitialize(ctx, in)
	}

	input, ok := in.Parameters.(*StartOutboundVoiceContactInput)
	if !ok {
		return out, metadata, fmt.Errorf("expected middleware input to be of type *StartOutboundVoiceContactInput ")
	}

	if input.ClientToken == nil {
		t, err := m.tokenProvider.GetIdempotencyToken()
		if err != nil {
			return out, metadata, err
		}
		input.ClientToken = &t
	}
	return next.HandleInitialize(ctx, in)
}
func addIdempotencyToken_opStartOutboundVoiceContactMiddleware(stack *middleware.Stack, cfg Options) error {
	return stack.Initialize.Add(&idempotencyToken_initializeOpStartOutboundVoiceContact{tokenProvider: cfg.IdempotencyTokenProvider}, middleware.Before)
}
