Kustomer API, how to add attachment in Conversation - c#

I am using Kustomer API, I have successfully created the attachment, but I am not able to add the attachment in the Conversation. I'm not able to find any API documentation about how to add in the conversation.
https://apidocs.kustomer.com/?version=latest
Can you guys please help me?
Thanks.

When you create a message with the Kustomer API you would include the attachment ID of the attachment you created in the attachments array on the message object.
You need to send a Patch request to the message you want to add this attachment to. Attachments are added to messages, not Conversations.
The attachment you created would look something like this:
"data": {
"id": "5ec42bbad47d84001a0dd107",
"type": "attachment",
"attributes": {
"name": "testing.png",
"contentType": "image/png",
"contentLength": 1282,
"redacted": false,
"uploaded": false,
"createdAt": "2020-05-19T18:55:54.390Z",
"updatedAt": "2020-05-19T18:55:54.390Z",
"context": "attachment"
},
"relationships": {
"org": {
"data": {
"id": "5e664db1c9639a0019c67fd0",
"type": "org"
},
"links": {
"self": "/v1/orgs/5e664db1c9639a0019c67fd0"
}
}
},
"links": {
"self": "/v1/attachments/5ec42bbad47d84001a0dd107"
}
},
"meta": {
"provider": "s3",
"upload": {
"url": "https://s3.amazonaws.com/kustomer-prod1-attachments",
"fields": {
"key": "attachments/5e664db1c9639a0019c67fd0/5ec42bbad47d84001a0dd107-testing.png",
"acl": "private",
"Content-Type": "image/png",
"X-Amz-Meta-Attachment-Id": "5ec42bbad47d84001a0dd107",
"bucket": "kustomer-prod1-attachments",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "AKIAIIKHW25JWTRL7R7Q/20200519/us-east-1/s3/aws4_request",
"X-Amz-Date": "20200519T185554Z",
"Policy": "eyJleHBpcmF0aW9uIjoiMjAyMC0wNS0xOVQxOToyNTo1NFoiLCJjb25kaXRpb25zIjpbWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsMTI4MiwxMjgyXSx7ImtleSI6ImF0dGFjaG1lbnRzLzVlNjY0ZGIxYzk2MzlhMDAxOWM2N2ZkMC81ZWM0MmJiYWQ0N2Q4NDAwMWEwZGQxMDctdGVzdGluZy5wbmcifSx7ImFjbCI6InByaXZhdGUifSx7IkNvbnRlbnQtVHlwZSI6ImltYWdlL3BuZyJ9LHsiWC1BbXotTWV0YS1BdHRhY2htZW50LUlkIjoiNWVjNDJiYmFkNDdkODQwMDFhMGRkMTA3In0seyJidWNrZXQiOiJrdXN0b21lci1wcm9kMS1hdHRhY2htZW50cyJ9LHsiWC1BbXotQWxnb3JpdGhtIjoiQVdTNC1ITUFDLVNIQTI1NiJ9LHsiWC1BbXotQ3JlZGVudGlhbCI6IkFLSUFJSUtIVzI1SldUUkw3UjdRLzIwMjAwNTE5L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QifSx7IlgtQW16LURhdGUiOiIyMDIwMDUxOVQxODU1NTRaIn1dfQ==",
"X-Amz-Signature": "f00ce41d04f3c962f68ac6f4f096b8054cb81183ab9dbc0e5dd795d12e0239dc"
}
}
}
You would need send another POST request to the meta.upload.url you found in your response form the attachment you created. Per the API documents this will need to include all of the meta.upload.fileds information in this POST request. Once you did that the attachement would have been uploaded. To add this to a message you would need to send a PATCH request to the message API end point.
https://api.kustomerapp.com/v1/messages/:id
https://apidocs.kustomer.com/?version=latest#959920e4-17ff-458d-af90-5458297f2148
You would add your attachment id in the attachments object on the message object.
"attachments": {
"links": {
"self": "/v1/messages/5ec15c3fb2f51f0019ebee09/attachments"
},
"data": [
{
"type": "attachment",
"id": "5ec15c71d120a7001ad1c14b"
}
]
}
I wanted to make an update here: The payload of the Patch request to the message would look like this:
{
"attachments":[
{
"_id": "5ec15c71d120a7001ad1c14b",
"name": "Yass.png",
"contentType": "image/png",
"contentLength": 11288
}
]
}
This would be for adding an attachment to an existing message. If you want to add an attachment to a message that has not yet been sent you would have to create a draft message and send a POST request to add the attachment to that draft. /v1/drafts/{id}/attachments
There would be two things you need to do here
pass a sourceId in the body that is the ID of the original attachment
I think in the request URL include a query param that says ?method=post
If you have further questions please reach out to the support#kustomer.com email and we would be happy to assist you.

