AWS CloudSearch cannot upload documents - amazon-web-services

I am new to AWS and CloudSearch. I have written a very simple app which is to upload docx document (already use cs-import-document to convert to JSON format) to my seach domain.
Code is very straightforward as this:
using (var searchdomainclient = new AmazonCloudSearchDomainClient("http://search-xxxxx-xysjxyuxjxjxyxj.ap-southeast-2.cloudsearch.amazonaws.com"))
{
// Test to upload doc
var uploaddocrequest = new UploadDocumentsRequest()
{
FilePath = #"c:\temp\testsearch.sdf", //docx to JSON already
ContentType = ContentType.ApplicationJson
};
var uploadresult = searchdomainclient.UploadDocuments(uploaddocrequest);
}
However the exception I got is: "Root element is missing."
Here is the JSON stuff in the sdf file I want to upload:
[{
"type": "add",
"id": "c:_temp_testsearch.docx",
"fields": {
"template": "Normal.dotm",
"application_name": "Microsoft Office Word",
"paragraph_count": "1",
"resourcename": "testsearch.docx",
"date": "2014-07-28T23:52:00Z",
"xmptpg_npages": "1",
"page_count": "1",
"publisher": "",
"creator": "John Smith",
"creation_date": "2014-07-28T23:52:00Z",
"content": "Test5",
"author": "John Smith",
"last_modified": "2014-07-29T04:22:00Z",
"revision_number": "3",
"line_count": "1",
"application_version": "15.0000",
"last_author": "John Smith",
"character_count": "5",
"character_count_with_spaces": "5",
"content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}
}]
So what's wrong with my approach?
Thanks heaps!
P.S. I can manually upload docx doc to that search doamin and use C# code to apply search.
============= Update 2014-08-04 ===================
I am not sure whether it is related to this or not. In the stack trace I found it tries to parse as XML file rather than JSON. But from my code I already set ContentType = JASON, but it seems no effect.
at System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo(String res)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at Amazon.Runtime.Internal.Transform.XmlUnmarshallerContext.Read()
at Amazon.Runtime.Internal.Transform.ErrorResponseUnmarshaller.Unmarshall(XmlUnmarshallerContext context)
at Amazon.Runtime.Internal.Transform.JsonErrorResponseUnmarshaller.Unmarshall(JsonUnmarshallerContext context)
at Amazon.CloudSearchDomain.Model.Internal.MarshallTransformations.UploadDocumentsResponseUnmarshaller.UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode)
at Amazon.Runtime.Internal.Transform.JsonResponseUnmarshaller.UnmarshallException(UnmarshallerContext input, Exception innerException, HttpStatusCode statusCode)
at Amazon.Runtime.AmazonWebServiceClient.HandleHttpWebErrorResponse(AsyncResult asyncResult, WebException we)
at Amazon.Runtime.AmazonWebServiceClient.getResponseCallback(IAsyncResult result)
at Amazon.Runtime.AmazonWebServiceClient.endOperation[T](IAsyncResult result)
at Amazon.CloudSearchDomain.AmazonCloudSearchDomainClient.EndUploadDocuments(IAsyncResult asyncResult)
at Amazon.CloudSearchDomain.AmazonCloudSearchDomainClient.UploadDocuments(UploadDocumentsRequest request)
at Amazon.CloudSearchDomain.Model.Internal.MarshallTransformations.UploadDocumentsResponseUnmarshaller.UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode)

Your document id contains invalid characters (period and colon). From https://aws.amazon.com/articles/8871401284621700 :
The ID must be unique across all of the documents you upload to the
domain and can contain the following characters: a-z (lowercase
letters), 0-9, and the underscore character (_). Document IDs must
start with a letter or number and can be up to 64 characters long.
It is also unclear what endpoint you're posting to but you may also have a problem there.

I had exactly the same exception with SDK version 2.2.2.0. When I had updated SDK to version 2.2.2.1 exception went away.

Related

How to get list of meaningful name upon fetching minted NFTs list from Alchemy Api?

