Archive for the 'Mail.app' Category

10/09 Mail.appで添付ファイルを指定してメール送信

Mail.appで指定のファイルを添付してメールを作成・送信するAppleScriptです。

Googleで「AppleScript Mail attachment」とキーワードを入れると(海外のサイトに掲載されているAppleScriptが)ザクザク出てくる程度の内容ではあるのですが、本Blogの過去の記事検索では出てこなかったので、掲載しておきます。

この基本的なサンプルをさらに書き換えると、

・choose fileなどというユーザーに場所を尋ねる(放置状態だと処理が止まってしまう)やりかたではなく、指定フォルダ中の指定ファイルを自動で指定
・添付ファイルの各種情報を取得して、その内容をメールの本文に反映させる
・所定の容量以上の場合には、添付しないでDropboxにアップロードしてそのURLをメール本文に添付して送信
・複数のファイルを添付指定(ループで)して送信

などのAppleScriptに発展させていけます。もちろん、サブルーチン化して使い回しのきく部品に仕立てると有用性はもっと上がります。

けっこうよく使う処理で……何か遠隔地で稼働しているMacのシステムからエラーを返す場合とか、必要な場合に画面のスナップショットをとって添付して送信してくるとか、シンプルではあるものの依然としてメールによるレポートが有用な手段であることに違いはありません。

Twitterで実行結果を知らせてくるとか、iChat経由でメッセージを送ってくるとか、Blogに新規記事を作成してレポートしてくるといった処理もAppleScriptで割と楽勝でできる昨今ですが、とりあえずMailで情報を送るやりかたは最低限マスターしておきたいものです。

スクリプト名:添付ファイルを指定してメール送信
set theName to “ぴよまるさん”
set theAddress to “maro@piyocast.com”
set theSubject to “メールの題名ですぴよ”
set theBody to “ぴよまるさんへ

メールにファイルを添付しましたよ〜。ぴよ〜。

ひよこさんより

set theAttachment to choose file with prompt “添付ファイルを選択してください”

tell application “Mail”
  set newMessage to make new outgoing message with properties {subject:theSubject, content:theBody & return & return}
  
tell newMessage
    set visible to false –サイレントでメール作成(メールのウィンドウを表示しない)
    
    
–受取人の指定
    
make new to recipient at end of to recipients with properties {name:theName, address:theAddress}
    
    
–添付ファイルの指定
    
tell content
      make new attachment with properties {file name:theAttachment} at after the last paragraph
    end tell
    
    
–メール送信
    
send
    
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/21 特定の語句を含むMail.appのフォルダ(mailbox)を抽出してフルパスを文字列化

Mail.app上で特定のキーワードを含むフォルダを探し出して、そのパスを一覧表示するAppleScriptです。

Mail.app上で、フォルダを作ってメールの整理をしている場合に、ある特定のキーワードを含むフォルダがどこに存在しているかを検索したくなることがあります。しかし、Mail.appにそういう機能は存在していません。

acs0.jpg

なければ作るまでで……AppleScriptで作り出して、フルパス表示用に作っておいたサンプルと合わせて所要時間5分ぐらいでしょうか。

Mail.appではフォルダ(mailbox)をフィルタ参照で抽出できるので、思いっきり楽でした。自分のメイン環境ではフォルダが1万6000個ぐらい存在(自動で作成させているので)しているのですが、個数のカウントも1秒かからない程度(MacBook Pro 2010 Core i7 2.66GHz)でした。

実際、本Scriptでもフォルダ(mailbox)のフィルタ参照による抽出はすぐに終わるのですが、フルパスをテキスト化するのに処理時間のほとんどの時間がかかっています。

acs1.jpg

acs2.jpg

本Scriptを早急に作る必要が出てきたのは……メールの整理中に間違えて「Accessibility Dev」MLのフォルダを捕まえてどこかにドロップしてしまって、フォルダが多すぎてどこに落としたか分からなくなってしまったためです。マウスを使っている場合には起こらない悲劇、、、

スクリプト名:特定の語句を含むMail.appのフォルダ(mailbox)を抽出してフルパスを文字列化
set searchKeyword to “AppleScript”

tell application “Mail”
  –特定キーワードを名前に含むフォルダ(mailbox)を抽出
  
