I am looking for the best way to implement an inbox with getstream.io
basically, just like the FB out twitter inbox. where a user can send a private message to another one.
I have the save requirement for private discussion groups.
How can I model this with getstream.io ?
Thank you
Stream supports this use-case very well. My suggestion is to use notification feeds, this way you have read/seen state counters out-of-the-box.
The flow is pretty simple: when a user sends a private message to another user, all you have to do is add an activity to the recipient's notification feed.
// John sends a message to Mike
client = stream.connect('key', 'secret')
activity = {'actor': 'user:jhon', 'verb': 'message', 'object': 'message:123'}
client.feed('notification', 'mike').add_activity(activity)
If you want, you can also add the same activity to both sender and recipient feeds with a single API call. In this case we add to John's user feed and to Mike's notification feed.
client = stream.connect('key', 'secret')
activity = {
'actor': 'user:john',
'verb': 'message',
'object': 'message:123',
'to': ['notification:mike']
}
client.feed('user', 'john').add_activity(activity)
You can find more information about notification feeds and to targeting field on Stream documentation pages.
Related
i am using the microsoft bot sdk in combination with an restify server (In package.json: "botbuilder": "^4.11.0"). I start a waterfall dialog that triggers a long running API. I save the the conversation reference and the id of the sent message to create an reply after the API call is completed:
replyToId = (await stepContext.context.sendActivity({ attachments: [ac]})).id; (in Dialog)
this.conversationReference = TurnContext.getConversationReference(context.activity); (in bot.ts)
After the completion of the API call, I want to create a reply to the last message of the dialog:
await this.adapter.continueConversation(this.conversationReference, async turnContext => {
await turnContext.sendActivity(newMessage);
});
newMessage is the Activity-object that contains further information for the user about the result of the API call.
The problem is that newMessage is not displayed as an reply to the existing message but as a separate message, although newMessage.replyToId is set to this.replyToId:
Additional information: Both messages, the last of the dialog and the "reply" are adaptive cards, but it does not make a difference if I send just simple text, same behaviour.
Would be grateful for any help :)
Instead of using "replyToId", put the id of the message you want to reply to, at the end of the conversation reference. As an example, if your conversationReference has a conversationId of 19:ac....cf#thread.skype, change it to: 19:ac...cf#thread.skype;messageid=12345678, where 12345678 is what you are currently using for "replyToId"
I'm using the Microsoft bot-framework to create a bot and integrate it into teams.
Part of the bot's requirements include proactively messaging users once per day. From what I understand, I can only message users that has been added to the team/groupChat after the bot, or that have messaged the bot directly.
My question is - can I somehow bypass this limitation?
A friend of my referred me to a new feature of graphAPI, as part of the new beta version - https://learn.microsoft.com/en-us/graph/api/user-add-teamsappinstallation?view=graph-rest-beta&tabs=http.
To me it doesn't seem like it could be related to the solution since I'm not getting any data back in the response, so if I have no conversationReference object I still can't message the user.
At the moment my solution is to simply broadcast a message in the channel when it's added, asking users to "register" with it by messaging it. Anyone has any other suggestion?
The easiest way is to:
Install the bot for the team
Query the Team Roster -- The link in Step 3 has an alternative way to do this towards the bottom
Create a conversation with the user and send a proactive message
There's a lot of code in those links and it's better to just visit them than to copy/paste it here.
The end of Step 3 also mentions trustServiceUrl, which you may find handy if you run into permissions/auth issues when trying to send a proactive message.
Edit for Node:
Install Necessary Packages
npm i -S npm install botbuilder-teams#4.0.0-beta1 botframework-connector
Note: The #<version> is important!
Prepare the Adapter
In index.js
const teams = require('botbuilder-teams');
adapter.use(new teams.TeamsMiddleware());
Get the Roster
// Get Team Roster
const credentials = new MicrosoftAppCredentials(process.env.MicrosoftAppId, process.env.MicrosoftAppPassword);
const connector = new ConnectorClient(credentials, { baseUri: context.activity.serviceUrl });
const roster = await connector.conversations.getConversationMembers(context.activity.conversation.id);
Send the Proactive Message
const { TeamsContext } = require('botbuilder-teams');
// Send Proactive Message
const teamsCtx = TeamsContext.from(context);
const parameters = {
members: [
roster[0] // Replace with appropriate user
],
channelData: {
tenant: {
id: teamsCtx.tenant.id
}
}
};
const conversationResource = await connector.conversations.createConversation(parameters);
const message = MessageFactory.text('This is a proactive message');
await connector.conversations.sendToConversation(conversationResource.id, message);
Trust the ServiceUrl, as Necessary
Read about it. You'd want this before the message is sent.
MicrosoftAppCredentials.trustServiceUrl(context.activity.serviceUrl);
EDIT: The Graph API you've referenced is only necessary if you wish to proactively message a user who is not in a channel/groupChat where the bot is installed. If you need to proactively message only people who are in context where the bot is installed already, the answer from mdrichardson is the easiest possible method.
We've identified a couple of issues with the Graph API beta endpoint you referenced that should be fixed in the near term. In the meantime workarounds are as follows:
Calling:
POST https://graph.microsoft.com/beta/me/teamwork/installedApps/
{"teamsapp#odata.bind":"https://graph.microsoft.com/beta/appcatalogs/teamsapps/APP-GUID"}
Will install an app in the personal scope of a user.
Known issue: Currently, if the app contains a bot, then installation will not lead to creation of thread between the bot and the user. However to ensure that any missing chat threads, get created, call:
GET https://graph.microsoft.com/beta/me/chats?$filter=installedApps/any(x:x/teamsApp/id eq 'APP-GUID')
Calling:
GET https://graph.microsoft.com/beta/me/chats?$filter=installedApps/any(x:x/teamsApp/id eq 'APP-GUID')
Gets the chat between a user and an app containing a bot.
Known issue: Calling this API will lead to sending a conversation update event to the bot even though there were no updates to the conversation. Your bot will essentially get two install events and you'll need to make sure you don't send the welcome message twice.
We'll also be adding more detailed documentation for the proactive messaging flow using these Graph APIs
I am building a slack bot using a third party service to handle responses based on inputs rather than just hard coding them into the bot. This service's API needs a client id & a conversation id to get the response. I found out that each time a slack bot receives a message, it creates a new message object each time so there isn't a way of keeping the clientID and conversation ID within the message object and have slack hold onto it.
rtm.on(RTM_EVENTS.MESSAGE, function(message // <-- new object each time the bot hears a message){
rtm.sendMessage('hello', message.channel);
});
So shortened down, does anyone know of a way to keep a conversation between a single user and the bot while holding onto some type of variable to hold the client and conversation ID?
You can store the message.user ID and track the conversation referring to that specific user. You will need to keep track of all ongoing conversations yourself. Something like this
rtm.on(RTM_EVENTS.MESSAGE, function(message // <-- new object each time the bot hears a message){
if(stored_conversations.indexOf(message.user) > -1){
//customize message depending on history
rtm.sendMessage('I remember you', message.channel);
}
});
Or, you could use Botkit - it manages bot-user conversations for you.
I am testing a bot that I am building using the Bot Framework. The emulator for local testing that Microsoft created has several events that can be provided to the bot to solicit a response.
I looked at the GitHub samples provided for Node.js here, but I can not find any example that responds to the different events within the Bot Framework Emulator.
The states are:
Bot Added to Conversation
Bot Removed from Conversation
User Added to Conversation
User Removed from Conversation
End of Conversation
Ping
Delete User Data
The API also does not make it clear how to achieve any of these actions.
Does anyone have any insight on where I should be looking for a example, or the API entries that I should be using?
In response to one of the answers, I did try code -
.onDefault(function (session) { console.log(session.message.type); }
But it only ever display "message" if a message was sent by the user.
The incoming message.type field will have "BotAddedToConversation" etc.
For the Node SDK, the botConnectorBot is able to trigger custom listeners on events using the on() handler.
Example
var builder = require('botbuilder');
var bot = new builder.BotConnectorBot({ appId: 'APPID', appSecret: 'APPSECRET' });
bot.on('DeleteUserData', function(message) {
// Handle Deleting User Data
});
More information can be found here.
You are also able to configure some standard messages using the configure() method.
Example
bot.configure({
userWelcomeMessage: "Hello... Welcome to the group.",
goodbyeMessage: "Goodbye..."
});
More information on what can be configured through options is located here.
Concerns
This is not part of the question, as the question was to identify how to listen to these events. But as a general concern, the event listener does not return a session object. It is unclear how to act once you handle the event.
I am working on SMS notification each time I receive an email that meets certain criteria; I decided to use Google App Scripts for this.
I have been inspired in particular by the following article https://developers.google.com/apps-script/articles/gmail_filter_sms. I also checked the related question in StackOverflow SMS Alerts for Important Mails in Gmail.
I improved the original script from developers.google.com by cleaning up the events the next time the script is run (I was receiving the SMS alerts each time the script is run). The script is currently working by using the label 'SendText' and creating events in calendar 'AlertSMS'.
However the SMS I receive only contain the subject and author of the email: I need to display the content of the email (or at least a part of it). I tried with no luck to add it to the description of the event. Anybody got an idea on how to do it?
Hereunder, the code of my script:
function sendText() {
var now = new Date().getTime();
// Delete old events
var events = CalendarApp.openByName('AlertSMS').getEvents(new Date('January 1, 2010 EST'), new Date(now-30000));
for (i in events) {
events[i].deleteEvent();
}
// Get list of emails to set alert for
var label = GmailApp.getUserLabelByName('SendText');
var threads = label.getThreads();
// Create new events for emails alert
for(i in threads){
var message=threads[i].getMessages()[0];
CalendarApp.openByName('AlertSMS').createEvent('[SMS] '+threads[i].getFirstMessageSubject()+' -from- '+message.getFrom(),
new Date(now+60000), new Date(now+60000), { description:message.getBody() }).addSmsReminder(0);
}
label.removeFromThreads(threads);
}
You can use services such as (the completely free) IFTTT or (the somewhat free) Zapier to trigger an SMS action upon receiving emails matching a criteria.
Here are some IFTTT "recipes" which connect GMail to SMS.
You don't really need the Calendar hack to send arbitrary text messages to yourself - every mobile provider has an email to text gateway. For verizon, for example, its 5551234567#vtext.com (substitute your phone number) and there exists similar for other carriers. Just use GmailApp to email those numbers and you can send whatever you want.