Joplin API is opening up all possibilities of integrations .
This piece of VBA (Visual Basic for Application) code to send the subject of selected emails from Outook to Joplin Desktop:
Public Sub SendToJoplin()
Dim sJSONString As String
Dim objItem As Outlook.MailItem
For Each objItem In ActiveExplorer.Selection
With CreateObject("MSXML2.XMLHTTP")
.Open "POST", "http://127.0.0.1:41184/notes?token=?", False
.Send "{ ""title"": """ & objItem.ConversationTopic & """}"
Do Until .ReadyState = 4: DoEvents: Loop
sJSONString = .ResponseText
End With
Next
'Debug.Print sJSONString 'Uncomment to see joplin response
End Sub
{“error”:“Internal Server Error: Unexpected token \r in JSON at position 60”}
2 characters ("Carriage Return", "New Line") need to be replaced and "Double Quote" need to be escaped.
So the code to send email body as HTML:
Public Sub SendToJoplin()
Dim sToken, sURL, sEscapedBody, sJSONString As String
Dim objItem As Outlook.MailItem
sToken = "??"
sURL = "http://127.0.0.1:41184/notes?token=" & sToken
For Each objItem In ActiveExplorer.Selection
sEscapedBody = EscapeBody(objItem.HTMLBody)
With CreateObject("MSXML2.XMLHTTP")
.Open "POST", sURL, False
.Send "{ ""title"": """ & objItem.ConversationTopic & """, ""body_html"": """ & sEscapedBody & """ }"
Do Until .ReadyState = 4: DoEvents: Loop
sJSONString = .ResponseText
End With
Next
'Debug.Print sJSONString 'Uncomment to see joplin response
End Sub
Public Function EscapeBody(sText As String)
EscapeBody = Replace(Replace(sText, Chr(34), "\" & Chr(34)), vbCrLf, "\n")
End Function
P.S. To send email body as plain text, use objItem.Body instead objItem.HTMLBody
This only works for the installed version, right?
I must use the portable one, because afaik it is not possible to change the path were Joplin stores the notes in the installed version, right?
The Joplin's API also works in the Portable version.
(And the Oultook part doesn't care: it sends the request to the API address and doesn't even know what handles it.)
Works great. Perhaps it is worth to mention that “sToken” must be filled with the token shown in the Joplin App.
And yes, it also works with the portable version.
The only thing im missing is: Could something be implemented that allows to select the notebook the mail is clipped to?
For now it is placed somewhere and could only be found by searching in Joplin
And would it be possible to clip the whole mail including sender, date, subject, etc?
I was testing on joplin instance with 1 notebook so I didn't think for this option and note immediately appear in this 1 notebook.
To select a notebook, parent_id need to be added to JSON. If you know your notebook id, use following code:
P.S. You need replace:
REPLACE ME WITH YOUR TOKEN
REPLACE ME WITH YOUR NOTEBOOK ID
Public Sub SendToJoplin()
Dim sToken, sURL, sEscapedBody, sJSONString As String
Dim objItem As Outlook.MailItem
sToken = "REPLACE ME WITH YOUR TOKEN"
sURL = "http://127.0.0.1:41184/notes?token=" & sToken
For Each objItem In ActiveExplorer.Selection
sEscapedBody = EscapeBody(objItem.HTMLBody)
With CreateObject("MSXML2.XMLHTTP")
.Open "POST", sURL, False
.Send "{ ""title"": """ & objItem.ConversationTopic & """" _
& ", ""parent_id"": ""REPLACE ME WITH YOUR NOTEBOOK ID""" _
& ", ""body_html"": """ & sEscapedBody & """" _
& " }"
Do Until .ReadyState = 4: DoEvents: Loop
sJSONString = .ResponseText
End With
Next
'Debug.Print sJSONString 'Uncomment to see joplin response
End Sub
If you don't know your notebook id, run this code to get all notebooks and their IDs:
Private Sub GetFoldersFromJoplin()
Dim sToken, sURL, sJSONString As String
sToken = "REPLACE ME WITH YOUR TOKEN"
sURL = "http://127.0.0.1:41184/folders?token=" & sToken
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", sURL, False
.Send
Do Until .ReadyState = 4: DoEvents: Loop
sJSONString = .ResponseText
End With
Debug.Print sJSONString
End Sub
Check the response in "Immediate Window" (CTLR+G), copy and paste JSON response into any JSON formatter tool (e.g. https://jsoneditoronline.org/). You can easily copy the target notebook id and use it in the SendToJoplin() procedure.
Thanks for that clarification, but this will mean I still have fixed notebook, where the mails are clipped to.
But what if I want to decide where to clipp a mail for each incoming mail, e.g. mail 1 => notebook test, mail 2 => notebook holiday, etc?
A workarround would be to create a notebook “clipped mails” and move all clipped mails from there to the final destiantion.
=> did this worked:), but the above mentioned would be nice:)
What about clipping not only the mail body but also the whole mail including sender, date, subject, etc?
{"error":"Internal Server Error: Unexpected token \t in JSON at position ..."}
{"error":"Internal Server Error: Unexpected token \r in JSON at position ..."}
Would you replace EscapeBody procedure with following code and try:
Public Function EscapeBody(sText As String)
EscapeBody = sText
EscapeBody = Replace(EscapeBody, "\", "\\") 'Backslash is replaced with \\
EscapeBody = Replace(EscapeBody, Chr(34), "\" & Chr(34)) 'Double quote is replaced with \"
EscapeBody = Replace(EscapeBody, vbCr, "\r") 'Carriage return is replaced with \r
EscapeBody = Replace(EscapeBody, vbLf, "\n") 'Newline is replaced with \n
EscapeBody = Replace(EscapeBody, Chr(8), "\b") 'Backspace is replaced with \b
EscapeBody = Replace(EscapeBody, Chr(12), "\f") 'Form feed is replaced with \f
EscapeBody = Replace(EscapeBody, vbTab, "\t") 'Tab is replaced with \t
End Function
I think this will be a bit complicated but partially doable. I can see 2 types of images:
Images in <img> tag if MailItem.BodyFormat is olFormatHTML. Most properly I should use third-party regex library to get the path in src.
"Embedded" or inline images if MailItem.BodyFormat is olFormatRichText and those should be handled at MailItem.Attachments.
First both types need to be saved into local files,
Second, use Joplin API: POST /resources to upload them to Joplin.
Third, it will be doable to replace <img> with resource id but impossible to place the inline image since there is not placeholder for it in MailItem.HTMLBody as far as I see.