set allPath to every mailbox whose name contains searchKeyword
  
  
–与えられたフォルダ
  
set bList to {}
  
repeat with i in allPath
    set the end of bList to getFullPath(i) of me
  end repeat
  
  
–結果の一覧表示
  
choose from list bList with prompt “検索結果:”
  
end tell

–与えられたmailboxのフルパスをテキストで返す
on getFullPath(mBox)
  tell application “Mail”
    set fullPath to name of mBox
    
    
repeat
      set mBox to getParent(mBox) of me
      
      
try
        set aClass to class of mBox
      on error
        exit repeat
      end try
      
      
if aClass is not equal to mailbox then
        exit repeat
      end if
      
      
set aName to name of mBox
      
set fullPath to aName & “/” & fullPath
    end repeat
  end tell
  
  
return fullPath
end getFullPath

–親フォルダを取得
on getParent(aMailBox)
  tell application “Mail”
    tell aMailBox
      try
        set a to properties
        
set b to container of a
      on error
        return {“”, “”}
      end try
    end tell
  end tell
  
return b
end getParent

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

06/15 Mail.appで指定のメールアカウントのみイネーブルに

Mail.appで複数のメールアカウントのみイネーブルにするAppleScriptです。

Mail.appに複数のメールアカウントを登録していて、職場や自宅などでメールアカウントの切り替えを行いたいような場合に使用します。

イネーブルにする対象は、Mail.appのメニューから「環境設定」で表示される環境設定ウィンドウの中の、「アカウント」で表示されるメールアカウントです。

mail_acc.jpg

Mail.appで場所に応じてメールアカウントの制御をしなくてはならず、最初は「送受信スケジュール」から当該のメールアカウントを外してみたのですが……恐ろしいことに、オフにしたはずのメールボックスへの送受信が行われたりしていました。そこで、メールアカウントそのもののオン/オフ制御を行う必要がある、と考えた次第です。

スクリプトメニューに入れて呼び出すと便利です。

mail1.jpg

スクリプト名:Mail.appで指定のメールアカウントのみイネーブルに
set eList to {“職場”, “Gmail”}

tell application “Mail”
  set enabled of every account to false
  
repeat with i in eList
    set j to contents of i
    
tell account j
      set enabled to true
    end tell
  end repeat
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

ちなみに、すべてのメールアカウントをイネーブルにする場合には、このように記述します。

スクリプト名:Mail.appですべてのアカウントをイネーブルに
tell application “Mail”
  set enabled of every account to true
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/05 Mail.appでメールの送信(プレーンテキストへの変換つき)

Mail.appでメールの送信を行うAppleScriptの、Mac OS X 10.6用に機能追加を行ったものです。

Mac OS X 10.6からは、AppleScript経由でMail.appをコントロールしてメールを作成・送信すると、なんとプレーンテキスト(=標準テキスト)ではなく、リッチテキストで送られてしまいます。言われてみないと、なかなか気づきにくい箇所です(コメント欄でのご指摘ありがとうございます)。

ただ……Mail.appの環境設定をいじくっても、挙動に変化はありません。AppleScriptから送信命令を送ると、リッチテキストになってしまいます。

バグ……だと思うのですが、すでにMac OS X 10.6.x上で修正の見込みはなく、その場しのぎにGUI Scriptingでメニューからコマンドを叩き込んで、強制的にプレーンテキストに変換してから送信するようにしてみました。

Mac OS X 10.7に向けて、修正の要望を出しておく必要があります。ただ、Appleはあくまでも統計的にバグの処理を行うため……1人や2人が騒いだところで取りあいません。このバグが直ってほしいと思った方は、Appleに意見を送ってください。

スクリプト名:Mail.appでメールの送信(プレーンテキストへの変換つき)
set aSubject to "メールのサブジェクトです"
set theSender to "maro@sender.com" –送信者アドレス
set recipientAddr to "maro@reciever.jp" –受信者アドレス
set bodyText to "ひよこさんへ
こんにちは。ひよこさん。
ひよこクラブへのおさそいです。

ぴよ〜"

sendMail(aSubject, theSender, recipientAddr, bodyText) of me

–Mail.appでメール送信を行う
on sendMail(theSubject, theSender, recipientAddr, bodyText)
  tell application "Mail"
    set newMessage to make new outgoing message with properties {subject:theSubject, content:bodyText}
    
