Teams presence.xml

teams_presence.xml
<templates>
    <template name="Teams Presence">
        <keyConfiguration>
            <lua>
                <code><![CDATA[
local gTeamsFailedIdAquire = false
local gTeamsReceivedServerResponse = false
local gTeamsServerResponseWasGood = false
local gTeamsServerResponse = 42
local gTeamsState = "Unknown" -- one of: Available, Away, BeRightBack, Busy, DoNotDisturb, Offline, Unknown
local gTeamsRefreshInterval = 17  -- poll for new state every xy seconds
local gTeamsId = nil
local gTeamsPresenceUrl = "https://graph.microsoft.com/beta/communications/presences/"
local gTeamsFetchIdUrl = "https://graph.microsoft.com/beta/users/"

--Updates the led depending on the Status
local function updateKey()
    if gTeamsFailedIdAquire then
        key:setLed("orange")
        key:setInfo("error getting ID: "..tostring(gTeamsServerResponse))
    elseif not persisted["msTeamsToken"] then
        key:setLed("orange")
        key:setInfo("refresh failure")
    elseif not gTeamsReceivedServerResponse then
        key:setLed("orange", true)
        key:setInfo("aquiring")
    elseif not gTeamsServerResponseWasGood then
        key:setLed("orange")
        key:setInfo("server response: "..tostring(gTeamsServerResponse))
    elseif gTeamsState == "Available" then
        key:setLed("green")
        key:setInfo(gTeamsState)
    else
        key:setLed("red")
        key:setInfo(gTeamsState)
    end
end

--Analyzes the response of Microsoft and check if the user in question is available
local function onTeamsPresenceStatus(responseCode, responseBody, responseHeaders)
    gTeamsReceivedServerResponse = true
    gTeamsServerResponseWasGood = responseCode == 200 and responseBody
    gTeamsServerResponse = responseCode
    if gTeamsServerResponseWasGood then
        values = json.eval(responseBody)
        debug.log("Teams Presence: current activity is "..values["activity"].." in state "..values["availability"])
        if values["availability"] == "AvailableIdle" then
            gTeamsState = "Available"
        elseif values["availability"] == "PresenceUnknown" then
            gTeamsState = "Unknown"
        elseif values["availability"] == "BusyIdle" then
            gTeamsState = "Busy"
        else
            gTeamsState = values["availability"]
        end
    else
        gTeamsState = "Unknown"
        if responseCode == 401 then
            debug.log("Teams Presence: triggering re-auth")
            shared["msTeamsReAuthNeeded"] = "true"
        end
    end
    updateKey()
end

--Requests the teams status of someone
local function requestTeamsPresenceStatus()
    gTeamsReceivedServerResponse = false
    debug.log("Teams Presence: requesting state", "d")
    local header = {}
    header["Authorization"] = "Bearer "..persisted["msTeamsToken"]
    http.get(gTeamsPresenceUrl..gTeamsId, onTeamsPresenceStatus, header)
end

-- read persons ID from response
local function onTeamsIdResponse(responseCode, responseBody, responseHeaders)
    gTeamsServerResponse = responseCode
    if responseCode== 200 and responseBody then
        values = json.eval(responseBody)
        gTeamsId = values["id"]
        debug.log("Teams Presence: got id"..gTeamsId, "d")
        requestTeamsPresenceStatus()
    else
        gTeamsFailedIdAquire = true
        if responseCode == 401 then
            debug.log("Teams Presence: triggering re-auth")
            shared["msTeamsReAuthNeeded"] = "true"
        end
    end
    updateKey()
end

-- if pTeamsId is an e-mail -> requests basic data from Microsoft to get the ID
local function fetchTeamsId()
    x,y = string.find(pTeamsId, "@", 1, true)
    if x ~= nil then
        local header = {}
        header["Authorization"] = "Bearer "..persisted["msTeamsToken"]
        http.get(gTeamsFetchIdUrl..pTeamsId, onTeamsIdResponse, header)
    else
        gTeamsId = pTeamsId
        debug.log("Teams Presence: got id"..gTeamsId, "d")
        requestTeamsPresenceStatus()
    end
end

local function teamsRefreshLoop()
    if not persisted["msTeamsToken"] then
        debug.log("Teams Presence: not ready yet", "d")
    elseif not pTeamsId then
        debug.log("Teams Presence: disabled", "d")
        return
    elseif not gTeamsId then
        debug.log("Teams Presence: fetch id", "d")
        fetchTeamsId()
    else
        requestTeamsPresenceStatus()
    end
    time.callbackIn(teamsRefreshLoop, gTeamsRefreshInterval)
end

function onKeyUp()
    -- think of something to do
end

teamsRefreshLoop()
updateKey()
]]></code>
                <params>
                    <param name="pTeamsId"/>
                </params>
            </lua>
        </keyConfiguration>
        <parameters>
            <parameter name="E-Mail">
                <path>//param[@name="pTeamsId"]/value</path>
            </parameter>
        </parameters>
    </template>
</templates>