I'm currently using SlackConnector Repo https://github.com/noobot/SlackConnector. I've created a bot and it sends interactive messages to my chat. I would like to add functionality to my interactive buttons but upon clicking them i get this response. Darn – that didn’t work. Only Slack Apps can add interactive elements to messages. Manage your apps here: https://api.slack.com/apps/ So it looks like I need a request URL to get my past my current roadblock. Is there a way to Test the Interactive Message button locally?
List<SlackAttachment> attachments = new List<SlackAttachment>();
List<SlackAttachmentAction> actions = new List<SlackAttachmentAction>();
actions.Add(new SlackAttachmentAction
{
Name = "game",
Text = "chess",
Type = "button",
Value = "Chess"
});
actions.Add(new SlackAttachmentAction
{
Name = "game",
Text = "Falken's Maze",
Type = "button",
Value = "Maze"
});
actions.Add( new SlackAttachmentAction
{
Name = "game",
Text = "Thermonuclear War",
Type = "danger",
Value = "war"
});
attachments.Add(new SlackAttachment
{
Text = "Choose a game to play",
Fallback = "You are unable to choose a game",
CallbackId = "wopr_game",
ColorHex = "#3AA3E3",
Actions = actions
});
connection.Say(new BotMessage
{
ChatHub = chatHub,
Text = "Usage: !talk <user>",
Attachments = attachments
});
return Task.CompletedTask;
One thing I tried was I set the request URL to use a url generated from https://webhook.site/#/ and I still get the same response upon clicking
It looks to me like you have two problems.
You don't have a Slack app
Interactive Messages only work if you have a registered Slack app. That is why you got that error message. But you can easily create one. Just go here and click on "Create a new app". One reason you need one is that you need to tell Slack to which URL to send the request, after a user clicks a button.
Slack can't reach your local app
Slack's interactive messages will only work with apps that can be reached from the public Internet. So if you want to develop your app locally you need to open your web server to the Internet. There are many ways to do it, one secure way is to use a VPN tunnel service. One provider for this kind of service is ngrok, which is also recommended in the official Slack tutorials. I use it myself and it works great.
Related
I am trying to upgrade an app which belongs to a chat. If the app is not installed, below code successfully install it:
await graph.Chats["19:7f...3#thread.v2"].InstalledApps
.Request()
.AddAsync(teamsAppInstallation);
But once the app is added, below code shows zero entries:
var installedApps = await graph.Chats["19:7f...3#thread.v2"].InstalledApps.Request().GetAsync();
I was expecting to see my app there. My target is to call Upgrade() for the app, because it should allow me to add ConversationReferences in one of the event functions (e.g. OnTurnAsync), that will allow me to send proactive message to the chat. Am I doing something wrong?
Permissions for an application are set:
TeamsAppInstallation.ReadWriteSelfForChat.All
TeamsAppInstallation.ReadWriteForUser.All
The authentication with the Graph API is done successfully, as I can create a chat, list channels etc.
https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token
data:
grant_type=client_credentials&client_id={ MS_APP_ID_ENC }&client_secret={ MS_APP_PASS_ENC }&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
I was adding the app to the chat both manually and with C# request:
var teamsAppInstallation = new TeamsAppInstallation {
AdditionalData = new Dictionary<string, object>()
{
{
"teamsApp#odata.bind", "https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/0c...68/"}
}
};
var installedApp = await graph.Chats["19:7f...3#thread.v2"].InstalledApps. Request().AddAsync(teamsAppInstallation);
And the app was added. It can be used in the chat.
It turned out that I've used wrong application permissions. Even though TeamsAppInstallation.ReadWriteSelfForChat.Al is listed in the docs, I needed to add TeamsAppInstallation.ReadWriteForChat.All to make it working.
I am using Bot Framework v4 with c# and deploying to Slack channel. I want to create a timer in the bot or outside using Azure functions. In case of no user input for x mins, the bot should send a message like "Are you there?"
Having read many article on Internet I couldn't find the desired solution
I tired to follow this Automatically Bot display rating card after few seconds to take user feedback
but do not fully understand what this person says there. Can any one help me out?
My method works for Directline Webchat, but you may be able to take this concept and use it in a solution that will work for Slack.
When using botframework-webchat, you are able to set up a custom store to track inactivity. In my example below, I'm using a combination of a page title "notification" with sending a message. But you could simply set the interval and send the message without any of the page title changes.
let interval;
var PageTitleNotification = {
Vars:{
OriginalTitle: document.title,
Interval: null
},
On: function(notification, intervalSpeed){
var _this = this;
_this.Vars.Interval = setInterval(function(){
document.title = (_this.Vars.OriginalTitle == document.title)
? notification
: _this.Vars.OriginalTitle;
}, (intervalSpeed) ? intervalSpeed : 1000);
},
Off: function(){
clearInterval(this.Vars.Interval);
document.title = this.Vars.OriginalTitle;
}
}
// We are using a customized store to add hooks to connect event
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
if (action.type === 'WEB_CHAT/SEND_MESSAGE') {
// Message sent by the user
PageTitleNotification.Off();
clearTimeout(interval);
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name !== "inactive") {
// Message sent by the bot
clearInterval(interval);
interval = setTimeout(() => {
// Change title to flash the page
PageTitleNotification.On('Are you still there?');
// Notify bot the user has been inactive
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'inactive',
value: ''
}
});
}, 300000)
}
return next(action);
});
The challenge when you are using Slack channel is that you can't inject something like this on Slack client side, so you will need to do it externally. The best guidance I can give you is to start from the proactive notification sample. You will need to get the conversation reference from turnContext via something like turnContext.getConversationReference() and store it. You can then send it to a function and start a timer. If the function doesn't receive another message for that reference during your specified time period, you can send the proactive message.
I think you would want to do this as a local function in your bot, not an Azure Function, because you want to reset the timer every time the user sends a new message. I'm not sure how you would keep track of that using an external Azure Function. Hopefully this will be enough to give you some ideas on implementing this functionality in Slack channel.
I'm writing a uwp app with notification listener and I'm trying to get the origin of a notification (like Google Chrome and the website it came from).
I tried using the AppInfo.DisplayInfo for a UserNotification but I can't get it to print the info, and I'm not sure if this is the right way to do this.
IReadOnlyList<UserNotification> notifs = await MainPage.listener.GetNotificationsAsync(Windows.UI.Notifications.NotificationKinds.Toast);
UserNotification n = notifs.Last();
var name = n.AppInfo.DisplayInfo.DisplayName;
I expected name to be the name of the app the notification came from but it seems to be empty or just not working. To be precise from a notification like this:
I want to extract the "Google Chrome" and / or "www.reddit.com".
Hopefully you have found a solution by now, but in case this helps anyone:
The notification doesn't know that your message is coming from a browser. The whole Windows notifications system doesn't take that into an account. Windows receives a UserNotification from an application, which in your case happens to be a browser. So your "origin" is the application "Google Chrome". Your best shot is to try and get the link from inside the notification itself, if it is inside the body somewhere.
I really think you should be able to find the link inside the text of the notification, but I would need more information on what exactly you are receiving to be sure. If you want to know how to read the text of the notification, do:
string appName = notif.AppInfo.DisplayInfo.DisplayName; //this will get you "Google Chrome"
NotificationBinding toastBinding = notif.Notification.Visual.GetBinding(KnownNotificationBindings.ToastGeneric);
if (toastBinding != null)
{
IReadOnlyList<AdaptiveNotificationText> textElements = toastBinding.GetTextElements();
string titleText = textElements.FirstOrDefault()?.Text;
string bodyText = string.Join("\n", textElements.Skip(1).Select(t => t.Text));
string website = ParseWebsiteFromText(bodyText); //my guess is the info you want is in here
}
From there you have to parse the information you want, if it's available.
If you want to know more, I suggest reading the documentation from here: https://learn.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/notification-listener.
I have a client that wants to have a local notification that the user can not dismiss and will be there until the app is closed. I can get this to work in android but not in iOS. I am working in xamarin and have had to break out of the pcl to accomplish this and the notifications in general. Is this something that can be accomplished(does apple allow this)? Or is a widget extension what I am in need of creating?
You can present a local notification on top of your running app
by implementing IUNUserNotificationCenterDelegate and calling the WillPresentNotification completionHandler with the UNNotificationPresentationOptions.Alert option.
But you can not prevent the user from dismissing it, thus is would be cleared from the Notification Center.
I'm not sure what information you are trying to show in the "permanent" notification, but it sounds like a Today View Widget is something you should look at. The downside of course is Today widgets require that the user manually adds the widget to the Today view and depending upon your needs that they enabled it for lock screen usage.
Here is how you would do a local notification and make it present itself on top of your app....
Implement IUNUserNotificationCenterDelegate:
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
completionHandler.DynamicInvoke( UNNotificationPresentationOptions.Alert );
}
Assign the UNUserNotificationCenter Delegate:
UNUserNotificationCenter.Current.Delegate = this;
Send a local notification:
var unAuthorizationOptions = UNAuthorizationOptions.Alert & UNAuthorizationOptions.Badge & UNAuthorizationOptions.Sound;
var authReply = await UNUserNotificationCenter.Current.RequestAuthorizationAsync(unAuthorizationOptions);
if (authReply.Item1 == true) // Xamarin.iOS does not label the tuple members ;-( (granted, error)
{
var content = new UNMutableNotificationContent
{
Title = "Local Notification",
Subtitle = "By SushiHangover",
Body = "StackOverflow rocks",
Badge = badgecount
};
var request = UNNotificationRequest.FromIdentifier("SushiHangover", content, null);
await UNUserNotificationCenter.Current.AddNotificationRequestAsync(request);
}
Is there a way to change the default user id (which is 'default-user') in bot emulator?
Or maybe it supports something about multi conversations in the same time?
I want to emulate two different users at the same time (because I have multiple user types in my project.
When I try to create new conversation like this
....
var connector = new ConnectorClient(new Uri(context.Activity.ServiceUrl));
var userAccount = new ChannelAccount("//here we need to provide user id which is always default-user", "Provider");
var botAccount = context.Activity.Recipient;
var conversation = await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount);
var message = context.MakeMessage();
message.Recipient = userAccount;
message.From = botAccount;
message.Conversation = new ConversationAccount(false, conversation.Id);
await connector.Conversations.SendToConversationAsync((Activity) message);
My emulator opens new conversation in the same chat-window
Bot Framework Channel Emulator had the functions you need in the previous versions. In the latest one AFAIK changing user id and group conversation simulation are not available out of the box. However the good thing is that what this tool is doing - it is just sending http requests to your WebApi endpoint. It means that you can catch those requests using Fiddler or any other similar tool and then edit and reissue the request. It is a workaround, but for testing pusposes I think it is okay to use such an approach.
Below is the Fiddler screen and screen of debug session to show it is working:
If you want to go further and automate it - there is a REST Api documentation on botframework site, so you can build your own client.
I work on the Bot Framework Emulator. We've recently added the ability to override generated user ids to be used in conversations without the need of a tool like Fiddler. You can utilize this feature in our latest release. I hope you find this useful for your scenario.
I don't know a way of having multiple conversations with different users, but you cant change the id/name of the user that is currently sending messages.
You can do this by editing the config file that the emulator uses to store its settings.
On linux I found this settings file here:
~/.config/botframework-emulator/botframework-emulator/server.json
You'll find a section "users" in that json file.
Change that section to:
"users": {
"currentUserId": "default-user2",
"usersById": {
"default-user": {
"id": "default-user",
"name": "User"
},
"default-user2": {
"id": "default-user2",
"name": "User2"
}
}
You'll need to restart the emulator and then your conversation should be with User2 now instead of User.
When you want to change it back you just need to change:
"currentUserId": "default-user2",
back to
"currentUserId": "default-user",
On windows follow these steps:
go to directory
%APPDATA%\botframework-emulator\botframework-emulator
locate server.json file
In the sections of users replace default-user
with id you need (in my case romel)
"users": {
"currentUserId": "default-user",
"usersById": {
"default-user": {
"id": "romel",
"name": "User"
}
}
}
restart bot emulator