I am new to block chain and I am using Alchemy and my NFTs and NFT Meta Data is on "Pinata". When I fetch my minted NFTs from Alchemy API, in response I get list of "contract addresses" and "Token Ids". Is there any way to get list of meaningful names of my minted NFTs instead of ids (without using loops). OR is there a way to store a meaningful name upon minting . Any help will be appreciated.
response upon calling API :
{"balance": "1", "contract": {"address": "0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}, "id": {"tokenId": "0x0000000000000000000000000000000000000000000000000000000000000000"}}]```
Is there any way to get list of meaningful names of my minted NFTs instead of ids (without using loops).
Yes! As of July 12th, 2022 (current time) -- the getNFTs endpoint includes a withMetadata query param option that defaults to true (see docs).
That means that the response should include the info you might want, including:
title: name of the NFT asset
description: brief human-readable description
media.gateway: public gateway uri for the raw asset
etc.
See full documentation here: https://docs.alchemy.com/alchemy/enhanced-apis/nft-api/getnfts
An example response might look like this:
{
"ownedNfts": [
{
"contract": {
"address": "0x0beed7099af7514ccedf642cfea435731176fb02"
},
"id": {
"tokenId": "28",
"tokenMetadata": {
"tokenType": "ERC721"
}
},
"title": "DuskBreaker #28",
"description": "Breakers have the honor of serving humanity through their work on The Dusk. They are part of a select squad of 10,000 recruits who spend their days exploring a mysterious alien spaceship filled with friends, foes, and otherworldly technology.",
"tokenUri": {
"raw": "https://duskbreakers.gg/api/breakers/28",
"gateway": "https://duskbreakers.gg/api/breakers/28"
},
"media": [
{
"raw": "https://duskbreakers.gg/breaker_images/28.png",
"gateway": "https://duskbreakers.gg/breaker_images/28.png"
}
],
"metadata": {
...
}
},
...
]
...
}
You should then be able to do something like this to get your names:
const names = ownedNfts.map((nft) => nft.title};
Use the getNFTMetadata method to get information on each NFT.

How do I extract a string of numbers from random text in Power Automate?

I am setting up a flow to organize and save emails as PDF in a Dropbox folder. The first email that will arrive includes a 10 digit identification number which I extract along with an address. My flow creates a folder in Dropbox named in this format: 2023568684 : 123 Main St. Over a few weeks, additional emails arrive that I need to put into that folder. The subject always has a 10 digit number in it. I was building around each email and using functions like split, first, last, etc. to isolate the 10 digits ID. The problem is that there is no consistency in the subjects or bodies of the messages to be able to easily find the ID with that method. I ended up starting to build around each email format individually but there are way too many, not to mention the possibility of new senders or format changes.
My idea is to use List files in folder when a new message arrives which will create an array that I can filter to find the folder ID the message needs to be saved to. I know there is a limitation on this because of the 20 file limit but that is a different topic and question.
For now, how do I find a random 10 digit number in a randomly formatted email subject line so I can use it with the filter function?
For this requirement, you really need regex and at present, PowerAutomate doesn't support the use of regex expressions but the good news is that it looks like it's coming ...
https://powerusers.microsoft.com/t5/Power-Automate-Ideas/Support-for-regex-either-in-conditions-or-as-an-action-with/idi-p/24768
There is a connector but it looks like it's not free ...
https://plumsail.com/actions/request-free-license
To get around it for now, my suggestion would be to create a function app in Azure and let it do the work. This may not be your cup of tea but it will work.
I created a .NET (C#) function with the following code (straight in the portal) ...
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string strToSearch = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String((string)data?.Text));
string regularExpression = data?.Pattern;
var matches = System.Text.RegularExpressions.Regex.Matches(strToSearch, regularExpression);
var responseString = JsonConvert.SerializeObject(matches, new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
return new ContentResult()
{
ContentType = "application/json",
Content = responseString
};
}
Then in PowerAutomate, call the HTTP action passing in a base64 encoded string of the content you want to search ...
The is the expression in the JSON ... base64(variables('String to Search')) ... and this is the json you need to pass in ...
{
"Text": "#{base64(variables('String to Search'))}",
"Pattern": "[0-9]{10}"
}
This is an example of the response ...
[
{
"Groups": {},
"Success": true,
"Name": "0",
"Captures": [],
"Index": 33,
"Length": 10,
"Value": "2023568684"
},
{
"Groups": {},
"Success": true,
"Name": "0",
"Captures": [],
"Index": 98,
"Length": 10,
"Value": "8384468684"
}
]
Next, add a Parse JSON action and use this schema ...
{
"type": "array",
"items": {
"type": "object",
"properties": {
"Groups": {
"type": "object",
"properties": {}
},
"Success": {
"type": "boolean"
},
"Name": {
"type": "string"
},
"Captures": {
"type": "array"
},
"Index": {
"type": "integer"
},
"Length": {
"type": "integer"
},
"Value": {
"type": "string"
}
},
"required": [
"Groups",
"Success",
"Name",
"Captures",
"Index",
"Length",
"Value"
]
}
}
Finally, extract the first value that you find which matches the regex pattern. It returns multiple results if found so if you need to, you can do something with those.
This is the expression ... #{first(body('Parse_JSON'))?['value']}
From this string ...
We're going to search for string 2023568684 within this text and we're also going to try and find 8384468684, this should work.
... this is the result ...
Don't have a Premium PowerAutomate licence so can't use the HTTP action?
You can do this exact same thing using the LogicApps service in Azure. It's the same engine with some slight differences re: connectors and behaviour.
Instead of the HTTP, use the Azure Functions action.
In relation to your action to fire when an email is received, in LogicApps, it will poll every x seconds/minutes/hours/etc. rather than fire on event. I'm not 100% sure which email connector you're using but it should exist.
Dropbox connectors exist, that's no problem.
You can export your PowerAutomate flow into a LogicApps format so you don't have to start from scratch.
https://learn.microsoft.com/en-us/azure/logic-apps/export-from-microsoft-flow-logic-app-template
If you're concerned about cost, don't be. Just make sure you use the consumption plan. Costs only really rack up for these services when the apps run for minutes at a time on a regular basis. Just keep an eye on it for your own mental health.
TO get the function URL, you can find it in the function itself. You have to be in the function ...

how to get facebook page creation date using facebook api

my try : https://graph.facebook.com/v12.0/{mypageid}?fields={fieldname_of_type_PageStartDate}
Could not get any response when using this api and i am also confused about {fieldname_of_type_PageStartDate} parameter value. i tried day,month,year value according to https://developers.facebook.com/docs/graph-api/reference/page-start-date/ this fb website but it didn't work.
please suggest any way to get facenook page creation date using api.
The documentation is a bit misleading, because what that page does not tell you on its own, is that those fields are part of the start_info property of the page - so you have to query that one.
https://graph.facebook.com/v12.0/pageid?fields=start_info
This will give you a structure of the following format:
"data": [
{
"name": "...",
"start_info": {
"type": "Started",
"date": {
"year": 2021,
"month": 11,
"day": 29
}
},
"id": "1234567890"
},
Not all sub-fields will always be set; you might for example encounter types Founded with only a year set, or Unspecified with no date info at all.
Note that this is not the actual page creation date; but the "start date" of the entity represented by the page. So it must be explicitly set in the page settings, otherwise this field will be empty.

Facebook Graph Api publishing to feed returns: "(#100) Param place must be a valid place tag ID"

I am searching at Facebook Graph Api, using graph api explorer, for some place using the following endpoint:
/search?type=place&q=centauro&fields=id,name,link
I am getting this as response:
"data": [
{
"id": "492103517849553",
"name": "Centauro",
"link": "https://www.facebook.com/Centauro-492103484516223/"
},
{
"id": "313439499156253",
"name": "Centauro",
"link": "https://www.facebook.com/Centauro-313439462489590/"
},
{
"id": "175812113006221",
"name": "Centauro",
"link": "https://www.facebook.com/Centauro-175812079672891/"
},
{
"id": "1423220914594882",
"name": "Centauro",
"link": "https://www.facebook.com/pages/Centauro/1423220891261551"
},...
When I try to publish using the field "id" returned:
/me/feed
with fields:
message: Testing
place: 492103517849553
I get the following reponse:
{
"error": {
"message": "(#100) Param place must be a valid place tag ID",
"type": "OAuthException",
"code": 100,
"fbtrace_id": "DfEKOjZX8g+"
}
}
But if I use de final number of the link:
"link": "https://www.facebook.com/Centauro-492103484516223/"
492103484516223
And try again:
/me/feed
with fields:
message: Testing
place: 492103484516223
It works perfectly.
So, is there a way to get te correct place id for publishing? Or is it a bug?
I was also getting the “(#100) Param place must be a valid place tag ID” error, but got it to go away by providing a JSON string within the 'place' element.
So where the content of your request was this:
place: 492103484516223
Format the place information like this instead:
place: {"id": "492103484516223"}
Currently, this is how you can solve it.
import requests
IG_USER_ID = <YOUR INSTAGRAM USER ID>
USER_ACCESS = <YOUR USER ACCESS TOKEN WITH VALID PERMISSIONS>
CONTAINER1_ID = <ID OF FIRST CONTAINER>
CONTAINER2_ID = <ID OF SECOND CONTAINER>
URL = f"https://graph.facebook.com/v13.0/{IG_USER_ID}/media?caption=Fruit%20candies&media_type=CAROUSEL&children={CONTAINER1_ID}%2C{CONTAINER2_ID}&access_token={USER_ACCESS}"
r = requests.post(URL)

Facebook Graph Api Get tagged comments

I am trying to gather information about the number of comments from a facebook past that include a tag to a user, i.e. when you type #Joe Bloggs.
I know you can get all comments by either getting using the Comments edge for a post v2.8/[Postid]/comments or by the comment id directly v2.8/[comment-id]
But the message field that is returned is plain text and includes no indication of tags. e.g. something like:
{
"created_time": "2017-02-28T09:31:08+0000",
"from": {
"name": "Fred Bloggs",
"id": "123"
},
"message": "Joe Bloggs look at this",
"id": "1234"
}
Is it possible to get this somehow?
You need to include the field message_tags in your request. It will give you an array of profiles tagged in this comment.