Autor Thema: Besprechung per Script erstellen und nach Outlook mailen  (Gelesen 13625 mal)

Offline AndreasWegener0815

  • Junior Mitglied
  • **
  • Beiträge: 53
Hallo Forum Gemeinde.
Wenn ich direkt einen  Termin im Notes Client erstelle und als "Erforderlich" eine Mail Adresse eines Outlook Users angebe klappt alles bestens. Die Mail kommt an und wird in OL auch direkt als Kalendereintrag erkannt. Im Anhang dieser Mail findet sich ein ical file (*.ics)

Nun erstelle ich einen Besprechungstermin in Notes per Script. Das klappt ohne für Notes auch ohne Probleme.
Leider kommt nur Müll in OL an, wenn ich das erstellte Doc versende.
Es wird nämlich kein .ics File erstellt.
1.Frage
Wie bringe ich Notes dazu in diesem Fall ein .ics automatisch zu erstellen und mit zu senden?
2. Frage
 Gehen wir mal davon aus ich hätte bereits selbst ein .ics File erstellt. (gibt ja genügend Scripts)
Wie binde ich das File korrekt in mein Mail Doc ein? Einfach einw Mail schreiben und als Attachment
das File funktioniert leider auch nicht. (Kommt als normale Mail in OL an)

Denke das hat was mit MIME Format zu tun o.Ä ?

Vielen Dank und Gruß

Andreas

Offline ata

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 5.092
  • Geschlecht: Männlich
  • drenaiondrufflos
    • Anton Tauscher Privat
Re: Besprechung per Script erstellen und nach Outlook mailen
« Antwort #1 am: 07.12.11 - 19:38:30 »
... wie sieht die Mail im OL denn im Quellcode aus - da kannst du es erkennen, wie die Mail hier tickt. Oder du debuggst dich durch Notes bis zum Versenden - das wäre mein erster Ansatz...

Toni
Grüßle Toni :)

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Besprechung per Script erstellen und nach Outlook mailen
« Antwort #2 am: 07.12.11 - 20:36:43 »
Das beste ist (neben dem reverse engineering), Du erstellst manuell eine entsprechende Einladung - bei angehaltenem Router. Dann fischst Du Dir das Memo aus der MAIL.BOX und analysierst es.

Des Pudels Kern findest Du wirklich (und logischerweise) im Body. Folgender Teil ist hier ganz entscheidend:

"--=_mixed 0DDCB88622E1298CC125795F006A9DA1_=
Content-Type: application/octet-stream; charset="UTF-8"; name="c202505.ics"
Content-Disposition: attachment; filename="c202505.ics"

BEGIN:VCALENDAR
X-LOTUS-CHARSET:UTF-8
VERSION:2.0
PRODID:-//Lotus Development Corporation//NONSGML Notes 7.0//EN
METHOD:REQUEST
BEGIN:VTIMEZONE
TZID:W. Europe
BEGIN:STANDARD
DTSTART:19501029T020000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19500326T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID="W. Europe":20111208T090000
DTEND;TZID="W. Europe":20111208T100000
TRANSP:OPAQUE
DTSTAMP:20111207T192505Z
SEQUENCE:0
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED
 ;CN="Bernhard Koehler/BKNotes/DE";RSVP=FALSE
 :mailto:ich@domain.de
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE
 :mailto:du@organisation.de
CLASS:PUBLIC
SUMMARY:Testerminh
ORGANIZER;CN="Bernhard Koehler/BKNotes/DE":mailto:ich@domain.de
UID:0DDCB88622E1298CC125795F006A9DA1-Lotus_Notes_Generated
X-LOTUS-BROADCAST:FALSE
X-LOTUS-UPDATE-SEQ:1
X-LOTUS-UPDATE-WISL:$S:1;$L:1;$B:1;$R:1;$E:1;$W:1;$O:1;$M:1
X-LOTUS-NOTESVERSION:2
X-LOTUS-NOTICETYPE:I
X-LOTUS-APPTTYPE:3
X-LOTUS-CHILD_UID:0DDCB88622E1298CC125795F006A9DA1
END:VEVENT
END:VCALENDAR

