Does anyone know of any examples or pages that I can go to that implements a Live one on one chat using the CF10 Websockets?
All the examples I found on the net were those of group chats where users subscribes to a certain channel. I need it so that there can be many instances of a one on one chat like how a Live Help Chat works that you see quite often on websites that allow you to chat with one of the support agents. Any help is appreciated and hopefully there will be examples (CF and JS).
Ben Nadel has a nice article about using CF10's websockets for pushing a message to a target user. He even added a nice demo video. This might be what you are looking for or could at least help you get started.
Here is some sample code that is currently working for me.
Instead of using the subscribeTo attribute, use the js function to subscribe the user and pass in some header values. These headers can then be used as filters on the publish call using selector
Example:
<cfwebsocket name="ChatSocket" onOpen="openHandler" onMessage="msgHandler" onError="errHandler">
<script>
function openHandler(){
//Subscribe to the channel, pass in headers for filtering later
ChatSocket.subscribe('chatChannel',{name: '#Session.Auth.FirstName#', UserID: '#Session.Auth.UserID#', AccountID: '#Session.Auth.AccountID#' });
}
function publish(txt, userID){
var msg = {
AccountID: "#Session.Auth.AccountID#",
publisher: '#Session.Auth.UserID#',
id: userID,
message: converthtml(txt)
};
//When including headers, the "selector" is where you will filter who it goes to.
var headers = {
AccountID: "#Session.Auth.AccountID#",
publisher: '#Session.Auth.UserID#',
id: userID,
selector: "UserID eq '"+userID+"' and AccountID eq '#Session.Auth.AccountID#'"
};
ChatSocket.publish('chatChannel',msg, headers);
}
function msgHandler(message){
console.log(message);
}
function errHandler(err){
console.log(err);
}
</script>
At first I was thinking about implementing something similar but there are some rudimentary limitations in CF10 as of now that detours me from investigating further.
WSS support is missing, see: Does CF10 support secure websocket wss?
Websocket doesn't work in a cluster environment, see: https://groups.google.com/forum/#!topic/houcfug/M7YQQyrBTaQ
I would look elsewhere for any serious one-to-one live chat solution, maybe Socket.IO on NodeJS or Java
WSS may be coming in CF11. I'm not sure.
Related
I have been trying to get the response from API gateway, but after countless tries and going through several online answers, I still wasn't able to solve my issue.
When I test my POST method for the API, it gives me proper response on lambda test and API gateway method test, but when I try it from my react app, it doesn't return the same output.
My lambda snippet:
const response = {
statusCode: 200,
body: JSON.stringify({payload: {"key": "value"}})
};
return response;
But the response I am getting using fetch API on my react app:
I am new to AWS and would appreciate if someone point me in the right direction.
So the fetch API allows you to receive responses as a readablestream, which is what it shows you are receiving in that image there. This resource here, should be helpful in how to properly handle the response.
There are also many other commonly used libraries like axios that are primarily promise / callback driven and you won't have to worry about streams too much unless you want to. You should be able to get fetch working with promises too, but I've never done it myself.
In general, streams are really useful when you have a large amount of data and receiving it all at once in a giant chunk would be really slow, cause timeouts, etc.
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/
I'm building an application that enables clients to book appointments with service providers. I'm using SNS -> SQS -> Lambda to process various emails that need to be sent when booking an appointment. IE I currently send an SNS message like so (in node.js):
await sns.publish({
Message: 'booking-request',
TopicArn: process.env.AWS_BOOKING_REQUEST_TOPIC_ARN,
MessageAttributes: {
artistEmail: SNSMF.string(artist.email),
artistName: SNSMF.string(artist.name),
clientEmail: SNSMF.string(req.body.email),
clientName: SNSMF.string(`${req.body.firstName} ${req.body.lastName}`),
date: SNSMF.string(moment(req.body.date).tz(studio.timeZone).format())
}
}).promise();
This all works fine, but I'm using MessageAttributes to pass the pertinent appointment details so my notifications layer can send the proper emails.
My main questions is, am I using MessageAttributes in the proper way, or is there a better way to pass all of this data? Should the data be the message itself? I ask because I believe that you can only have 10 MessageAttributes and I'm going to run into a limit with the appointment details (currently collecting about 10-12 data points about the appointment that I want to include in the emails). Any ideas? Thank you!
Normally, the 'main' information you wish to pass would be in the Body of the message. It is quite common the use JSON to pass various types of information.
MessageAttributes are normally something about the message itself rather than the content of the message, such as timestamps, priority and user information.
Given your requirements, I putting your data in the Body (eg in JSON) would avoid hitting limits and would also be more extensible.
I've been trying to use the javacscript version of the Eclipse Paho MQTT client to access the Google IOTCore MQTT Bridge, as suggested here:
https://cloud.google.com/iot/docs/how-tos/mqtt-bridge
However, whatever I do, any attempt to connect with known good credentials (working with other clients) results in this connection error:
errorCode: 7, errorMessage: "AMQJS0007E Socket error:undefined."
Not much to go on there, so I'm wondering if anyone has ever been successful connecting to the MQTT Bridge via Javascript with Eclipse Paho, the client implementation suggested by Google in their documentation.
I've gone through their troubleshooting steps, and things seem to be on the up and up, so no help there either.
https://cloud.google.com/iot/docs/troubleshooting
I have noticed that in their docs they have sample code for Java/Python, etc, but not Javascript, so I'm wondering if it's simply not supported and their documentation just fails to mention as such.
I've simplified my code to just use the 'Hello World' example in the Paho documentation, and as far as I can tell I've done things correctly (including using my device path as the ClientID, the JWT token as the password, specifying an 'unused' userName field and explicitly requiring MQTT v3.1.1).
In the meantime I'm falling back to polling via their HTTP bridge, but that has obvious latency and network traffic shortcomings.
// Create a client instance
client = new Paho.MQTT.Client("mqtt.googleapis.com", Number(8883), "projects/[my-project-id]/locations/us-central1/registries/[my registry name]/devices/[my device id]");
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// connect the client
client.connect({
mqttVersion: 4, // maps to MQTT V3.1.1, required by IOTCore
onSuccess:onConnect,
onFailure: onFailure,
userName: 'unused', // suggested by Google for this field
password: '[My Confirmed Working JWT Token]' // working JWT token
function onFailure(resp) {
console.log(resp);
}
// called when the client connects
function onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("onConnect");
client.subscribe("World");
message = new Paho.MQTT.Message("Hello");
message.destinationName = "World";
client.send(message);
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
// called when a message arrives
function onMessageArrived(message) {
console.log("onMessageArrived:"+message.payloadString);
}
I'm a Googler (but I don't work in Cloud IoT).
Your code looks good to me and it should work. I will try it for myself this evening or tomorrow and report back to you.
I've spent the past day working on a Golang version of the samples published on Google's documentation. Like you, I was disappointed to not see all Google's regular languages covered by samples.
Are you running the code from a browser or is it running on Node.JS?
Do you have a package.json (if Node) that you would share too please?
Update
Here's a Node.JS (JavaScript but non-browser) that connects to Cloud IoT, subscribes to /devices/${DEVICE}/config and publishes to /devices/${DEVICE}/events.
https://gist.github.com/DazWilkin/65ad8890d5f58eae9612632d594af2de
Place all the files in the same directory
Replace values in index.js of the location of Google's CA and your key
Replaces [[YOUR-X]] values in config.json
Use "npm install" to pull the packages
Use node index.js
You should be able to pull messages from the Pub/Sub subscription and you should be able to send config messages to the device.
Short answer is no. Google Cloud IoT Core doesn't support WebSockets.
All the JavaScript MQTT libraries use WebSocket because JavaScript is restricted to perform HTTP requests and WebSocket connections only.
I build an application in Django, and I have a function to get attendance log from a fingerprint machine, basically like this:
import requests
from xml.etree import ElementTree
def main(request):
Key="xxxxxx"
url="http://192.168.2.188:80"
soapreq="<GetAttLog><ArgComKey xsi:type=\"xsd:integer\">"+Key+"</ArgComKey><Arg><PIN xsi:type=\"xsd:integer\">All</PIN></Arg></GetAttLog>"
http_headers = {
"Accept": "application/soap+xml,multipart/related,text/*",
"Cache-Control": "no-cache",
"Pragma": "no-cache",
"Content-Type": "text/xml; charset=utf-8"
}
response = requests.post(url+"/iWsService",data=soapreq,headers=http_headers)
root = ElementTree.fromstring(response.content)
Now, that process will be repeated for hundred++ fingerprint machines, and I need to display some kind of progress status and also error messages ( if any, like connection cannot be eastablished, etc) on a page, periodically and sequentially, after each events. I mean something like :
....
"machine 1 : download finished."
"downloading data from machine 2 .. Please wait "
"machine 2 : download finished."
...
Thanks.
I'm not really sure what is the main hurdle you're facing. Can you try framing the question in a more precise way?
From what I understand, you want a page that changes dynamically based on something that's happening on the server. I think django may not be the best tool for that, as its basic use is to compute a full view in one go then display it. However, there are a few things that can be done.
The easiest (but not the best in terms of server load) would be to use Ajax requests from the webpage.
Have a "main view" that loads the user-facing page as well as some JS libraries (e.g. jQuery), which will be used to query the server for progress.
Have a "progress view" that displays the current status and that is queried from the main view via AJAX.
This is not the best architecture because you may end up reloading data from the server too often or not often enough. I would suggest to have a look at websockets, which allow you to keep a client-server connection open and use it when needed only, but there is no native support for them in django.