Related

Actions on Google smart home project can't parse QUERY response

I have the following problem. When I turn on/off my bulb in Google Home app it sends me EXECUTE request and then QUERY request for state check. That behaviour is okay, but the problem is that Actions on Google project can't parse my QUERY response.
For clarification: I don't have problems with C# JSON parsing and any of similar topics. I have problem with that the Actions on Google can't understand my QUERY response. I reponse in correct format according to Google's docs but in the web console I see that error occurs and I don't know what is wrong.
It shows following error in the Google Cloud Console:
{
"insertId": "166g06lg15lgekt",
"jsonPayload": {
"executionLog": {
"executionResults": [
{
"actionResults": [
{
"action": {
"actionType": "STATE_QUERY"
},
"device": {
"deviceType": "OUTLET"
},
"status": {
"externalDebugString": "JSON payload not an object.",
"isSuccess": false,
"statusType": "PARTNER_RESPONSE_INVALID_PAYLOAD"
}
}
],
"executionType": "PARTNER_CLOUD",
"latencyMsec": "191",
"requestId": "4734217757620110233"
}
]
},
"locale": "en-US"
},
"logName": "projects/smartlightproject-f47f4/logs/assistant_smarthome%2Fassistant_smarthome_logs",
"receiveTimestamp": "2022-07-13T13:23:04.088211105Z",
"resource": {
"labels": {
"project_id": "smartlightproject-f47f4"
},
"type": "assistant_action_project"
},
"severity": "ERROR",
"timestamp": "2022-07-13T13:23:04.088211105Z"
}
QUERY request which I receive is
{
"inputs": [
{
"intent": "action.devices.QUERY",
"payload": {
"devices": [
{
"customData": {
"barValue": true,
"bazValue": "foo",
"fooValue": 74
},
"id": "123"
}
]
}
}
],
"requestId": "5460596871498683621"
}
And my response to that QUERY request is
{
"requestId": "5460596871498683621",
"payload": {
"devices": {
"123": {
"on": true,
"online": true
}
}
}
}
I think that everything is as Google wants to in documentation but I can't find the solution nor cause of that issue. I appreciate your help, really.
If it matters I write my local fulfillment in ASP.NET.
That's how I send the QUERY response
var queryObj = JsonConvert.DeserializeObject<dynamic>("{\"requestId\":\"" + requestId + "\",\"payload\":{\"devices\":{\"123\":{\"on\":true,\"online\":true}}}}");
_logger.LogInformation("Odpowiedź na żądanie QUERY." + originalRequest + "\n\n" + JsonConvert.SerializeObject((object)queryObj));
return Ok((object)queryObj);

Sending email with Azure logic app after triggering via httpRequest

I've a azure logic app which contains two operations.
When a httpRequest is received.
Send email (v2)
I'm trying to send an email with the content of "task" when triggered by the httpRequest.
HttpRequest body json schema:
"properties": {
"due": {
"type": "string"
},
"email": {
"type": "string"
},
"task": {
"type": "string"
}
},
"type": "object"
}
I've added the "task" object from the dynamic content in the body of the email. I want the body of the email to contain the content of the "task" sent in the httpRequest.
Below is how I'm sending the httpRequest with the required json data. However, the email is always empty with no body. I must be doing something wrong. Any pointers would be appreciated.
await client.PostAsync(
logicAppUrl, new StringContent(jsonData, Encoding.UTF8, "application/json"));
jsonData content:
{"email":"test#gmail.com","due":"4/1/2020","task":"content1-------------"}
You can debug with Postman what your json should look like. It seems that you 1) either forgot to include the curly braces in your string or 2) forgot to escape your double quotes in the string. It should look like
string jsondata = "{ \"email\": \"test#gmail.com\", \"due\": \"4/1/2020\", \"task\": \"content1-------------\"}"
EDIT:
If the json doesn't match, go to the logic app's HTTP task, click Use sample payload to generate schema and copy your json into it. In your case, it should be
{
"type": "object",
"properties": {
"email": {
"type": "string"
},
"due": {
"type": "string"
},
"task": {
"type": "string"
}
}
}