"

HTH,
Bernhard

Offline AndreasWegener0815

  • Junior Mitglied
  • **
  • Beiträge: 53
Re: Besprechung per Script erstellen und nach Outlook mailen
« Antwort #3 am: 08.12.11 - 07:52:54 »
Hallo Toni, Hallo Bernhard.

Vielen Dank für eure Tipps.

Bernhard ich habe mir auch schon sowas gedacht und mit

Code
Set body = doc.CreateMIMEEntity
Set header = body.CreateHeader("Type")
Call header.SetHeaderVal(|attachment; filename="test.ics"|)
experimentiert.

Leider kommt die Mail immer noch als "Mail" und nicht als "Kalendereintrag" an.

Dein log sieht gut aus.

Da drängen sich nun wieder (:-))Fragen auf:

Kann ich in den Body einfach den Text so reinschreiben wie in deinem Log
Oder muss ich wie oben über CreateMIMEEntity etc. gehen?
Wenn ich deinen  Text einfach mit

Code
Call stream.WriteText("## DEIN LOG###")
Call body.SetContentFromText (stream, "text/plain;charset=UTF-8", ENC_NONE) 
 
in den Body schreibe ist das der richtige weg ?

Viele Grüße
Andreas

Offline AndreasWegener0815

  • Junior Mitglied
  • **
  • Beiträge: 53
Re: Besprechung per Script erstellen und nach Outlook mailen
« Antwort #4 am: 08.12.11 - 09:20:13 »
So nach etlichen Versuchen  gebe ich es nun erst mal auf.

Der untenstehende Code sendet nun eine Einladung nach Outlook o.Ä.
Leider wird diese nicht direkt als Termin erkannt.

Man muss die Mail erst öffnen und auf das ICS File doppelklicken.
Der Rest wird brav erkannt.

Zeit und Ort sind noch hart Codiert, sollte aber kein Problem sein hier Variablen einzusetzen.

Wenn jemand noch eine Idee hat freue ich mich über Tipps.

Viele Dank allen für die Hilfe

Viele Grüße
Andreas