tell newMessage
      set visible to true
      
set sender to theSender
      
make new to recipient at end of to recipients with properties {address:recipientAddr}
      
      
makeAMessageToPlain() of me
      
      
send
    end tell
  end tell
end sendMail

–作成したメールがリッチテキストなら標準テキスト(プレーンテキスト)に直す
on makeAMessageToPlain()
  activate application "Mail"
  
  
tell application "System Events"
    tell process "Mail"
      –メニュー内容が「Mail.app」>「フォーマット」>「標準テキストにする」だったら現在リッチテキストだと判断し、コマンド実行
      
set aTitle to title of menu item 11 of menu 1 of menu bar item 8 of menu bar 1
      
      
if aTitle = "標準テキストにする" then
        –「標準テキストにする」をクリック
        
click menu item 11 of menu 1 of menu bar item 8 of menu bar 1
      end if
    end tell
  end tell
end makeAMessageToPlain

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/08 Mail.appで選択しておいたメッセージに返信してsubjectと本文を加える

Mail.app上で選択しておいたメッセージの返信メッセージをreplyコマンドで作成し、その返信メッセージのサブジェクトと本文を変更するAppleScriptです。

USのAppleScript Users MLに投稿があった質問に答えておいたものです。どうも、Mail.appの動作が遅いらしくて……AppleScriptがMail.app側の動作を待ち切れず、返信メッセージを作成し終わる前に次のステップに進んでしまうため、delayコマンドなしではエラーが出てしまっていました。

GUI上でだいたい現象は観察できていたので、delayコマンド(最小限でいいので待機時間は0.1秒)を入れて動作を確認できました。3箇所に入れているdelayコマンドのうち、たぶん最初のものだけが必要不可欠なもので、あとの2つは「おまじない」に近いものです。ウチのCore i7 2.66GHzのMacBook Proではそのように感じられました。もっと高速で大量にCPU Coreが乗っているMac Proでは状況が違うかもしれません。

AppleScriptの処理系自体は、世間で言われるほど遅くないため……アプリケーションの状態を取得したり命令を発行したりすると、(AppleScript側が)けっこう待たされる感じです。そのため、アプリケーションとの通信頻度を下げることで大幅なスピードアップを図ったり、AppleScriptだけで処理をすることで速度を稼いだりするというテクニックが存在します。

やや、Mail.app側のバグのようにも見えますが、AppleScriptチームがMail.appチームを説得するには相当時間がかかりそうなので、Apple側が社内で対応する前に自衛手段を講じておくというのが、ベストな対策といったところでしょうか。

スクリプト名:Mail.appで選択しておいたメッセージに返信してsubjectと本文を加える
tell application “Mail”
  set msg to selection –Mail.appでメッセージを選択状態にしておく
  
set msg to first item of msg
  
  
set replied_msg to reply msg with opening window –選択しておいたメールの返信メッセージを作成
  
delay 0.1
  
  
–返信メッセージに対して操作を加える。
  
tell replied_msg
    set subject to “replied message”
    
delay 0.1
    
    
set content to “this is a replied message”
    
delay 0.1
    
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

12/14 選択中のMailのSubjectの変化を吸収するための試作

Mail.appで選択中のメールをもとに、同一スレッド内のSubjectの変化を吸収して、最低限の変化のみを検出するようにするための試作AppleScriptです。

目下、Mail.app上で選択中のメールをもとにスレッドの参照関係図をMindjet MindManager上にプロットするAppleScriptを開発・実戦投入しており、入り組んだメールのフローをビジュアライズできています。

mind1.jpg

海外のMLに対しては非常に有効に使えているのですが、日本のMLの運用方法が海外のものと異なる場合が多いため、日本語のMLの情報をプロットしようとすると、Subject変更点がうまく検出できず、1通ずつSubjectが変更されているものとして検出されていたりします。

これを防ぐために、日本国内のMLの特殊な運用がどこなのか考えてみたところ……すべてのケースでそうとはいえないものの、

・Subject内のMLの識別子にシリアル番号を入れており、この部分が1通1通変化する

という現象に対処してあげればよいということが分りました。日本語Subjectの末尾が化けるといったMLに遭遇したこともありましたが、さすがに最近はそういうこともなくなってきたようで……。

