Node js - Creating persistent private chat rooms - ajax

I've been reading so much a bout node js lately, and the chat capabilities seem very nice. However, the only chat examples I've seen basically broadcast a chat server to a fixed URL (like a meeting room). Is it possible to use node js in part to create a chat client more like gchat? - where a chat window is popped up on the current page and then persists through multiple pages. Has anyone seen an example of this yet?
If not, suggestions for other technologies to use for this purpose (I know that's been answered in other questions)?
Thanks.

I'll give you a pseudo implementation relying on jquery and now to abstract away tedious IO and tedious DOM manipulation from the solution.
// Server
var nowjs = require('now');
var everyone = nowjs.initialize(httpServer);
everyone.now.joinRoom = function(room) {
nowjs.getGroup(room).addUser(this.user.clientId);
}
everyone.now.leaveRoom = function(room) {
nowjs.getGroup(room).removeUser(this.user.clientId);
}
everyone.now.messageRoom = function(room, message) {
nowjs.getGroup(room).now.message(message);
}
// Client
var currRoom = "";
$(".join").click(function() {
currRoom = ...
now.joinRoom(currRoom);
});
$(".send").click(function() {
var input = ...
now.messageRoom(currRoom, input.text());
});
now.messageRoom = function(message) {
$("messages").append($("<div></div>").text(message));
};
I only just noticed myself that the new version of nowjs (0.5) has the group system in build. This basically does what you want for you. No hassle.
If you want you can remove the nowjs dependency and replace it with 100/200 lines of code. I'll leave that as an exercise for the user.

Take a look at AjaxIM: https://github.com/freq32/AjaxIM
This is a facebook-style chat application (think friends list, small persistent chat bar at the bottom of the screen, popup chats) based on nodejs.

Related

Is it possible to scope a Teams Messaging Extension?

I developed a messaging extension for Teams. I want it to only be available for the teams i specifically install the app to. Is that possible and how? I can't find any info on this, but my use-case does not seem to be far-fetched, so i would expect it to be possible.
use-case: Members of a team use an external system to register cases. I want them to be able to search and reference cases within the teams corresponding project site in the external system. I add a tab to the general channel that refers to the project site, and the messaging extension uses the contentUrl of that tab to query the right case list. I don't want the extension to be available outside the teams channels. By default it seems that the extension is available in every chat input option.
Message extensions do no have a scope defined and they are available once you install it in teams. Currently, it is no possible to restrict to show the message extension in one team
I ended up responding with a card that handles the error:
private MessagingExtensionResponse errorResponse(string title, string errorText)
{
MessagingExtensionResult composeExtensionResult = new MessagingExtensionResult
{
Type = "result",
AttachmentLayout = "list",
Attachments = new List<MessagingExtensionAttachment>(),
};
ThumbnailCard h = new ThumbnailCard()
{
Title = title,
Text = errorText,
};
composeExtensionResult.Attachments.Add(h.ToAttachment().ToMessagingExtensionAttachment());
var messagingExtensionResponse = new MessagingExtensionResponse();
messagingExtensionResponse.ComposeExtension = composeExtensionResult;
return messagingExtensionResponse;
}
Although it would be nice to be able to scope the extension, this way i can catch some more invalid usage. For example:
var currentTeam = new TeamDetails();
IList<ChannelInfo> currentTeamChannels = new List<ChannelInfo>();
try
{
currentTeam = await TeamsInfo.GetTeamDetailsAsync(turnContext, turnContext.Activity.TeamsGetTeamInfo().Id, cancellationToken);
currentTeamChannels = await TeamsInfo.GetTeamChannelsAsync(turnContext, turnContext.Activity.TeamsGetTeamInfo().Id, cancellationToken);
}
catch
{
return errorResponse("Permission error", "This app has no permissions to this team / channel. Please add the app to this team / channel.");
}
Got the suggestion from this question: Is it possible for a teams messaging extension to return a plaintext response instead of a card?

Microsoft Teams bot - debug link unfurling

I'm trying to implement pretty simple teams bot but constantly facing an issues with unpredictable behavior. E.g. documentation clearly says that Teams applies Adaptive card as link unfurling response but when I'm sending pretty simple response like:
var card = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0));
card.Body.Add(new AdaptiveTextBlock { Text = "Title", Size = AdaptiveTextSize.ExtraLarge });
var attachment = new MessagingExtensionAttachment { ContentType = AdaptiveCard.ContentType, Content = card };
var result = new MessagingExtensionResult(AttachmentLayoutTypes.List, "result", new[] { attachment });
return new MessagingExtensionResponse(result);
Teams doesn't render anything or follback to the default behavior.
So the question is - are there any way to debug why it doesn't work?
Had the same issue, the problem is this is not documented at all. You'll need to send a hero card (maybe something else works as well?) as preview and the adaptive card as full card:
return {
composeExtension: {
type: 'result',
attachmentLayout: 'list',
attachments: [{
preview: CardFactory.heroCard("title", "description")
...CardFactory.adaptiveCard(card)
}]
}
};
This will display an "expandable" hero card which resolves to the adaptive card.
one easy way to find out what's going on and if your part is generally ok is by sending a full "static" card as a test. Just create the JSON layout somewhere, load it and sent it unchanged to MS Teams.
Also creating AdaptiveCard's like that is not the best way to do it, have a look at https://learn.microsoft.com/en-us/adaptive-cards/templating/ its a lot easier to handle cards like that.
Specific to your question there's no real way to debug anything inside ms teams. You can get a few errors in the analytics part of the bot framework and some times console output of your browser gives a few hints.
I wrote a similar thing some time ago which inserts a card on specific links similar to what you're trying to do and generally, that was (and still is) working fine.

