Problem in creating a chat room in openfire server - xmpp

When I try to create a room in Multi User Chat (MUC) the server responds 'This room is locked from entry until configuration is confirmed'. How can I overcome this?
Thanks in advance

You need to send a configuration form for the room. If you are using smack the code would look something like this:
Form submitForm = multiUserChat.getConfigurationForm().createAnswerForm();
submitForm.setAnswer("muc#roomconfig_publicroom", false);
submitForm.setAnswer("muc#roomconfig_roomname", room);
multiUserChat.sendConfigurationForm(submitForm);

I was having this problem using Candy Chat 1.7.1 with Openfire 3.9.3.
This took me a while to work out, but after reading through the Multi-User Chat spec:
http://xmpp.org/extensions/xep-0045.html#createroom
I eventually solved it; first with Strophe, then from that found the Candy way.
So to answer your question:
In Strophe
After creating the room by sending the presence (Example 153 in spec)
I sent the below (as per Example 155 in spec)
conn.sendIQ($iq({
type: "set",
to: escapedRoomId,
from: me.getEscapedJid(),
id: "create:" + conn.getUniqueId()
}).c("query", {
xmlns: "http://jabber.org/protocol/muc#owner"
}).c("x", {
xmlns: "jabber:x:data",
type: "submit"
}));
where conn is the Strophe.Connection
Then to help others who may have the same problem in Candy Chat:
In Candy Chat
After searching for bits of the Strophe message above in the candy libs bundle I found this:
createInstantRoom: function(room, success_cb, error_cb) {
var roomiq;
roomiq = $iq({
to: room,
type: "set"
}).c("query", {
xmlns: Strophe.NS.MUC_OWNER
}).c("x", {
xmlns: "jabber:x:data",
type: "submit"
});
return this._connection.sendIQ(roomiq.tree(), success_cb, error_cb);
},
So then this solves it in Candy Chat.
$(Candy).on('candy:view.room.after-add', function(evt, args) {
Candy.Core.getConnection().muc.createInstantRoom(Candy.Util.escapeJid(args.roomJid));
});
Irritatingly simple when you know how. Incidentally I think the method should be called configureAsInstantRoom and Candy chat should have an option for this on the init method or similar.

Related

adding custom attribute to message not storing message in Archive table on server using stanza.io

I am working on ionic-framework and i'm using stanza.io library to implement chatting with xmpp server, I want to add some custom attributes while sending message, for that i have followed the steps for creating plugin. my code is as follow...
sendMsg() {
console.log("Sending message");
function customMessage(client, stanzas) {
const NS = 'http://www.w3.org/2005/Atom';
var types = stanzas.utils;
const messageAttribute = stanzas.define({
name: 'messageAttribute',
element: 'messageAttribute',
namespace: NS,
fields: {
title: types.textSub(NS, 'title'),
summary: types.textSub(NS, 'summary'),
published: types.textSub(NS, 'published'),
updated: types.textSub(NS, 'updated'),
cont: types.textSub(NS, 'cont')
}
});
stanzas.withMessage((Message) => {
stanzas.extend(Message, messageAttribute);
});
}
this.client.use(customMessage);
this.client.sendMessage({
to: this.recep,
body: "",
messageAttribute: {
'title': "some title",
'summary': "message",
'published': "time stamp here",
'updated': "time stamp here",
'cont': "cht"
}
});
console.log("Message sent " + this.sMsg);
}
but doing this way message are not being stored in Archive table on server. that will create a problem to get the history from the server. if we use the simple code then that messages being stored on Archive table on server. simple code as follow..
this.client.sendMessage({
to: this.recep,
body: this.sMsg
});
in simple code we can only send message as a string inside body. can anyone help me to solve this?
My server is only archiving messages which contain a body element with text, which is a pretty common archiving configuration. One trick would be trying to include a dummy body text to trigger message archiving, but you'd have to check if the server is storing and returning the full stanza or just extracting and saving the body text.
done everything correctly with extending Stanza to include the additional fields, but need to adjust server to get what i want. confirmed from here.
You need to add an extra param store in message stanza which makes the message to store in Archive table by default.
const store = stanzas.define({
name: 'store',
element: 'store',
namespace: 'urn:xmpp:hints'
});
stanzas.withMessage(Message => {
stanzas.extend(Message, store);
});
Sent store attribute as true in message stanza
this.client.sendMessage({
to: this.recep,
body: this.sMsg,
store: true
});
You should see store inside message stanza like
<store xmlns='urn:xmpp:hints'/>