そこで、そうした日本国内MLのSubjectの特性に合わせてSubjectの変化を吸収するような処理を試作してみました。実際に、現在使っているプログラムに組み合わせて使ってみようと思います。

スクリプト名:選択中のMailのSubjectの変化を吸収するための試作
–選択中のMailのSubjectの変化を吸収するための試作
tell application "Mail"
  set aSel to selection
  
set sbjList to {}
  
repeat with i in aSel
    set the end of sbjList to subject of i
  end repeat
end tell
sbjList
–> (*[sampleml:00019] ○○の話 , [sampleml:00021] Re: ○○の話 , [sampleml:00020] Re: ○○の話 , [sampleml:00024] Re: ○○の話 *)

set newList to {}
repeat with i in sbjList
  set j to contents of i
  
if "[" is in j and "]" is in j then
    set j1 to offset of "]" in j
    
set j2 to text (j1 + 1) thru -1 of j
    
set j2 to repChar(j2, " Re: ", "") of me
    
set j2 to repChar(j2, " ", "") of me
    
set the end of newList to j2
  end if
end repeat
newList
–>{"○○の話", "○○の話", "○○の話", "○○の話"}

–文字置換ルーチン
on repChar(origText, targStr, repStr)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

10/01 Mail.appの指定メールボックス内に任意のメールボックスを新規作成 v2

Mail.appの指定メールボックス内に任意のメールボックスを新規作成するAppleScriptです。

Mail.appのメールボックス・フォルダは階層構造にすることができ、かなり自由にAppleScriptから制御できます。目下、各メーリングリストのメールはMail.appのルールで各フォルダに仕分けるようにしており……そのルール設定をAppleScriptから読み出して、US Appleの主催しているメーリングリストの各仕分けフォルダに、一括で「10.6,Snow Leopard」というフォルダを作成指示するAppleScriptを作りたいと思っていました(このScriptはすでに完成し、一括で全MLに同一名称のメールボックスを作成できるようになりました。いや、便利便利)。

まずはMail.appのメールボックス・オブジェクトからメールボックスのフルパスを取得するAppleScriptを作成し、その次の段階として本AppleScriptを作成した次第です。

スクリプト名:Mail.appの指定メールボックス内に任意のメールボックスを新規作成 v2
global aFullPath

set aFullPath to ""

set aNewFolName to "10.6,Snow Leopard"
tell
application "Mail"
  –mailboxオブジェクトを渡すのは、全メール振り分けルールからML用のもの(名称に「_ML」が入っている)
  
–を抽出して、それに対してすべて処理を行うことを考えているため。その際に入手できるのは
  
–該当するメールボックスのオブジェクト(のリスト)
  set
aMB to mailbox "ML/Apple US/ASに関係のあるもの/SyncService" –mailboxオブジェクトを作ってみた
end tell
makeAFolderIfNotExist(aNewFolName, aMB) of me


on
makeAFolderIfNotExist(aNewFolName, aFolder)
  –パラメータとして渡されたメールボックスオブジェクトからフルパスの階層を取得する
  
–make mailbox full-path text from Mail.app’s mailbox object
  set
aFullPath to ""
  
extraxctTextFullPathOfMBObject(aFolder) of me
  set
aNewFolFullPath to aFullPath & "/" & aNewFolName
  set
aFullPath to ""
  
  tell
application "Mail"
    –指定名称を「含む」フォルダが存在するかどうかチェック
    tell
aFolder
      set tmpFolList to name of every mailbox whose name contains aNewFolName
    end tell
    
    if
tmpFolList is equal to {} then
      try
        make new mailbox at beginning with properties {name:aNewFolFullPath}
      on error erM
        display dialog erM & return & "Error in making new mail folder by name: " & aNewFolName
      end try
    end if
  end tell
end makeAFolderIfNotExist

–Mail.appのメールボックスオブジェクトを渡すと、テキストのフルパスに変換
on
extraxctTextFullPathOfMBObject(aPath)
  tell application "Mail"
    try
      set parentPath to container of aPath
    on error
      return
    end try
    
    set
meName to name of aPath
    if
aFullPath = "" then –1回目のみスラッシュを入れないで処理
      set aFullPath to meName
    else
      –通常処理はこちら
      set