Code
Sub Initialize
	Dim s As New NotesSession
	Dim db As NotesDatabase
	Dim doc As NotesDocument
	Dim body As NotesMIMEEntity
	
	Dim header As NotesMIMEHeader
	 
	Dim stream As NotesStream
	
	Set db = s.CurrentDatabase
	Set stream = s.CreateStream
	s.ConvertMIME = False ' Do not convert MIME to rich text
	Set doc = db.CreateDocument
	Call doc.ReplaceItemValue("Form", "Memo")
	Set body = doc.CreateMIMEEntity
	
	Set header = body.CreateHeader("Subject")
	Call header.SetHeaderVal("Ihr Termin")
	
	Set header = body.CreateHeader("To")
	Call header.SetHeaderVal("andreas.wegener@cap-it.de")
	
	Set header = body.CreateHeader("Type")
	Call header.SetHeaderVal(|text/calendar; method=REQUEST;name="cal.ics"|)
	Set header = body.CreateHeader("Content-Disposition")
	Call header.SetHeaderVal(|attachment; filename="cal.ics|)
	Call stream.WriteText(|BEGIN:VCALENDAR
X-LOTUS-CHARSET:UTF-8
VERSION:2.0
PRODID:-//Lotus Development Corporation//NONSGML Notes 7.0//EN
METHOD:REQUEST
BEGIN:VTIMEZONE
TZID:W. Europe
BEGIN:STANDARD
DTSTART:19501029T020000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19500326T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID="W. Europe":20111208T090000
DTEND;TZID="W. Europe":20111208T100000
TRANSP:OPAQUE
DTSTAMP:20111207T192505Z
SEQUENCE:0
LOCATION:Conference room
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED
;CN="Hans Wurst/D/Company-EU";RSVP=FALSE
:mailto:hans.wurst@gmx.de
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE
:mailto:hans.wurst@gmx.de
CLASS:PUBLIC
SUMMARY:Testermin
ORGANIZER;CN="Der Organizer":mailto:ich@domain.de
UID:0DDCB88622E1298CC125795F006A9DA1-Lotus_Notes_Generated
X-LOTUS-BROADCAST:FALSE
X-LOTUS-UPDATE-SEQ:1
X-LOTUS-UPDATE-WISL:$S:1;$L:1;$B:1;$R:1;$E:1;$W:1;$O:1;$M:1
X-LOTUS-NOTESVERSION:2
X-LOTUS-NOTICETYPE:I
X-LOTUS-APPTTYPE:3
X-LOTUS-CHILD_UID:0DDCB88622E1298CC125795F006A9DA1
END:VEVENT
END:VCALENDAR
|)

	Call body.SetContentFromText (stream, "text/plain;charset=ISO-8859-1", ENC_NONE)  
	
		
	Call doc.Send(False)
	s.ConvertMIME = True ' Restore conversion
	
End Sub

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.169
  • Geschlecht: Männlich
    • Foconis Object Framework
Re: Besprechung per Script erstellen und nach Outlook mailen
« Antwort #5 am: 08.12.11 - 09:37:43 »
Hallo Andreas

Lies dir erst mal den Artikel durch und versuch die Mime-Items zu verstehen
http://atnotes.de/index.php/topic,52040.0.html

Dann vergleich mal die von dir erstellte Mail mit einer die funktioniert (bei angehaltenem Router)
Analysiere insbesondere die "Baumstruktur" des funktionierenden Mails
Zeichne dir auf, welcher Knoten was enthält (Mime Type etc)

In deinem Beispiel fällt mir auf, dass du das .ICS-File in den Root-Knoten hängst...
Das ist höchstwahrscheinlich falsch, da der Root-Knoten vom Typ Multipart/mixed oder related sein müsste (s. funktionierende Mail)

Gruß
Roland
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline AndreasWegener0815

  • Junior Mitglied
  • **
  • Beiträge: 53
Re: Besprechung per Script erstellen und nach Outlook mailen
« Antwort #6 am: 08.12.11 - 13:47:33 »
Hallo zusammen.

Der Tipp von Roland hat mich doch nochmal inspiriert :-)

Und man soll es nicht glauben es funktioniert nun.

Anstelle des BASE64 codierten Bildes (Konstante "LARRY" im Original" 
habe ich nun einen VCALENDAR Text verwendet (Konstante VCALENDAR) und im den original Aufruf

Code
Call stream.Writetext(LARRY)
cid = mime.attach(stream, ENC_BASE64, "", "image/gif")
ausgetauscht in

Code
Call stream.Writetext(VCALENDAR)
cid = mime.attach(stream, ENC_NONE, "", |text/calendar; method=REQUEST; name="subject.ics"|)

ENC_NONE da wir nun puren Text haben.
Der Content Type bringt den Unterschied

text/calendar; method=REQUEST; name="subject.ics"

Jetzt wird die Mail direkt als Kalendereintrag angezeigt und kann über "Akzeptieren" eingetragen werden.
Was natürlich noch fehlt ist nun eine Funktion die den VCALENDAR Text entsprechend erstellt, aber dafür gibt es ja schon Lösungen
und wir wollen ja keine Langeweile aufkommen lassen :-)

Nochmals vielen dank an alle helfenden Hände

Viele Grüße
Andreas




Code
%REM
	Agent MimeTestRoland
	Created 08.12.2011 by Andreas Wegener/D/Crawco-EU
	Description: Comments for Agent
%END REM
Option Public
Option Declare


