Bot mentions to meetings groups are blank on Desktop/Web chat view - c#

We're developing a bot that proactively messages people in a group chat.
Bot mentions are showing blank on Desktop/Web chat view. Interestingly, on mobile and in the notification bar on the left, the full text does show correctly.
This issue may apply to other chats, but I have not tested.
I'm using similar code to the following Microsoft guide by constructing the mention object:
https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-and-group-conversations?tabs=dotnet#add-mentions-to-your-messages
Yes, I have tried using XMLConvert on the name as in the example, however, that does not make a difference, in fact, it puts the XML verbatim into the message sent by the bot.
I've also submitted a bug report here, as I suspect it's a bug in Teams itself (although, I could not find any other mentions of this or other similar example code):
https://microsoftteams.uservoice.com/forums/555103-public/suggestions/43922577-bot-mentions-to-meetings-groups-are-blank-on-deskt
Relevant C# code:
...
using (ConnectorClient _client = new ConnectorClient(new Uri(groupChat.ServiceUrl), GetMicrosoftAppCredentials(), new HttpClient()))
{
var theMessage = Activity.CreateMessageActivity();
theMessage.Text = messageDto.Message;
// Process the message text for <at>mentions</at>
var textMentions = System.Text.RegularExpressions.Regex.Matches(theMessage.Text, "<at>(.*?)</at>");
var mentionObjects = new List<Entity>(); // For storing the mentions
foreach (var textMention in textMentions)
{
// The mentioned person should be between the tags
var theName = textMention.ToString().Split(new string[] { "<at>", "</at>" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (!String.IsNullOrEmpty(theName))
{
// Find the teamsUser based on their name
var teamsUser = _botContext.Users.FirstOrDefault(u => u.Name.Equals(theName));
if (teamsUser != null)
{
var mention = new Mention
{
Mentioned = new ChannelAccount(teamsUser.TeamsUserId),
Text = textMention.ToString()
};
mentionObjects.Add(mention);
}
}
}
theMessage.Entities = mentionObjects;
try
{
var response = await _client.Conversations.SendToConversationAsync(groupChat.GroupChatId, (Activity)theMessage);
return Ok(response.Id);
}
catch (Exception e)
{}
}
...
Desktop Teams Chat:
Activity shows name OK:
Mobile app looks OK:
Images edited for privacy

Try passing "User Name" also in ChannelAccount() like below:
var mention = new Mention
{
Mentioned = new ChannelAccount(
turnContext.Activity.From.Id,
**turnContext.Activity.From.Name,**
role: null,
aadObjectId: null),
Text = textMention.ToString()
};
I tried above code and it's working for me.

Related

How do you add thumbnails to an embed message in DSharpPlus?

I have been bashing my head against the wall for 8 hours now, trying to figure out how to add thumbnails to embeded messages. I've been following this tutorial that uses ThumbnailURL, something that doesn't exist in the context he's using it for. Instead I just have Thumbnail which does not take a string, but rather an EmbedThumbnail which I can't access at all.
var avatarEmbed = new DiscordEmbedBuilder
{
Title = "Enter the game.",
Thumbnail = ctx.Client.CurrentUser.AvatarUrl,
Color = DiscordColor.Azure,
};
Please don't send links to docs and tutorials. I've tried. I've really tried. But this just seems like an issue that is very recent and therefore resources on it would be next to none. Also the docs don't seem to have example code, making it all more frustrating.
Not sure about your version but I use the latest nightly build.
and I do it like this
var builder = new DiscordEmbedBuilder
{
Title = "Title Here",
Color = DiscordColor.Azure
};
builder.WithThumbnail(ctx.Client.CurrentUser.AvatarUrl);
but you can also do it this way
var builder = new DiscordEmbedBuilder
{
Title = "Title Here",
Color = DiscordColor.Azure,
Thumbnail = new DiscordEmbedBuilder.EmbedThumbnail
{
Url = ctx.Client.CurrentUser.AvatarUrl
}
};

How to add emojis on a bot message and be able to "vote"?

I made a MEME command of Discord Bot that posts a list of memes from phpMyAdmin DB. But it is not about that. I want to add specific emojis on that bot message that people could press on those emojis and kinda vote.
It is how it posts:
It is what I want to do:
[Command("meme")]
public async Task meme(CommandContext commandInfo, int id = -1, SocketUserMessage userMsg, string emoteName)
{
var description = "";
MySqlClient.Connect();
if (id == -1)
{
var query = "SELECT * FROM memes;";
var memeReader = MySqlClient.GetDataReader(query);
if (memeReader == null) return;
while (memeReader.Read())
{
var memeid = memeReader.GetUInt64("id");
var title = memeReader.GetString("title");
description += $"**{memeid}** {title}\n";
}
}
var memeEmbed = new DiscordEmbedBuilder()
{
Color = DiscordColor.Gold,
Title = "**The Meme of The Year**",
Description = description
};
var msg = await commandInfo.Channel.SendMessageAsync(embed: memeEmbed);
}
Adding Reactions
Assuming you are using Discord.Net, you need to react to your own message using the AddReactionAsync method.
Adding Emojis
Emojis are unicode characters. To use them, pass the utf-code (e.g. "\uD83D\uDC4C") as an argument to the constructor of the Emoji` object.
await userMsg.AddReactionAsync(new Emoji("\U0001f643"));
Adding Emotes
An Emote is a 'custom Emoji' which can be set by server admins/mods.
As an argument you need to pass a custom Emote string, like this "<:thonkang:282745590985523200>".
A safe wrapper to catch non-existing emotes could look like that (taken from the docs).
public async Task ReactWithEmoteAsync(SocketUserMessage userMsg, string escapedEmote)
{
if (Emote.TryParse(escapedEmote, out var emote))
{
await userMsg.AddReactionAsync(emote);
}
}
https://docs.stillu.cc/guides/emoji/emoji.html
Counting Reactions
As a second step you need to listen to user-events, when they react to your post. This should be done in a separate event handler, as your poll will likely be up for several hours/days.
Here is an example on how to implement an event handler
You then need to keep track of the reactions and need to associate it with the matching database entry.

C# Google API throws exception

I am using Google API for the first time and I want to use Natural Language API.
But I don't know how.
So I search the internet and found an example code.
But when it uses APIs, the program throws an exception.
problem source code and thrown exception:
using Google.Cloud.Language.V1;
using System;
namespace GoogleCloudSamples
{
public class QuickStart
{
public static void Main(string[] args)
{
// The text to analyze.
string text = "Hello World!";
try
{
var client = LanguageServiceClient.Create();
var response = client.AnalyzeSentiment(new Document()
{
Content = text,
Type = Document.Types.Type.PlainText
});
var sentiment = response.DocumentSentiment;
Console.WriteLine($"Score: {sentiment.Score}");
Console.WriteLine($"Magnitude: {sentiment.Magnitude}");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
The console output:
The Application Default Credentials are not available.
They are available if running on Google Compute Engine.
Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials.
See https://developers.google.com/accounts/docs/application-default-credentials for more information.
What should I do?
I had used NLP a year ago for entity analysis. I had used Google.Apis.CloudNaturalLanguage.v1. I put together my code with what you have written for sentiment analysis. You will need the API key for this:
var service = new CloudNaturalLanguageService(new CloudNaturalLanguageService.Initializer { ApiKey = ApiKey });
var req = new AnalyzeSentimentRequest {
Document = new Document()
{
Content = text,
Type = Document.Types.Type.PlainText
},
EncodingType = "UTF8"
};
var output = service.Documents.AnalyzeSentiment(req);
var exe = output.Execute();
Hope this works.

Xamarin IOS UIActivityViewController ExcludedActivityTypes how to include linked

I am trying to exclude Linkedin but when i checked UIActivityType Class, I found only below members.
AddToReadingList
AirDrop
AssignToContact
CopyToPasteboard
Mail
Message
OpenInIBooks
PostToFacebook
PostToFlickr
PostToTencentWeibo
PostToTwitter
PostToVimeo
Print
SaveToCameraRoll
Is there a way we can exclude linkedin?
Update:
I thought this radar concerning third-party values was closed, but it is still open :-(
http://openradar.appspot.com/20170408
...
The ExcludedActivityTypes is just an array of NSStrings that include the bundle id of the share extension. So use com.linkedin.LinkedIn.ShareExtension to exclude linkedin.
Example:
var activityItemsNSUrl = NSUrl.FromString("http://stackoverflow.com");
var activityItemsString = new NSString("StackOverflow");
var activityItems = new NSObject[] { activityItemsString, activityItemsNSUrl };
var activityViewController = new UIActivityViewController(activityItems, null)
{
ExcludedActivityTypes = new NSString[] {
UIActivityType.PostToVimeo,
new NSString("com.linkedin.LinkedIn.ShareExtension"),
UIActivityType.PostToFlickr
}
};
PresentViewController(activityViewController, true, () => { });
Re: https://developer.linkedin.com/docs/ios-sdk

How to get all installations when using Azure Notification Hubs installation model?

Using NotificationHubClient I can get all registered devices using GetAllRegistrationsAsync(). But if I do not use the registration model but the installation model instead, how can I get all installations? There are methods to retrieve a specific installation but none to get everything.
You're correct, as of July 2016 there's no way to get all installations for a hub. In the future, the product team is planning to add this feature to the installations model, but it will work in a different way. Instead of making it a runtime operation, you'll provide your storage connection string and you'll get a blob with everything associated with the hub.
Sorry for visiting an old thread... but in theory you could use the GetAllRegistrationsAsyc to get all the installations. I guess this will return everything without an installation id as well, but you could just ignore those if you choose.
Could look something like this
var allRegistrations = await _hub.GetAllRegistrationsAsync(0);
var continuationToken = allRegistrations.ContinuationToken;
var registrationDescriptionsList = new List<RegistrationDescription>(allRegistrations);
while (!string.IsNullOrWhiteSpace(continuationToken))
{
var otherRegistrations = await _hub.GetAllRegistrationsAsync(continuationToken, 0);
registrationDescriptionsList.AddRange(otherRegistrations);
continuationToken = otherRegistrations.ContinuationToken;
}
// Put into DeviceInstallation object
var deviceInstallationList = new List<DeviceInstallation>();
foreach (var registration in registrationDescriptionsList)
{
var deviceInstallation = new DeviceInstallation();
var tags = registration.Tags;
foreach(var tag in tags)
{
if (tag.Contains("InstallationId:"))
{
deviceInstallation.InstallationId = new Guid(tag.Substring(tag.IndexOf(":")+1));
}
}
deviceInstallation.PushHandle = registration.PnsHandle;
deviceInstallation.Tags = new List<string>(registration.Tags);
deviceInstallationList.Add(deviceInstallation);
}
I am not suggesting this to be the cleanest chunk of code written, but it does the trick for us. We only use this for debugging type purposes anyways

Categories

Resources