Twilio Autopilot Custom and Dynamic on_failure message on validation failure - twilio

In Twilio Autopilot, I want to validate user input. In this case order_number.
Assume order_number can be anything between 8-12 characters. I have a webhook for validation.
I want to let the user know why the validation failed if they entered an order number that was lt 8 or gt 12 characters, or if the order_number doesn't exists in our db.
My webhook returns { valid: true } or { valid: false } based on success or failure of validation.
My goal is to customize my failure message based on what validation failed. Is there a seamless way to achieve that ?
{
collect: {
name: 'collect_order_number',
questions: [
{
question: 'Can I have your order number ?',
name: 'order_number',
type: 'Twilio.ALPHANUMERIC',
validate: {
on_failure: {
messages: [ # How to customize this based on webhook validation ?
{ say: 'Order number too short' },
{ say: 'Order number too long' },
{ say: 'Could not find order number' },
],
repeat_question: true,
},
webhook: {
url: `https://<www.domain.com>/autopilot/validate_field`,
method: 'POST',
},
on_success: {
say: 'Great! got your order number',
}
}
},
{ ... more questions }
]
}
}

Related

onlineMeetingUrl is coming null and onlineMeetingProvider is 'unknown' while creating event for a user by using graph api, Why?

I am using graph api to create events for almost 50 users and for all users when i am creating event with
isOnlineMeeting: true and onlineMeetingProvider: 'teamsForBusiness' keys in request body events are creating successfully and returning the response
endpoint I am calling is
axios.post(`https://graph.microsoft.com/v1.0/users/${userId}/calendar/events`,requestBody,options)
request body
requestBody = {
subject:MeetSubject,
start:{
dateTime:isoStart,
timezone:'UTC'
},
end:{
dateTime:isoEnd,
timezone:'UTC'
},
recurrence: recurrenceData,
attendees: [
{
emailAddress: {
address: attendeEmail,
name: attendeName,
},
type: 'required',
},
],
isOnlineMeeting: true,
onlineMeetingProvider: 'teamsForBusiness'
};
response
{
....
....
onlineMeetingProvider: 'teamsForBusiness',
onlineMeeting: {
joinUrl: 'https://teams.microsoft.com/l...../.
}
}
}
But for a perticular user when I am creating the event with simillar request body so event is created successfully but in the response event Object i am getting
response
{
....
....
onlineMeetingProvider: 'unknown',
onlineMeeting: null
}
why it is like that
is there something which i am missing for that perticular i don't know what
and app has those permissions already
TeamSettings.Read.All
TeamSettings.ReasWrite.All
OnlineMeetings.Read
OnlineMeetings.ReadWrite

How do I create a GraphQL appSubscriptionCreate mutation with the Ruby shopify_api gem?