Private Const VCALENDAR = |BEGIN:VCALENDAR
X-LOTUS-CHARSET:UTF-8
VERSION:2.0
PRODID:-//Lotus Development Corporation//NONSGML Notes 7.0//EN
METHOD:REQUEST
BEGIN:VTIMEZONE
TZID:W. Europe
BEGIN:STANDARD
DTSTART:19501029T020000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19500326T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID="W. Europe":20111208T090000
DTEND;TZID="W. Europe":20111208T100000
TRANSP:OPAQUE
DTSTAMP:20111207T192505Z
SEQUENCE:0
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED
;CN="Hans Wurst/D/Company";RSVP=FALSE
:mailto:hans.wurst@gmx.de
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE
:mailto:hans.wurst@gmx.de
CLASS:PUBLIC
SUMMARY:Testerminh
ORGANIZER;CN="Bernhard Koehler/BKNotes/DE":mailto:ich@domain.de
UID:0DDCB88622E1298CC125795F006A9DA1-Lotus_Notes_Generated
X-LOTUS-BROADCAST:FALSE
X-LOTUS-UPDATE-SEQ:1
X-LOTUS-UPDATE-WISL:$S:1;$L:1;$B:1;$R:1;$E:1;$W:1;$O:1;$M:1
X-LOTUS-NOTESVERSION:2
X-LOTUS-NOTICETYPE:I
X-LOTUS-APPTTYPE:3
X-LOTUS-CHILD_UID:0DDCB88622E1298CC125795F006A9DA1
END:VEVENT
END:VCALENDAR
|