Debugging webOS TV service

I'm currently developing a webOS TV application which includes a background running service. I'm having trouble getting logs to print in the NodeJS console.
I have no prior experience working with Node so I'm unsure whether any additional modules are required to get this done(but I highly doubt it, and the docs don't seem to suggest so.)
As of now my service side code is as follows;
var Service = require('webos-service');
var service = new Service("com.nuwan.helloworld.service");
// code to keep the service from being terminated
var keepAlive;
service.activityManager.create("keepAlive", function(activity) {
keepAlive = activity;
});
service.activityManager.complete(keepAlive, function(activity) {
console.log("completed activity");
});
// hello command implementation
service.register("hello", function(message) {
var response = message.respond({
data: "Hello, " + message.payload.name + "!"
});
});
It would be great if someone could give me some pointers.
As it is right now, I'm not getting any output whatsoever on the Node Profiler console.
The way i did it ( i don't know if that's the only way) to debug the code is through the chromium debugger eg.
This is a generic image to see from where you are going to check the code.

Telegram Bot Random Images (How to send random images with Telegram-Bot)

const TeleBot = require('telebot');
const bot = new TeleBot({
token: 'i9NhrhCQGq7rxaA' // Telegram Bot API token.
});
bot.on(/^([Hh]ey|[Hh]oi|[Hh]a*i)$/, function (msg) {
return bot.sendMessage(msg.from.id, "Hello Commander");
});
var Historiepics = ['Schoolfotos/grr.jpg', 'Schoolfotos/boe.jpg',
'Schoolfotos/tobinsexy.jpg'];
console.log('Historiepics')
console.log(Math.floor(Math.random() * Historiepics.length));
var foto = Historiepics[(Math.floor(Math.random() * Historiepics.length))];
bot.on(/aap/, (msg) => {
return bot.sendPhoto(msg.from.id, foto);
});
bot.start();
The result I'm getting from this is just one picture everytime, but if I ask for another random picture it keeps showing me the same one without change.
I recently figured this out, so I'll drop an answer for anyone that runs into this issue.
The problem is with Telegram's cache. They cache images server side so that they don't have to do multiple requests to the same url. This protects them from potentially getting blacklisted for too many requests, and makes things snappier.
Unfortunately if you're using an API like The Cat API this means you will be sending the same image over and over again. The simplest solution is just to somehow make the link a little different every time. This is most easily accomplished by including the current epoch time as a part of the url.
For your example with javascript this can be accomplished with the following modifications
bot.on(/aap/, (msg) => {
let epoch = (new Date).getTime();
return bot.sendPhoto(msg.from.id, foto + "?time=" + epoch);
});
Or something similar. The main point is, as long as the URL is different you won't receive a cached result. The other option is to download the file and then send it locally. This is what Telebot does if you pass the serverDownload option into sendPhoto.

Problems with findEntity()

I am having a problem similar to Botframework findEntity() issue.
I have created a node.js botframework app using the azure interface. I am using the azure ide for development (to keep things simple).
The relevant code is:
// Main dialog with LUIS
var recognizer = new builder.LuisRecognizer(LuisModelUrl);
var intents = new builder.IntentDialog({ recognizers: [recognizer] })
/*
.matches('<yourIntent>')... See details at http://docs.botframework.com/builder/node/guides/understanding-natural-language/
*/
.matches('Help',(session, args) => {
var entities = args.entities;
var itype = builder.EntityRecognizer.findEntity(args.entities, 'ItemTypes');
session.send(args.entities[0]["entity"]);
session.send(args.entities[0]["type"]);
session.send('How may I assist you? ' + JSON.stringify(args));
session.send('Value of entity (didnt match) you said: \'%s\'.', itype);
})
the findEntity function returns null in itype (at least that is what I see in the session.send results.
I tried using both args.entities and args.intents.entities, no change.
When I look at the results of the args.entities[0]["entity"] and [type] I do get values. The results of the JSON.stringify are below (also showing it is finding the entity).
How may I assist you?
{"score":0.970185757,"intent":"Help","intents":[{"intent":"Help","score":0.970185757},{"intent":"Joke","score":0.0711096451},{"intent":"Greeting","score":0.0438234434},{"intent":"None","score":0.0408537947},{"intent":"Goodbye","score":0.04074517}],"entities":[{"entity":"stapler","type":"ItemTypes","
I'm assuming there is more but that it was cut off by the chat window.
I'm new to every technology involved and will take any help I can get.

Resources