Algolia search within scope - algolia

I am trying to implement Algolia for a directory. I've created a huge index for listings with data like:
{
"id": 120,
"listing_type": "restaurant",
"location": "In example street, so so area",
"brand":{
"name": "Mc Donald's",
"image":"1130824.jpg",
"description": "Find fastest burgers and fries around. "
},
"neighbourhood":{
"name": "Downtown",
"city":{
"name": "Philadelphia",
"state": "PA"
}
},
"_tags":["burgers","fries","fast food","quick service"],
"has_deals": true,
"images":["file1.jpg","file2.jpg"],
...
}
I want to create separate pages for each city, and would like to restrict searches for that specific city. How can I achieve this?
I can find a parameter that can be added here:
var search = instantsearch({
// Replace with your own values
appId: 'xxxxxx',
apiKey: 'xxxx', // search only API key, no ADMIN key
indexName: 'listings',
urlSync: true,
searchParameters: {
hitsPerPage: 10
}
});

There are two ways to restrict a search, both based on the filters. For that you first need to add some single attribute you can filter on for the city to attributesForFaceting (in the settings, for example with the dashboard). In this case we can use neighbourhood.city.
Then in InstantSearch on your page you can add to searchParameters the value: filters: 'neighbourhood.city:Philadelphia'.
You can also use "secured API keys" to refine on this value before actually launching the page. This will prevent someone from taking that API key and searching themselves. Read more about that in the docs

Related

Strapi API Rest V 3.6.8 how to search posts by title?

I have installed version 3.6.8 of Strapi
In the docs for v3.x
https://strapi.gitee.io/documentation/v3.x/content-api/parameters.html#filter
Filters are used as a suffix of a field name:
No suffix or eq: Equals
ne: Not equals
lt: Less than
gt: Greater than
lte: Less than or equal to
gte: Greater than or equal to
in: Included in an array of values
nin: Isn't included in an array of values
contains: Contains
ncontains: Doesn't contain
containss: Contains case sensitive
ncontainss: Doesn't contain case sensitive
null: Is null/Is not null
And I can see those examples
GET /restaurants?_where[price_gte]=3
GET /restaurants?id_in=3&id_in=6&id_in=8
etc..
So I tried
/posts?_where[title_contains]=foo
/posts?title_contains=foo
And I also tried the "new way" in V4
/posts?filters[title][contains]=foo
But all of this attempts return all the post, exactly the same than just doing
/posts?
Any idea how to filter by post title and/or post body?
Almost there my friend! The issue you are facing called deep filtering (please follow the link for documentation).
In Short: the title field is located inside the attributes object for each item
Your items may look something similar to this:
{
"data": [
{
"id": 1,
"attributes": {
"title": "Restaurant A",
"description": "Restaurant A's description"
},
"meta": {
"availableLocales": []
}
},
{
"id": 2,
"attributes": {
"title": "Restaurant B",
"description": "Restaurant B's description"
},
"meta": {
"availableLocales": []
}
},
]
}
And therefor the filter should be
/api/posts?filters[attributes][title][$contains]=Restaurant
Also note:
the $ sign that should be included for your operator (in our case contains)
the api prefix you should use before the plural api id (e.g. posts, users, etc.)
you may prefer using $containsi operator in order to ignore upper and lower case letters (better for searching operations)
Let me know if it worked for you!

Turning the "Autocreate conversation" setting on via API