When I copy the example below from https://help.shopify.com/en/api/guides/billing-api/implement-your-business-model#implement-the-appsu...:
appSubscriptionCreate(
name: "Super Duper Recurring Plan"
returnUrl: "http://super-duper.shopifyapps.com"
lineItems: [{
plan: {
appRecurringPricingDetails: {
price: { amount: 10.00, currencyCode: USD }
}
}
}]
) {
userErrors {
field
message
}
confirmationUrl
appSubscription {
id
}
}
}
and run it via the "Shopify GraphiQL App", the mutation is successfully created.
I am not sure how to do it with Ruby and the shopify_api gem though (note that I am new to Ruby as well as GraphQL, so it's probably something very basic I am missing, but I have not been able to find the answer anywhere).
I attempted the following:
##client = ShopifyAPI::GraphQL.new
PAYMENT_MUTATION = ##client.parse <<-'GRAPHQL'
{
mutation {
appSubscriptionCreate(
name: "Super Duper Recurring Plan"
returnUrl: "http://super-duper.shopifyapps.com"
lineItems: [{
plan: {
appRecurringPricingDetails: {
price: {
amount: 10.00,
currencyCode: USD
}
}
}
}]
) {
userErrors {
field
message
}
confirmationUrl
appSubscription {
id
}
}
}
}
GRAPHQL
def initialize
#result = ##client.query(PAYMENT_MUTATION)
end
def confirmationUrl
#result.data.appSubscriptionCreate.confirmationUrl
end
end
I get the following error though:
GraphQL::Client::ValidationError (Field 'mutation' doesn't exist on type 'QueryRoot'):
I tried skipping the mutation part, but then I just get the error:
GraphQL::Client::ValidationError (Field 'appSubscriptionCreate' doesn't exist on type 'QueryRoot'):
This led me to have a look at the GraphQL class of the shopify_api gem, hoping to find a "mutation" method to use instead of the "query" method, but there is none.
I cannot figure it out from the graphql-client gem that shopify_api is using either - there's no mutation examples in the readme.
What am I missing?
Thanks,
-Louise
Got the answer on the Shopify forum - I just have to remove the outer {} in PAYMENT_MUTATION.
PAYMENT_MUTATION = ##client.parse <<-'GRAPHQL'
mutation {
appSubscriptionCreate(
name: "Super Duper Recurring Plan"
returnUrl: "http://super-duper.shopifyapps.com"
lineItems: [{
plan: {
appRecurringPricingDetails: {
price: {
amount: 10.00,
currencyCode: USD
}
}
}
}]
) {
userErrors {
field
message
}
confirmationUrl
appSubscription {
id
}
}
}
GRAPHQL

Google Cloud Print Node API TICKET not working

This is my code and I am using npm node-gcp and sadly, the ticket is not working, I tried to make the copies = 3 to see if the printer will print 3 and to see if the ticket is working or not, But it's not working :(
I tried all the resources i can find, php ticket, c# ticket, But all are not working,
I am inside the code of npm node-gcp and I am trying to modify its code and see what will work and not, because the original code is he is not passing any ticket.
return preq({
method: "POST",
uri: "https://www.google.com/cloudprint/submit",
form: {
title: "Print job title",
content:
"test print",
ticket: {
version: "1.0",
print: {
copies: {
copies: 3
},
page_orientation: {
type: 0
},
margins: {
top_microns: 0,
bottom_microns: 0,
left_microns: 0,
right_microns: 0
}
}
},
contentType: "url", //optional, default = url
printerid: xxxxxxxxxxxxx,
tags: ["tag1", "tag2"] //optional, default = [],
},
headers: {
"X-CloudPrint-Proxy": "node-gcp",
Authorization: "OAuth " + this.options.accessToken
},
json: true
})
.then(function(result) {
return result;
})
.nodeify(cb);
});
i am expecting a response of number of pages is 3 but all I am getting is 1 piece of paper.
I just had to deal with this issue and discovered that ticket needs to be sent as a stringified json object.
For form, try this instead:
form: {
title: "Print job title",
content:
"test print",
ticket: JSON.stringify({
version: "1.0",
print: {
copies: {
copies: 3
},
page_orientation: {
type: 0
},
margins: {
top_microns: 0,
bottom_microns: 0,
left_microns: 0,
right_microns: 0
}
})
},

Combining results of two tables in mongoid/mongo

Hi guys what would be the best way to combine results of two mongoid queries.
My issue is that I would like to know active users, A user can send a letter and a notification, both are separate table and a user if he sends either the letter or the notification is considered active. What I want to know is how many active users were there per month.
right now what I can think of is doing this
Letter.collection.aggregate([
{ '$match': {}.merge(opts) },
{ '$sort': { 'created_at': 1 } },
{
'$group': {
_id: '$customer_id',
first_notif_sent: {
'$first': {
'day': { '$dayOfMonth': '$created_at' },
'month': { '$month': '$created_at' },
'year': { '$year': '$created_at' }
}
}
}
}])
Notification.collection.aggregate([
{ '$match': {}.merge(opts) },
{ '$sort': { 'created_at': 1 } },
{
'$group': {
_id: '$customer_id',
first_notif_sent: {
'$first': {
'day': { '$dayOfMonth': '$created_at' },
'month': { '$month': '$created_at' },
'year': { '$year': '$created_at' }
}
}
}
}])
What I am looking for is to get the minimum of the dates and then combine the results and get the count. Right now I can get the results and loop over each of them and create a new list. But I wanted to know if there is a way to do it in mongo directly.
EDIT
For letters
def self.get_active(tenant_id)
map = %{
function() {
emit(this.customer_id, new Date(this.created_at))
}
}
reduce = %{
function(key, values) {
return new Date(Math.min.apply(null, values))
}
}
where(tenant_id: tenant_id).map_reduce(map, reduce).out(reduce: "#{tenant_id}_letter_notification")
end
Notifications
def self.get_active(tenant_id)
map = %{
function() {
emit(this.customer_id, new Date(this.updated_at))
}
}
reduce = %{
function(key, values) {
return new Date(Math.min.apply(null, values))
}
}
where(tenant_id: tenant_id, transferred: true).map_reduce(map, reduce).out(reduce: "#{tenant_id}_outgoing_letter_standing_order_balance")
end
This is what I am thinking of going with, one of the reason is that, lookup does not work with my version of mongo.
the customer created a new notification, or a new letter, and I would like to get the first created at of either.
Let's address this first as a foundation. Given examples of document schema as below:
Document schema in Letter collection:
{ _id: <ObjectId>,
customer_id: <integer>,
created_at: <date> }
And, document schema in Notification collection:
{ _id: <ObjectId>,
customer_id: <integer>,
created_at: <date> }
You can utilise aggregation pipeline $lookup to join the two collections. For example using mongo shell :
db.letter.aggregate([
{"$group":{"_id":"$customer_id", tmp1:{"$max":"$created_at"}}},
{"$lookup":{from:"notification",
localField:"_id",
foreignField:"customer_id",
as:"notifications"}},
{"$project":{customer_id:"$_id",
_id:0,
latest_letter:"$tmp1",
latest_notification: {"$max":"$notifications.created_at"}}},
{"$addFields":{"latest":
{"$cond":[{"$gt":["$latest_letter", "$latest_notification"]},
"$latest_letter",
"$latest_notification"]}}},
{"$sort":{latest:-1}}
], {cursor:{batchSize:100}})
The output of the above aggregation pipeline is a list of customers in sorted order of created_at field from either Letter or Notification. Example output documents:
{
"customer_id": 0,
"latest_letter": ISODate("2017-12-19T07:00:08.818Z"),
"latest_notification": ISODate("2018-01-26T13:43:56.353Z"),
"latest": ISODate("2018-01-26T13:43:56.353Z")
},
{
"customer_id": 4,
"latest_letter": ISODate("2018-01-04T18:55:26.264Z"),
"latest_notification": ISODate("2018-01-25T02:05:19.035Z"),
"latest": ISODate("2018-01-25T02:05:19.035Z")
}, ...
What I want to know is how many active users were there per month
To achieve this, you can just replace the last stage ($sort) of the above aggregation pipeline with $group. For example:
db.letter.aggregate([
{"$group":{"_id":"$customer_id", tmp1:{$max:"$created_at"}}},
{"$lookup":{from:"notification",
localField:"_id",
foreignField:"customer_id",
as:"notifications"}},
{"$project":{customer_id:"$_id",
_id:0,
latest_letter:"$tmp1",
latest_notification: {"$max":"$notifications.created_at"}}},
{"$addFields":{"latest":
{"$cond":[{"$gt":["$latest_letter", "$latest_notification"]},
"$latest_letter",
"$latest_notification"]}}},
{"$group":{_id:{month:{"$month": "$latest"},
year:{"$year": "$latest"}},
active_users: {"$sum": "$customer_id"}
}
}
],{cursor:{batchSize:10}})
Where the example output would be as below:
{
"_id": {
"month": 10,
"year": 2017
},
"active_users": 9
},
{
"_id": {
"month": 1,
"year": 2018
},
"active_users": 18
},

Ant Design. How to set form field error message dynamically?

A form field has many asynchronous check rules, since a composited api can check these rules one time by return different result, i do not want to fire so many api request.
the syntax is updated in v4
new syntax is:
setFields. | Set fields status | (fields: FieldData[]) => void
example :
form.setFields([
{
name: 'field-to-update',
errors: ['error-string'],
},
]);
Use form.setFields
Syntax
Function({ fieldName: { value: any, errors: Error } })
Example from here -
this.props.form.setFields({
user: {
value: values.user,
errors: [new Error('forbid ha')],
},
});
When you need to add a custom error message just use validateStatus && help attributes.
For example, you've got an error as loginError (string) in your props:
<Form.Item
{ ...props.loginError && {
help: props.loginError,
validateStatus: 'error',
}}>
{getFieldDecorator('email', {
rules: [
{ required: true, message: 'You have to write the email' },
],
})(
<Input size="large"/>,
)}
</Form.Item>
form.setFields([
{
name: "email", // required
value: "myemail##gmail.com",//optional
errors: ["Invalid email"],
},
]);
I used it in v4.16.11

Resources