I have come into ownership of a ASP.NET MVC site that utilizes Biztalk 2013 to handle tasks like sending emails. I am completely new to biztalk so forgive obvious mistakes in this post.
Quick overview
The service is called through the application and then the orchestration calls a stored procedure in a sql db to populate some of values for the email (including html for the email) and then sends the email out.
I now want to add a pdf attachment to the email.
As a test, I added a pdf file to the server and then I have tried adding ActualEmailMsg(SMTP.Attachments) = "C:\\PDFs\\test.pdf";
ActualEmailMsg(SMTP.MessagePartsAttachments) = 2; to the message assignment expression shape as suggested in this post to no avail. (I also tried the physical path with only 1 "\" like "C:\\PDFs\test.pdf" and that didn't work)
I have ruled out the possibility of a lack of permissions from the service account to the PDF folder. The email sends correctly but no attachment is present. I am getting no errors in the code or in the event viewer on the server so at this point I am at a loss for what it might be.
After lots of googling I found the issue was related to the send pipeline. This thread got me on the right track.
In the send ports section of the BizTalk Admin Console of the app, the send pipeline was using a custom pipeline I believe was made by the previous owner. I changed it to the 'Pass Thru Transmit' type in the dropdown and it is now working.
I use the following pattern for sending Emails. I’m not sure but maybe you need to use the ActualEmailMsg(MIME.FileName) attribute for message in email.
ActualEmailMsg(MIME.FileName) ="Report_{"+FullFileName+"}.xml";
ActualEmailMsg(SMTP.CC)=ReportNotificationEmailAddress;
ActualEmailMsg(SMTP.Subject)="Report Notification Email";
ActualEmailMsg(SMTP.EmailBodyFile)=#"C:\...\ReportNotificationBody.htm";
ActualEmailMsg(SMTP.Attachments)=#"C:\..\ReportNotificationBody.png”;
ActualEmailMsg (SMTP.EmailBodyTextCharset)="UTF-8";
Related
I added Service Account to my email#gmail.com, activated OAuth2 for it and downloaded the key. Then I followed the steps described in this (life saving) post with the only difference that I instantiated "credential" from Json file (loading p12 would always give me "Invalid network password"). With this I can successfully get Access Token, here is the line which does it:
Task<bool> result = credential.RequestAccessTokenAsync(CancellationToken.None);
Then I instantiate SmtpClient from MailKit and try to connect and authenticate:
client.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
var oauth2 = new SaslMechanismOAuth2("email#gmail.com", credential.Token.AccessToken);
client.Authenticate(oauth2);
The last line generates exception that reads 555: 5.5.2 Syntax error, goodbye. l13sm3080685qtv.82 - gsmtp. The part that ends with .82 changes with each subsequent call. As per this post, I tried different variants for "email#gmail.com" (i.e. <email#gmail.com>). I also tried to use the Service Account email instead (the one similar to this: appName#serviceName.iam.gserviceaccount.com) but to no avail. I mad sure I am using latest versions of MailKit, MimeKit and Google.Api* and searched extensively but found nothing that could provide a solution.
Interestingly, without any change to the code I started experiencing different exception. It now comes partially base64 ecoded and reads this (after decoding):
334: {"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}
In the meantime I tried 2 other implementations that claim they got it right. None works - they all succeed with getting access token but break on "authenticate". All of that blows once's mind and makes the effort even more hopeless. One wonders if there is any C# code that is truly successful in sending gmail message using OAuth2... Any hint or other form of help would be greatly appreciated.
The method pointed by jstedfast below works well but I'd like to follow up with few issues. Too much for standard comment, so I added it here:
When the flow is executed for the first time, it opens popup browser window and user must login/approve the application/service to access gmail account. It loooks like access key must be stored on the hard drive. If I removed "DataStore" from GoogleAuthorizationCodeFlow constructor, the browser seems to popup each time when executing the code. The app I have to fix normally runs without any user interaction. Is there a way to avoid browser popup by enabling/disabling something in gmail account or service/app defined in developer's console? If standard gmail account cannot be used this way, perhaps email that is a part of GSuite domain can? The customer who owns the application uses Google GSuite and they have their domain with emails and documents. I think that now I understand jstedfast's remark on client-to-server vs server-to-server.
Follow these directions to get this working: https://github.com/jstedfast/MailKit/blob/master/GMailOAuth2.md
If you are loading a .p12, then you are doing it wrong. That method is for service-to-service, not client-to-service. The instructions I provided above is for client-to-service.
We are experiencing a problem with Rich Text Emails that are forwarded as attachments having the ContentIDs being stripped from the attachments, which prevents us from correctly rebuilding the email message.
Here is an example response from EWS for a Rich Text Email with a picture
<t:ItemAttachment>
<t:AttachmentId Id="AAMkAGRlNWE5MTc1LTUyODktNDRjNi05NTcwLWZjZGM1ODNkMmUxYwBGAAAAAABtOoJbAYfVSZzEDvklEbbPBwBBckyCi9TiT4cjPa5DHYwwAAAAemCwAABBckyCi9TiT4cjPa5DHYwwAABknfz6AAABBgAEAAAAAAA="/>
<t:Name>Message with Attachments</t:Name>
<t:Size>97993</t:Size>
<t:LastModifiedTime>2014-06-10T13:19:25</t:LastModifiedTime>
<t:IsInline>false</t:IsInline>
<t:ContentId>F4880FA606E4DC9BBC5143C97C52AC554A3AE55B#1</t:ContentId>
</t:ItemAttachment>
Here is the same Email that is forwarded as an attachment:
<t:FileAttachment>
<t:AttachmentId Id="AAMkAGRlNWE5MTc1LTUyODktNDRjNi05NTcwLWZjZGM1ODNkMmUxYwBGAAAAAABtOoJbAYfVSZzEDvklEbbPBwBBckyCi9TiT4cjPa5DHYwwAAAAemCwAABBckyCi9TiT4cjPa5DHYwwAABknfz6AAACBgAEAAAAAAAGAAQAAQAAAA=="/>
<t:Name>Picture (Device Independent Bitmap)</t:Name>
<t:Size>5210</t:Size>
<t:LastModifiedTime>2014-06-10T13:19:25</t:LastModifiedTime>
<t:IsInline>true</t:IsInline>
</t:FileAttachment>
Of Note - Exhange 2010 SP2
EWS API v2.2 (also happens in 2.0)
My Questions are:
Is this intended behavior? (if so why?)
Is this configurable on exchange (not the correct forum - but still)
If it is configurable on exchange what are the implications of said configuration.
I'll be opening an MSFT Support Incident here shortly.
Steps to recreate:
New Message
Set Message to Rich Text
Attach Image
Send Email
Open Email
Forward as attachment to another Rich Text Email (this can also be done by saving the msg to disk and then attaching it manually)
I've delt with exchange alot when building an outlook addin. I'm talking about older versions of exchange and outlook but I have painful memories dealing with custom email sending and rebuilding. Especially with RTF.
Is this intended behavior? - my guess is yes and most likely because if exchange doesn't strip the ContentId, it might present a security issue or cause unintended behavior on the client. It would be difficult for the exchange developers to support tracking exchange emails attached to other exchange emails. It doesn't consider it an exchange item any more when it's an attachment, to exchange it's just another block of data.
Is this configurable? - I'm not sure as I haven't dealt with any of the newer versions of exchange lately but based on my answer to number 1, probably not.
If it is configurable on exchange what are the implications of said configuration? - see answer #1, my guess is security related and/or development difficulty.
You need look at the RTF contents of the message. But take note that in many cases the RTF body content is usually compressed with base-64 so you may need to decompress it first.
-
I have difficulties implementing the following scenario.
Let's say you have a web site with ability to send and recieve messages between users.
User recieves an email with notification he has a new message on the software system (doesn't matter in what it is implemented). He can respond to this message by sending a reply via email or by logging into the site and replying to the 'message' using the site.
In case of the first approach if user simply replies to the email notification, how can you (as a developer) know what 'message' (ID) is the reply for?
I'm thinking the info would be stored in the MIME extensions. Are the MIME extensions transfered to the reply of the message? If yes than the solution could be to see the data of the original message notification for wich the user replyes to.
Any ideas? Thank you
The only “reliable” way would be to encode that information in the sender's address to which the user replies; you could also put it into subject or body of the message, and “hope” that the user doesn't tamper with it. There is an “in reply to (message-id)” header, but a lot of existing eMail clients don't set the header properly.
The usual mechanism is something like this: create an eMail alias prefix, and the append a message-id-code fragment to the end; for example, if this was for a purchase order confirmation, you could create an eMail alias handling addresses of the form po-*#example.com, where * is the unique message ID. Then, when you send your message out, you'd put the appropriate address in both the From: and Reply To: headers. EG:
From: "Purchase Order Confirmation (#1234)" <po-1234#example.com>
To: "John Doe" <jdoe#example.com>
Reply-To: "Purchase Order Confirmation (#1234)" <po-1234#example.com>
Subject: Confirm your order (#1234)
Depending upon your mail server, you should be able to define a “separator” character (typically - or +) that is used to split up the parts of the “local part” (left of #) of the eMail address; there is typically then another mechanism to map a prefix to a script to handle all addresses of a certain form. The script interface is often very much like CGI on the web, sending in some environment variables and piping the message itself in on the standard input. If your app is primarily web-based, you might find it more “comfortable” to gather the incoming eMail body, and POST it to a private (perhaps http://[::1]/getMailReply) handler. This may help you reuse existing code more readily.
We have set up a catch-all email address on our server - for example catch-all#myserver.com. When we send emails to users, we encode the message id and any other meta information we may need in the from address. You can obfuscate this or not, depending on what your needs are. So, for example, if the user has a new message in the system whose ID is 100, the from address of the email we send to the user would be something like reply-to-message-100#myserver.com. Make sure that whatever format you use for the from address would never generate a real email address on your mail server.
So, when the user responds to this message, it will get sent to the catch-all inbox you have set up. From here, you have a number of choices to make on how you process this email. In times past, we wrote a little scheduled service that would run every few minutes and check this inbox for new emails, process them as you like (insert into db, send more emails, whatever), and delete the message since you're done processing it. This is fragile since email clients all have slightly different ways of sending emails and it becomes difficult to parse the variety of client messages out there.
The second way we've done it is by integrating with http://postmarkapp.com/ - which has an incoming email api that should go public soon (we got in on the beta). You'd set everything up the same way only make your server's catch-all address forward to the postmark incoming address you'll set up with Postmark, and then Postmark does the message processing and calls a webhook you also set up to do what you like with the object received.
I highly recommend Postmark, but even the homespun method worked effectively, for the most part.
-M
Just a followup to the previous answer, Postmark Inbound is now live and public http://postmarkapp.com/inbound For each email sent to your specially formatted inbound email address, you'll receive a JSON formatted web hook API call with all the email components, headers, attachments sorted for you.
I am trying to find a solution that can handle messaging via email.
When a user creates a message in my application, an email is sent using subject #4857474.
Then, the email recipient can reply, without changing the subject, and my application would know what message it used, based on the #id in the subject.
Now, I do not want to implement such service because its rather complex. What I am looking for is a service that provides this, and just calls my web services for a request when a new message has arrived.
Is there such thing? Thanks!
In the smtp standard there are two header fields that can be used for this: message-id and in-reply-to.
Assign a unique message id when you send the mail, then inspect the in-reply-to field in messages you receive. Since the field is hidden from user input, there is no risk that the user messes with it.
I don't think there is a default component you could use. Also it wouldn't be a very complex flow i think.
Just read out the subject and trigger your app?
Is email a must or can you also use a webbased reply form? Then you could use just a database.
Edit:
Read email from C# http://www.codeproject.com/KB/IP/despop3client.aspx
Create a thread that runs for ever and reads out the mailbox. If a email matches your criteria (subject) then trigger your webservice.
Well, for my program(s) I'd like to let the user send me an e-mail with any errors. Instead of relying on a forsaken SMTP server, I decided to let the user use his very own e-mail client to send an e-mail to a specified address.
So what I need is:
A sender (should not be changeable) (example: mysupportemail#gmail.com)
An attached file (should not be changeable) (example: "C:\a file.log")
(Optional) A body (changeable)
I hope it is possible!
You can use the mailto command for this. See http://msdn.microsoft.com/en-us/library/aa767737(VS.85).aspx for more information. Some mail clients support attachments on this. See the comments of the MSDN page for some information on this.
The mailto protocol has limitations, such as not being able to specify an attachment (some mail clients support it, but it's not in the official protocol). Your best option is probably to use the MAPISendMail function to let MAPI do the hard work. See this article for details:
Sending files via the default e-mail client
I used this technique in the past, it seems to work perfectly.
Using mailto directly from you application cause potential problems. If you have specified mail account for receive e-mails you can be sure, that someone will use it somehow to sent you spam or thousands unwanted emails. In our company we struggled with this problem many times - at last, we decided to allow our customers to report problems in any other way - web page form.
Now, when customer click 'report problem' this option displays a form for reporting bugs in default web browser. Opened link include some additional information which causing partial fill of the form opened by customer. Now, we have an intermediate layer and absolute control on server side who report problem (ip) and we can limit reporting for specified users. Next advantage of these solution is that you can forward emails to different departments depending on what form fields are marked/filled with.
Well, I have found the perfect solution!
For those who want to see it...
http://social.msdn.microsoft.com/Forums/en/netfxnetcom/thread/a75533eb-131b-4ff3-a3b2-b6df87c25cc8
http://www.eggheadcafe.com/community/aspnet/2/10019665/email-through-gmail-in-c.aspx