I'm attaching a picture here to make it more clear about what exactly I'm trying to do. I have sub-accounts under my account for which I purchase a number and that turn on "auto create conversation" setting for each of those subaccounts.
The way I do it from the Twilio Online GUI screeen is attached in the picture. However, I'd like to automate this using API. I haven't been able to do this exactly.
The closest thing I found was here. https://www.twilio.com/docs/conversations/api/address-configuration-resource
This hasn't worked for me.
Can someone suggest what I'm doing wrong?
Here are the steps I'm doing right now
Create a sub-account under main account
Purchase a number under sub-account
Attach the phone number to the default messaging service using the snippet below
await client.messaging.v1.services(service.sid)
.phoneNumbers
.create({
phoneNumberSid: activeNumberSid
});
Then create the addressConfiguration for this newly purchased number
as mentioned below
Address Configuration
client.conversations.v1.addressConfigurations
.create({
friendlyName: 'My Test Configuration',
'autoCreation.enabled': true,
'autoCreation.type': 'webhook',
'autoCreation.conversationServiceSid': 'ISXXXXXXXXXXXXXXXXXXXXXX',
'autoCreation.webhookUrl': 'https://example.com',
'autoCreation.webhookMethod': 'POST',
'autoCreation.webhookFilters': ['onParticipantAdded', 'onMessageAdded'],
type: 'sms',
address: '+37256123457'
})
.then(address_configuration => console.log(address_configuration.sid));
Here's the configuration of the default conversation service
I ran this code
async function _test() {
let service = await client.conversations.v1.services('IS4faafa8...').fetch();
console.log(JSON.stringify(service, null, 4));
}
to get this output (I have removed some characters from the ids for privacy reasons)
{
"accountSid": null,
"sid": "IS4faafa8.....",
"friendlyName": "Default Conversations Service",
"dateCreated": "2022-03-09T23:29:02.000Z",
"dateUpdated": "2022-07-20T17:49:19.000Z",
"url": "https://conversations.twilio.com/v1/Services/IS4faafa8.....",
"links": {
"users": "https://conversations.twilio.com/v1/Services/IS4faafa8...../Users",
"roles": "https://conversations.twilio.com/v1/Services/IS4faafa8...../Roles",
"participant_conversations": "https://conversations.twilio.com/v1/Services/IS4faafa8...../ParticipantConversations",
"conversations": "https://conversations.twilio.com/v1/Services/IS4faafa8...../Conversations",
"bindings": "https://conversations.twilio.com/v1/Services/IS4faafa8...../Bindings",
"configuration": "https://conversations.twilio.com/v1/Services/IS4faafa8...../Configuration"
}
}
Picture attached of the GUI Screen

Create Entities and training phrases for values in functions for google action

