I want to setup a simple Amazon Connect call-flow that dials back any customer who leaves behind a phone number on my website. I am a rank beginner at Amazon Connect and cannot find any example code showing how to setup outbound calling to dynamically supplied phone numbers via a web-client.
Can someone point me to any example code. I have seen documentation of AWS Connect APIs including those for StartOutboundCall etc but am looking for some example code if possible.
https://blogs.perficient.com/2018/11/19/ac-outbound-api/ has a good example, that I've followed successfully.
The call is:
let params = {
"InstanceId" : '12345l-abcd-1234-abcde-123456789bcde',
"ContactFlowId" : '987654-lkjhgf-9875-abcde-poiuyt0987645',
"SourcePhoneNumber" : '+1xxxxxxxxx',
"DestinationPhoneNumber" : customerPhoneNumber,
"Attributes" : {
'name' : customerName,
'dayOfWeek' : dayOfWeek
}
}
let connect = new AWS.Connect();
connect.startOutboundVoiceContact(params, function (error, response) { ... });
Given a contact flow (of type "Contact Flow"), with arn: arn:aws:connect:us-east-1:xxxxxxxx:instance/12345l-abcd-1234-abcde-123456789bcde/contact-flow/987654-lkjhgf-9875-abcde-poiuyt0987645
The SourcePhoneNumber is required and must be one of those in your Amazon Connect. Or use a queue number if you have any defined.
The Attributes property will be passed as-is and will be available in text-to-speech, in your Contact Flow, with a form similar to $.Attributes.dayOfWeek.
The Contact Flow can be as simple as one Start, connected to one 'Play Prompt', connected to 'Disconnect/Hang up'.
All props go to https://blogs.perficient.com/author/dhodanic/
Related
Im trying to add a process instance using this post request to /message
{
"messageName" : "DocumentReceived",
"businessKey" : "3",
"processVariables" : {
"document" : {"value" : "This is a document...", "type": "String"
}
}
}
But instead of getting 1 instance im getting 2 instances of the same id and same everything, I tried creating a process directly from the webapp (TaskList) but it still creates 2 duplicates, and i noticed one the instances gets stuck on user task while the other can just pass it without doing anything, ill attach a screenshot after running the post request above
Check your process model carefully. I believe you accidentally have two outgoing sequence flows on the start event. One connects to the user task, the other connects directly to the gateway. Because the two flows overlap, it is hard to spot. However, when you look closely at the "Send the new document" user task, you can see a faint line passing "behind" the task. Move the user task model element 3 cm up and you will see what is wrong.
We need to get the service name under which a fargate task runs so we can perform some per service configuration (we have one service per customer, and use the service name to identify them).
By knowing the service discovery namespace for our cluster and the Task IP address, we are able to do find out the service by doing the following.
Get the task ip address, eaither by calling http://169.254.170.2/v2/metadata endpoint or by using the ECS_ENABLE_CONTAINER_METADATA method in my follow-up answer.
With the cluster namespace we call AWS.ServiceDiscovery.listNamespaces
From there we extract the nameSpace id.
We pass that to AWS.ServiceDiscovery.listServices
We pass the id of each service to AWS.ServiceDiscovery.listInstances
We flat map the results of that and look for an instance that matches our IP address above.
VoilĂ ! that record gives us the service name.
Works fine, it just seems like a super circuitous path! I'm just wondering whether there is some shorter way to get this information.
Here's a working C# example in two steps. It gets the taskARN from the metadata to retrieve the task description, and then reads its Group property, which contains the name of the service. It uses AWSSDK.ECS to get the task description and Newtonsoft.Json to parse the JSON.
private static string getServiceName()
{
// secret keys, should be encoded in license configuration object
var ecsClient = new AmazonECSClient( ACCESS_KEY, SECRET_KEY );
var request = new DescribeTasksRequest();
// need cluster here if not default
request.Cluster = NAME_OF_CLUSTER;
request.Tasks.Add( getTaskArn() );
var asyncResponse = ecsClient.DescribeTasksAsync( request );
// probably need this synchronously for application to proceed
asyncResponse.Wait();
var response = asyncResponse.Result;
string group = response.Tasks.Single().Group;
// group returned in the form "service:[NAME_OF_SERVICE]"
return group.Remove( 0, 8 );
}
private static string getTaskArn()
{
// special URL for fetching internal Amazon information for ECS instances
string url = #"http://169.254.170.2/v2/metadata";
string metadata = getWebRequest( url );
// use JObject to read the JSON return
return JObject.Parse( metadata )[ "TaskARN" ].ToString();
}
private static string getWebRequest( string url )
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( url );
request.AutomaticDecompression = DecompressionMethods.GZip;
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using Stream stream = response.GetResponseStream();
using StreamReader reader = new StreamReader( stream );
return reader.ReadToEnd();
}
You can get the service name from startedBy property of the task definition. Using boto sdk you can call a describe_tasks (or its equivalent in aws-cli: aws ecs describe-tasks) which will provide a
'startedBy': 'string'
The tag specified when a task is started. If the task is started by an Amazon ECS service, then the startedBy parameter contains the deployment ID of the service that starts it.
From:
boto3 ecs client
aws-cli ecs client
Hope it helps.
The answer above requires reading the container metadata that appears if you set the ECS_ENABLE_CONTAINER_METADATA environment variable in the task. The work flow is then:
Read the container metadata file ecs-container-metadata.json to get the taskArn
Call the aws.ecs.describe-tasks function to get the startedBy property
Call aws.servicediscover.get-service.
Two steps instead of three, if you don't count reading the metadata file. Better, to be sure, but I'm probably not going to change the way we do it for now.
I am trying to make a contact flow in amazon connect, in basic terms it should;
"Do you need support" -> Person: "Yes" -> "What is your name?" Person: "John doe", it should save "john doe" and send it to a lamba. this is how the contact flow looks like;
this is the code of my lambda;
error in CloudWatch,
Lambda;
connect;
I have tried a couple of different settings and variables in order to send the right value with it, and this is what is set as of right now;
I think you are using the wrong attribute type when sending the firstname to the lambda. From the type drop down you should select either: User Defined and then use firstname as the key and the value or just select Lex Slots and reference the same value you do in your Set Contact Attributes block.
Also not familiar with Java Lambdas, but I do know connect sends your lambda a JSON object and it looks like you have input set as a string. May be worth looking into that.
It depends, take into account different things:
1- You have to authorize amazon connect to trigger the lambda function.
2- You could send the data to lambda in different ways, for example if you have data in the same ContactFlow but it comes for previous part of the flow or store and send directly to lambda, see the image:
This is how we receive tc_date
And this is how we receive tc_numero but we send to a lambda that encrypts and tc_numero lives in the flow and we called how I show you in first image
Thanks to this community I've learned that is possible to send AWS SNS Push notifications via Lambda with node.js (as a result of Parse migration). I am still struggling with the following:
Can this be done client to client x likes y's z. Where x is user 1, y is user 2 and z is the object being liked? If so, it seems like Cognito is not required that it can read directly from the database but is that accurate?
Does anyone have an example of how this was implemented?
Again, we don't want to broadcast to all users on a schedule but rather when a client performs an action.
Thanks so much in advance!
Let's say you have Device1 which creates a piece of content. That is distributed to a number of users. Device2 receives this content and "likes" it.
Assumption:
you have registered for push notifications on the device, and created a SNS endpoint on AWS. You have stored that endpoint ARN in your database, and associated it with either the Cognito Id, or the content Id. If your data is normalized, then you'd typically have the SNS endpoint associated with the device.
Your Lambda will need to have access to that data source and look up that SNS endpoint to send push notifications to. This will depend on what sort of data store you are using (RDS, DynamoDB, something else). What sort of access that is, and how you secure it is a whole other topic.
From your Lambda, you fetch the ARN to send the push notification to. If you pass in the content Id from the Like, and have the Cognito Id from the device that Liked it, you can then look up the information you need. You then construct a SNS payload (I'm assuming APNS in this example), then send it off to SNS.
var message = {
"default": "New Like!",
"APNS": {
"aps": {
"alert": "New Like!"
}
}
};
var deviceParams = {
Message: JSON.stringify(message),
Subject: "New Like",
TargetArn: targetArn,
MessageStructure: "json"
};
self.sns.publish(deviceParams, function (err) {
if (err) {
console.error("Error sending SNS: ", err);
}
});
It's not all done for you like it might be with Parse. You need to work a lot harder on AWS, but you have near unlimited power to do what you want.
If this is a bit too much, you may want to consider Google's newly updated Firebase platform. It's very Parse-like: https://firebase.google.com/
Hope that helps you move forward a bit.
Further reading:
http://docs.aws.amazon.com/sns/latest/dg/mobile-push-apns.html
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html
I am fresh in implementing Amazon Web services. I am working on implementing an application for sending bulk emails from a queue. I have to check emails and remove non-verified emails from the queue before sending.
My question is: Is there any method available in Amazon to check whether emails are valid or not?
From your question, it is not clear whether you want to:
1-avoid sending messages to malformed email addresses; or
2-avoid sending messages to email addresses which are not verified under your AWS account.
The answer for 1 is spread in different forms accross forums, SO, etc. You either do it simple, i.e., craft a short and clear regular expression which validates roughly 80% of the cases, or you use a very complex regular expression (in order to validate against the full compliance -- good luck, check this example), check whether the domain is not only valid but also up and running, and, last but not least, check if the account is valid under that domain. Up to you. I'd go with a simple regex.
The answer for 2 is available at Verifying Email Addresses in Amazon SES -- the Amazon SES API and SDKs support the operations below, so you should be covered in any case:
Using the Amazon SES API
You can also manage verified email addresses with the Amazon SES API. The following actions are available:
VerifyEmailIdentity
ListIdentities
DeleteIdentity
GetIdentityVerificationAttributes
Note
The API actions above are preferable to the following older API actions, which are deprecated as of the May 15, 2012 release of Domain Verification.
VerifyEmailAddress
ListVerifiedEmailAddresses
DeleteVerifiedEmailAddress
You can use these API actions to write a customized front-end application for email address verification. For a complete description of the API actions related to email verification, go to the Amazon Simple Email Service API Reference.
You can use the "getIdentityVerificationAttributes" operation to check whether emails are valid or not. You can use this as shown below:
var params = {
Identities: arr // It is a required field (array of strings).
};
ses.getIdentityVerificationAttributes(params, function(err, data) {
if(err)
console.log(err, err.stack); // an error occurred
else
console.log(data); // successful response
});
And the Response will be:
{ ResponseMetadata: { RequestId: '7debf2356-ddf94-1dsfe5-bdfeb-efsdfb5b653' },
VerificationAttributes:
{ 'abc#gmail.com': { VerificationStatus: 'Pending' },
'xyz#gmail.com': { VerificationStatus: 'Success' } } }
If there is an email-id which is not sent previously for email verification request, then there is no key present in 'VerificationAttributes' object.
AmazonSimpleEmailServiceClient ses= new AmazonSimpleEmailServiceClient(credentials);
List lids = ses.listIdentities().getIdentities();
if (lids.contains(address)) {
//the address is verified so
return true;
}