How do you set the avatar of API-triggered messages? - node.js

Looking at the slack api, I can't see any way to set the avatar of things posted through the API, although they show many examples of api messages coming with avatars, like this
I'm using chat.postMessage to post messages as my app. I can alter the username, but I can't figure out any way to set the icon.
My posts just end up looking like this:

When sending messages through a web-request - you can supply the icon_emoji property with a supported emoji name, such as:
{
..
"icon_emoji":":ghost"
}
Or, with an icon_url property:
{
..
"icon_url":"<your valid url>"
}

Related

BotFramework conversation not found

I've been trying to test a function app sending an activity to a bot that has an existing conversation, but to simplify for this post, I'll speak in terms of sending it via postman. I've have been butting up against an issue wherein the conversationId is not being found, despite confirming it does exist beforehand and I'm not entirely sure what I've done wrong.
I log onto portal azure, and go to my bot to Test in Web Chat. I authenticate the bot, and the conversation starts.
Here, I've checked the conversationId is exactly what I expect to be by examining the conversation calls response in Chromes debug tools, in this case it is 1GJ0N9UYKGyELu3LqpDF6b-a
Here is the exact conversation response...
conversationId: "1GJ0N9UYKGyELu3LqpDF6b-a"
expires_in: 3600
referenceGrammarId: "fcab5fbf-67c7-bf55-934a-274e525c78a9"
streamUrl: "wss://webchat.botframework.com/v3/directline/conversations/1GJ0N9UYKGyELu3LqpDF6b-a/stream?watermark=-&t=ew0KICAi...."
token: "ew0KICA..."
So from here, in my mind I should be able to do the following in postman
POST https://webchat.botframework.com/v3/directline/conversations/1GJ0N9UYKGyELu3LqpDF6b-a/activities
Content-Type: application/json
Authorization: Bearer {My webchats channels secret code}
Body:
{
"type": "message",
"from": {
"name": "foo"
},
"text": "bar"
}
I'd expect a 200OK and the message 'bar' to appear in my Test In Web Chat from 'foo', but it does not. Instead I get an error in postman stating:
{
"error": {
"code": "BadArgument",
"message": "Conversation not found"
}
}
How exactly can this be? If I've just created that conversation and can demonstrate that conversationId is in use, why is the post message saying it can't be found? Am I incorrectly using channels? Or doing something blindingly obvious here?
So to answer my own question, to make a long story short. It looks like the example activity supplied in the Microsoft documentation doesn't quite cut it. There is something else that is required, although I didn't have time to narrow it down.
The solution I took, as I was running low on time was to write a method to save an activity to cosmosDb as part of the authentication flow. This way I have an ironclad activity that I know has worked in at least the invoke stages of the dialog, and I know a conversation reference is correct and present. From there I pulled the activity and changed 4 fields in it.
activity.Type = "message",
activity.From = new From { Id = "{BotId}", Name = "Gilbert Bottfried", Role = "bot },
activity.Text = "{My message}",
activity.Subject = "{my message subject}"
From there, it was essentially a case of just creating a connector client and firing off this repurposed activity.
AppCredentials.TrustServiceUrl(serviceUrl, DateTime.MaxValue);
ConnectorClient client = new ConnectorClient(
new Uri(serviceUrl),
MicrosoftAppId,
MicrosoftAppPassword);
await client.Conversations.SendToConversationAsync(activity.Conversation.Id, activity);
It seems that this was enough to get it working, and it makes for a nice referenceable conversation Id for future messages. Although I found other issues with working with WebChat, because I suspect it's not entirely stable sending messages to and throw via websockets. The testing experience was much more stable on msteams itself, it seemed to handle my barrage of test messages like a champ.
This is essentially a bruteforce method, as I'm storing and sending a lot of unnecessary data, but it works. I may append this answer to trim down what I find to be necessary in the future, but that will require testing.

How to remove the embed from specific messages and from messages coming from specific users/bots using Discord.js

I'm trying to code a bot that is able to remove the embed of specific messages or the embed created from the links posted by specific users and bots present in the server.
For example, let's say I don't want to see the twitter embed when someone posts a tweet: my bot would automatically remove the twitter embed.
Other case, I don't want people to see the embed of the messages posted by another user or bot present in the server, my bot would then automatically remove the said embeds.
However, reading the API documentation, I didn't see any possibility to do so. Maybe I missed it or maybe there's a trick to do so. Or maybe it's not supported by the API yet.
So does anyone know how I could achieve that goal please?
PS: Yes, I know I could simply deactivate embeds in the server settings, but that's not the goal I want to achieve here. I want it to be specific to certains links/messages and users/bots.
Thanks
You can use the suppressEmbeds method of message.
client.on("message", message => {
if (message.author.bot) return false;
if (message.author.id !== "YourID") { // Example Condition
message.suppressEmbeds(true) // Removes all embeds from the message.
}
})

Proactive messaging bot in Teams without mentioning the bot beforehand

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

Permission for all users to post to a specific feed

I have been attempting to implement stream via react native and seem to be struggling with what looks like a permissions issue in relation to all users being unable to post to another 'entities' feed. My use case is essentially several 'topic' pages, where all users of my app can post to and comment etc. The topic page will also have an owner who can manage the page if needs be, so they too are essentially a 'user.
I've read elsewhere that global write permissions are not enabled by default so may need a member of the stream team to look at this for me if possible.
Here is the code I'm trying to use on the client side:
let user = client.feed('user', "bob");
let activity = {
actor: "bob",
verb: 'post',
object: "Hello world",
foreign_id: 'post:1',
to: ['user:topic-page-1'],
};
user
.addActivity(activity)
.then(data => {
console.log('success');
})
.catch(reason => {
alert(reason);
});
Another small issue I can't seem to get to the bottom of, is even when posting to the same user's timeline, the post username is always displaying as "Unknown" no matter what data I attach. What am I getting wrong here please?
For the actor field to be treated as a user entity, you should use a reference, something like client.currentUser or client.user('bob'). This should fix your post username issue.

Slack RTM API post from a given username

I have integrated the Slack RTM API into my program, and I am able to post to Slack as well as receive new messages from Slack.
The one problem I am having is when posting to Slack, the post comes from my username. I know it is possible to change the posting user in the Web API by setting the "username" and "as_user" field, so I am not sure why this would be any different. Below is my message that I am using. Comment.user.name is a string.
var message =
{
id : 1,
type : "message",
channel : self.channel,
text : comment.text,
thread_ts : self.timestamp,
username : comment.user.name,
as_user : false
};
self.websocket.send(JSON.stringify(message));
Is this possible with the way I am doing it, or is there a better way? Thanks.
It is not possible in the Slack Web API to set a user in that way. There is only one way to achieve this: Obtain an API token for the user you want to post as and use it when making your API request.

Resources