Sending an HTML attachment from a Microsoft Teams bot - c#

I'm working on a Teams bot and I'm trying various ways to send rich messages to users (we need clickable buttons) from my bot. I have tried adaptive cards, which are almost perfect, but noticed that on the toast popup for the message it just says "Testbot sent a card". This isn't ideal as we'd like an overview of the message to appear instead.
I noticed that when you use the weather app to send a card to another user, it has the desired effect- a short summary of the weather appears in the toast popup. Looking inside the JSON that represents that message shows that the "card" is actually an HTML attachment.
Am I able to replicate this by sending an HTML attachment? I have (naively) tried the following but it causes an exception:
Activity reply = new Activity();
reply.Type = ActivityTypes.Message;
reply.Text = "Test the toast";
reply.Conversation = new ConversationAccount()
{
Id = conversationResponse.Id
};
reply.Attachments.Add(new Attachment()
{
ContentType = "text/html",
Content = "<div>Some generated html</div>"
});
Am I just barking up the wrong tree completely?
Thanks.
Edit:
The exception I'm getting is "Operation returned an invalid status code 'BadRequest'" from within mscorlib.dll.
For an adaptive card, I can do the following, and it works fine:
reply.Attachments.Add(new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject("{Some generated JSON}")
});
When trying to send the attachment as HTML, I assume I need to do more than simply send a string as Content. I tried rendering an adaptive card to HTML and attaching the resultant RenderedAdaptiveCard object, but still got the same exception.
--
Edit 2:
When a colleague sends me a card using the weather app:
https://i.imgur.com/BlBk557.png
I get the following toast:
https://i.imgur.com/EoO8COj.png
When using that tool to send a message to the bot, I can see a message with an attachment of type text/html.
I was attempting to replicate this by sending a message from the bot to a user with an attachment of type text/html and some HTML in the content field. I now see that when I do this there is a 400 response from the serviceUrl which says
{"error":{"code":"BadArgument","message":"Unknown attachment type"}}
I think maybe the assumption I made was based on a misunderstanding. I take it that we can't have informative text on the toast for a card in the same manner as the weather app?

It seems like this is impossible. See comment on OP:
"Bots does not support an Html Attachment" - Gousia-MSFT

Related

SendGrid throws "Error while copying content to a stream"