I have created a trivia game using the SDK, it takes user input and then compares it to a value in my DB to see if its correct.
At the moment, I am just passing a raw input variable through my conversation, this means that it regularly fails when it mishears the user since the exact string which was picked up is rarely == to the value in the DB.
Specifically I would like it to only pick up numbers, and for example realise that it must extract '10' , from a speech input of 'my answer is 10'.
{
"actions": [
{
"description": "Default Welcome Intent",
"name": "MAIN",
"fulfillment": {
"conversationName": "welcome"
},
"intent": {
"name": "actions.intent.MAIN"
}
},
{
"description": "response",
"name": "Raw input",
"fulfillment": {
"conversationName": "rawInput"
},
"intent": {
"name": "raw.input",
"parameters": [{
"name": "number",
"type": "org.schema.type.Number"
}],
"trigger": {
"queryPatterns":[
"$org.schema.type.Number:number is the answer",
"$org.schema.type.Number:number",
"My answer is $org.schema.type.Number:number"
]
}
}
}
],
"conversations": {
"welcome": {
"name": "welcome",
"url": "https://us-central1-triviagame",
"fulfillmentApiVersion": 2
},
"rawInput": {
"name": "rawInput",
"url": "https://us-central1-triviagame",
"fulfillmentApiVersion": 2
}
}
}
app.intent('actions.intent.MAIN', (conv) => {
conv.data.answers = answersArr;
conv.data.questions = questionsArr;
conv.data.counter = answersArr.length;
var thisQuestion = conv.data.questions;
conv.ask((conv.data.answers)[0]));
});
app.intent('raw.input', (conv, input) => {
if(input == ((conv.data.answers)[0])){
conv.ask(nextQuestion());
}
app.intent('actions.intent.TEXT', (conv,input) => {
//verifying if input and db value are equal
// at the moment input is equal to 'my number is 10' (for example) instead of '10'
//therefore the string verification never works
conv.ask(nextQuestion());
});
In a previous project i used the dialogflow UI and I used this #system.entities number parameter along with creating some training phrases so it understands different speech patterns.
This input parameter I am passing through my conv , is only a raw string where I'd like it to be filtered using some sort of entity schema.
How do I create the same effect of training phrases/entities using the JSON file?
You can't do this using just the Action SDK. You need a Natural Language Processing system (such as Dialogflow) to handle this as well. The Action SDK, by itself, will do speech-to-text, and will use the actions.json configuration to help shape how to interpret the text. But it will only return the entire text from the user - it will not try to determine how it might match an Intent, nor what parameters may exist in it.
To do that, you need an NLP/NLU system. You don't need to use Dialogflow, but you will need something that does the parsing. Trying to do it with simple pattern matching or regular expressions will lead to nightmares - find a good system to do it.
If you want to stick to things you can edit yourself, Dialogflow does allow you to download its configuration files (they're just JSON), edit them, and update or replace the configuration through the UI or an API.

MS Graph REST API checkout user

I've managed to successfully checkout a file using the https://graph.microsoft.com/beta/drives/{driveId}/items/{itemId}/checkout
Now, I'd like to get the information about the user, who actually perform the checkout operation.
It's possible to check if the item is locked:
https://graph.microsoft.com/beta/drives/{driveId}/items/{itemId}?select=*,publication
However, according to DOCs, publication doesn't provide information about the checked user. Without information who locked the file is the whole checkin/checkout logic is useless.
This kind of information could be retrieved via the metadata for an item in a list as demonstrated below:
https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items/{item-id}?expand=fields(select=CheckoutUserLookupId)
Once you get checkout user id (CheckoutUserLookupId field) , user details could be determined via the following endpoint:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists('User Information List')/items/{CheckoutUserLookupId}
where CheckoutUserLookupId is the user id from the previous request
https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items/{item-id} can't work with folders.
Anyway, drive endpoint "Allows access to the list as a drive" (according to MS Graph Docs). It works with folders as expected.
So I have
get the drive-id: /sites/${siteId}/drives
list root folder: /drives/{drive-id}/items/root/children?select=name,publication
if an item is locked, it's possible to list the activity on the item:
/drives/${idObj.driveId}/items/${idObj.fileId}?select=id&expand=activities
return list of actions:
"activities": [
{
"#odata.type": "#oneDrive.activityEntity",
"#odata.id": "https://xxxxxxxxxx/v2.0/oneDrive.activityEntity2a3649d6-2xxxxx",
"#odata.editLink": "oneDrive.activityEntity2a3649d6xxxxxx",
"#sharePoint.localizedRelativeTime": "0|July 30",
"action": {
"checkout": {}
},
"actor": {
"user": {
"email": "XXX#XXX",
"displayName": "vladimir",
"self": {},
"userPrincipalName": "XXX#XXX
}
},
"id": "XXXXXXXXXXXXXX",
"times": {
"recordedTime": "2018-07-31T04:59:03Z"
}
},
although no user ID at least a have the email....

Setting required action on new keycloak user account

I am using a client to create a new keycloak user. Something like this:
keycloak.realm(realm)
.users()
.create(user);
The user variable is a UserRepresentation object, and I'm trying to add an Update Password required action:
user.setRequiredActions(singletonList("Update Password"))
User gets created ok, the problem is that I don't have the required action set
Not sure what I'm doing wrong, should I specify a different value in the required actions list?
Thanks
Figured out what was up.
Keycloak has an enum to represent various user actions:
public static enum RequiredAction {
VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD, TERMS_AND_CONDITIONS
}
So the value should be "UPDATE_PASSWORD" not "Update password"
To find out all the possible required actions aliases, export your targeted realm as json from the admin interface. In the json you will find the "requiredActions" array in which all the legal actions are listed like so:
"requiredActions": [
{
"alias": "CONFIGURE_TOTP",
"name": "Configure OTP",
"providerId": "CONFIGURE_TOTP",
"enabled": true,
"defaultAction": false,
"priority": 10,
"config": {}
},
{
"alias": "terms_and_conditions",
"name": "Terms and Conditions",
"providerId": "terms_and_conditions",
"enabled": false,
"defaultAction": false,
"priority": 20,
"config": {}
},
Just use the string under the "alias" tag when setting the list of required actions in the code.
Now in Keycloak 8.x you can use
UserResource.toRepresentation().setRequiredActions(...);
to manually trigger an action like "verify email" after changing the loginname.