'/**
' * Diese Klasse dient zum Erstellen von Multipart-Related Mime-Items
' * @author: Roland Praml/01/int/FOCONIS
' */
Public Class MultipartRelatedMime
	 Private doc 		As NotesDocument
	 Private itemName 	As String
	 Private session	 As NotesSession
	 Private oldCvtMime	 As Integer

	 Private rootMime	 As NotesMIMEEntity
	 Private contentMime As NotesMIMEEntity
	 Private  rootheader As NotesMIMEHeader
	 

	 '/**
	 ' * Erzeuge ein neues Objekt dieser Klasse. Im Anschluss können mittels
	 ' * "attach" beliebig viele Attachments angelegt werden. Will man diese
	 ' * im HTML anzeigen, so muss man sich den Rückgabewert von Attach merken
	 ' * und als srv-URL im IMG-Tag verwenden (siehe Beispiel)
	 ' * @param doc das Dokument, auf dem das MIME-Processing statt findet
	 ' * @param itemName das MIME-Item (Normalerweise Body)
	 ' * @return ein Objekt vom Typ MultipartRelatedMime
	 ' */
	 Public Sub New(doc As NotesDocument, itemName As String)
		 Set me.doc 	= doc
		 Me.itemName 	= itemName
		 If doc.Hasitem(Itemname) Then 		' Sicherheitsprüfung
			 Error 1000, "The Item " + itemName +" already exists."
		 End If
		 Set session 	= New NotesSession
		 oldCvtMime 	= session.convertMime 	' alte Einstellung merken
		 session.convertMime = False			 ' Konvertierung abschalten
		
		 ' -- Anlegegen des Root-Mimes
		 Dim stream	 As NotesStream
		 Set rootMime 	= doc.CreateMIMEEntity(itemName)
		 Set  stream 	=  session.CreateStream()
		 Call stream.WriteText("This is a multipart message in MIME format.")
		 Call rootMime.SetContentFromText(stream, "multipart/alternative", ENC_NONE )
         
         ' anlegen des root headers
		 
		 Set rootheader = rootMime.CreateHeader("content-class")
		 Call rootheader.SetHeaderVal("urn:content-classes:calendarmessage")
		 
		 
		 ' !! Es wird auch gleich ein Dummy-content angelegt, denn wenn man
		 ' !! das Dokument jetzt speichert, dann wird es korrupt
		 Set contentMime = rootMime.Createchildentity()
		 Call stream.truncate()
		 Call stream.WriteText("empty")	
		 Call contentMime.SetContentFromText(stream, "text/plain", ENC_NONE )
		 Call stream.Close()
	 End Sub

	 '/**
	 ' * Destruktor, erledigt noch ein paar Aufräumarbeiten. 
	' * !! Achtung, danach ist die MIME-Konvertierung wieder aktiviert. !!
	 ' */
	 Public Sub Delete
		 Call closeMime() ' sicherheitshalber nochmals close aufrufen
		 session.Convertmime = oldCvtMime ' 
	End Sub

	 '/**
	 ' * Diese Methode beendet die MIME-Verarbeitung, erst danach darf wieder
	 ' * auf das Dokument zugegriffen werden.
	 ' */
	 Public Function closeMime()
		 If Not doc Is Nothing Then 
			Set rootMime 		= Nothing
			 Set contentMime 	= Nothing
			 Call doc.Closemimeentities(True, itemName)
			 Set doc = Nothing
		 End If
	 End Function

	 '/**
	 ' * "attach" hängt eine Datei an das MIME an. Die FileData werden idR. 
	' * binär oder base64-codiert übergeben. Gibt man einen Filenamen an,
	 ' * so erscheint die Datei als Attachment, andernfalls erscheint bei 
	' * Bildern, welche im HTML referenziert werden, kein zusätzliches 
	' * Attachmentsymbol/"Büroklammer"
	 ' * @param fileData Die Filedaten
	 ' * @param encoding Das Enoding, z.B. ENC_BASE64
	 ' * @param filename Der Dateiname, kann auch leer sein, s.o.
	 ' * @param contentType z.B.: gif/jpeg
	 ' * @return content-identifier 
	' */
	 Public Function attach(fileData As NotesStream, encoding As Integer, _
	 filename As String, ByVal contentType As String) As String
		 ' -- es wird ein neues Kind angelegt
		 Dim mimePart 	As NotesMIMEEntity
		 Set mimePart 	=  rootMime.CreateChildEntity()
		
		 If contentType = "" Then	
			 contentType = "application/octet-stream" ' Default
		 End If
		
		 If filename <> "" Then
			 ' Wichtig: Dateinamen sollten nicht doppelt vorkommene und 
			' dürfen keine Sonderzeichen enthalten. Dies wird hier aber
			 ' nicht geprüft. Dateiname ggf. nach RFC2047 codieren.
			 Call mimePart.CreateHeader("Content-Disposition"). _
			 SetheaderValAndParams({attachment; filename="} +filename + {"})
		 End If
		
		 ' -- eine zufällige Content-ID erzeugen
		 Dim cid As String
		 Dim randomGenerator As New NotesDocument(doc.Parentdatabase)
		 cid = randomGenerator.Universalid+"@mydomain"
		 Call mimePart.CreateHeader("Content-ID")._
		 SetheaderValAndParams("<" + cid + ">")

		 ' -- und die Daten schreiben
		 Call mimePart.SetContentFromText(fileData, contentType, encoding)
		 attach = "cid:" + cid
	 End Function
		 
End Class


'/**
' * Diese Prozedur erstellt ein neues Dokument, erzeugt mit obiger Klasse ein MIME-Item und versendet das Dokument dann
' */
Sub Initialize
	 Dim session As New NotesSession
	 Dim stream As NotesStream
	 Dim doc As New NotesDocument(session.Currentdatabase)
	 Dim cid As String
	 doc.Subject = "Dies ist ein Termin"
	 Dim mime As New MultipartRelatedMime(doc, "Body")		 ' Klasse anlegen
	 Set stream = session.createStream
	 Call stream.Writetext(VCALENDAR)
	 cid = mime.attach(stream, ENC_NONE, "", |text/calendar; method=REQUEST; name="subject.ics"|)	 ' Kalender anhängen und CID merken
	 Call stream.close()
	 Call mime.closeMime()
	 Call doc.send(False,"hans.wurst@gmx.de") ' Mail senden
	 
	
 End Sub


 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz