When I make requests to the Microsoft Graph API's invite endpoint to create secure (email-based) sharing links for a specific collection of emails that are external to our organization, the response does not contain the requested sharing link for certain email addresses. When I look at the SharePoint site UI to see how the permissions are listed for the item, the email address with issue (RealEmail) shows up differently from the one that does return a sharing link through the API (TestEmail). Both RealEmail and TestEmail are marked as external users, but it seems that the RealEmail external user is recognized as an actual external or guest user account, rather than just being an email unknown to SharePoint, like TestEmail.
Here's the request I made on Microsoft Graph Explorer:
POST https://graph.microsoft.com/v1.0/sites/{site-id}/drives/{drive-id}/items/{item-id}/invite
{
"requireSignIn": true,
"sendInvitation": false,
"roles": [
"read"
],
"recipients": [
{
"email": "RealEmail#example.com"
},
{
"email": "TestEmail#example.com"
}
]
}
And this was the response (with real data removed):
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(permission)",
"value": [
{
"#odata.type": "#microsoft.graph.permission",
"id": "removed",
"roles": [
"read"
],
"grantedTo": {
"user": {
"email": "RealEmail#example.com",
"id": "removed",
"displayName": "RealFirstName RealLastName"
}
}
},
{
"#odata.type": "#microsoft.graph.permission",
"roles": [
"read"
],
"grantedToIdentities": [
{
"user": {
"email": "TestEmail#example.com"
}
}
],
"invitation": {
"signInRequired": true
},
"link": {
"type": "view",
"webUrl": "removed"
}
}
]
}
This is what the Manage Access UI looks like (with real data removed)
I try to setup an application insights alert to a webhook (MS Teams to be precise). I already successfully managed to create the alert and the data is already sent to the webhook and displayed in Teams.
This is a log-alert.
All I am now missing is the query-RESULT of that log-alert.
The documentation [https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-log-webhook#log-alert-with-a-custom-json-payload] simply states that I need to add a simple configuration-parameter into the payload:
"IncludeSearchResults":true
Which I did. But still no Json-Attachment (or anything else) to be seen containing the query result.
My complete payload (which works fine apart from the result-part) looks like this:
{
"#context": "http://schema.org/extensions",
"#type": "MessageCard",
"IncludeSearchResults":true,
"themeColor": "CC4216",
"title": "#alertrulename",
"text": "#alertrulename returned #searchresultcount records which exceeds the threshold of #thresholdvalue .",
"summary": "Query: #searchquery",
"potentialAction": [{
"#type": "OpenUri",
"name": "See details in AppInsights",
"targets": [{
"os": "default",
"uri": "#linktosearchresults"
}]
}],
"sections": [{
"facts": [{
"name": "Severity:",
"value": "#severity"
},
{
"name": "Query:",
"value": "#searchquery"
},
{
"name": "ResultCount:",
"value": "#searchresultcount"
},
{
"name": "Search Interval StartTime:",
"value": "#searchintervalstarttimeutc"
},
{
"name": "Search Interval End time:",
"value": "#searchintervalendtimeutc"
},
{
"name": "AppInsights Application ID:",
"value": "#applicationid"
}]
}]
}
What I want to achieve is that the "top 10 results" that are automatically added to any email-notification also be shown in Teams:
O365 connector card schema does not contain IncludeSearchResults property.
You will need to fetch the result and then bind the data to card.
Are you able to fetch the results?
I want to access archived stories on Instagram private api and list them.
I am using the endpoint below
https://i.instagram.com/api/v1/archive/reel/day_shells/
and response is
{
"items": [
{
"timestamp": 1603929700,
"media_count": 1,
"id": "archiveDay:18142006969109114",
"reel_type": "archive_day_reel",
"latest_reel_media": 1603966678
},
...
],
"num_results": 97,
"more_available": false,
"max_id": null,
"suggested_highlights": {
"unseen_count": 0,
"items": []
},
"status": "ok"
}
I sent a new response to get archieved story
https://i.instagram.com/api/v1/media/18142006969109114_1603966678/list_reel_media_viewer/
It's response is
{
"message": "Cannot access media viewer info",
"status": "fail"
}
What am i missing?
The solution is feed/reels_media
https://i.instagram.com/api/v1/feed/reels_media/?user_ids=highlight:18142006969109114
I am trying to integrate DialogFlow bot with Hangouts Chat (for G Suite). I have enabled the integration on DialogFlow and the basic intents are working fine.
In order to perform backend operations using fulfillment, I have created a firebase cloud function and added this as the webhook URL on DialogFlow fulfillment page.
I have written the cloud function code to identify the intent, and to generate the Webhook response format for a simple text response. This is working, and I am seeing the firestore data being modified in response to the intent.
However for a more complicated intent, I wish to use more of the dynamic card based response that Chat offers. In order to achieve this, I have looked at the documentation for dialogflow card response.
I saw this following code at https://cloud.google.com/dialogflow/docs/integrations/hangouts. When I paste this into the dialogflow intent editor UI under hangouts custom payload (after disabling webhook integration), it works
{
"hangouts": {
"header": {
"title": "Pizza Bot Customer Support",
"subtitle": "pizzabot#example.com",
"imageUrl": "..."
},
"sections": [{
"widgets": [{
"keyValue": {
"icon": "TRAIN",
"topLabel": "Order No.",
"content": "12345"
}
},
{
"keyValue": {
"topLabel": "Status",
"content": "In Delivery"
}
}]
},
{
"header": "Location",
"widgets": [{
"image": {
"imageUrl": "https://dummyimage.com/600x400/000/fff"
}
}]
},
{
"header": "Buttons - i could leave the header out",
"widgets": [{
"buttons": [{
"textButton": {
"text": "OPEN ORDER",
"onClick": {
"openLink": {
"url": "https://example.com/orders/..."
}
}
}
}]
}]
}]
}
}
This is exactly what I need, but I need this response from the webhook. I'm not getting the correct response format to map between the two.
When I try to integrate the same code with the webhook, I am not getting any reply on hangouts chat. When I check the history section on dialogflow UI, here is the response structure as mentioned in Raw interaction log
{
"queryText": "<redacted>",
"parameters": {},
"intent": {
"id": "<redacted>",
"displayName": "<redacted>",
"priority": 500000,
"webhookState": "WEBHOOK_STATE_ENABLED"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 284
},
"languageCode": "en",
"slotfillingMetadata": {
"allRequiredParamsPresent": true
},
"id": "<redacted>",
"sessionId": "<redacted>",
"timestamp": "2020-07-30T12:05:29.094Z",
"source": "agent",
"webhookStatus": {
"webhookUsed": true,
"webhookPayload": {
"hangouts": {
"header": {
"subtitle": "pizzabot#example.com",
"title": "Pizza Bot Customer Support",
"imageUrl": "..."
},
"sections": [
{
"widgets": [
{
"keyValue": {
"content": "12345",
"topLabel": "Order No.",
"icon": "TRAIN"
}
},
{
"keyValue": {
"topLabel": "Status",
"content": "In Delivery"
}
}
]
},
{
"widgets": [
{
"image": {
"imageUrl": "https://dummyimage.com/600x400/000/fff"
}
}
],
"header": "Location"
},
{
"widgets": [
{
"buttons": [
{
"textButton": {
"text": "OPEN ORDER",
"onClick": {
"openLink": {
"url": "https://example.com/orders/..."
}
}
}
}
]
}
],
"header": "Buttons - i could leave the header out"
}
]
}
},
"webhookStatus": {
"message": "Webhook execution successful"
}
},
"agentEnvironmentId": {
"agentId": "<redacted>",
"cloudProjectId": "<redacted>"
}
}
I also found this link on chat docs which explains how to show an interactive card based UI https://developers.google.com/hangouts/chat/how-tos/cards-onclick. However I'm not able to understand how to integrate the same with the webhook.
UPDATE
I have followed a tutorial at https://www.leeboonstra.com/Bots/custom-payloads-rich-cards-dialogflow/ and was able to get the card response to show up using the sample code they mention. It is using this deprecated library (https://github.com/dialogflow/dialogflow-fulfillment-nodejs). Here is the code for that to work,
let payload = new Payload("hangouts", json, {
rawPayload: true,
sendAsMessage: true,
});
agent.add(payload);
Here the json variable should be the previous JSON structure I have mentioned. So now, I'm able to map to the correct response format using the deprecated API. However, I'm not able to get the button to send the right response to the back end. Here is the buttons field that I modified from the previous json,
"buttons": [
{
"textButton": {
"text": "Click Me",
"onClick": {
"action": {
"actionMethodName": "snooze",
"parameters": [
{
"key": "time",
"value": "1 day"
},
{
"key": "id",
"value": "123456"
}
]
}
}
}
}
]
As far as I know, responding to a Google Chat (formerly Hangouts Chat) button isn't possible when using the direct Dialogflow integration.
The problem is that the button response can be sent one of two ways:
An event will be sent back to the bot code indicating the click.
Using the onClick.openLink.url property, as most of your test show.
This will take the person clicking it to the URL in question. But once there, you're taken out of the bot flow.
However, the documentation for the Hangouts Chat integration with Dialogflow doesn't provide any information about how this event is passed to Dialogflow, and the last time I tested it - it isn't.
You can write your own integration using Google Chat's API on something like Cloud Functions or Apps Script and have your script call Dialogflow's Detect Intent API to determine what Intent would be triggered by the user (and determine replies or call the webhook for additional processing). Under this scheme, you can choose how to handle the onClick event. Making your own integration also provides you a way to do Incoming Webhooks, which isn't possible when using the Dialogflow integration.
I am creating a Sign Up With Google+ API. When inserting data into my Users table, I want to get the user's email. I get an error when trying to do that. My code looks like this:
var API_KEY = 'A*****';
plus.people.get({
auth: API_KEY,
userId: req.body.userID
}, function (err, user) {
if( err ) { res.json( JSON.stringify( err ) ); return; }
console.log(user.emails);
User.find({ where:{ social_id:req.body.userID, type: 2 } }).then( existingUser =>{
if( existingUser ) throw new Error('social_user_existing');
if(!existingUser){
User.build({
username: user.displayName,
social_id : req.body.userID,
social_token :req.body.token,
type : 2
}).save();
}
}).then(function( new_g_user ){
return res.json( rs.success({ username: user.displayName, user_id: user.id, jwt: new_g_user.getJwt() }) );
}).catch(function(err){
res.json( rs.errorCode(err.message) );
});
});
I tried to get the email of the user with user.emails and user.emails[0].value to get at least the value of the first email. Each time, the response was 'undefined'. I mention that user.kind is 'plus#person', not "plus#personOpenIdConnect". Can this cause the response I get? Thank you!
You are authencating using an API key so that means that you will only have access to public data.
Request
GET https://www.googleapis.com/plus/v1/people/+lindalawton
response
{
"kind": "plus#person",
"etag": "\"Sh4n9u6EtD24TM0RmWv7jTXojqc/8CXX3KsOcUfAF5mmrG4vyB-YNig\"",
"occupation": "Google Developer Expert, BIA Developer at Targit",
"skills": "Experience primarily in regards Microsoft products, Visual Studio, Bids, C# and asp.net. Past experience with PHP,JavaScript, MySQL and Linux. In recent years I have begun focusing on Business Intelligence, Data Warehousing, SQL Server / Analysis Services / Integration Services. Experience with OAuth2, Google Analytics API, Google Drive SDK.",
"gender": "female",
"urls": [
{
"value": "http://www.youtube.com/user/Atthena71",
"type": "otherProfile",
"label": "Linda Lawton"
},
{
"value": "http://twitter.com/LindaLawtonDK",
"type": "otherProfile",
"label": "lindalawtondk"
},
{
"value": "http://stackoverflow.com/users/1841839/daimto",
"type": "otherProfile",
"label": "Stackoverflow / StackExchange"
},
{
"value": "http://www.linkedin.com/profile/edit?trk=nav_responsive_sub_nav_edit_profile",
"type": "otherProfile",
"label": "Linkedin"
},
{
"value": "http://daimto.com/",
"type": "contributor",
"label": "Daimto - data import tutorials"
},
{
"value": "https://github.com/LindaLawton",
"type": "contributor",
"label": "GitHub - projects"
},
{
"value": "https://github.com/google/google-api-dotnet-client",
"type": "contributor",
"label": "Google APIs .Net client - GitHub"
},
{
"value": "https://github.com/LindaLawton/Google-Dotnet-Samples",
"type": "contributor",
"label": "Google APIs .Net Samples - GitHub "
},
{
"value": "https://developers.google.com/analytics/",
"type": "other",
"label": "Google Analytics"
},
{
"value": "https://developers.google.com/",
"type": "other",
"label": "Google Developers"
},
{
"value": "https://developers.google.com/experts/+LindaLawton",
"type": "other",
"label": "Google Developer Expert - Linda Lawton"
}
],
"objectType": "person",
"id": "117200475532672775346",
"displayName": "Linda Lawton",
"name": {
"familyName": "Lawton",
"givenName": "Linda"
},
"tagline": "Google Developer Expert 2014 - 2017",
"braggingRights": "Extreme Beekeeper first to recorded an Hive inspection using Google Glass with out a veil on.",
"aboutMe": "\u003cdiv\u003e\u003cb\u003eBackground\u003c/b\u003e\u003c/div\u003e\u003cdiv\u003e\u003cdiv\u003eI have been working as an application developer since 1995. I have worked with a number of database systems Oracle, Microsoft SQL Server, and MySQL. In recent years I have been mainly working with Microsoft products, Visual Studio, SSIS, and C#. I the past I worked a lot with web development PHP, JavaScript, Ajax, power-builder, Cobol and ASP.net.\u003c/div\u003e\u003c/div\u003e\u003cdiv\u003e\u003cbr /\u003e\u003c/div\u003e\u003cdiv\u003eWhile I have done front end development in the past. I find working with backed development working on automated systems fascinating. I have spent the last 5 years creating custom SSIS (Dlls), and services and APIs for the cloud (Azure).\u003c/div\u003e\u003cdiv\u003e\u003cbr /\u003e\u003c/div\u003e\u003cdiv\u003e\u003cb\u003eGoogle API Addiction\u003c/b\u003e \u003c/div\u003e\u003cdiv\u003eIn 2012 I began working with the Google APIs, starting with the Google Analytics API. I learned to appreciate the fact that Google is so open and willing to give us access to their systems. I started blogging about how to use the APIs writing short tutorials with sample projects. \u003ca href=\"http://www.daimto.com/\" rel=\"nofollow\" target=\"_blank\"\u003eDaimto - Data Import Tutorials\u003c/a\u003e. This along with my presents on a number of \u003ca href=\"http://stackoverflow.com/users/1841839/daimto\" rel=\"nofollow\" target=\"_blank\"\u003eDeveloper forms\u003c/a\u003e lead me to discovered by Google. I became one of the first \u003ca href=\"https://developers.google.com/experts/+LindaLawton\" rel=\"nofollow\" target=\"_blank\"\u003eGoogle Developer Experts for Google Analytics\u003c/a\u003e. \u003c/div\u003e\u003cdiv\u003e\u003cbr /\u003e\u003c/div\u003e\u003cdiv\u003eI also help support the \u003ca href=\"https://github.com/google/google-api-dotnet-client\" rel=\"nofollow\" target=\"_blank\"\u003eGoogle APIs client Library for .NET\u003c/a\u003e which provides simple, flexible, and powerful access to Google APIs such as Drive, YouTube, Calendar, Storage and Analytics.\u003c/div\u003e\u003cdiv\u003e\u003cbr /\u003e\u003c/div\u003e\u003cdiv\u003e\u003cb\u003eLife\u003c/b\u003e\u003c/div\u003e\u003cdiv\u003eI grew up in a small town in \u003ca href=\"http://en.wikipedia.org/wiki/Dartmouth,_Massachusetts\" rel=\"nofollow\" target=\"_blank\"\u003eMassachusetts\u003c/a\u003e, USA, I moved to \u003ca href=\"http://en.wikipedia.org/wiki/Denmark\" rel=\"nofollow\" target=\"_blank\"\u003eDenmark \u003c/a\u003ein 1998 and have lived here since. I have a 22 year old daughter. My hobbies include reading science fiction, painting, and gardening. \u003c/div\u003e",
"url": "https://plus.google.com/+LindaLawton",
"image": {
"url": "https://lh5.googleusercontent.com/-a1CWlFnA5xE/AAAAAAAAAAI/AAAAAAAAdVM/sHkU9F-AwwQ/photo.jpg?sz=50",
"isDefault": false
},
"organizations": [
{
"name": "Newberry College",
"title": "computer science",
"type": "school",
"startDate": "1991",
"endDate": "1994",
"primary": false
},
{
"name": "TARGIT",
"title": "Business Intelligence Developer",
"type": "work",
"startDate": "2011",
"primary": true
},
{
"name": "Logimatic",
"title": "developer",
"type": "work",
"startDate": "2008",
"endDate": "2010",
"primary": false
}
],
"placesLived": [
{
"value": "Aalborg Denmark",
"primary": true
},
{
"value": "Marathon Florida"
},
{
"value": "Dartmouth Massachusetts"
},
{
"value": "Ashford Connecticut"
},
{
"value": "Nykøbing Mors Denmark"
}
],
"isPlusUser": true,
"circledByCount": 2006,
"verified": false,
"cover": {
"layout": "banner",
"coverPhoto": {
"url": "https://lh3.googleusercontent.com/t2ViXd7ar3MeiOCeTe2g86Qd7wOnbRvuf3eTW3LPrs8jwBJwKS6gsC4KWhvbRSytJ5fsDne3sw=s630-fcrop64=1,00000000ffffffff",
"height": 528,
"width": 940
},
"coverInfo": {
"topImageOffset": 0,
"leftImageOffset": 0
}
}
}
Is only going to return what said user has set to public. If their email is not public your not going to be able to see it.
As #DalmTo mentioned, the API keys can be used to access public data. If you want to get access to the user private information you have to use OAuth.
Use the OAuth2 class from googleapis to set up the authentication:
const google = require('googleapis');
const OAuth2 = google.auth.OAuth2;
const CREDENTIALS = require("./credentials.json");
var googleAuth = new OAuth2(
CREDENTIALS.web.client_id,
CREDENTIALS.web.client_secret,
CREDENTIALS.web.redirect_uris[0]
);
credentials.json is the file you can download from your Google app (the credentials section) which contains the application keys.
Once you get the access token, you need to do:
googleAuth.setCredentials({
access_token: yourAccessToken
});
And finally, instead of using auth: API_KEY you will do auth: googleAuth.
plus.people.get({
auth: googleAuth,
userId: req.body.userID
}, function (err, user) {
if( err ) { res.json( JSON.stringify( err ) ); return; }
console.log(user.emails);
});
If everything goes well, you should be able to get the private information from the user.
Note that to access the emails, you need the https://www.googleapis.com/auth/userinfo.email scope.
To get an access token for testing, you can use the OAuth playground:
Open https://developers.google.com/oauthplayground/
Enter the auth scopes you need, and then click the blue button:
It will make a couple of redirects.
In Step 2 click the blue button again to exchange the authorization code into access tokens.
And now, you will see in the right side of the screen your access_token:
{
"access_token": "ya29.G....OEDi",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "....hLA",
"id_token": ".....B1LGce02PMQHig"
}
You can use it for testing. When implementing OAuth2 in your app, you will need to set up the redirections, following the OAuth2 protocol rules.