aFullPath to meName & "/" & aFullPath
    end if
    
    
extraxctTextFullPathOfMBObject(parentPath) of me –再帰呼び出し
  end tell
end extraxctTextFullPathOfMBObject

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

09/26 Mail.appのメールボックスオブジェクトを渡すと、テキストのフルパスに変換 v1

Mail.appのmailboxオブジェクトを与えると、そのフォルダ階層のパスを「/」で区切ったテキストにして返すサブルーチンです。

mailfol.jpg

Mail.appのmailboxオブジェクトのプロパティには、名称や上位階層のmailboxオブジェクトの情報は入っているものの、現在の階層を示すフルパスの情報が入っていません。mailboxオブジェクトを生成する際に、フォルダ階層のテキストで指定することになるので、mailboxオブジェクトを相手にするのではなく、その元となるテキスト情報を相手にすれば「楽」に処理はできます。ただ、それだとあまり柔軟性に富んだ処理が行えません。

そこで、mailboxオブジェクトを渡すと、フルパスをテキスト化するAppleScriptを書いてみました。

そもそも、こんなルーチンが欲しいと思ったのは……Mac OS X 10.6が登場して、Appleの各MLフォルダ内に「10.6, Snow Leopard」(カンマで区切って名前を付けておくと、それらのどれかでヒットしたメールをフォルダに振り分けるAppleScriptを運用中)といったフォルダを一括で作成する必要が出てきたためで……ほぼすべてのUS Appleのデベロッパー系MLを購読しているため、それをすべて手作業で行うのは骨が折れます。また、すでに手でフォルダを作ってあるところに対しては作成しない、という処理も行わなくてはなりません。

スクリプト名:Mail.appのメールボックスオブジェクトを渡すと、テキストのフルパスに変換 v1
(*

Mail.appのmailboxオブジェクトはフルパスのプロパティを持っていないため、オブジェクトで渡されると、それがどのパスに存在
しているものなのか、処理するのが非常に面倒。

そこで、mailboxオブジェクトを渡すと、再帰でパスを求めるルーチンを作ってみた。
処理前にグローバル変数aFullPathをクリアしておく必要がある
ルート階層に達したときにエラートラップで判定を行うが、ここはもう少しスマートな書き方に変えたほうがいい

*)

global aFullPath

set aFullPath to “”
tell application “Mail”
  set aMB to properties of mailbox “ML/Apple US/ASに関係のあるもの/SyncService” –mailboxオブジェクトを作ってみた
end tell

extraxctTextFullPathOfMBObject(aMB) of me
aFullPath
–> “ML/Apple US/ASに関係のあるもの/SyncService”

–Mail.appのメールボックスオブジェクトを渡すと、テキストのフルパスに変換
on extraxctTextFullPathOfMBObject(aPath)
  tell application “Mail”
    try
      set parentPath to container of aPath
    on error
      return
    end try
    
    
set meName to name of aPath
    
if aFullPath = “” then –1回目のみスラッシュを入れないで処理
      set aFullPath to meName
    else
      –通常処理はこちら
      
set aFullPath to meName & “/” & aFullPath
    end if
    
    
extraxctTextFullPathOfMBObject(parentPath) of me –再帰呼び出し
  end tell
end extraxctTextFullPathOfMBObject

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

03/09 アプリケーションに命令を行う記述方法で最短のもの

ひどくなまりのつよい記述方法であり、可読性が著しく下がるため推奨はしないのですが、アプリケーションにこんな記法でも命令できるという(悪い)見本です。

スクリプト名:アプリケーションに命令を行う記述方法で最短のもの
application "Mail" activate

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

03/09 Mail.appに登録されている各MLのフォルダ直下にあるメールのうち昨日の0時0分以降に受信したものを個別に数える

Mail.appに登録されているメール振り分けルールのうち、ルール名に「ML」がついているルールの振り分け先フォルダを求め、各メールフォルダの直下に存在するメールのうち、前日の0:00以降に受信したメールの本数をすべてカウントします。

mail05.jpg

メール振り分けルールのうち、「ML」がついているものが、メーリングリスト関連(と仮定して処理)。

MLの投稿数をランキング表示するAppleScript StudioのGUIつきアプリを作った際の初期試作品です。

