i'm building a connector for MS Teams and Outlook. I have registered the connector on Connectors Developer Dashboard but when I sideload it on outlook and I try to configure the connector... Nothing happens in my setup page. Indeed,
microsoftTeams.settings.getSettings is not working.
Does the microsoftTeams js library works for Outlook too? If not how do I do?
It seems that Connect To Office 365 Button aren't the ongoing way to do it.
Documentation with dead links and mix between Teams & Outlook doesn't help :(
Thank you!
Edit 1:
AngularJS code called on my configuration page:
$scope.setValidateState = function() {
microsoftTeams.settings.setValidityState(true);
};
$scope.authenticate = function() {
microsoftTeams.authentication.authenticate({
url: isSettings.serverUrl + '/microsoft/auth-start/',
with: 500,
height: 800,
successCallback: function(data) {
$scope.isAuthenticated = data && data['accessToken'];
localStorage.setItem("microsoft-oauth", JSON.stringify(data));
displayConfiguration();
},
failureCallback: function(reason) {
console.log(reason);
}
});
};
function displayConfiguration() {
microsoftTeams.settings.setValidityState(true);
microsoftTeams.settings.registerOnSaveHandler(function(saveEvent) {
microsoftTeams.settings.setSettings({
entityId: 'icescrum-connector-pkey-' + $scope.settings.project.pkey,
contentUrl: isSettings.serverUrl + '/microsoft/setup/',
configName: $scope.settings.project.name
});
microsoftTeams.settings.getSettings(function(settings) {
$scope.settings.webhookUrl = settings.webhookUrl;
console.log(settings.webhookUrl);
saveEvent.notifySuccess();
});
});
microsoftTeams.settings.getSettings(function(settings) {
$scope.setup = !settings.configName;
ProjectService.listByUserAndRole(Session.user.id, 'productOwner', {light: true}).then(function(projects) {
$scope.projects = projects;
if (settings.entityId) {
$scope.settings.project = _.find($scope.projects, {pkey: settings.entityId.split('icescrum-connector-pkey-')[1]});
}
$scope.ready = true;
});
});
}
// Init
$scope.settings = {};
$scope.projects = [];
$scope.ready = false;
var tokenData = JSON.parse(localStorage.getItem("microsoft-oauth"));
$scope.isAuthenticated = tokenData && tokenData['accessToken'];
microsoftTeams.initialize();
if($scope.isAuthenticated){
displayConfiguration();
}
My manifest.json:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.3/MicrosoftTeams.schema.json",
"manifestVersion": "1.3",
"id": "a15dcb92-35af-400e-ab9b-99efda40138f",
"version": "1.0.0",
"packageName": "com.iceScrum2",
"developer": {
"name": "Developer",
"websiteUrl": "https://www.icescrum.com",
"privacyUrl": "https://www.icescrum.com",
"termsOfUseUrl": "https://www.icescrum.com"
},
"description": {
"full": "iceScrum connector",
"short": "integration iceScrum with Microsoft Teams with a bot, a connector and a tab"
},
"icons": {
"outline": "icescrum-icon-32x32.png",
"color": "icescrum-icon-192x192.png"
},
"connectors": [
{
"connectorId": "a15dcb92-35af-400e-ab9b-99efda40138f",
"scopes": [
"team"
],
"configurationUrl": "https://icescrum.ngrok.io/icescrum/microsoft/setup/"
}
],
"name": {
"full": "iceScrum2",
"short": "iceScrum2"
},
"accentColor": "#FFFFFF",
"validDomains": [
"*.icescrum.com",
"icescrum.ngrok.io"
]
}
My microsoft Teams js lib was outdated (1.3.4). With the last version (1.4.1) it works well on Outlook and on Teams.
Related
I can't seem to successfully send a handoff request in Bot Framework Composer. On clicking "Start bot" I get the error Error: Dialog.onComputeId(): not implemented.
Full error log:
Error occurred building the bot
Error: Dialog.onComputeId(): not implemented.
at SendHandoffActivity.onComputeId (C:\Users\User\Handoff\Handoff\node_modules\botbuilder-dialogs\lib\dialog.js:336:15)
at SendHandoffActivity.get id [as id] (C:\Users\User\Handoff\Handoff\node_modules\botbuilder-dialogs\lib\dialog.js:133:29)
at C:\Users\User\Handoff\Handoff\node_modules\botbuilder-dialogs-adaptive\lib\actions\actionScope.js:276:57
at Array.map (<anonymous>)
at ActionScope.onComputeId (C:\Users\User\Handoff\Handoff\node_modules\botbuilder-dialogs-adaptive\lib\actions\actionScope.js:276:34)
at ActionScope.get id [as id] (C:\Users\User\Handoff\Handoff\node_modules\botbuilder-dialogs\lib\dialog.js:133:29)
at DialogSet.add (C:\Users\User\Handoff\Handoff\node_modules\botbuilder-dialogs\lib\dialogSet.js:126:71)
at C:\Users\User\Handoff\Handoff\node_modules\botbuilder-dialogs-adaptive\lib\adaptiveDialog.js:140:75
at Array.forEach (<anonymous>)
at AdaptiveDialog.ensureDependenciesInstalled (C:\Users\User\Handoff\Handoff\node_modules\botbuilder-dialogs-adaptive\lib\adaptiveDialog.js:140:43)
The bot is an empty bot with a "Send a handoff request" in "Unknown intent". Full bot code:
{
"$kind": "Microsoft.AdaptiveDialog",
"$designer": {
"name": "Handoff",
"description": "",
"id": "A79tBe"
},
"autoEndDialog": true,
"defaultResultProperty": "dialog.result",
"triggers": [
{
"$kind": "Microsoft.OnConversationUpdateActivity",
"$designer": {
"id": "376720"
},
"actions": [
{
"$kind": "Microsoft.Foreach",
"$designer": {
"id": "518944",
"name": "Loop: for each item"
},
"itemsProperty": "turn.Activity.membersAdded",
"actions": [
{
"$kind": "Microsoft.IfCondition",
"$designer": {
"id": "641773",
"name": "Branch: if/else"
},
"condition": "=string(dialog.foreach.value.id) != string(turn.Activity.Recipient.id)",
"actions": [
{
"$kind": "Microsoft.SendActivity",
"$designer": {
"id": "859266",
"name": "Send a response"
},
"activity": "${SendActivity_Greeting()}"
}
]
}
]
}
]
},
{
"$kind": "Microsoft.OnUnknownIntent",
"$designer": {
"id": "mb2n1u"
},
"actions": [
{
"$kind": "Microsoft.SendHandoffActivity",
"$designer": {
"id": "74xAHm"
},
"context": {
"context": "c"
},
"transcript": {
"transcript": "t"
}
}
]
}
],
"generator": "Handoff.lg",
"id": "Handoff",
"recognizer": "Handoff.lu.qna"
}
I haven't found anything on Google/Stack Overflow. Any help would be appreciated.
According to Hand off to human or virtual agent, You need to install an appropriate handoff package for the platform that you wish to have conversations handed off to when you use a Send a handoff request activity.
The following are available handoff packages
ServiceNow
LivePerson
I'm currently seeing this error when I try and save my connector configuration:
21T21:05:12.087Z ngClickDecorator: value not found in enum type. value:
and
21T21:05:12.155Z Received error from connectors {"seq":1611247472155,"timestamp":1611263112143,"flightSettings": {"Name":"ConnectorFrontEndSettings","AriaSDKToken":"d127f72a3abd41c9b9dd94faca947689-d58285e6-3a68-4cab-a458-37b9d9761d35-7033","SPAEnabled":true,"ClassificationFilterEnabled":true,
"ClientRoutingEnabled":true,"EnableYammerGroupOption":true,
"EnableFadeMessage":false,"EnableDomainBasedOwaConnectorList":false,
"EnableDomainBasedTeamsConnectorList":false,"DevPortalSPAEnabled":true,
"ShowHomeNavigationButtonOnConfigurationPage":false,"DisableConnectToO365InlineDeleteFeedbackPage":true},"status":500,"clientType":"SkypeSpaces",
"connectorType":"c6adb316-46b2-4e46-a511-8b4947b3d554","name":"handleMessageError"}
And the SO post: Can't save custom connector configuration is very close to my problem however I have added my configurationURL to my valid domains, and removed mine from the manifest but with still no luck. I'm all set up on my permissions as well unless there is something specific I am missing to configure?
Any suggestions, below is my manifest and code:
Manifest:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.8/MicrosoftTeams.schema.json",
"manifestVersion": "1.8",
"version": "1.0.3",
"showLoadingIndicator": true,
"isFullScreen": true,
"id": "c6adb316-46b2-4e46-a511-8b4947b3d554",
"packageName": "com.test",
"developer": {
"name": "Test, Inc",
"websiteUrl": "https://test.com",
"privacyUrl": "https://test.com/privacy",
"termsOfUseUrl": "https://test.com/toc"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"connectors": [
{
"connectorId": "c6adb316-46b2-4e46-a511-8b4947b3d554",
"scopes": [
"team"
],
"configurationUrl": "https://localdev-test.test.com/connector"
}
],
"name": {
"short": "Test Development",
"full": "Test for Microsoft Teams"
},
"description": {
"short": "Test Development",
"full": "Test for Microsoft Teams"
},
"accentColor": "#FFFFFF",
"staticTabs": [
{
"entityId": "22f101b6-f9a2-44d3-8eba-74309295f398",
"scopes": [
"personal"
],
"context":[
"personalTab",
"channelTab"
],
"name": "TestSite",
"contentUrl": "https://localdev-test.test.com",
"websiteUrl": "https://localdev-test.test.com",
"searchUrl": "https://localdev-test.test.com"
}
],
"devicePermissions": [
"notifications",
"openExternal"
],
"permissions": [
"identity",
"messageTeamMembers"
]
}
Code:
ngOnInit(): void {
microsoftTeams.initialize();
microsoftTeams.settings.registerOnSaveHandler((saveEvent) => {
microsoftTeams.settings.setSettings({
entityId: 'Create',
contentUrl: 'https://localdev-test.test.com/connector',
removeUrl: 'https://localdev-test.test.com/connector',
configName: 'Create'
});
microsoftTeams.settings.getSettings((settings) => {
this.webhookUrl = settings.webhookUrl;
localStorage.setItem('connectorWebHook', this.webhookUrl);
});
saveEvent.notifySuccess();
});
}
onClick(): void {
if (!this.webhookUrl) {
microsoftTeams.settings.setValidityState(true);
}
}
This is a Microsoft Bug, the "Configuration page for your Connector" on the Connector Portal is immutable (even though it is in an edit field). Meaning that the URL you set on the creation of the Connector can not change through development or you will get this error. So just making a new connector through the portal with my changed configuration URL fixed my problem.
A comment on their git points to this as well: https://github.com/MicrosoftDocs/msteams-docs/issues/1738#issuecomment-647675420
I have followed the microsoft documentation.
From it, I understand that "I can run my own custom HTML/JavaScript code" and make it display on teams with Task Module.
I have done everything recommended my card is showing blank each time invoke the task module.
I'm using the BotBuilder-Sample Node JS SDK
teamsTaskModuleBot.js file contains
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
const {
TeamsActivityHandler,
MessageFactory,
CardFactory,
} = require("botbuilder");
class TeamsTaskModuleBot extends TeamsActivityHandler
{
constructor ()
{
super();
// See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types.
this.onMessage(async (context,next) =>
{
const card = this.getHeroCardMenu();
const message = MessageFactory.attachment(card);
await context.sendActivity(message);
// By calling next() you ensure that the next BotHandler is run.
await next();
});
this.onMembersAdded(async (context,next) =>
{
const card = this.getHeroCardMenu();
const message = MessageFactory.attachment(card);
await context.sendActivity(message);
// By calling next() you ensure that the next BotHandler is run.
await next();
});
}
getHeroCardMenu ()
{
return CardFactory.heroCard(
"Task Module Invocation from Hero Card",
null, // No images
[
{
type: "invoke",
title: "Open",
value: {type: "task/fetch"},
},
]
);
}
handleTeamsTaskModuleFetch (context,taskModuleRequest)
{
// taskModuleRequest.data can be checked to determine different paths.
return {
task: {
type: "continue",
value: {
url: "https://botiframe.netlify.app/index.html",
height: "medium",
width: "medium",
title: "Task Module Bot",
fallbackUrl: "https://botiframe.netlify.app/index.html"
},
},
};
}
}
module.exports.TeamsTaskModuleBot = TeamsTaskModuleBot;
My manifest.json file
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
"manifestVersion": "1.5",
"version": "1.0.0",
"id": "208a91ef-baa9-460d-bf8d-7c7bc2f475e0",
"packageName": "com.dipolediamond.taskmodule",
"developer": {
"name": "dipoleDiamond Ltd",
"websiteUrl": "https://www.dipolediamond.com",
"privacyUrl": "https://www.dipolediamond.com/blog",
"termsOfUseUrl": "https://www.dipolediamond.com/contact"
},
"icons": {
"color": "icon-color.png",
"outline": "icon-outline.png"
},
"name": {
"short": "Task Module Bot",
"full": "Simple Task Module Bot"
},
"description": {
"short": "Test Task Module Sample Bot",
"full": "Simple Task Module Sample Bot"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "208a91ef-baa9-460d-xxxx-xxxxxxx",
"scopes": ["personal", "team", "groupchat"],
"supportsFiles": false,
"isNotificationOnly": false
}
],
"permissions": ["identity", "messageTeamMembers"],
"composeExtensions": [
{
"botId": "208a91ef-baa9-460d-xxxx-xxxx",
"canUpdateConfiguration": true,
"commands": [],
"messageHandlers": [
{
"type": "link",
"value": {
"domains":"www.botiframe.netlify.app"
]
}
}
]
}
],
"validDomains": ["www.botiframe.netlify.app"]
}
Before showing your web content, Teams does some basic validation of the end address. This requires, as you've done, that the domain be registed with validDomains and domains sections. However, when I visit the site, I'm getting a certificate error, so it's likely that Teams is blocking your site for that reason. Are you able to get that resolved (custom domain, or cert matching domain (the cert is for *.netlify.com, but your site is running on netlify.app)? Try that first.
I have started developing an addon which would work on package.json of a Github repo. On loading the addon, it requires an additional page refresh for the addon to take effect instead of applying the border as soon as the url is recognized.
manifest.json
{
"manifest_version": 2,
"name": "Border It",
"version": "0.0.1",
"permissions": ["activeTab", "tabs", "https://github.com/*"],
"content_scripts": [
{
"matches": ["https://github.com/*/package.json"],
"js": ["src/scripts/borderify.js"],
}
]
}
borderify.js
document.body.style.border = '5px solid red';
What am I doing wrong?
GitHub updates page content dynamically, so you need to run your script on every GitHub pages ("matches": ["https://github.com/*"]) and observe the location change. Here is more hints:
Event when window.location.href changes
(updated)
Example implementation based on MutationObserver:
{
"manifest_version": 2,
"name": "Border It",
"version": "0.0.1",
"permissions": [
"activeTab",
"tabs",
"https://github.com/*"
],
"content_scripts": [
{
"matches": ["https://github.com/*"],
"js": ["borderify.js"]
}
]
}
function onLocationChanged() {
if (/\/package.json([?#]|$)/.test(location.pathname))
document.body.style.border = '5px solid red';
else
document.body.style.border = '';
}
onLocationChanged(); // executed when the page is initially loaded
let lastUrl;
const observer = new MutationObserver(mutations => {
// executed on any dynamic change in the page
if (location.href == lastUrl)
return;
lastUrl = location.href;
onLocationChanged();
});
const config = {
childList: true,
subtree: true
};
observer.observe(document.body, config);
I am following the tutorials on https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/tabs/tabs-configuration with the configuration code provided. When I hit save after some seconds I get the error that it was not successful.
As far as I am concerned all needed valid domains are added.
Manifest.json
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.3/MicrosoftTeams.schema.json",
"manifestVersion": "1.3",
"id": "ec3e802c-506d-4301-9ae4-868b93461ca0",
"version": "1.0.0",
"packageName": "com.Package",
"developer": {
"name": "Developer",
"websiteUrl": "https://privateDomain.de",
"privacyUrl": "https://privateDomain.de",
"termsOfUseUrl": "https://privateDomain.de"
},
"description": {
"full": "Text",
"short": "More Text"
},
"icons": {
"outline": "IncomingWebhook.jpg",
"color": "IncomingWebhook.jpg"
},
"connectors": [
{
"connectorId": "ec3e802c-506d-4301-9ae4-868b93461ca0",
"scopes": [
"team"
],
"configurationUrl": "*linkToConfigurationPage*"
}
],
"name": {
"full": "Package",
"short": "Package"
},
"accentColor": "#FFFFFF",
"validDomains": [
"bing.com",
"google.com",
"*.google.com",
"*.bing.com",
"teams-get-started-sample.azurewebsites.net",
"*.microsoft.com",
"*.skype.com",
"*.privateDomain.de",
"vater-gruppe.de",
"static2.sharepointonline.com",
"secure.aadcdn.microsoftonline-p.com",
"code.jquery.com",
"statics.teams.microsoft.com",
"*.microsoftonline.com",
"ajax.googleapis.com"
],
"needsIdentity": "false"
}
The code in the index on the SSL capable server(linkToConfigurationPage) is
`<body>
<form>
<input type="radio" name="maptype" value="bing" onclick="onClick()"> Bing Maps<br>
<input type="radio" name="maptype" value="google" onclick="onClick()"> Google Maps
</form>
<script src="https://statics.teams.microsoft.com/sdk/v1.2/js/MicrosoftTeams.min.js"></script>
<script type="text/javascript">
microsoftTeams.initialize();
microsoftTeams.settings.registerOnSaveHandler(function(saveEvent){
var radios = document.getElementsByName("maptype");
if (radios[0].checked) {
microsoftTeams.settings.setSettings({
entityId: "bing",
contentUrl: "https://www.bing.com/maps/embed",
suggestedDisplayName: "Bing Map",
websiteUrl: "https://www.bing.com/maps",
removeUrl: "https://teams-get-started-sample.azurewebsites.net/tabremove.html",
});
} else {
microsoftTeams.settings.setSettings({
entityId: "google",
contentUrl: "https://www.google.com/maps/embed",
suggestedDisplayName: "Google Map",
websiteUrl: "https://www.google.com/maps",
removeUrl: "https://teams-get-started-sample.azurewebsites.net/tabremove.html",
});
}
saveEvent.notifySuccess();
});
function onClick() {
microsoftTeams.settings.setValidityState(true);
}
</script>
</body>
</html>`
The error message I get is
angular.min.js:112 2018-09-04T09:26:24.007Z Received error from connectors {"seq":1536048346894,"timestamp":1536053183994,"flightSettings":{"Name":"ConnectorFrontEndSettings","AriaSDKToken":"d127f72a3abd41c9b9dd94faca947689-d58285e6-3a68-4cab-a458-37b9d9761d35-7033","SPAEnabled":true,"ClassificationFilterEnabled":true,"ClientRoutingEnabled":true,"EnableYammerGroupOption":true,"EnableFadeMessage":false,"EnableDomainBasedOwaConnectorList":false,"EnableDomainBasedTeamsConnectorList":false,"DevPortalSPAEnabled":true,"ShowHomeNavigationButtonOnConfigurationPage":false},"status":500,"clientType":"SkypeSpaces","connectorType":"ec3e802c-506d-4301-9ae4-868b93461ca0","name":"handleMessageError","nonPIIInfo":"{\"exception\":{}}"}
Can anyone help me what I am doing wrong?
The content URL in microsoftTeams.settings.setSettings() is used to handle edits. This URL also need to be under the same domain which is added in Connector Portal's valid domain section. You could try following as your linkToConfigurationPage is already part of valid domains.
microsoftTeams.settings.setSettings({
entityId: "bing",
contentUrl: "*linkToConfigurationPage*",
suggestedDisplayName: "Bing Map"
})
The solution is to remove the "validDomains" attribute from the generated mainfest.json.