Google action doesn't provide user.profile.payload object after successful account linking

I followed this guide in order to create account linking in my app
https://developers.google.com/actions/identity/google-sign-in#json
I'm able to verify the user's jwt decoder and send back a response that the user is authorised. Then, according to the guide, in the next request, I should get the user's profile payload (user.profile.payload in the json structure) but It's missing from the next request. More than that, I get the tokenId for jwt verification again.
I think that what i miss here is in the possibleIntent object but I'm not sure, as I didn't see any documentation for that, because I work with asp.net server. There are SDKs with documentation for java and nodeJS only
this is the request provided for the sign in the contain the tokenId
{
"user": {
"locale": "en-US",
"lastSeen": "2019-07-11T14:18:10Z",
"idToken": "<tokenId>",
"userVerificationStatus": "VERIFIED"
},
"conversation": {
"conversationId": "ABwppHH9uZfcKj6pS6A6wItKC1dOXuZJ5oFYt2Og7cqrElSQYC9bv-aV7iQ5FDYaJPp-fa7tQNhc2yS0fw3QBu-M",
"type": "ACTIVE",
"conversationToken": "e0e78f40-a207-49c2-9050-50c6ed526c24"
},
"inputs": [
{
"intent": "actions.intent.SIGN_IN",
"rawInputs": [
{
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"name": "SIGN_IN",
"extension": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "OK"
}
},
{
"name": "text"
}
]
}
],
"surface": {
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.ACCOUNT_LINKING"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
},
"isInSandbox": true,
"requestType": "SIMULATOR"
}
this is the response that i provide after verifying the user.
I tried it with both intents actions.intent.TEXT and actions.intent.SIGN_IN but with no success. the next request is provided with the user.idToken property again instead of the user.profile (that should contain the payload)
{
"conversationToken": "b09d915e-6df9-496d-acde-b76858cd95b4",
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Hi",
"displayText": "Hi"
}
}
],
"suggestions": []
}
},
"possibleIntents": [
{
"intent": "actions.intent.TEXT",
"inputValueData": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "OK"
}
}
]
}
]
}
The user.profile attribute you're talking about is something that is provided via the actions-on-google library for JavaScript. It isn't in the JSON that you will receive. But...
You don't need it because the basic profile information (name, email, and Google ID) is encoded in the user.idToken. That string, which will be sent to you for every request, is just a JWT token which you can verify and decode. The profile will be in the "payload" section.
I don't know c#, but https://jwt.io/ contains a list of libraries which can decode the JWT string for you so you can read the "payload".
Keep in mind that you don't need to verify the token each time (although if you do it right, this shouldn't be expensive), but that you can decode it to get the information that you're looking for.
If you don't want to decode it, you can decode it when you first verify it, get the information you need, and store that information in the userStorage string (assuming you don't expect it to change).

Autodesk Forge: Download checklist attachment

