AppleScript创建链接'特定的Messages.app对话?

时间:2017-08-28 23:09:13

标签: macos applescript message macos-high-sierra

目标

我想要一个AppleScript,让我获取所选的Messages.app对话/聊天的ID或类似内容,然后再使用AppleScript打开正确的消息对话/聊天对应这个ID。

  • 获取当前所选Messages.app chat
  • 的ID /引用
  • 根据ID /参考
  • 打开特定的Messages.app聊天

到目前为止我尝试了什么

使用Mail.app我可以执行以下操作:

tell application "Mail" set selectedMessages to selection set theMessage to item 1 of selectedMessages set messageid to message id of theMessage -- Make URL (must use URL-encoded values for "<" and ">") set urlText to "message://" & "%3c" & messageid & "%3e" return urlText end tell

但是使用Messages.app,有selection个对象。

尝试获取the clipboard的内容以查看是否有任何可以使用的ID或值,但看起来剪贴板访问不像通过cocoa那样强大编程(在那里你可以获得大量的元数据和替代的剪贴板内容)。

双击对话,以便用它自己的窗口打开。试图获取此窗口的ID,然后稍后打开它。没有工作。

1 个答案:

答案 0 :(得分:1)

将此 AppleScript 脚本用作脚本(。scpt)或应用程序(.app ),您需要先在 Messages.app 会话列表中选择目标会话,以便此后始终返回,并且最初运行两次。然后,这会将property theSelectedRow : 0设置为property theSelectedRow : i,其中i将是row 数字最初运行两次时选择的对话列表中的>对话。 脚本还将property thisName : ""设置为,即description of UI element 1 of row i中包含的名称。在这两个属性之间,脚本将始终将焦点设置回后续选定的目标对话即使其row 数字发生更改,它仍然存在。如果所选目标会话不再存在,则会通知用户。

阅读脚本中的注释,以便了解代码正在做什么。

AppleScript 代码

--  # These two properties are used to hold information about the target 
--  # conversation in order to always set focus to it when the script runs
--  # after the initial runs. Initially, the script must be run twice to have 
--  # the selected target conversation be returned to on subsequent runs.
--  # 
--  # Note: This is also true anytime the script is modified or compiled, in
--  # Script Editor, as that resets the value of a property to its original value.

property thisRowNumber : 0
property thisName : ""


--  # See if the shift modifier key was pressed. This allows 
--  # setting the focus to a different target conversation.
--  # Note: Unlike when the script is modified or compiled from within
--  # Script Editor, when invoking this, the change is immediate when
--  # done after the initial runs to have the values of the properties set.

if my shiftKeyWasDown() then set thisRowNumber to 0


--  ### Main ###

tell application "Messages"
    if running then
        my selectTargetConversation()
        if minimized of window "Messages" is true then
            set minimized of window "Messages" to false
        end if
    else
        activate
        delay 2 -- # Allow time for Messages.app to open, adjust as/if necessary.
        my selectTargetConversation()
    end if
    activate
end tell


--  ### Handlers ###


--  # Detects if the shift modifier key was pressed.

on shiftKeyWasDown()
    if (do shell script "/usr/bin/python -c 'import Cocoa; print Cocoa.NSEvent.modifierFlags() & Cocoa.NSShiftKeyMask '") > 1 then
        return true
    else
        return false
    end if
end shiftKeyWasDown


--  # The 'getNameFromDescription' handler extracts the name portion of the 'description'
--  # within the 'UI element' of the 'row' of the target conversation. Example 'description':
--  # "Conversation with: Johnny Appleseed. Last activity: 6:10 PM. Last message: Look at all these trees!. "
--  # This is called from within a 'repeat' loop within the 'selectTargetConversation' handler:
--  # 'set thisName to my getNameFromDescription(description of UI element 1 of row i)'
--  # The 'thisName' property, in this example, would get set to: "Johnny Appleseed"

on getNameFromDescription(theText)
    set TID to AppleScript's text item delimiters
    set AppleScript's text item delimiters to {": "}
    set theText to text item 2 of theText
    set AppleScript's text item delimiters to {". "}
    set theText to text item 1 of theText
    set AppleScript's text item delimiters to TID
    return theText
