Is it possible to, given a UCMA application (using application or user end points), to create an outbound sip call and then join this call to an active audio conference on lync server?
If so, how would I do that?
I know one can create an outbound call and also I know it's possible to join an endpoint to an active conference, but has anyone done this two things at the same time?
Thanks,
Assuming you're creating a new Conversation with your UCMA application (instead of getting an incoming call to your app), you can connect this new conversation to a conference.
The trick to to use the conversation's ConferenceSession object to join the conference, rather than calling to it directly, and then establishing the call without a target uri.
Note that you need to impersonate the conversation if you attempt to make multiple calls to the same conference from the same application endpoint.
For reference of the BeginJoin, see this MSDN page: ConferenceSession.BeginJoin.
var conversation = new Conversation( <your application endpoint> );
conversation.ConferenceSession.BeginJoin("<your conference uri>", (joinresult) => {
conversation.ConferenceSession.EndJoin(joinresult);
// User has joined conference here.
var call = new AudioVideoCall(conversation);
call.BeginEstablish(new AudioVideoCallEstablishOptions(), (establishresult) => {
call.EndEstablish(establishresult);
// Call is established with conference now.
});
});
Related
Realising this is gonna be a very general question but I am gonna try to be as specific as possible:
What is the best way to design/structure an Socket.IO app?
I have a NodeJS backend with React frontend, with authentication (user must log in). I have several REST endpoints, for example /foo, /bar, /baz.
I know you can use rooms and namespaces, and I know you can add authentication to the connect as middleware, but I have no idea what the best solution is to glue this all together. I will be using this socket for multiple purposes. For each purpose I am curious what the best way to go is (flow).
General CRUD messages: When someone posts a "foo" on the server side, it needs to also send this to that particular user. WHen someone deletes a "foo", it also needs to send something to this user. So this CRUD messaging should only be for one specific user (based on logged in user ID). How would structure those messages? Namespace for "foo"? Multiple event listeners: on "foo create", on "foo delete", on "foo update?" How to make sure you only send to this user?
I have multiple pages on the client side, for the respective CRUD endpoint. So when I am on the "foo" page, I need to get updates on the "foo" backend object. How can I accomplish this?
General server side messages: I will be running long-running scripts on the server side, started by a user (or by a time trigger). If I go to that page in react and if there are long running scripts active that belong to me, I need to see those logging. (but again, they are personal so those messages are only for me).
Thanks in advance if you need more clarification just ask me and I will add this to my question.
EDIT:
I think the CRUD part can better be created as having only an "listener for updates" (like the firebase onSnapshot). So on page foo, I will listen to updates in the foo database, but the updates or creations are dont through normal REST API. Is that indeed the better way?
You can authenticate socket.io connection in 'connection' event or using middleware - doc.
Also you can use some package from npm, for example this
After authentication store user data in socket object or as separate object in 'connection' event scope.
io.on('connection', (socket) => {
const handshake = socket.handshake;
const user = // fetch user obj according data in handshake, for example, from jwt token in header
});
So after you can use user object in other events for this connection.
Private messages according to your task I implemented in my project using rooms. Here abstract example:
// this is just a helper to get room name according to userId
getUserRoomName(userId) {
return `user_${userId}`;
}
// function to send data to user
sendToUser(userId, event, data) {
io.to(getUserRoomName(userId)).emit(event, data);
}
// in 'connection' event add join to user room
io.on('connection', (socket) => {
const handshake = socket.handshake;
const user = // fetch user obj according data in handshake, for example, from jwt token in header
// join to private room
socket.join(getUserRoomName(user.userId), () => {
// some logic
});
});
So, when the user connected to socket.io we join his connection to private user room. And every connection of same user will be joined to same room, so we can isolate data sending messages to this room.
Using sendToUser method you can send any type of data to all user connections from any part of your application:
sendToUser(userId, 'foo_create', data);
OR
sendToUser(userId, 'foo', {
action: 'create',
// some other data
});
How can I (or is there a way) get the number of subscribers connected and watching a publisher's stream, using OpenTok's REST API?
I know that I can count the connections on the server side by listening respective event, but if there is a REST API that I can query session information including the connected subscribers, I prefer to use it.
OpenTok QA staff here.
As Carlos says, the answer is simple. You can't. There is no API to get the number of subscribers that are actually connected to a session. You have to handle it by yourself, using the events that the platform provides.
Check the official API docs: https://tokbox.com/developer/sdks/js/reference/ConnectionEvent.html, the session object dispatches some events that tell you when some one connects or disconnects from your session:
...
var session = OT.initSession(apiKey, sessionID);
session.on('connectionCreated', function(e) {
connectionCount++;
...
});
session.on('connectionDestroyed', function(e) {
connectionCount--;
...
});
I have created a basic REST API where a user can ask for an acronym, and the web-page will return the meaning of the acronym via a POST call.
The majority of my end-users don't use the Internet as much as they use the Microsoft Lync application.
Is it possible for me to create a Lync account, and have it pass questions to my API, and return the answers to the user? Meaning the user just needs to open a new chat in Lync rather than a new web-page.
I'm sure this is possible, but I can't find any information on Google or on the web. How can this be accomplished?
Thanks very much.
Edit :
Adding a bounty in the hopes of someone creating a simple example as I believe it would be very useful for a large number of devs :).
Yep, absolutely. UCMA (the Unified Communications Managed API) would be my choice of API to use here, and a good place to start - UCMA apps are "normal" .net applications, but also expose an application endpoint, which can be added to a user's contact list. When users send messages, that can trigger events in your application so you can take the incoming IM, do the acronym translation and return the full wording.
I have a bunch of blog posts about UCMA, but as of yet no defined collection of "useful" posts to work through, but coming soon! In the meantime, feel free to browse the list.
-tom
To elaborate on Tom Morgan's answer, it would be easy to create an UCMA application for this.
Create an UCMA application
Now this doesn't have to be complicated. Since all you want is to receive an InstantMessage and reply to it, you don't need the full power of a trusted application. My choice would be to use a simple UserEndpoint. As luck would have it, Tom has a good example of that online: Simplest example using UCMA UserEndpoint to send an IM.
Make it listen to incoming messages
Whereas the sample app sends a message when it is connected, we need to listen to messages. On the UserEndpoint, set a message handler for instant messages:
endpoint.RegisterForIncomingCall<InstantMessagingCall>(HandleInstantMessagingCall);
private void HandleInstantMessagingCall(object sender, CallReceivedEventArgs<InstantMessagingCall> e)
{
// We need the flow to be able to send/receive messages.
e.Call.InstantMessagingFlowConfigurationRequested += HandleInstantMessagingFlowConfigurationRequested;
// And the message should be accepted.
e.Call.BeginAccept(ar => {
e.Call.EndAccept(ar);
// Grab and handle the toast message here.
}, null);
}
Process the message
There is a little complication here, your first message can be in the 'toast' of the new message argument, or arrive later on the message stream (the flow).
Dealing with the Toast message
The toast message is part of the conversation setup, but it can be null or not a text message.
if (e.ToastMessage != null && e.ToastMessage.HasTextMessage)
{
var message = e.ToastMessage.Message;
// Here message is whatever initial text the
// other party send you.
// Send it to your Acronym webservice and
// respond on the message flow, see the flow
// handler below.
}
Dealing with the flow
Your message flow is where the actual data is passed around. Get a handle on the flow and store it, because it's needed later to send messages.
private void HandleHandleInstantMessagingFlowConfigurationRequested(object sender, InstantMessagingFlowConfigurationRequestedEventArgs e)
{
// Grab your flow here, and store it somewhere.
var flow = e.Flow;
// Handle incoming messages
flow.MessageReceived += HandleMessageReceived;
}
And create a message handler to deal with incoming messages:
private void HandleMessageReceived(object sender, InstantMessageReceivedEventArgs e)
{
if (e.HasTextBody)
{
var message = e.TextBody;
// Send it to your Acronym webservice and respond
// on the message flow.
flow.BeginSendInstantMessage(
"Your response",
ar => { flow.EndSendInstantMessage(ar); },
null);
}
}
That would about sum it up for the most basic example of sending/receiving messages. Let me know if any parts of this need more clarification, I can add to the answer where needed.
I created a Gist with a full solution. Sadly it is not tested because I'm currently not near a Lync development environment. See UCMA UserEndpoint replying to IM Example.cs.
I never used Lync but while I was looking at the dev doc, I stumble upon a sample which could be what you're looking for.
Lync 2013: Filter room messages before they are posted
Once you have filtered the messages, you just need to catch the acronym and call your custom code that calls your API.
Unless I'm missing something, I think you could do it with a simple GET request as well. Just call your API like this yoursite.com/api/acronym/[the_acronym_here].
You can use UCWA (Microsoft Unified Communications Web API),is a REST API.For detail , can reference as the following..
https://ucwa.lync.com/documentation/what-is-lync-ucwa-api
We are planning to use UCWA to build a Lync client. For multiple participant chats, we would like to be able to pass some information from the person who start the multiple participant chats to all other participants, just wonder if there is anyway to attach such customized property at UCWA. I check the Lync UCWA API Reference and I didn't find anything.
Thanks in advance.
UCWA (as of CU4) doesn't have any access to push information to a conversation that is not plain/text or html. Depending on the data being pushed to all users it could become a special command that the UCWA implementation would read from the conversation's message and instead of adding to the visual representation of messages process it.
// Sample message
var message = 'do_stuff "{"data":{"value1":123,"value2":456}}"'
// Event handler for incoming messages
function handleMessage(data) {
var message = data._links.plainMessage.href;
if (message.indexOf('do_stuff ') === 0) {
// Retrieve the data from the command string however works best here...
var d = JSON.parse(message.split('do_stuff ')[1].slice(1,-1));
// Do something with the resulting data...
processData(d);
}
}
In UCMA this is typically done via the Context Channel which UCWA does not have access to.
I'm currently trying to make a Strophe based javascript script to get the list of available users in an OpenFire server (live refreshing needed). I don't care if I have to create a group, room or whatever it's called (anyway, the server will be running for only a small group of users, everyone connected to eachother), but I want to be able to make the server give such a list.
How can I do this? I've read that I need to use muc extension, but I can't seem to find it anywhere...
Problem solved! I had to add the users I was working with to a group and eachtime a user leaves or enters the room OpenFire notifies the other users of the room with a presence stanza wrapped inside a body tag most of the times. This makes Strophe to not identify those presence stanzas very well, so I had to overwrite the xmlInput function from the Strophe connection to get every single xml stanza that I get from the server.
conn.xmlInput = onXmlInput;
function onXmlInput(data) {
Strophe.forEachChild(data, "presence", function(child) {
var from = child.getAttribute('from');
from = from.substring(0, from.indexOf('#'));
//'type' will contain "unavailable" when offline and no attribute 'type' when online
if (!child.hasAttribute('type')) {
addUser(from);
} else {
deleteUser(from);
}
});
}