I'm creating a Core 2.1 solution in Visual Studio 2017 where I send emails via Sendgrid. When trying to send an email via SendGrid, I get the following error:
An unhandled exception occurred while processing the request.
IOException: The server returned an invalid or unrecognized response.
System.Net.Http.HttpConnection.FillAsync() HttpRequestException: Error
while copying content to a stream.
System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task
serializeToStreamTask, MemoryStream tempBuffer)
Here is what my code looks like. I'm entering the following in parameters:
recipients: list containing "****#gmail.com"
Subject: "Hello"
Body: Html generated via Heml. It compiles in an online editor without problem.
private async Task<bool> SendAsync(List<string> recipients, string subject, string body)
{
var client = new SendGridClient(this.configuration["Sendgrid:ApiKey"]);
var from = new EmailAddress(
this.configuration["Administration:MainEmailAddress"],
this.configuration["Administration:MainEmailName"]);
var tos = await GetRecipientsForEnvironment(recipients);
var message = MailHelper.CreateSingleEmailToMultipleRecipients(
from,
tos,
subject,
"",
body,
false);
var response = await client.SendEmailAsync(message);
return response.StatusCode == HttpStatusCode.Accepted;
}
What is the cause of this error?
It turns out that there is a known bug in Sendgrid. If the html content entered is very big, the correct error message will not be sent. Instead, this error will show up. In my case, my apiKey was not found and I should therefore have gotten an Unauthorized error message. When I changed my html into one much smaller, this gave me the correct error.
Read more about the issue here.
I'm having the same problem, but in my case it's because the email quota has expired (I'm using the free version for testing):
Lib version 9.21.0
On the mentioned thread https://github.com/sendgrid/sendgrid-csharp/issues/648 some people were passing the wrong apiKey, and others exceeding the HTML size.
As said in the thread above, apparently it's a bug in the sendgrid library when interpreting the error.
Therefore, in addition to the problems mentioned (passing the wrong apiKey, exceeding the HTML size) the return “Error while copying content to a stream” is hiding other problems as well (like in my case: quota expired).

Twilio Error - 12200 - Schema validation warning - Content is not allowed in prolog

I have a webHook receiver that listens to Twilio POST. Scenario: SMS message is sent to my Twilio number, Twilio does POST to the webHook receiver, webHook processes the request (works as expected) and finally WebHook returns back a response object Twilio.TwiML.MessagingResponse. The problem is I'm receiving a warning in the Twilio Debugger with message "Content is not allowed in prolog." The warning shows in the REQUEST section of the Request Inspector and didn't know what to do about it.
screenshot of error/warn message
Thanks all for looking into this. Answer by #marcos-placona in here made me revisit the webHook return type. Sure enough the return type needs to be a TwiML formatted XML. That led to the discovery of the overloaded ToString() extension method.
public string ToString([System.Xml.Linq.SaveOptions formattingOptions = System.Xml.Linq.SaveOptions.None])
Member of Twilio.TwiML.TwiML
Summary:
Generate XML string from TwiML object
Parameters:
formattingOptions: Change generated string format.
for this to work, [System.Xml.Linq] needs to be referenced.
using Twilio.TwiML;
var twilioResponse = new MessagingResponse();
var message = new Twilio.TwiML.Messaging.Message("Thanks for your response.");
twilioResponse.Append(message);
return twilioResponse.ToString();
Hope this helps someone.

EWS reply mail with original body

When i want to reply a mail via EWS like below, if I retrieve a email body in html format like below. How can I put some reply text conveniently, just at the top of the original message?
Although I can parse the html, I am wondering there is any smart way doing it. thank you
EmailMessage mesg = email.CreateReply(false).Save();
mesg.Load();
MessageBody lvMessageBody = mesg.Body;
You should be able to do this by setting the BodyPrefix property on the reply. See https://msdn.microsoft.com/EN-US/library/office/dn617213(v=exchg.150).aspx

Telegram C# example send message

I can't find an example of sending message by telegram protocol from C#. I tried to use this but failed.
Can you give me any examples?
TLSharp is basic implementation of Telegram API on C#. See it here https://github.com/sochix/TLSharp
You can use the WTelegramClient library to connect to Telegram Client API protocol (as a user, not a bot)
The library is very complete but also very easy to use. Follow the README on GitHub for an easy introduction.
To send a message to someone can be as simple as:
using TL;
using var client = new WTelegram.Client(); // or Client(Environment.GetEnvironmentVariable)
await client.LoginUserIfNeeded();
var result = await client.Contacts_ResolveUsername("USERNAME");
await client.SendMessageAsync(result.User, "Hello");
//or by phone number:
//var result = await client.Contacts_ImportContacts(new[] { new InputPhoneContact { phone = "+PHONENUMBER" } });
//client.SendMessageAsync(result.users[result.imported[0].user_id], "Hello");
For my bot I use Telegram.Bot nuget package. Full sample code is here.
Here is example of sending message in reply to incoming message.
// create bot instance
var bot = new TelegramBotClient("YourApiToken");
// test your api configured correctly
var me = await bot.GetMeAsync();
Console.WriteLine($"{me.Username} started");
// start listening for incoming messages
while (true)
{
//get incoming messages
var updates = await bot.GetUpdatesAsync(offset);
foreach (var update in updates)
{
// send response to incoming message
await bot.SendTextMessageAsync(message.Chat.Id,"The Matrix has you...");
}
}
The simplest way is to send http request directly to the Telegram BOT API as url string, you may test those url strings even in your browser, please see details in my another answer here:
https://stackoverflow.com/a/57341990/11687179
at the first step you have to generate a bot in botfather then use the code in bellow in C#
private void SendMessage(string msg)
{
string url = "https://api.telegram.org/{botid}:{botkey}/sendMessage?chat_id={#ChanalName}&text={0}";
WebClient Client = new WebClient();
/// If you need to use proxy
if (Program.UseProxy)
{
/// proxy elements are variable in Program.cs
Client.Proxy = new WebProxy(Program.ProxyUrl, Program.ProxyPort);
Client.Proxy.Credentials = new NetworkCredential("hjolany", "klojorasic");
}
Client.DownloadString(string.Format(url, msg));
}));
}
Telegram has an official API that can do exactly what you need, you will have to look into http requests though..
Here is the documentation on sending a message:
Function
messages.sendMessage
Params
peer InputPeer User or chat where a message will be sent
message string Message text
random_id long Unique client message ID required to prevent message resending
Query example
(messages.sendMessage (inputPeerSelf) "Hello, me!" 12345678901)
Return errors
Code Type Description
400 BAD_REQUEST PEER_ID_INVALID Invalid peer
400 BAD_REQUEST MESSAGE_EMPTY Empty or invalid UTF8 message was sent
400 BAD_REQUEST MESSAGE_TOO_LONG Message was too long.
Current maximum length is 4096 UTF8 characters
For the full documentation go here.

(Outlook 2010) Getting mail headers in C#

I've adapted Ken Slovak's code from here to read MailItem headers on a message before it is sent, but my header string is coming up as empty. Does this only work on received messages? If so, what would be a good method for pulling in the headers of the original message before composing Forward/Reply/Reply-To-All?
Here is my re-done code:
Outlook.PropertyAccessor oPA = msg.PropertyAccessor as Outlook.PropertyAccessor;
const string PR_MAIL_HEADER_TAG = #"http://schemas.microsoft.com/mapi/proptag/0x007D001E";
try
{
string strHeaders = (string)oPA.GetProperty(PR_MAIL_HEADER_TAG);
}
catch { }
Thanks
The message headers will only be populated once the original message has been sent. I tried your code and it returned the message headers for mail that I had received. I did get the security popup when trying to access the message though.

Categories