end getNameFromDescription


--  # This handler provides all the logic necessary to ensure the 'Messages' window
--  # is available to set/reset focus back to the target conversation with each run,
--  # providing the target conversation still exists and sets focus to the target if it does.

on selectTargetConversation()

    tell application "System Events"

        --  # Make sure the 'Messages' window is available.
        --  # 
        --  # This branch of the 'if' block handles when Messages.app
        --  # is open, but without any windows showing.

        if (count of windows of application process "Messages") is equal to 0 then

            click UI element "Messages" of list 1 of application process "Dock"
            delay 0.25

        else
            --  # A least one window is open, make sure it's the 'Messages' window.

            --  # Set a flag to test against.

            set theMessagesWindowIsNotOpen to true

            set theWindowList to every window of application process "Messages"
            repeat with thisWindow in theWindowList
                if name of thisWindow is equal to "Messages" then
                    set theMessagesWindowIsNotOpen to false
                    exit repeat
                end if
            end repeat

            --  # If the value of 'theMessagesWindowIsNotOpen' is still 'true', 
            --  # then the 'Messages' window was not open, so open it.

            if theMessagesWindowIsNotOpen then
                tell application "Messages" to activate
                delay 0.25
                keystroke "0" using {command down}
            end if

        end if

        --  # When 'thisRowNumber is equal to 0' it's either the first time the script has run or it has been reset.
        --  # Get the 'row' number of the selected target conversation and set its value to 'thisRowNumber'.
        --  # Get the name within the 'description' of the 'UI element' of the selected 'row' and set it to 'thisName'.
        --  # Between the value of these two properties, the script will always set focus back to the selected target
        --  # conversation, providing it still exists. If the selected target conversation no longer exists, notify user.

        tell table 1 of scroll area 1 of splitter group 1 of window "Messages" of application process "Messages"

            if thisRowNumber is equal to 0 then

                repeat with i from 1 to (count rows)
                    if selected of row i is equal to true then
                        set thisRowNumber to i
                        set thisName to my getNameFromDescription(description of UI element 1 of row i)
                        exit repeat
                    end if
                end repeat

            else
                --  # Make sure the 'row' number, 'thisRowNumber', and the name within 'description of UI element' 
                --  # matches the value of the 'thisName' property, and if so, then set focus to it.

                if description of UI element 1 of row thisRowNumber contains thisName then

                    set selected of row thisRowNumber to true

                else
                    --  # The values no longer match. Ascertain the new 'row' number for 'thisRowNumber' that 
                    --  # contains the value of 'thisName', while verifying the target conversation still exists, and 
                    --  # reset focus back to the original selected target conversation, if it still exists.

                    --  # Set a flag to test against.

                    set theConversationNoLongerExists to true

                    repeat with i from 1 to (count rows)
                        if description of UI element 1 of row i contains thisName then
                            set thisRowNumber to i
                            set selected of row i to true
                            set theConversationNoLongerExists to false
                            exit repeat
                        end if
                    end repeat

                    --  # If the value of 'theConversationNoLongerExists' is still 'true',
                    --  #  then the conversation no longer exists, notify the user.

                    if theConversationNoLongerExists then
                        tell current application
                            display dialog "The target conversation has been deleted since the target was last set. Reset to a new target by selecting a conversation and then press the shift key down when running this script." buttons {"OK"} default button 1 with title "Target Conversation Reset Needed"
                        end tell
                    end if

                end if
            end if
        end tell
    end tell

end selectTargetConversation

注意:这是在OS X 10.8.5下编写和测试的,但是,我相信它将在OS X / macOS和Messages.app的更高版本下以的形式工作,即使是当前的macOS 10.13 beta。

此外,脚本使用最少的错误处理,并且没有任何try 语句on error 处理程序 。虽然除delay 命令中的之外,可以根据需要进行调整,但如果没有额外的错误处理,它应该可以正常运行。与往常一样,用户可以根据需要添加/删除和/或调整代码