I am creating an ical event dynamically in my web application and when someone cancel the appointment on the application we are generating a delete ical event *.ics file to their email to remove the event in their calendar.
Creating is working perfectly but when we try to delete the appointment we created it doesn't remove it from the calendar
Creating Ical event code :
string[] contents = {
"BEGIN:VCALENDAR",
"VERSION:2.0",
"PRODID:-//dev.com//iCal//EN",
"X-WR-CALNAME:development",
"X-WR-RELCALID:928C8448-048A-4aa2-BE27-A920773AF3DC",
"X-FUNAMBOL-ALLDAY:0",
"METHOD:REQUEST",
"BEGIN:VEVENT",
"UID:" + Args.EventUID,
"SEQUENCE:1",
"DTSTART:" + Args.EventStartTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"),
"DTEND:" + Args.EventEndTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"),
"LOCATION: " + Args.EventLocation,
"ORGANIZER: test#outlook.com",
"DESCRIPTION;ENCODING=ESCAPED-CHAR:" + Args.EventName,
"SUMMARY:" + Args.EventDescription,
"STATUS:CONFIRMED",
"TRANSP:OPAQUE",
"PRIORITY:" + Args.EventPriority.ToString(),
"END:VEVENT",
"END:VCALENDAR"
};
Creating an event works perfectly on iphone/android/outlook
Delete event part:
string[] contents = {
"BEGIN:VCALENDAR",
"VERSION:2.0",
"METHOD:CANCEL",
"X-WR-CALNAME:development",
"X-WR-RELCALID:928C8448-048A-4aa2-BE27-A920773AF3DC",
"PRODID:-//dev.com//iCal//EN",
"X-FUNAMBOL-ALLDAY:0",
"BEGIN:VEVENT",
"UID:" + Args.EventUID,
"SEQUENCE:2",
"DTSTART:" + Args.EventStartTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"),
"DTEND:" + Args.EventEndTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"),
"LOCATION: " + Args.EventLocation,
"DESCRIPTION;ENCODING=ESCAPED-CHAR:" + Args.EventName,
"SUMMARY:" + Args.EventDescription,
"ORGANIZER: test#outlook.com",
"PRIORITY:" + Args.EventPriority.ToString(),
"STATUS:CANCELLED",
"TRANSP:OPAQUE",
"END:VEVENT",
"END:VCALENDAR"
};
When I click this file generated to remove the event that is already created it doesn't remove the event and sometimes it duplicates the event.
The ical UID on creating and delete are the same.
First, scrutinise the UID. I know you say they're the same, but check ! Whitespace? Case?
Next, put PRODID on the second line, straight after BEGIN (Ignore the validators when they tell you to put VERSION on the second line.) This sounds trivial, the field is not even used, but Outlook in particular is ridiculously picky. Copy a working example. Test and tell me if I'm wrong.
Next, SEQUENCE is indexed from 0. Clients may interpret SEQUENCE:1 as an update, and wonder where is the original invitation.
Next, check the structure and mime type headers of your emails. I got best results by sending a simple single part email with Content-type: text/calendar; method="[REQUEST/CANCEL]" in the MIME header.
Still not working? Try adding an ATTENDEE element, with participation required, rsvp true etc, repeating the email address of the recipient.
Still problems? Use the online Icalendar validators to check your output, but also copy exactly a working example. Send yourself an invitation, then cancel it, from gmail and/or outlook. Everything is important - the structure of the message, the order of the fields in the Icalendar, the MIME headers of the email. Sending to GMail lets you see exactly what is received, via the gmail show original option.
I notice you are doing nothing for wrapping. Ical lines are limited to 75 characters, not much, and overflowing lines must start with a space. A validator will quickly tell you.
The difference may also be whether the calendar app has 'subscribed' or 'imported' the ics file? Subscribed events should update, imported ones generally may not as the user could have changed them - may vary between calendar apps.
Try using PUBLISH as METHOD and 0 as SEQUENCE for submitting and 1 as SEQUENCE for erasing.
Example of submitting:
string[] contents = {
"BEGIN:VCALENDAR",
"VERSION:2.0",
"PRODID:-//site.domain//iCal//EN",
"METHOD:PUBLISH",
"BEGIN:VEVENT",
"UID:" + Args.EventUID,
"SEQUENCE:0",
"DTSTART:" + Args.EventStartTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"),
"DTEND:" + Args.EventEndTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"),
"SUMMARY:" + Args.EventDescription,
"STATUS:CONFIRMED",
"END:VEVENT",
"END:VCALENDAR"
};
Example of erasing:
string[] contents = {
"BEGIN:VCALENDAR",
"VERSION:2.0",
"PRODID:-//site.domain//iCal//EN",
"METHOD:CANCEL",
"BEGIN:VEVENT",
"UID:" + Args.EventUID,
"SEQUENCE:1",
"DTSTART:" + Args.EventStartTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"),
"DTEND:" + Args.EventEndTime.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"),
"SUMMARY:" + Args.EventDescription,
"STATUS:CANCELLED",
"END:VEVENT",
"END:VCALENDAR"
};
Related
I'm trying to write to the eventlog from a VSTO Outlook Plugin, but I haven't figured out how.
I've tried this a few different ways and I'm still not sure if I'm hitting a security permission issue between the Outlook plugin and the eventlog or something code related.
I tried with 2 different pieces of code. This is my testing piece and even it doesn't write:
EventLog myLog = new EventLog("Application");
myLog.Source = "ReportPhishing";
myLog.WriteEntry("Reporting Email");
This is the code I'm ultimately trying to add in:
string sourceName = "ReportPhishing";
//Defines who was the sender email
string SenderEmail = obj_CurrentItem.SenderEmailAddress;
//Defines who the end receiving email address is
string ReceiverEmail = obj_CurrentItem.ReceivedByName;
//Defines the schema used to pull the header information out of the email
string EmailHeaders = obj_CurrentItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E");
//Defines FileName as from the subject line
string FileName = obj_CurrentItem.Subject;
//Specifies the main event context
string eventSubject = "Reported Phishing Email";
//Creates the payload information for sending to the local eventlog
string eventPayload = eventSubject + "%n%nSenderEmail: " + SenderEmail + "%n%nReceivingEmail: " + ReceiverEmail + "%n%nSubject: " + FileName + "%n%nHeaders: " + EmailHeaders;
//string eventpayload = #"<EventData><Data Name=""SenderEmail"">"+ SenderEmail +"</Data><Data Name=""ReceivingEmail"">" + SenderEmail + "</Data><Data Name=""Subject"">" + FileName + "</Data><Data Name=""Headers"">" + EmailHeaders + "</Data></EventData>";
EventLog.WriteEntry(sourceName, eventPayload, EventLogEntryType.Error);
What I've tried:
I tried to create the event source from the plugin, but that never worked as it wouldn't execute without admin permissions.
I manually created the source via the registry, but that didn't seem to work either.
I removed the registry entry and created the source via an elevated command line using eventcreate. By creating it via commandline, I confirmed that a non-elevated command line could still write to the event source
Verified permissions from the Registry (I added a lot more permissions as a just in case)
Read through a number of other StackOverflow posts around the EventLog. None really discussed the plugin aspect. Most focused on permission issues or incorrect implementation of MS code examples.
Created a basic form application that created a log event. This appears to work with my above sample code:
There appears to be something within the VSTO Plugin functionality that prevents logging to the EventLog. I'm unsure where to go from here.
I'm working on coding a bot that will retrieve an image based on search parameters. When the bot returns the message after the command, I want the bot to alert the user that sent the command with a ping. (the notification of a message using the "#" symbol in discord).
Here's what I've got so far:
await Context.Channel.SendMessageAsync("#" + Context.Message.Author + "\n" + imageNode.Attributes["src"].Value);
I'm able to correctly grab the author of the command and it sends as it should--
Output in channel:
However, it's not actually sent as a tag, just plain text.
Is there a way to actually ding the user with a notification?
Yes, using User.Mention.
await Context.Channel.SendMessageAsync(Context.Message.Author.Mention + "\n" + imageNode.Attributes["src"].Value);
You can also just put their id in between <#>. For example, "Hello <#1234>"
One of my favorite things about C# 6 is that you can also use String Interpolation. Very useful in Discord.Net!
var id = Context.Message.Author.Id;
await Context.Channel.SendMessageAsync($"<#{id}> \n {imageNode.Attributes["src"].Value}";
I register two different templates for my WindowsPhone clients (one for tile-update and one for toasts).
Is there a possibility to only send one notification and my WindowsPhone clients getting a toast notification and a tile update?
I found a forum thread on msdn with following message (in the answer):
If you call a method SendTemplateNotificationAsync({“properties of
template”}, “en-us”)) like this, That will target the toast and tile
both notifications to the device A.
But that won't work for me. My client only gets the tile-update and not the toast notification.
I also tried a template with both in xml (tile and toast). Found here. But that also won't work (only toast visible on client).
I know, I can work with additional tags (like "toast" and "tile") and send the notifications like following code snippet. But I think this is an ugly solution:
await hubClient.SendTemplateNotificationAsync(content, tags + " && toast");
await hubClient.SendTemplateNotificationAsync(content, tags + " && tile");
Any help is appreciated. Thanks
Edit: My templates and my notification-properties:
Properties:
var content = new Dictionary<string, string>
{
{"title_en", "English title"},
{"message_en", "English content"},
{"title_de", "Deutscher Titel"},
{"message_de", "Deutscher Inhalt"},
{"url", url},
{"count", count.ToString()}
};
Toast-Template (WindowsPhone)
String.Format("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>$(title_{0})</wp:Text1>" +
"<wp:Text2>$(message_{0})</wp:Text2>" +
"<wp:Param>$(url)</wp:Param>" +
"</wp:Toast>" +
"</wp:Notification>", language);
Tile-Template (WindowsPhone)
String.Format("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Tile Template=\"IconicTile\">" +
"<wp:SmallIconImage>Small.png</wp:SmallIconImage>" +
"<wp:IconImage>Large.png</wp:IconImage>" +
"<wp:WideContent1>$(title_{0})</wp:WideContent1>" +
"<wp:WideContent2>$(message_{0})</wp:WideContent2>" +
"<wp:WideContent3 Action=\"Clear\"></wp:WideContent3>" +
"<wp:Count>$(count)</wp:Count>" +
"<wp:Title>AppName</wp:Title>" +
"</wp:Tile>" +
"</wp:Notification>", language)
await hubClient.SendTemplateNotificationAsync(content, tags + " && toast");
await hubClient.SendTemplateNotificationAsync(content, tags + " && tile");
This is not an ugly solution, actually there is a reason behind it.Selection of
template/registration always based on tags not based on payload keys. so actually you've registered the templates to different set of tags like =>
device A - toast template, tags: {"en-us", "toast"}
device A - tile template , tags : {"en-us", "tile"}
In this case Device tile template is registered with tags : {"en-us", "tile"} and Toast is tags: {"en-us", "toast"} and these two registrations are different so you can't send them in single request.
IMO you can't have the both notification with this single call => SendTemplateNotificationAsync({“properties of template”}, “en-us”))' because again IMO(As I was not able to work it out some time before) Notification hub is not able to decide which template (tile, toast) he has to send to the device. because each of them is registered with different tags set as mentioned above.
Also Why it is not an ugly solution, because It gives you more control over your notifications because you know toast and tile notifications have different purpose, they simultaneously don't provide any extra value.
Tile notification => It is used for info that can last long for some time and does not stale sooner. Like counter, Back image, Some new update etc. also this info does not require instant user's attention immediately.
Toast Notification => It is used for sending out info that is quite instant(hope you understand what I mean).Like some new message came, you have released a new update etc.
If you send two notification simultaneously all the time then in that case It really does not add extra value.
So, I'm fairly certain this is a relatively remedial question with a likely simple solution, but I just can't seem to find it. I've currently got a program that writes the variables it sets to the console on execution, as well as writing them to the logfile when called through Autosys.
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + " Output Variable: " + variable1);
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + " Output Variable: " + variable2);
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + " Output Variable: " + variable3);
Simple stuff. But for some reason, when I call this...
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + " Endpoint: " + endpointAddress);
after previously setting
endpointAddress = "https://endpointaddress.com";
for debug
or
string endpointAddress = Environment.GetEnvironmentVariable("ENDPOINT");
for the Autosys call, with ENDPOINT set in the jobvars file to
JV_ENDPOINT https://endpointaddress.com
and JV_ENDPOINT set in the cmd file to
SET ENDPOINT=%JV_ENDPOINT%
with the end result of it pretty much being exactly the same as it is when the program is run through Visual Studio or the executable itself,
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + " Endpoint: " + endpointAddress);
is just skipped entirely in the log. The other ten or so WriteLines that are called all work fine, but nothing at all is written in that line's place.
A few lines up in the log file, I get
D:\server_apps\PROCESS_FOLDER>SET ENDPOINT=https://endpointaddress.com
showing that the endpoint is properly set, but not calling it later.
And...this just in...the most recent time I have run it, the endpoint line just WAS put into the log file. Huh. Well, let's adjust this question a bit. Would anyone happen to have any idea why this particular line might be so uniquely temperamental? I haven't changed anything significant in more than an hour, so I can't fathom why it would suddenly work. But any insight into why it may have happened (and why it might not again) could go a long way toward working any bugs or kinks out of this. Hopefully.
As always, thanks for your time!
This is a long shot. I have no idea why this is happening, and I am hoping this is something someone else has run into.
I have an email utility that sends me an email whenever a user gets an error, and I use it like so:
MyUtility.SendEmail(shortNTID,
"support#mycompany.com",
new string[] { "supportlist#mycompany.com" },
"Application error has occured for user: " + shortNTID,
"Message: " + ex.Message.ToString() +
" Source: " + ex.Source.ToString() +
" Target Site: " + ex.TargetSite.ToString() +
" Stack Trace: " + ex.StackTrace.ToString());
Now for some reason today I got some emails from the application that had this in the subject AND the body:
Application error has occured for
user: Example User
That text should only be in the subject. In addition, the rest of the message body was blank, but obviously should have exception details.
To reiterate, there are two wierd things about this:
I have done a search through my application using "Find" for "Application error has occured for user:" and there are only a few places, and nowhere do I have this text in the message body.
The email is supposed to have all that exception information in the message body, and the emails had nothing but that sentence "Application error has occured for user: Example User"
Any ideas what is going on?
Richard,
Check that there isn't a comma [unlikely to affect code, however...!!] (,) embedded inside the shortNTID variable and especially check that ex is in fact not null.
just a very long shot...
Ok so I'm just dumb. My SendMail method in my utility is overloaded and one of the overloads had a mistake where the subject was getting put in for the message. Problem solved. Thanks to all of you for humoring me and trying. . .