背景
Outlook のメールを org-mode の TODO に連携させる の改良版。
前回は直接アジェンダファイルを更新していたが、org-protocolを利用すると、よりスマートに対応出来る。
- アジェンダファイルを再読込しなくても、更新が反映される
- 手元での更新と、Outlookからの更新で衝突が無い
- 書き出すテンプレートを簡単に設定出来る
方針
Outlook からの更新はorg-protocolを使用して行う。
- Outlookにマクロを登録して、メール画から簡単にEmacsに送れるようにする
- org-mode上で、Outlookのメールにリンクして直接開けるようにする
手順
- org-protocolをダウンロード
- list-package から org-protocol-jekyll を使用する(自分はどっかから落としてきた)
- Windowsに
org-protocol:/
を関連付けする - Emacsでorg-protocolを受け取れるようにする
コード
Outlook側
Outlookのマクロに以下を登録。 メール画面からWriteToOrgFileマクロを呼び出すと実行される。 クイックアクセスツールバーにマクロを登録しておくと Alt+1 等で呼び出せて便利。
ちなみにスクリプトでは自動的に本文をクリップボードにコピーする。
Sub WriteToOrgFile() ' コピペスピードアップの為、最初にIEオブジェクトを生成 Set objIE = CreateObject("InternetExplorer.Application") Dim mail As MailItem Set mail = ActiveExplorer.Selection.Item(1) Dim wshell Set wshell = CreateObject("WScript.Shell") Call objIE.navigate("about:blank") objIE.document.Body.innerText = mail.Body ' JS の encodeURI を使用する Dim sc Set sc = CreateObject("ScriptControl") sc.Language = "JScript" Dim js Set js = sc.CodeObject Subject = js.encodeURI(mail.Subject) Subject = Replace(Subject, "[", "「") Subject = Replace(Subject, "]", "」") 'Subject = Replace(Subject, " ", "%20") Subject = Replace(Subject, "/", "%2F") 'org-protocol:/capture:/x/outlook:$MailEntryId/$MailSubject/" の形式でURLが実行される captureUrl = "org-protocol:/capture:/x/outlook:" & mail.EntryID & "/" & Subject & "/" ' 本文をクリップボードに格納して、後で利用出来るように非同期で実行する ' 事前にコピーすると capture によってクリップボードがリンクで上書きされる Call wshell.Run(captureUrl) ' 必要に応じて本文を使用出来るようにクリップボードにコピーする Body = Replace(mail.Body, vbCrLf, Chr(10)) Body = js.encodeURI(Body) Call copyText(mail.Body, objIE) End Sub Private Sub copyText(text, objIE) OLECMDID_COPY = 12 OLECMDID_SELECTALL = 17 If objIE Is Nothing Then Set objIE = CreateObject("InternetExplorer.Application") Call objIE.navigate("about:blank") objIE.document.Body.innerText = text End If Call objIE.execWB(OLECMDID_SELECTALL, 0) Call objIE.execWB(OLECMDID_COPY, 0) Call objIE.Quit End Sub
レジストリ側
これを登録すると、 org-protocol:/
の形式のURLをEmacsに送れるようになる。
REGEDIT4 [HKEY_CLASSES_ROOT\org-protocol] @="URL:Org Protocol" "URL Protocol"="" [HKEY_CLASSES_ROOT\org-protocol\shell] [HKEY_CLASSES_ROOT\org-protocol\shell\open] [HKEY_CLASSES_ROOT\org-protocol\shell\open\command] @="\"C:\\tools\\emacs\\bin\\emacsclientw.exe\" \"%1\""
Emacsのパスは環境に合わせて変える。
Emacs側
前回と同じスクリプト
;; outlook 形式のURLを開く ;; see http://lists.gnu.org/archive/html/emacs-orgmode/2008-08/msg00172.html (defun org-open-outlook-url (uid) "Open an outlook format url" (interactive "sGUID: ") (w32-shell-execute nil (format "outlook:%s" uid))) (org-add-link-type "outlook" 'org-open-outlook-url) ;; org-protocol ;; see http://orgmode.org/worg/org-contrib/org-protocol.html (require 'org-protocol)
CaptureのTemplateの設定。必要に応じてカスタマイズ。
(add-to-list 'org-capture-templates (quote ( ("x" "From external" entry (file+headline (concat my-project-directory "org/tasks.org") "*Task Stuck*") "* ACTN %?%a :outlook: :PROPERTIES: :CREATED_AT: %U :END: %c %i" :empty-lines 1 t TODO))))
課題
org-protocolはemacsclientを使用してURLをEmacsに送る。 実行後、何故かemacsclientのプロセスが残ってしまう。 メモリなどは影響が無いが、気持ち悪い。
まとめ
前回より大分スマートになった。 あとはプロセスが自動的に消えれば完璧なんだけど・・。