UCWA: Unable to send/Receive formatted text

I have a simple chat application working fine with plain text implemented using UCWA api in a ASP.Net MVC web application. I have to implement a formatted text next.
Referring to UCWA: integrating advanced chat options
, I go to know that, before sending the message to using ucwa.Transport.clientRequest we have to set the contentType to text/html which currently is text/plain.
So i have the function to send a message as shown below:
function sendMessage(displayName, msg, timestamp) {
var encodedMsg = encodeURIComponent(msg);
ucwa.Transport.clientRequest({
url: messagingLinks.SendMessage + "?SessionContext=" + ucwa.GeneralHelper.generateUUID(),
type: "post",
contentType: "text/html",
data: encodedMsg,
callback: function () {
addMessageToChat(displayName, encodedMsg, timestamp);
}
});
}
The implementation of handleMessage() is as shown below:
function handleMessage(data, parts) {
alert("Inside Handle message");
if (!data._embedded.message._links.plainMessage) return false;
var message = decodeMessage(data._embedded.message._links.plainMessage.href);
var decodedMsg = decodeURIComponent(message);
addMessageToChat(data._embedded.message._links.participant.title, decodedMsg, formatTime(new Date(Date.now())));
}
The problem in the above implementation is that, on the receiving end, the handleMessage() method is not entered which means i'm not receiving the incoming message.
Can anyone point me where i'm going wrong and Are the any other changes i need to do along with the above changes, so that i can send a formatted text across. A sample will be really helpful regarding the same.
Any suggestion would also be good enough. Thanks in advance.
Edit:
As suggested i have modified my makeMeAvailable method. below is the definition of the same in Authentication.js:
function makeMeAvailable() {
if (!_authenticated) {
cache.read({
id: "main"
}).done(function (cacheData) {
if (cacheData) {
var data = {
SupportedModalities: ["Messaging"],
supportedMessageFormats: ["Plain","Html"]
};
transport.clientRequest({
url: cacheData._embedded.me._links.makeMeAvailable.href,
type: "post",
data: data,
callback: handleState
});
}
});
} else {
handleState({
status: 204
});
}
}
However, the output is still the same.
The second suggestion regarding the communication API, i'm unable to locate it.
Any suggestions with this?
Here are two reasons I did not receive messages sent through UCWA API:
Charset: Default value was ISO-8859-1, I had to use UTF-8 to receive any message.
Negotiated message formats: The receiving contact only supported plain message format, but the messages were sent with text/html content type.
When it comes to the messaging formats in UCWA it should be known that by default all endpoints that support the messaging modality by default support plain messages. It is interesting to note that this limitation does not prevent sending of HTML formatted messages as you have seen in your examples.
There are two ways to enable HTML formatted messages as follows:
When issuing a request to makeMeAvailable supply an SupportedMessageFormats (array) and include Html
Issue a PUT request to communication and include Html in SupportedMessageFormats
Until either 1 or 2 has executed successfully it will be impossible to receive HTML formatted messages.

Safe Methods in Meteor

