I have a task to create javascript realtime app. Server side is ready (wss://), I have to create client-side.
The main tasks I have problems with:
The client can ping the server to check your connectivity. Client does a ping, including the sequence number (which allows to trace the exact ping duration).
{
"$type": "ping",
"seq": 1
}
server will respond:
{
"$type": "pong",
"seq": 1
}
Client request
{
"$type": "subscribe_tables"
}
Server will respond with the list of tables, and update the client with table_added, table_removed and table_updated messages whenever the status has changed.
{
"$type": "table_list",
"tables": [
{
"id": 1,
"name": "table 1",
"description" : "one, two"
}, {
"id": 2,
"name": "table 2"
"description" : "two, three"
}
]
}
table_updated event
{
"$type": "update_table",
"table": {
"id": 3,
"name": "table - Foo Fighters",
"participants": 4
}
}
Question: I know, that I can use new EventSource(), is this correct? How can I send data $type, for example with it?
I know, that I can use new EventSource(), is this correct? How can I
send data $type, for example with it?
No, that is not correct. If your server is expecting a webSocket connection, then you use new WebSocket(...) from the client to make the connection from client to server. And EventSource() object is used for server-side events which is a completely different transport from webSocket.
You can see programming examples here on MDN for using webSocket.
Also, if you are trying to send Javascript objects as data, you would typically use JSON.stringify() to serialize them into a string and then send that and then on the receiving end, you would use JSON.parse() to parse the JSON string back into a Javascript object. That's how you would send info like your $type along with other data in the same message.
FYI, socket.io is a library built on top of webSocket that has become very popular because it does a lot of things for your automatically that are typically needed in webSocket programming such as JSON serialization, automatic reconnect, automatic keep alive, connection drop detection, etc... You certainly don't have to use it in client and server, but it often saves a lot of time.
Related
Following this documentation https://docs.tcgplayer.com/reference/catalog_getcategories
I have been able to generate a fetch request to get category search manifest from the endpoint. https://docs.tcgplayer.com/reference/catalog_getcategorysearchmanifest
However I am having trouble with this request https://docs.tcgplayer.com/reference/catalog_searchcategory
specifically the body portion. In my local project I am either getting an error "missing body" or when the body is attached "ops something when wrong" I believe that I am following all of the specifications provided in their documentation.
Here is a code snip of the working request and then one that I am having issues with, although the second request just seems to log and empty array in this environment. https://codesandbox.io/s/romantic-khorana-9tcez5?file=/src/App.js
I have been able to get https://docs.tcgplayer.com/reference/catalog_searchcategory to work with Thunderbolt Client vscode extension using this as a body
{
"sort": "ProductName ASC",
"limit": 500,
"offset": 0,
"filters": [
{
"name": "ProductName",
"values": ["Black"]
},
{
"name": "Rarity",
"values": ["T"]
}
]
}
So I am using Mailgun API to send E-mails and recently started using their mailing list feature as well.
When I send to the mailing list for instance: somelist#mg.address.com
It returns a single message Id.
However when I receive the webhook responses that messageId is not contained within the data, it gives the message ID pertaining to the individual address mail sent by server. (So if i send an e-mail to somelist#somedomain.com which contains 100 addresses, I will receive notifications with 100 different message ID's.
I could potentially match it up by subject, but that doesn't seem right.. What is the correct way to match the event to the mailing list email?
I was able to solve this by generating a random tag when sending the email and including it in the data.
https://documentation.mailgun.com/en/latest/api-tags.html
Every MailGun Event that you will receive will have message ID in it. Usually it may be found under message.headers.message-id. For instance, your event may look like this
{
"id": "ABC123...",
"message": {
"headers": {
"to": "somebody#somewhere.com",
"message-id": "20211012201139.1.XYZ...#somedomain.com",
"from": "you#somedomain.com",
"subject": "Test email"
},
"attachments": [],
"size": 29123
},
"event": "accepted"
...
}
Overview
I am using the Node.js library actions-on-google client to build a smarthome action for the Garage Door device type. This action is deployed as a Cloud Function in GCP. I can confirm that the following works perfectly so far:
Accounting linking with our OAuth flow
Responding to sync intents (ie. onSync() in the client)
Responding to execute intents (ie. onExecute() in the client)
Problem
Despite that other callbacks (onSync() and onExecute()) work fine, we do not see any evidence of onQuery() being called no matter what. There aren't any errors showing in Stackdriver nor are their any logs being generated in Stackdriver under the "Google Actions" filter either.
We expect onQuery() to run when we ask Google Assistant things like is the garage door open? and is Matt's Door closed?
We tried removing async to see if the call was hanging
We tried removing headers in the lambda
We tried removing all other code and redploying to isolate onQuery()
Code
The following code shows the simple onQuery() callback. onExecute() and onSync code has been removed for clarity.
'use strict';
const functions = require('firebase-functions');
const {smarthome} = require('actions-on-google');
const app = smarthome({
jwt: require('./XXXXXXXXX-XXXXXXXXXX.json'),
debug: true,
});
//
// Note: Removed onSync() and onExecute() for clarity
//
app.onQuery(async (body, headers) => {
// Expecting to see these logging statements in
// Stackdriver like we do for onExecute() and
// onSync() ... but nothing ever shows up.
console.info('=== onQuery.body', body);
console.info('=== onQuery.headers', headers);
// We have hardcoded the following ID and a "closed"
// state. It matches a valid device ID to the testing
// account we are using.
return {
requestId: body.requestId,
payload: {
devices: {
'2489e4a92799728292b8d5a8b1c9d177': {
on: true,
online: true,
openPercent: 0,
}
}
}
};
});
exports.smarthome = functions.https.onRequest(app);
We considered the possibility that the JSON returned in the call to onSync() might be missing a trait or something that prevents it from responding to a query intent properly but we have not been able to identify anything that might be incorrect or missing. Here is the JSON payload returned from onSync():
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"agentUserId": "1836.15267389",
"devices": [{
"id": "1234",
"type": "action.devices.types.GARAGE",
"traits": [
"action.devices.traits.OpenClose"
],
"name": {
"defaultNames": ["Smart Garage Door"],
"name": "Matt's Door",
"nicknames": ["Matt's Door"]
},
"willReportState": true,
"attributes": {
"openDirection": [
"UP",
"DOWN"
]
},
"deviceInfo": {
"manufacturer": "ABC Corp",
"model": "test",
"hwVersion": "1.0",
"swVersion": "1.0"
}
}]
}
}
Expected Result
We expect Google Assistant to respond with "Garage door is closed" or some other equivalent. Instead, we receive "Sorry, I can't reach Matt's Door right now. Please try again."
Answering my own question here in case anyone else has this trouble. The reason why my action was handling the SYNC and EXECUTE intents but not the QUERY intent came down to what default/user names I assigned each device in the SYNC response.
Ultimately, I started using the following and my action began responding to QUERY intents as expected again:
...
name: {
defaultNames: ['Garage Door'],
name: door.name,
nicknames: [door.name, 'Garage Door']
},
...
where door.name is a name which is set by the user and is returned by an API call.
I'm working with the js/node api of getstream and I'm trying to add a realtime feature to the comments on the activities, but I'm receiving a 403 error, displaying I dont have permission.
I've tried using targetFeeds: '[timeline:userid]' but it wrecks the application.
Also I tried to use the notification feed as in the documents is being used, and I can set targetFeeds like this: '[notification:userid]' which obviously is not the desired thing to do because this will cause that every message on different activities of this user will be shown on the callback.
client.reactions.add("comment", activityId, {
"text": newComment,
"profileImage": 'https://i.pravatar.cc/300',
"timestamp": date,
"from": userId,
"id": foreignId,
},
{targetFeeds: [`CommentsFeed:${activityId}`]});
And the response of the 403 is the next one:
{
code: 17
detail: "You don't have permission to do this"
duration: "0.18ms"
exception: "NotAllowedException"
status_code: 403
}
The expected result is not having the 403, that will trigger the callback I implemented.
The default permission settings allow users to only write activities to their own feeds; in this case you are adding an activity to CommentsFeed:${activityId}.
You can request support (support#getstream.io) to whitelist this for you app(s). Just make sure to mention this case and include your applications.
I have a WebRTC multi-party app that works on both localhost and on an ngrok.io localhost tunnel. However, when I try and test it with my friend, who is connected through a router on their end, I am able to see an offer/answer exchange as well as an ICE candidate exchange, but no sound gets streamed through.
After first having this problem, I did some research and learned that you need a TURN server to get through a router's NAT. I'm using a public TURN server that I've confirmed works in https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
var configuration = {
"iceServers": [{ "url": "stun:stun2.1.google.com:19302" }],
url: 'turn:192.158.29.39:3478?transport=udp',
credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
username: '28224511:1379330808'
};
yourConn = new webkitRTCPeerConnection(configuration);
yourConn2 = new webkitRTCPeerConnection(configuration);
yourConn3 = new webkitRTCPeerConnection(configuration);
The sound packets should be routed through this TURN server and through my friend's NAT, but we still can't stream to each other.
Your turn server credentials are taken from https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/ and have expired in 2013. If you used https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ it should have told you this doesn't work -- i'd be rather surprised if it gave you relay candidates.
Run your own server.
You should change configuration:
var configuration = {
"iceServers": [
{ "url": "stun:stun2.1.google.com:19302" },
{
"url": "turn:192.158.29.39:3478?transport=udp",
"credential": "yourpassword",
"username": "yourusename"
}
],
};