スクリプト名:Mail.appに登録されている各MLのフォルダ直下にあるメールのうち昨日の0時0分以降に受信したものを個別に数える
global mList, mList_r

set yesterdayDate to ((current date) - 1 * days)
set time of yesterdayDate to 0
set mList to {}
set mList_r to a reference to mList

set mlLocList to getMLRulesStorage() of me
tell application "Mail"
  repeat with i in mlLocList
    tell i
      set mCount to count (every message whose date received > yesterdayDate)
    end tell
    
if mCount > 0 then
      set the end of mList_r to {name of i as string, mCount}
    end if
  end repeat
end tell

set bList to shellSortListDecending(mList, 2) of me
bList

Mail.appのRuleのうち名称に「_ML」が入っているものの、保存先メールボックスを抽出
on getMLRulesStorage()
  tell application "Mail"
    set mbList to move message of every rule whose name contains "ML" and name of it does not contain "会社"
  end tell
  
return mbList
end getMLRulesStorage

シェルソートで入れ子のリストを昇順ソート
on shellSortListAscending(a, keyItem)
  set n to length of a
  
set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1}
  
repeat with h in cols
    if (h (n - 1)) then
      repeat with i from h to (n - 1)
        set v to item (i + 1) of a
        
set j to i
        
repeat while (j h) and ((contents of item keyItem of item (j - h + 1) of a) > (item keyItem of v))
          set (item (j + 1) of a) to (item (j - h + 1) of a)
          
set j to j - h
        end repeat
        
set item (j + 1) of a to v
      end repeat
    end if
  end repeat
  
return a
end shellSortListAscending

シェルソートで入れ子のリストを降順ソート
on shellSortListDecending(a, keyItem)
  set n to length of a
  
set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1}
  
repeat with h in cols
    if (h (n - 1)) then
      repeat with i from h to (n - 1)
        set v to item (i + 1) of a
        
set j to i
        
repeat while (j h) and ((contents of item keyItem of item (j - h + 1) of a) < (item keyItem of v))
          set (item (j + 1) of a) to (item (j - h + 1) of a)
          
set j to j - h
        end repeat
        
set item (j + 1) of a to v
      end repeat
    end if
  end repeat
  
return a
end shellSortListDecending

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

03/09 Mailで表示しているフォルダで送信日時が重複しているメールを削除v1

Mail.appで表示しているフォルダ中で送信日時(日付、時:分:秒)が重複しているメールを削除するAppleScriptです。

たとえば、たまたまメーリングリストに登録しているメールアドレスを他のものに変更する作業を行ったとして、たまたま2つのアドレスが重複して登録されている時間帯があって……同じメールを重複して受信してしまっているような時に、これを送信日時で検出して削除を行います。

すべて処理対象にすると処理対象が多すぎることが予想されたため、指定日時「以降」のメールのみを対象とするように絞り込みを行っています。

Mail.appでは複数のビューワーウィンドウを表示できるので、複数あった場合には最前面のビューワーウィンドウが対象となります。

mail01.jpg

こんな風にメールフォルダが階層構造になっていて……

mail02.jpg

最前面のビューワーで選択されているメールフォルダが対象で……

mail03.jpg

重複しているメールを……

mail04.jpg

すべて削除します。

スクリプト名:Mailで表示しているフォルダで送信日時が重複しているメールを削除v1

set yesterdayDate to "2009/3/1" 指定日時以降を対象とする
set yesterdayDate to date yesterdayDate

set aMailBox to getSelectedOneMailBox() of me
tell application "Mail"
  
  
tell aMailBox
    set mList to (every message whose date sent > yesterdayDate)
  end tell
  
  
set sList to {}
  
repeat with i in mList
    set the end of sList to date sent of i
  end repeat
  
  
  
set {itemList, ssList} to detectDuplicationSimple(sList) of me
  
  
repeat with i in itemList
    set anMessage to item i of mList
    
tell anMessage
      delete
    end tell
  end repeat
end tell

リスト中の重複検出
on detectDuplicationSimple(cList)
  copy cList to ccList
  
  
set j to length of ccList
  
set dupList to {}
  
set itemList to {}
  
  
repeat with i from 2 to j
    set first_item to item 1 of ccList
    
    
set ccList to rest of ccList
    
