# This is an adaptive card
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{ "type": "TextBlock", "size": "Medium", "weight": "Bolder", "text": "ℹ️ License status" },
{ "type": "TextBlock", "wrap": true, "color": "good", "text": "__SUMMARY__" },
{ "type": "ActionSet", "actions": [
{ "type": "Action.ShowCard", "title": "Details", "card": {
"type": "AdaptiveCard", "version": "1.4",
"body": [
{ "type": "FactSet", "facts": [
{ "title": "Enterprise", "value": "__ENTERPRISE__" },
{ "title": "Purchased", "value": "__TOTAL_PURCHASED__" },
{ "title": "Consumed", "value": "__TOTAL_CONSUMED__" },
{ "title": "Available", "value": "__SEATS_AVAILABLE__" },
{ "title": "% Consumed", "value": "__PERCENT_CONSUMED__%" },
{ "title": "% Remaining", "value": "__PERCENT_REMAINING__%" },
{ "title": "Threshold (__METRIC_LABEL__)", "value": "__THRESHOLD__%" }
] }
]
} }
] }
],
"msteams": { "width": "Full" }
}
The secret which is needed to post : TEAMS_WORKFLOW This can be found by creating a workflow on the team, and it would be URL to post message to channel. The user generating must be an owner of the channel. The channel must be public to the group it is in.
#!/usr/bin/env bash
set -euo pipefail
# Expects env vars:
# TEAMS_WEBHOOK_URL, SUMMARY, ENTERPRISE, TOTAL_PURCHASED, TOTAL_CONSUMED,
# SEATS_AVAILABLE, PERCENT_CONSUMED, PERCENT_REMAINING, THRESHOLD, METRIC_LABEL
# Optional: TEMPLATE_PATH (defaults to .data/info_card.json)
BASE="https://defaultxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.05.environment.api.powerplatform.com:443/powerautomate/automations/direct"
URI="${BASE}/workflows/${TEAMS_WORKFLOW}/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=${TEAMS_SIG}"
TEMPLATE_PATH="${TEMPLATE_PATH:-data/license_infor.card}"
ADAPTED_PATH="${RUNNER_TEMP:-/tmp}/info_card.adapted.json"
PAYLOAD_PATH="${RUNNER_TEMP:-/tmp}/info_payload.json"
jq \
--arg SUMMARY "${SUMMARY}" \
--arg ENTERPRISE "${ENTERPRISE}" \
--arg TOTAL_PURCHASED "${TOTAL_PURCHASED}" \
--arg TOTAL_CONSUMED "${TOTAL_CONSUMED}" \
--arg SEATS_AVAILABLE "${SEATS_AVAILABLE}" \
--arg PERCENT_CONSUMED "${PERCENT_CONSUMED}" \
--arg PERCENT_REMAINING "${PERCENT_REMAINING}" \
--arg THRESHOLD "${THRESHOLD}" \
--arg METRIC_LABEL "${METRIC_LABEL}" \
'
def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key ({}; . + {($key): ($in[$key] | walk(f))})
elif type == "array" then
map(walk(f))
else
f
end;
walk(
if type=="string" then
.
| gsub("__SUMMARY__"; $SUMMARY)
| gsub("__ENTERPRISE__"; $ENTERPRISE)
| gsub("__TOTAL_PURCHASED__"; $TOTAL_PURCHASED)
| gsub("__TOTAL_CONSUMED__"; $TOTAL_CONSUMED)
| gsub("__SEATS_AVAILABLE__"; $SEATS_AVAILABLE)
| gsub("__PERCENT_CONSUMED__"; $PERCENT_CONSUMED)
| gsub("__PERCENT_REMAINING__"; $PERCENT_REMAINING)
| gsub("__THRESHOLD__"; $THRESHOLD)
| gsub("__METRIC_LABEL__"; $METRIC_LABEL)
else . end
)
' "${TEMPLATE_PATH}" > "${ADAPTED_PATH}"
jq -n --slurpfile card "${ADAPTED_PATH}" \
'{type:"message",attachments:[{contentType:"application/vnd.microsoft.card.adaptive",content:$card[0]}]}' \
> "${PAYLOAD_PATH}"
curl -sS -X POST -H 'Content-Type: application/json' \
-d @"${PAYLOAD_PATH}" "${URI}" | cat