I have created a sharepoint list which contains contact information (name, phone number, ...). I have set conditional formatting on the column to include a phone icon with a hyperlink (deep link) to https://teams.microsoft.com/l/call/0/0?users=4:%2B to call the phone number. So far so good ;-)
Condittional formatting applied to the column containing the phone number:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"children": [
{
"elmType": "span",
"style": {
"padding-right": "8px"
},
"txtContent": "#currentField"
},
{
"elmType": "a",
"style": {
"text-decoration": "none"
},
"attributes": {
"iconName": "=if(substring(#currentField,0,1) == '+','phone','')",
"class": "sp-field-quickActions",
"href": {
"operator": "+",
"operands": [
"https://teams.microsoft.com/l/call/0/0?users=4:",
"=replace(#currentField,'+','%2B')"
]
}
}
}
]
}
The SharePoint list is added as a tab in my Teams client and opening correctly showing all the entries but when I click the phone button the Teams client will show the "stay better connected with the Teams desktop app" window (see screenshot) instead off opening the pop-up box asking if it may call the number.
Picture showing Teams asking what client to use:
I also created a power automate flow which uses the same info to post an adaptive card to a user with a button to call the number and there everything works as expected with the same URL format.
Opening the SharePoint list as a webpage and clicking on the phone icon results in the Teams desktop client asking for permission to call the number but a webpage tab is kept open with the message "stay better connected with the Teams desktop app ..." (not clean)
Am I doing something wrong? Should this be working and have I stumbled on a bug?
Related
We're using an CRM that has switched to using Graph to add events into our users Office 365 calendars. We're getting error messages that there are duplicate calendars called calendar for some users, the users are all users who were migrated from on premise Exchange to Office 365.
Looking in Office 365 via Powershell (get-mailboxfolderstatics -Identity user#contos.com -FolderScope Calendar | ft or in Outlook itself, there is only the one calendar named calendar.
But if I look at the same user via Graph
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('XXXXXXX-762d-47ee-9f82-XXXXXXXXXXX')/calendars",
I see 2 calendars with name Calendar, with slightly different IDs (see last few characters)
Azure support closed the case but the problem remains, how do I get Graph to see only the ONE calendar named calendar, or, how to rename one to something other THAN calendar?
Here's a dump of what I see:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('Bob.Smith%40contoso.com')/calendars",
"value": [
{
"id": "**snipped**_MRaRoNlRUYsQkAAAAABwPAAA=",
"name": "Calendar",
"color": "lightBlue",
"hexColor": "#a6d1f5",
"isDefaultCalendar": true,
"changeKey": "rX0CNBsSo0inAqdEAWRRmQAFRAI=",
"canShare": true,
"canViewPrivateItems": true,
"canEdit": true,
"allowedOnlineMeetingProviders": [
"teamsForBusiness"
],
"defaultOnlineMeetingProvider": "teamsForBusiness",
"isTallyingResponses": true,
"isRemovable": false,
"owner": {
"name": "Bob Smith",
"address": "Bob.Smith#contoso.com"
}
},
{
"id": "**snipped**_MRaRoNlRUYsQkAAApN6VAAAA=",
"name": "Calendar",
"color": "auto",
"hexColor": "",
"isDefaultCalendar": false,
"changeKey": "dt7cZZK/jEWkaDZUVGLEJAAGY8x28w==",
"canShare": true,
"canViewPrivateItems": true,
"canEdit": true,
"allowedOnlineMeetingProviders": [
"teamsForBusiness"
],
"defaultOnlineMeetingProvider": "teamsForBusiness",
"isTallyingResponses": false,
"isRemovable": true,
"owner": {
"name": "Bob Smith",
"address": "Bob.Smith#contoso.com"
}
}
]
}
I have no access to the software creating events, it's a third party SaaS system.
In the short term, one way to do this would be to fetch the calendar by id, then use the query parameters to customize the response using the changeKey. The longer term solution would be to engage your exchange admin to help with setting the right calendar for the users in question, which will eliminate the two calendars returned by graph.
I am looking for solution where I could upload an attachment in message extension.
So far, I am able to get the button in the hero card, but how can:
I use this button to upload a file?, or
Through this button I could open a new Adaptive Card or any card, where I use upload logic?
Attaching image below
As far as i know You can't upload attachment using the actions/buttons functionality of TeamsCards.
However you can use Teams TaskModule which allows you to create modal popup window in your Teams application.
Inside the popup window you can run your own custom HTML/JavaScript code where you can use the <input type="file"> tag to upload your attachment.
To open a popup window you have to include "msteams":{"type":"task/fetch"} into "data" object of the action object of the card.
I used AdaptiveCardDesigner to create an example for you.
But i think it's not necessary to use Adaptive Cards to achieve this, this should work with HeroCards too.
So here's an example:
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "Request Task"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.3",
"actions": [
{
"type": "Action.Submit",
"title": "Open Task Window",
"data": {
"msteams": {
"type": "task/fetch"
},
"messageId": "12345"
},
}
]
}
Next step is to handle this request on the backend and reply with an URL for the TaskModule window.
Here's an example project from Microsoft.
Hope this helped.
What I would like to achieve?
For internal purposes only / within our enterprise only, I would like to have Android tablets, which run only one single app (made with Ionic/Angular) which even appears after restarting the tablet and the user is not able to leave it.
I think the technical description of what I would like to achieve is called a dedicated devices (formerly called corporate-owned single-use, or COSU).
How would I like to achieve it?
I would like to achieve this with Android Management API, which looks like a great choice for a MDM (Mobile Device Management) solution.
Here Google shows how to achieve this with an Android Management API policy.
The Problem?
I am not able to get rid of the status and navigation bar.
For testing purposes I tried to achieve this with the regular YouTube app. With "statusBarDisabled": true, I was able to disable the status bar, so the user can not interact with it, but it is still visible.
And same goes for the navigation bar with
"persistentPreferredActivities":[
{
"receiverActivity":"com.google.android.youtube",
"actions":[
"android.intent.action.MAIN"
],
"categories":[
"android.intent.category.HOME",
"android.intent.category.DEFAULT"
]
}
]
I was able to hide the home and recents buttons, but the back button is still there and the whole navigation bar is visible.
The following image visualises the problem:
Anyone an idea how I can get rid of the status and navigation bar completely?
This is how my whole policy looks like:
import json
policy_name = enterprise_name + '/policies/policy1'
policy_json = '''
{
"safeBootDisabled": true,
"statusBarDisabled": true,
"keyguardDisabled": true,
"screenCaptureDisabled": true,
"factoryResetDisabled": true,
"cameraDisabled": true,
"blockApplicationsEnabled": true,
"systemUpdate": {
"type": "WINDOWED",
"startMinutes": 120,
"endMinutes": 240
},
"policyEnforcementRules": [{
"settingName": "persistentPreferredActivities",
"blockAction": {
"blockAfterDays": 0
},
"wipeAction": {
"wipeAfterDays": 3,
"preserveFrp": true
}
}],
"applications": [
{
"packageName": "com.google.android.youtube",
"installType": "FORCE_INSTALLED",
"lockTaskAllowed": true,
"defaultPermissionPolicy": "GRANT"
}
],
"persistentPreferredActivities": [
{
"receiverActivity": "com.google.android.youtube",
"actions": [
"android.intent.action.MAIN"
],
"categories": [
"android.intent.category.HOME",
"android.intent.category.DEFAULT"
]
}
]
}
'''
androidmanagement.enterprises().policies().patch(
name=policy_name,
body=json.loads(policy_json)
).execute()
The two bars you've highlight are actually part of the youtube app NOT part of the android OS/UI. So you can't hide those using the device management API.
I'm creating buttons for a slackbot using something like:
const messageB = {
"attachments": [
{
"text": "Essa mensagem foi útil?",
"callback_id": "button_feedback",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "button_click_yes",
"text": "sim",
"type": "button",
"value": "yes"
},
{
"name": "button_click_no",
"text": "não",
"type": "button",
"value": "no"
}
]
}
]
};
But the button remain active after the message was sent, and can be used again by the user. I want to deactivate it, or delete it after it was used. But i can't find about it anywhere in the docs.
Clicking on a button will always fire a request to your Slack app. If you want to remove the button after it was clicked you need to update your original message with a new one that reflects the changed state (e.g. button removed). Its not possible to show deactivated buttons with Slack though, so you need to remove it.
To replace the original message all you need to do is respond to the Slack request with an updated message.
However, it will technically still be possible for users to click on your button twice (e.g. due to network delays), so you app should be able to response to multiple clicks on your buttons by the same user in an appropriate way.
See also here for the official documentation on the topic.
See also here and here for answer on a similar topic.
update !important: The API has changed a lot, this question shouldn't be taken into consideration anymore
I am trying to use the REST api (via Node.js API) to create cards that the user can respond to and create an interaction in this way.
Reading the docs the creator attribute is not really specified anywhere, so I have no idea how to insert that.
Also this video doesn't help. Nor this guide =)
I believe there is an URL I should set as callback somehow? I'd like to know how to get these responses, please.
update
This is the card I am sending.
{
bundleId: 'veryuniqueBundle',
id: 'veryuniqueBundle:reply',
text: "want to hear moar?",
menuItems: [
{action: "REPLY"}
]
}
that's the response I get:
{
"collection": "timeline",
"itemId": "119c4dc8-c0ce-4a83-aa76-41aab4e8dbe1",
"operation": "INSERT",
"verifyToken": "42",
"userToken": "id:520ef63cde31145deb000001",
"userActions": [
{
"type": "REPLY"
}
]
}
The problem is, I can't see what the user responded (an text) and the reference to the original card id (or bundle) that was responded to. How can I get those
Cards do not provide a direct callback. Instead, when a user selects a menu item it causes the card to be updated with their menu selection. This change subsequently triggers a notification ping to your timeline subscription.
Follow these steps to detect a menu item selection:
Subscribe to notifications for changes in the timeline collection
{
"collection": "timeline",
"userToken": "awesome_kitty",
"verifyToken": "random_hash_to_verify_referer",
}
Insert a timeline card with a custom menu item
{
"text": "Hello world",
"menuItems": [
{
"action": "CUSTOM",
"id": "complete"
"values": [{
"displayName": "Complete",
"iconUrl": "http://example.com/icons/complete.png"
}]
}
]
}
Select the item on Glass
Receive the notification on your subscription URL
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"userActions": [
{
"type": "CUSTOM",
"payload": "PING"
}
]
}
Do cool stuff in your code
???
Profit