if first_item is in ccList then
      set the end of dupList to first_item
      
set the end of itemList to (i - 1)
    end if
  end repeat
  
  
return {itemList, dupList}
end detectDuplicationSimple

Message Viewerで現在表示中のメールボックスの情報を1つのみ返す
on getSelectedOneMailBox()
  tell application "Mail"
    tell message viewer 1
      set mbList to selected mailboxes
    end tell
  end tell
  
if length of mbList is equal to 0 then
    return ""
  end if
  
  
set aMailBox to contents of (item 1 of mbList)
  
return aMailBox
end getSelectedOneMailBox

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 選択中のメッセージの実ファイルが存在する場所を取得するv3

Mail.appで選択中のメッセージの実ファイルが存在するパスを取得します。MLから拾ってきたものをベースにサブルーチン化したものです。

スクリプト名:選択中のメッセージの実ファイルが存在する場所を取得するv3
Phillip Akerによる投稿を元にサブルーチン化
(*

philip@vcn.bc.ca
Subject: Re: Get .emlx file for Mail message?
Date: 2006年9月24日 18:49:39:JST
*)

set mRes to retSelectedMessagePath() of me

Mail.appで選択中のメッセージの実ファイルが存在するパスを取得する
on retSelectedMessagePath()
  set lpath to POSIX path of (path to library folder from user domain)
  
set res to {}
  
tell applicationMail
    set sels to (get selection)
    
if (sels = {}) or ((count of sels) is not equal to 1) then
      return false
    end if
    
    
repeat with i from 1 to count of sels
      set p to.mbox/Messages/
      
set m to mailbox of item i of sels
      
set mid to id of item i of sels
      
tell m
        set n to name
        
if (its account exists) then
          tell its account
            if (account type is not pop) then set p to.imapmbox/Messages/
            
set end of res to account directory & “/” & n & p & mid & “.emlx
          end tell
        else
          set c to its container
          
set p to n & p
          
repeat while c exists
            set p to c’s name & “/” & p
            
set c to c’s container
          end repeat
          
set end of res to lpath & “Mail/Mailboxes/” & p & mid & “.emlx
        end if
      end tell
    end repeat
  end tell
  
set aRes to item 1 of res
  
set fPath to POSIX file aRes
  
return fPath
end retSelectedMessagePath

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 添付ファイルのダウンロード先を求める

Mail.appの添付ファイルのダウンロード先フォルダを取得します。

スクリプト名:添付ファイルのダウンロード先を求める
download_path() of me

on download_path()
  set p to (path to preferences folder from user domain ?
    as Unicode text) & “com.apple.mail.plist
  tell applicationSystem Eventsto set f to value of ?
    property list itemMailDownloadsPathof property list file p & “/
  if f does not start with~then return f
  
set h to POSIX path of (path to home folder)
  
if (count f) < 3 then return h
  
h & f’s text 3 thru -1
end download_path

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 Mail.appで選択中のメッセージから迷惑メールフラグの状態を取得する

Mail.appで選択中のメッセージから迷惑メールフラグの状態を取得するサンプルです。メッセージは複数選択されている場合もあるため、それに対応しておく必要があります。

スクリプト名:Mail.appで選択中のメッセージから迷惑メールフラグの状態を取得する
tell applicationMail
  set a to selection
  
set b to item 1 of a
  
tell b
    set c to junk mail status
  end tell
end tell

> false

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 Mail.appで現在選択されているメールボックスの情報を取得する

Mail.appで現在選択中のメールボックスの情報を取得します。メッセージは選択されている場合と選択されていない場合があり、それぞれの状況を考慮しておく必要がありますが、メールボックスについては必ずどれかが選択されています。

mail5.jpg

スクリプト名:Mail.appで現在選択されているメールボックスの情報を取得する
tell applicationMail
  tell message viewer 1
    set mbList to selected mailboxes
  end tell
end tell

> {mailbox “ML/Apple US/ASに関係のあるもの/Apple Help” of application “Mail”}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 Mail.appでメッセージビューワーの情報を取得する

Mail.appでメッセージ表示用ビューワーウィンドウの情報を取得します。Mail.appは複数のビューワーウィンドウを同時に表示できるため、AppleScript側でもそれを考慮しておく必要があります。