When I retrieve a checklist instance, I got the following section related to attachment.
{
"type": "instance_item_attachments",
"id": "5a0a2acf-b02a-4b88-86cc-962c3831bdee",
"attributes": {
"name": "6856ad10-6ab0-11e9-9150-9fda3da0626e.png",
"attachmentType": "OSS",
"mimeType": "image/png",
"uploadStatus": "COMPLETED",
"urns": [
{
"urn": "urn:adsk.wipprod:fs.file:vf.gy4mB910SneymU86Gc4O0A?version=1",
"type": "WIP"
},
{
"urn": "urn:adsk.objects:os.object:wip.dm.prod/ede3de59-1b68-485c-82fe-f1f2af3442fe.png",
"type": "OSS"
},
{
"urn": "urn:adsk.checklists.cs.attachment:58b8afcf-d7cd-49ad-aa10-78c50610761b/5a0a2acf-b02a-4b88-86cc-962c3831bdee",
"type": "CHECKLIST"
}
],
"createdAt": "2019-04-29T18:55:51.334Z",
"updatedAt": "2019-04-29T18:55:54.137Z",
"createdBy": "TAKCJQU6HGXW",
"modifiedBy": "TAKCJQU6HGXW",
"permittedActions": [
"canArchive",
"canEdit"
],
"permittedAttributes": [
"mimeType",
"uploadStatus"
]
},
"links": {
"self": "/containers/58b8afcf-d7cd-49ad-aa10-78c50610761b/instance_item_attachments/5a0a2acf-b02a-4b88-86cc-962c3831bdee"
},
"relationships": {
"container": {
"meta": {
"relation": "primary",
"readOnly": false
},
"links": {
"self": "/containers/58b8afcf-d7cd-49ad-aa10-78c50610761b/instance_item_attachments/5a0a2acf-b02a-4b88-86cc-962c3831bdee/relationships/container",
"related": "/containers/58b8afcf-d7cd-49ad-aa10-78c50610761b/instance_item_attachments/5a0a2acf-b02a-4b88-86cc-962c3831bdee/container"
},
"data": {
"type": "containers",
"id": "58b8afcf-d7cd-49ad-aa10-78c50610761b"
}
},
"item": {
"meta": {
"relation": "primary",
"readOnly": false
},
"links": {
"self": "/containers/58b8afcf-d7cd-49ad-aa10-78c50610761b/instance_item_attachments/5a0a2acf-b02a-4b88-86cc-962c3831bdee/relationships/item",
"related": "/containers/58b8afcf-d7cd-49ad-aa10-78c50610761b/instance_item_attachments/5a0a2acf-b02a-4b88-86cc-962c3831bdee/item"
},
"data": null
}
}
}
Now, I want to download this attachment, the provided URN is: wip.dm.prod/ede3de59-1b68-485c-82fe-f1f2af3442fe.png
If I try to access it using the following link, it says not found
developer.api.autodesk.com/oss/v2/buckets/wip.dm.prod/b30e3ffe-333b-446c-b834-e2f2141096b4.png
However, if I changed the URL a bit (by adding objects), it works fine.
developer.api.autodesk.com/oss/v2/buckets/wip.dm.prod/objects/b30e3ffe-333b-446c-b834-e2f2141096b4.png
Am I doing something wrong here? or this is a bug in the provided urn?
Adding to Adam Nagy reply, you would need to break the URN. From your original question:
urn:adsk.objects:os.object:wip.dm.prod/ede3de59-1b68-485c-82fe-f1f2af3442fe.png
In .NET you can try (using System.Linq):
string bucketKey = urn.Split("/").First().Split(":").Last();
string objectName = urn.Split("/").Last();
Then rebuild as:
string attachemtnUrl = string.Format("{0}/oss/v2/buckets/{1}/objects/{2}", BASE_URL, bucketKey, objectName);
And you'll also need the Authorization header with a valid access token.
The id / urn of an object in OSS (Object Storage Service) contains the bucket name and object name after the "urn:adsk.objects:os.object:" section.
There is a tutorial on downloading a file https://forge.autodesk.com/en/docs/data/v2/tutorials/download-file/
It shows that the reply concerning an item contains both the id and the actual URL of the download link under the storage section:
"storage": {
"data": {
"type": "objects",
"id": "urn:adsk.objects:os.object:wip.dm.prod/977d69b1-43e7-40fa-8ece-6ec4602892f3.rvt"
},
"meta": {
"link": {
"href": "https://developer.api.autodesk.com/oss/v2/buckets/wip.dm.prod/objects/977d69b1-43e7-40fa-8ece-6ec4602892f3.rvt"
}
}
}
There you can see the connection between the id and the URL you can use to download the file

Get all information about Facebook posts including reactions

I'm having a problem with the URL of the Facebook Graph API. Is there any possibility to get all the fields of a Facebook post including reactions? I use the following URL for the posts:
https://graph.facebook.com/{pageName}/feed?access_token={access_token}
Now I'm getting data like this (which is quite nice):
{
"data": [
{
"id": "someId",
"from": {
"Name": "Page name",
"category": "Sports Team",
"id": "someId"
},
"message": "Hello world!",
[...]
"shares": {
"count": 1
},
"likes": {
"data": [
{
"id": "someId",
"name": "Some person"
}
]
}
},
[...]
]
}
As for now I have to get the reactions (LOVE, WOW, HAHA, SAD, ANGRY and THANKFUL) by downloading the json from the following URL for every single post (and this is very time consuming):
https://graph.facebook.com/v2.9/{postId}?access_token={access_token}&fields=reactions
The only problem is that I can't get the reactions when using the "normal" URL (without &fields). Is there any chance to get all information including reactions without having to add all the fields to &fields=from,message,likes,shares,reactions?
From CBroe's comment:
I had to pass all the fields I wanted to save to my DB in my URL:
https://graph.facebook.com/v2.9/{pageName}/feed?access_token={access_token}&fields=id,from,message,name,[...],likes,comments,reactions,shares

Categories

Resources