I've developed an app and connector for Microsoft teams, whenever I try to setup a connector for a specific channel and save the connector when the setup is finished there is an unexpected error message
If I then look in the developer tools I see that some request is send to https://outlook.office.com/connectors/ConnectToO365Inline/Manage/UpdateAsync with a http 500 response. I have followed the documentation provided by Microsoft at https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-creating I also stripped down our code to the bare minimum but still get the unexpected error while saving.
It's also very odd that the connector works perfectly on our Microsoft partner account, but whenever I try the connector on an other microsoft account it gives the unexpected error while saving.
Here you can see the manifest.json for the app:
{
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.11/MicrosoftTeams.schema.json",
"manifestVersion": "1.11",
"version": "1.0.0",
"id": "0fa0f150-fd7e-4c4e-822e-793951af07f6",
"packageName": "com.package",
"developer": {
"name": "App name",
"websiteUrl": "https://www.domain",
"privacyUrl": "https://www.domain",
"termsOfUseUrl": "https://www.domain"
},
"name": {
"short": "short",
"full": "full"
},
"description": {
"short": "short description",
"full": "long description"
},
"icons": {
"outline": "icon.png",
"color": "icon.png"
},
"accentColor": "#3F487F",
"connectors": [
{
"connectorId": "8b4fe7a3-a04d-4d60-b204-0519ca2f0d04",
"configurationUrl": "https://domain/teams/config",
"scopes": [
"team"
]
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"domain"
]
}
And this is our save handler as part of our file to setup the connector:
microsoftTeams.settings.registerOnSaveHandler(function (saveEvent) {
microsoftTeams.getContext(context => {
microsoftTeams.settings.getSettings(s => {
let data = {
url: s.webhookUrl,
name: context.teamName + ' - ' + context.channelName,
channel_id: context.channelId,
token: s.entityId,
origin: window.location.origin
};
let xhr = new XMLHttpRequest();
xhr.open('POST', '/teams/token/updateWebhook');
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
let response = JSON.parse(xhr.response);
if (response.status === true) {
context.webhookUrl = response.value;
saveEvent.notifySuccess();
}
}
}
xhr.send(JSON.stringify(data));
});
});
});
I already contacted Microsoft support but they said their expertise to developed software and connectors are very little, so we should ask it on Stackoverflow.
What is going wrong, and what do i need to do to make it work?
Related
I tried omnibox with the following code from MDN. When I trying, I temporarily loaded manifest.json from about:debugging. This worked in a normal browser, and typing cs a show a some suggestion.
However, this suggestion feature is not working in private mode. This did not change even if I allowed it to run in a private window.
How can I get the omnibox suggestion feature to work in private mode?
browser.omnibox.setDefaultSuggestion({
description: "Type the name of a CSS property"
});
/*
Very short list of a few CSS properties.
*/
const props = [
"animation",
"background",
"border",
"box-shadow",
"color",
"display",
"flex",
"flex",
"float",
"font",
"grid",
"margin",
"opacity",
"overflow",
"padding",
"position",
"transform",
"transition"
];
const baseURL = "https://developer.mozilla.org/en-US/docs/Web/CSS/";
/*
Return an array of SuggestResult objects,
one for each CSS property that matches the user's input.
*/
function getMatchingProperties(input) {
var result = [];
for (prop of props) {
if (prop.indexOf(input) === 0) {
console.log(prop);
let suggestion = {
content: baseURL + prop,
description: prop
}
result.push(suggestion);
} else {
if (result.length != 0) {
return result;
}
}
}
return result;
}
browser.omnibox.onInputChanged.addListener((input, suggest) => {
suggest(getMatchingProperties(input));
});
browser.omnibox.onInputEntered.addListener((url, disposition) => {
switch (disposition) {
case "currentTab":
browser.tabs.update({url});
break;
case "newForegroundTab":
browser.tabs.create({url});
break;
case "newBackgroundTab":
browser.tabs.create({url, active: false});
break;
}
});
My manifest.json follows below:
{
"manifest_version": 2,
"name": "text",
"version": "1.0",
"description": "text",
"background": {
"scripts": [
"background.js"
]
},
"omnibox": {
"keyword": "cs"
},
"permissions": [
"bookmarks",
"tabs"
]
}
Windows 10
Firefox 84.0.1 (64 bit)
Here is my issue:
I am trying to set-up an http trigger using Azure functions in javascript. I have been able to post this data into Cosmosdb using my POST function.
CosmosDB Example Item I am looking for:
{
"id": "POLL:FAVECOLORS:LM:LMBWZ18",
"partition": "POLL:LM",
"value": {
"name": "fave colors poll",
"question": "Which color do you like the most?",
"answers": [
{
"text": "Orange",
"count": 0
},
{
"text": "Yellow",
"count": 0
},
{
"text": "Blue",
"count": 0
}
]
},
"_rid": "<info>",
"_self": "<info>",
"_etag": "\"<info>\"",
"_attachments": "<info>/",
"_ts": <info>
}
I am trying to pull this information via input into my Azure Function.
Here is my function.json.
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"route": "<MyURL>/{type}/{objname}/{brand}/{site}",
"methods": [
"get",
"post",
"patch"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"name": "CosmosSend",
"type": "documentDB",
"databaseName": "PropDB",
"collectionName": "WithoutCCN",
"createIfNotExists": false,
"connection": "<Connection-Info>",
"direction": "out"
},
{
"type": "documentDB",
"name": "documents",
"databaseName": "PropDB",
"collectionName": "WithoutCCN",
"connection": "<Connection-Info>",
"direction": "in",
"sqlQuery": "SELECT * FROM c WHERE c.id = {id}"
}
],
"disabled": false
}
I am not sure how I can change my requests format so that it uses the request parameters for the query instead of looking for "https:///{type}/{objname}/{brand}/{site}?id=POLL:FAVECOLORS:LM:LMBWZ18"
module.exports = function (context, req) {
var documents = context.bindings.documents;
var totalDocuments = documents.length;
var azureAppId = req.headers["azure-app-id"];
context.log('azure-app-id = ' + azureAppId);
var idx = '' + (req.params.type + ':' + req.params.objname + ':' + req.params.brand + ':' + req.params.site).toUpperCase();
var paritionx = '' + (req.params.type + ":" + req.params.brand).toUpperCase();
var valuex = req.body;
if (req.method === 'GET') {
context.log('Found '+ totalDocuments +' documents');
if(totalDocuments === 0)
{
context.done(null, createResult(200, 'application/json', "The
requested document was not found."));
}
else {
context.done(null, createResult(200, 'application/json', documents));
}
} else if (req.method === 'POST') {
if (typeof req.body === 'object') {
context.bindings.CosmosSend = JSON.stringify({
id: idx,
partition: paritionx,
value: valuex
});
context.done(null, createResult(201, 'application/json', req.body));
}
else {
context.done(null, createResult(400, 'text/plain', 'The message must be of type application/json.'));
}
I have tried to take the variable 'idx' and put that into the query since it is already in the same format as the POST sends the 'id', but since it is not apart of the function.json itself it cannot be found. If I change the query in the function to:
"sqlQuery": "SELECT * FROM c WHERE c.id = /"{TYPE}:{OBJNAME}:{BRAND}:{SITE}/""
and anything remotely close to that kinda thinking it doesnt work. If I shove what I am looking for exactly into it:
"sqlQuery": "SELECT * FROM c WHERE c.id = \"POLL:FAVECOLORS:LM:LMBWZ18\""
It will find it perfectly every time, but only that one record, and it defeats the purpose of the GET request including its own target information.
I have really been racking my brain on this issue and any tips would really help. I have read a lot of microsoft docs related to the Azure Function and javascript but nothing has helped with this specific issue.
The expected results will be the item in cosmos returned when given the http GET request from the Azure Function app. it will look for the item by the information located in the URL of the request.
Have you tried adding the id as an optional parameter in the route?
"route": "<MyURL>/{type:alpha}/{objname:alpha}/{brand:alpha}/{site:alpha}/{id:alpha?}",
Keep in mind though, that doing this in the same HTTP Trigger Function will always execute the query, even on a POST where you don't send the id. So you are consuming RU's that you are not using.
Ideally you would split this into separate Functions, one for POST, one for GET, which helps them scale independently and you have a greater separation of concerns.
I am creating an API that gets Patients data(id and name), Physicians data(id and name) and Appointments(id, phyId, patId, app_date) and displays the Patients appointed to a particular physician. I need to create a remote method in physician.js in such a way that I get related Appointment that has phyId and print the details of the Patients using the patId obtained from appointment.
I'm using loopback 3.
Refer this link for clear idea:
https://loopback.io/doc/en/lb3/HasManyThrough-relations.html
I have related models (Physicians, Patients) that are related by "hasMany" with each other "through" Appointment(another model) and Appointment is related to each of these by belongsTo, in my loopback application and i need to print the Patients of a particular Physician.
Patient data:
[
{
"id": 1,
"name": "Anna Mull"
},
{
"id": 2,
"name": "Paige Trner"
}
]
Physician data:
[
{
"id": 1,
"name": "Cardiologist"
}
]
Appointment data:
[
{
"id": 1,
"physicianId": 1,
"patientId": 1,
"appointmentDate": "2019-01-28T10:06:33.530Z"
},
{
"id": 2,
"physicianId": 1,
"patientId": 2,
"appointmentDate": "2019-01-28T10:06:33.530Z"
}
]
I know there is a method already available to query the Patients of a Physician, but I want to code it myself to learn and also print it in the following format.
My idea is to get all the Appointments having the specific phyId in it and find the patId in those appointment and store it in an array. I then use that array to get the patients from the Patient model. I managed to get the Patient details in a function, but I can only console.log(Patients) but I am not able to display it in the API response.
The following is the format i need it in. (EXPECTED OUTPUT in API response)
Physician:
{
"id": 1,
"name": "Cardiologist"
}
Patients:
[
{
"id": 1,
"name": "Anna Mull"
},
{
"id": 2,
"name": "Paige Trner"
}
]
or any similar format.
I've tried to the same and here is my code.
common/models/physician.js
'use strict';
var app = require('../../server/server');
module.exports = function (Physician) {
Physician.getDetails = function (phyid, cb) {
var Appointments = app.models.Appointment;
var Patient = app.models.Patient;
Physician.findById(phyid, function (err, Physician) {
Appointments.find({ where: { physicianId: phyid } }, function (err, Appointment) {
if (err) {
cb(null, "Errorrrrrrrr", "Errorrrrrr");
}
else {
var patients = [], i = 0;
var patobj= [];
for (i in Appointment) {
patients[i] = Appointment[i].patientId;
//console.log(patients);
Patient.findById(patients[i], function(err, Patients){
if(err){
cb("Error in patients", "--");
}
else{
patobj[i]=Patients;//doesnt have any effect
console.log(Patients);//prints in console
}
});
}
cb(null, Physician, patobj);//only Physician is printed, patobj is empty.
}
});
});
}
Physician.remoteMethod('getDetails', {
http: {
path:
'/:phyid/getDetails',
verb: 'get'
},
accepts: {
arg: 'phyid',
type: 'number'
},
returns: [{
arg: 'Physician',
type: 'Object'
}, {
arg: 'Patient',
type: 'Object'
}]
});
};
I am actually getting this in the API response:
{
"Physician": {
"id": 1,
"name": "Cardiologist"
},
"Patient": []
}
and this in the console:
D:\Project\Project1>node .
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
{ name: 'Anna Mull', id: 1 }
{ name: 'Paige Trner', id: 2 }
How am I supposed to get the patient data to be printed in the API response?
You patients are empty because, finding Patients by Id is an asynchronous operation. But the for loop is synchronous. The loop finishes and calls the following line before any of the Patients are found.
cb(null, Physician, patobj);//only Physician is printed, patobj is empty.
You need to wait for all the patients to be found by using either Promise.all or async.each.
I'm using facebook Graph API to retrieve action values from campaigns. But the JSON returned is always different from any values from facebook screen.
My Request from JavaScript
var d = new FormData();
d.append("access_token", "MY_ADS_INSIGHTS_TOKEN");
d.append("fields", "actions");
d.append("date_preset", "lifetime"); // I want lifetime data
return await (await fetch("https://graph.facebook.com/v3.1/" + campaignid + "/insights", {
method: "post",
body: d
})).json();
and after I access the report insights using the URL:
https://graph.facebook.com/v3.1/REPORT_RUN_ID/insights?access_token=MY_ADS_INSIGHTS_TOKEN
JSON returned after access report task
{
"data": [
{
"actions": [
{
"action_type": "comment",
"value": "2"
},
{
"action_type": "like",
"value": "4"
},
{
"action_type": "photo_view",
"value": "30"
},
{
"action_type": "post",
"value": "1"
},
{
"action_type": "link_click",
"value": "7"
},
{
"action_type": "page_engagement",
"value": "249"
},
{
"action_type": "post_engagement",
"value": "245"
},
{
"action_type": "post_reaction",
"value": "205"
}
],
"date_start": "2018-07-09",
"date_stop": "2018-07-15",
"ad_id": null // removed
}
],
"paging": {
"cursors": {
"before": "MAZDZD",
"after": "MAZDZD"
}
},
"__fb_trace_id__": null // removed
}
Facebook Post Results
I want to know:
Why Facebook Graph API return the post_reaction as 205 since from facebook view it is 160 or 150? the value doesn't match anything, happens to action like too
Notes:
I'm not using any SDK, but this isn't the problem.
The Ad has only ONE ads group and the group has only ONE campaign
I make the requisition at the same time as I see the post. There are no major interactions in this post, it is old enough that the values do not change.
I known that Facebook cache anything, but this Ad is from 10, July.
Ad Campaign Insights reference: https://developers.facebook.com/docs/marketing-api/reference/ad-campaign-group/insights/
I accept answers using SDKs or different programming languages like C#, php or Java as example, I want only know HOW make the right request or what is exactly happening.
I am trying to add JSON request into a HTTP POST javascript code like below. Please see the code below.
My problem is, I need to input following format JSON and send it. But, I am getting Uncaught SyntaxError: Unexpected token : Could you please advise, What is wrong formatting JSON in my code below?
Sample JSON format to be sent=> {"records":[{"value":{"foo":"bar"}}]}
Code:
function savedata() {
var membernameStr = parseInt(document.getElementById("MemberID").value).toString();
var data = JSON.stringify({
"records": [["value":{"MemberID":membernameStr,"MemberName":"Anna", "AccountNo":"7623", "Address":"Peter", "AccountType":"Peter"}]]
});
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.status == 200) {
console.log(this.responseText);
// Based on successful response, call next POST API.
var xhr1 = new XMLHttpRequest();
xhr1.open("POST", "http://localhost:3500");
xhr1.send(data);
}
});
xhr.open("POST", "http://localhost:8082/topics/topictest");
xhr.setRequestHeader("Content-Type", "application/vnd.kafka.json.v2+json; charset=utf-8");
xhr.setRequestHeader("Accept", "application/vnd.kafka.v2+json; charset=utf-8");
xhr.send(data);
}
Your JSON was incorrect in the syntax, please have a look at below JSON:
{
"records": [
[
{
"value": {
"MemberID": membernameStr ,
"MemberName": "Anna",
"AccountNo": "7623",
"Address": "Peter",
"AccountType": "Peter"
}
}
]
]
}
why did you use array within array ? you can also use as below ..
{
"records": [
{
"value": {
"MemberID": membernameStr ,
"MemberName": "Anna",
"AccountNo": "7623",
"Address": "Peter",
"AccountType": "Peter"
}
}
]
}