mail3.jpg

mail4.jpg

スクリプト名:Mail.appでメッセージビューワーの情報を取得する
tell applicationMail
  count every message viewer
  
set aProp to properties of message viewer 1
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 Mail.appで新着メールの確認インタバルを変更する

Mail.appで新着メールの確認間隔(単位:分)を取得/変更するサンプルです。

スクリプト名:Mail.appで新着メールの確認インタバルを変更する
tell applicationMail
  set a to fetch interval取得
  
set fetch interval to 5設定
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 Mail.appで新着メールを確認する

Mail.appで新着メールを確認します。

スクリプト名:Mail.appで新着メールを確認する
tell applicationMail
  check for new mail
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 Mail.appでAccountの情報を取得する

Mail.appでメールアカウントの情報を取得するサンプルです。Mail.app上には複数のアカウントが登録されている可能性があるため、それに対応しておく必要があります。

スクリプト名:Mail.appでAccountの情報を取得する
tell applicationMail
  set a to every account
  
set anAccount to item 1 of a
  
tell anAccount
    set b to properties
  end tell
end tell

> {move deleted messages to trash:false, account type:pop, email addresses:{”maro@XXXXXX.jp”}, empty trash on quit:true, file path:”/Users/maro/Library/Mail/POP-maro@XXX.XXX.XXX.XXX”, authentication:none, empty junk messages frequency:0, delayed message deletion interval:7, enabled:true, class:pop account, password:”Account passwords can only be set, not read.”, big message warning size:-1, full name:”Takaaki Naganoya”, uses ssl:false, empty sent messages on quit:false, name:”xxxx.jp”, port:110, empty trash frequency:0, empty junk messages on quit:true, delete mail on server:missing value, user name:”maro”, smtp server:smtp server “xxxxxxx.xxx.xx.jp” of application “Mail”, empty sent messages frequency:-1, include when getting new mail:true, server name:”XXX.XXX.XXX.XXX”, delete messages when moved from inbox:false}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 Mail.appで選択したメッセージの所属するメールボックスを得る

Mail.app上で選択しているメールが入っているメールボックスを求めます。画面図の状態になっている場合に、得られる結果は

  mailbox “ML/Apple US/ASに関係のあるもの/AppleScript Users” of application “Mail”

となります。

mail2.jpg

スクリプト名:Mail.appで選択したメッセージの所属するメールボックスを得る
tell applicationMail
  set a to selection
  
set b to item 1 of a
  
set aMailBox to mailbox of b
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 Mail.appでメールボックスのcontainerを求める

Mail.appで選択中のメールボックス「を含むもの」(container)を取得します。この画面図の例では、mailbox “ML/Apple US/ASに関係のあるもの” of application “Mail”が返ってきます。

mail1.jpg

スクリプト名:Mail.appでメールボックスのcontainerを求める
tell applicationMail
  set a to selection
  
set b to item 1 of a
  
set aMailBox to mailbox of b
  
set aCon to container of aMailBox
  
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

03/21 メール送信

メール送信はAppleScriptによる自動化で、ぜひとも会得しておきたい技術のひとつです。24時間動き続けているシステムで、エラー発生時に画面のスナップショットを撮ってメールに添付して送信するといった用途や、特定のSubjectのメールが送られたらプログラムを実行し、結果をメールで返信するといった用途が考えられます。

遠隔地に設置したシステムをメールでコントロールするというのは、実用性が高いばかりでなく、なかなか楽しいものです。

スクリプト名:メール送信
set aSubject toメールのサブジェクトです
set theSender tosender@any_address” –送信者アドレス
set recipientAddr tosomebody@mail_reciever” –受信者アドレス
set bodyText toひよこさんへ
こんにちは。ひよこさん。
ひよこクラブへのおさそいです。

ぴよ〜

sendMail(aSubject, theSender, recipientAddr, bodyText) of me

Mail.appでメール送信を行う
on sendMail(theSubject, theSender, recipientAddr, bodyText)
  tell applicationMail
    set newMessage to make new outgoing message with properties {subject:theSubject, content:bodyText}
    
tell newMessage
      set visible to true
      
set sender to theSender
      
make new to recipient at end of to recipients with properties {address:recipientAddr}
      
send
    end tell
  end tell
end sendMail

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に