I'm working on a messaging app using Meteor. I disabled any insert/update/remove called from the client for security reasons. The only way to insert messages now is by using Methods.
Meteor.methods({
sendMessage: function (text) {
Messages.insert({ userId: Meteor.userId(), roomId: Rooms.findOne()._id, name: Meteor.users.find(Meteor.userId()).fetch()[0].profile.name , message: text });
}
});
This approach asks only for the content of the message, so there's no way for a user to call the method using other name or try to send the same message to other Chat Rooms.
I'm a beginner using Meteor so I wonder, wouldn't the real method (not the Stub) which is run on the server get different values from userId and roomId? Rooms.findOne()._id on the server could be any random room document on the db, as well as userId any user.
If this is the case I would have to include extra parameters on the function which would make it much less secure.
I'm probably not understanding about Methods here.
You are on the right track. Using Rooms.findOne() certainly doesn't make sense on the server, and frankly isn't that good on the client either (if you ever publish more that one room this will break). You need to pass both the message and the room id to your method. The method should validate that the insert makes sense. For example, is this user currently in the room. Assuming that's tracked in room.members, sendMessage could be implemented as follows:
Meteor.methods({
sendMessage: function(message, roomId) {
check(message, String);
check(roomId, String);
if (!this.user)
throw new Meteor.Error(401, 'You must be logged in.');
if (_.isEmpty(message))
throw new Meteor.Error(403, 'Message must not be empty.');
var room = Rooms.findOne(roomId);
if (!room)
throw new Meteor.Error(404, 'Room not found.');
if (!_.contains(room.members, this.userId))
throw new Meteor.Error(403, 'You are not in the room.');
var name = Meteor.user().profile.name;
return Messages.insert({
userId: this.userId,
roomId: roomId,
name: name,
message: message
});
}
});
Not all of these checks may be necessary, but this example should give you an idea of the rich set of validations that a method can provide.

How to make POST API calls with google-api-nodejs-client?

I am trying to make a Google Calendar push notification API call (https://developers.google.com/google-apps/calendar/v3/push). I figured out how to make a calendar list call. So, I am fairly confident that my Oauth 2.0 authentication piece is working. I am guessing that I need to specify that the push notification call is a POST. Here are my codes:
var params = { calendarId: calendarId,
id: 'my-unique-id-00001',
type: "web_hook",
address: "https://mydomain.com/notifications" };
client
.calendar.events.watch(params)
.withAuthClient(authClient)
.execute(callback);
I keep getting this error message:
{ errors:
[ { domain: 'global',
reason: 'required',
message: 'entity.resource',
debugInfo: 'com.google.api.server.core.Fault: ImmutableErrorDefinition{base=REQUIRED, category=USER_ERROR, cause=com.google.api.server.core.Fault: Builder{base=REQUIRED, ...
While I was attempting to watch something using the Google Drive API, I ran into the same issue. The issue turned out to be that some of the parameters need to be in the response body.
In your case I believe that the calendarId needs to be a path parameter and the others need to be in the request body. Something like this should work
var pathParams = { calendarId: calendarId };
var bodyParams = {
id: 'my-unique-id-00001',
type: 'web_hook',
address: 'https://mydomain.com/notfications'
};
client
.calendar.events.watch(pathParams, bodyParams)
.withAuthClient(authClient)
.execute(callback);

XEP-0077: In-Band Registration

i am a newbie for xmpp. i plan to start a 'chat' web application.at client,i prepare use 'Strophe',but i found strophe cannot support registeration module.
someone said can use 'XEP-0077: In-Band Registration'.can u tell me what i can do it?
thanks
XEP-0077 is the way to go here. Make sure you've read it thoroughly. Next, look at the strophejs-plugins project to get some examples of how to write a strophe plugin. Then, you'll want to create protocol that imlements XEP-0077, starting with something like:
Strophe.addConnectionPlugin('register', {
_connection: null,
init: function(conn) {
this._connection = conn;
Strophe.addNamespace('REGISTER', 'jabber:iq:register');
},
get: function(callback) {
var stanza = $iq({type: "get"}).c("query",
{xmlns: Strophe.NS.REGISTER});
return this._connection.sendIQ(stanza.tree(), callback, function(){});
}
});
Make sure to contribute your patch to strophejs-plugins back on github.