Gupshup consume post to create Embedding form - facebook

im working with Gupshup and I want to add subview in my chat.
To make this I create this vars:
var url="https://api.gupshup.io/sm/api/facebook/smartmsg/form/create";
var header = {"apikey":"xxxxxxxxxxxxxxxxxxx","Content-Type": "application/x-www-form-urlencoded","Accept":"application/json"};
var param={"formJSON":{
"title": "This is a test.",
"autoClose": false,
"message": "Thank You",
"callback-url": "https://www.gupshup.io/developer/bot/Cotizador/public",
"fields": [{
"type": "fbid",
"name": "fbname",
"label": "fbName"
}, {
"type": "input",
"name": "name",
"label": "Name",
"validations": [{
"regex": "^[A-Z a-z]+$",
"msg": "Only alphabets are allowed in this field"
}, {
"regex": "^[A-Z a-z]{6,}$",
"msg": "Minimum 6 characters required"
}]
}, {
"type": "radio",
"name": "gender",
"label": "Gender",
"options": [
"Male",
"Female"
],
"validations": [{
"regex": "",
"msg": ""
}]
}, {
"type": "select",
"name": "account",
"label": "AccountType",
"options": [
"current",
"savings"
],
"validations": [{
"regex": "",
"msg": ""
}]
}, {
"type": "checkbox",
"name": "interest",
"label": "Interests",
"options": [
"Cooking",
"Reading"
],
"validations": [{
"regex": "",
"msg": ""
}]
}],
"users": [
"Testing"
]
}}
And call post with:
context.simplehttp.makePost(url,JSON.stringify(param),header,parser);
And my call back
function parser(context, event) {
context.console.log("Handler https")
var result= JSON.parse(event.getresp);
if(result=="success"){
context.sendResponse("We have successfully stored your data");
}else{
context.sendResponse("We dont shoot");
}
}
But when, make the request post, but don't show me response in chat or in callback. What im doing wrong?

Sohan from Gupshup here.
The result from the API that you are using is this:
[{
"embedlink": "https://api.gupshup.io/sm/api/facebook/smartmsg/embed/66438dde-ec76-4d6e-a0d0-8cfc0c730e57",
"expired": false,
"fb-button": {
"title": "This is a test.",
"type": "web_url",
"url": "https://api.gupshup.io/sm/api/facebook/smartmsg/embed/66438dde-ec76-4d6e-a0d0-8cfc0c730e57",
"webview_height_ratio": "tall"
},
"id": "66438dde-ec76-4d6e-a0d0-8cfc0c730e57",
"signed-for": {
"display": "Testing",
"subdisplay": "Testing"
},
"smid": "1009"
}]
Thus when you do:
var result= JSON.parse(event.getresp);
if(result=="success"){
context.sendResponse(result) will display the entire JSON that you see above. To display the 'expired' field you can use result.expired.
Check this document for more information.

Related

Having issues matching local and foreign fields in a $lookup pipeline for a MongoDB aggregate query

I have a two different collections, one for emailtemplates, and one for emails. And what I'm trying to do is write an aggregate pipeline that will show how many times each template has been sent using the templates name from the emailtemplates collection. I know I could just execute a pipeline on the emails collection and count each one by the template name, but that will exclude templates that have never been sent.
Here are some example documents I worked up...
// Example emailtemplate documents:
[
{
"name": "WELCOME-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, Welcome to the club"
},
{
"name": "GOODBYE-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, were sorry to see you go"
},
{
"name": "YOURE-FIRED-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, Pack your stuff and go"
}
]
// Example email documents:
[
{
"templateName": "WELCOME-01",
"recipient": "john.doe#gmail.com",
"parameters": {
"firstName": "John",
"lastName": "Doe"
}
},
{
"templateName": "WELCOME-01",
"recipient": "david.chappelle#gmail.com",
"parameters": {
"firstName": "David",
"lastName": "Chappelle"
},
},
{
"templateName": "GOODBYE-01",
"recipient": "the.joker#gmail.com",
"parameters": {
"firstName": "The",
"lastName": "Joker"
}
}
]
So you can see how each email document has the templateName value which matches with the name from each emailtemplates document. And what I'm trying to do is select from the templateName collection and show how many emails documents are associated to it.
I know how to do it using the localField and foreignFIeld options:
db.notificationtemplates.aggregate([
{
$lookup:{
from: "notifications",
localField: "name",
foreignField: "templateName",
as: "notifications"
}
},
{
$project:{
_id: 0,
templateName: "$name",
amountSent: { $size: "$notifications"}
}
}
]);
Which gives me the results:
[
{ templateName: 'WELCOME-01', amountSent: 2 },
{ templateName: 'GOODBYE-01', amountSent: 1 },
{ templateName: 'YOURE-FIRED-01', amountSent: 0 }
}
And that works just fine, but I need to add some logic to the $lookup, which means I need a $pipeline in there, which means I can't simply use the localField and foreignField. Otherwise I get the error:
MongoServerError: $lookup with 'pipeline' may not specify 'localField' or 'foreignField'
Here's the query I've written thus far to try to do the same thing:
db.emailtemplates.aggregate([
{ $match:{channel: 'email'} },
{
$lookup: {
from: "emails",
let: {
templateName: "$templateName",
name: "$name"
},
pipeline: [
{ $match: { $expr: {$eq: [ "$$templateName","$name"] } } },
{ $project:{
"templateName":"$templateName",
"name":"$name"
} }
],
as: "emails"
}
}
])
Here are the results of the query above:
[
{
"name": "WELCOME-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, Welcome to the club",
"emails":[
{
"templateName": "WELCOME-01"
},
{
"templateName": "WELCOME-01",
},
{
"templateName": "GOODBYE-01"
}
]
},
{
"name": "GOODBYE-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, were sorry to see you go",
"emails":[
{
"templateName": "WELCOME-01"
},
{
"templateName": "WELCOME-01",
},
{
"templateName": "GOODBYE-01"
}
]
},
{
"name": "YOURE-FIRED-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, Pack your stuff and go",
"emails":[
{
"templateName": "WELCOME-01"
},
{
"templateName": "WELCOME-01",
},
{
"templateName": "GOODBYE-01"
}
]
}
]
Note: I'm only outputting the templateName now so I can see what documents get matched for the emails value.
If you look at the emails value for each document that's output, it doesn't at all only look for the emails with the templateName matching the local name value of the emailtemplate documents.
The output I'm expecting to see would be something more along the line of:
[
{
"name": "WELCOME-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, Welcome to the club",
"emails":[
{
"templateName": "WELCOME-01"
},
{
"templateName": "WELCOME-01"
}
}
]
},
{
"name": "GOODBYE-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, were sorry to see you go",
"emails":[
{
"templateName": "GOODBYE-01"
}
]
},
{
"name": "YOURE-FIRED-01",
"channel": "email",
"status":"active",
"title": "Hello, welcome {firstname} {lastnane}",
"parameters":[{
"name": "firstname",
"type": "string",
"required": true
},{
"name": "lastname",
"type": "string",
"required": true
}],
"body":"Dear {firstname}, Pack your stuff and go",
"emails":[]
}
]
You are very close actually. You just mixed up the variables and the field names. Note that $$ indicates variable in MongoDB aggregation pipeline. In your $let clause, you are using the value from emailtemplates.name to create variable name. So for the $lookup sub-pipeline you should compare $$name with $templateName, which refers to emails.templateName as you are looking up the emails collection.
The correct syntax should be like this:
db.emailtemplates.aggregate([
{
$match: {
channel: "email"
}
},
{
$lookup: {
from: "emails",
let: {
templateName: "$templateName",
name: "$name"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$templateName",
"$$name"
]
}
}
},
{
$project: {
"templateName": "$templateName",
"name": "$name"
}
}
],
as: "emails"
}
}
])
Mongo Playground

Why does Adaptive Card Input.Date subtract 1 day from the selected date?

Using botframework with msteams channel.
The adaptive card. Nothing special, just a few textblocks and date inputs. The input values are saved to memory.
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.3",
"body": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"style": "emphasis",
"width": 2,
"items": [
{
"type": "TextBlock",
"text": "Please enter the information below",
"size": "Large"
},
{
"type": "Container",
"style": "emphasis",
"items": [
{
"type": "TextBlock",
"text": "End Of Last Month",
"wrap": true
},
{
"type": "Input.Date",
"id": "Date_EndOfLastMonth",
"value": "${dialog.requestForm.Date_EndOfLastMonth}",
"placeholder": ""
},
{
"type": "TextBlock",
"text": "${dialog.requestForm.Date_EndOfLastMonthError}",
"size": "small",
"wrap": true,
"color": "attention"
}
]
},
{
"type": "Container",
"style": "emphasis",
"items": [
{
"type": "TextBlock",
"text": "End Of Last Year",
"wrap": true
},
{
"type": "Input.Date",
"id": "Date_EndOfLastYear",
"value": "${dialog.requestForm.Date_EndOfLastYear}",
"placeholder": ""
},
{
"type": "TextBlock",
"text": "${dialog.requestForm.Date_EndOfLastYearError}",
"size": "small",
"wrap": true,
"color": "attention"
}
]
},
{
"type": "Container",
"style": "emphasis",
"items": [
{
"type": "TextBlock",
"text": "Valuation Key Date",
"wrap": true
},
{
"type": "Input.Date",
"id": "ValuationKeyDate",
"value": "${dialog.requestForm.ValuationKeyDate}",
"placeholder": ""
},
{
"type": "TextBlock",
"text": "${dialog.requestForm.ValuationKeyDateError}",
"size": "small",
"wrap": true,
"color": "attention"
}
]
},
{
"type": "Container",
"style": "emphasis",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "Submit",
"data": {
"msteams": {
"type": "messageBack",
"displayText": "Form Submitted",
"text": "submitform"
}
}
}
]
}
]
}
]
}
]
}
]
}
The code that goes with the card. I save the input values to memory, so when there is a reprompt happening, I can fill them back to the form. In the last part are the lines for debugging. I am printing out the values directly from the activity, so nothing happens between the submission and the debug.
new CodeAction(async (dc, options) =>
{
dc.State.SetValue("dialog.requestForm.Date_EndOfLastMonth", "");
dc.State.SetValue("dialog.requestForm.Date_EndOfLastYear", "");
dc.State.SetValue("dialog.requestForm.ValuationKeyDate", ""); //ValuationKeyDate
dc.State.SetValue("dialog.requestForm.Date_EndOfLastMonthError", "");
dc.State.SetValue("dialog.requestForm.Date_EndOfLastYearError", "");
dc.State.SetValue("dialog.requestForm.ValuationKeyDateError", "");
return await dc.EndDialogAsync();
}),
new TextInput()
{
Id = "repromptTRT",
Prompt = new ActivityTemplate("${TreasuryCase()}"),
AllowInterruptions = true,
MaxTurnCount = "if(turn.activity.text != 'submitform', '0', '100')",
},
// deal with interrupt, cancel everything else
new IfCondition()
{
Condition = "turn.activity.text != 'submitform'",
Actions = new List<Dialog>()
{
new EndDialog()
}
},
// save form
new CodeAction(async (dc, options) =>
{
var json = JsonConvert.SerializeObject(dc.Context.Activity.Value);
await dc.Context.SendActivityAsync(MessageFactory.Text(json));
var d = JsonConvert.SerializeObject(DateTime.Now);
await dc.Context.SendActivityAsync(MessageFactory.Text(d));
var o = JsonConvert.DeserializeObject<TC>(json);
dc.State.SetValue("dialog.requestForm", o);
return await dc.EndDialogAsync();
}),
For more visibility, adding answer here from comment section:
The fix should be rolling through the rings, so the change should manifest in public clients in a couple of weeks.

Pass callback_id without attachments in Slack

I'm using Slack Api to send message.
So, I have this block message:
{
"blocks": [
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Do you have access ?"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Yes"
},
"style": "primary",
"value": "click_me_123"
},
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Skip"
},
"style": "danger",
"value": "click_me_123"
}
]
}
]
}
As you see, this is block message and it have no any attachments. So, it doesn't send any callback_id when click button Yes or No. But I need send callback_id when click button Yes or No. How can do that?
Or another hack. Anyway to remove border left of attachments?
Thanks.
Am assuming you are looking to have a way to let your code parse the choices when the button is pressed. You need to assign the unique value that you can parse and determine the choice. Something like
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Yes"
},
"style": "primary",
"value": "yes"
},
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Skip"
},
"style": "danger",
"value": "skip"
}
]
}

I need receive the messages created in response texts in some intentions of the API.AI

My issue:
I have two responses, but my chat return only one specified "the speech", but i need that return the two, like do the console of api
example of response JSON from API:
{
"id": "XXXXXXXXXXX",
"timestamp": "2017-07-12T20:08:48.101Z",
"lang": "es",
"result": {
"source": "agent",
"resolvedQuery": "Hello how are you?",
"action": "",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "intent",
"parameters": {},
"lifespan": 1
}
],
"metadata": {
"intentId": "XXXXXXXXXXXXXXXXXXXXXXXX",
"webhookUsed": "false",
"webhookForSlotFillingUsed": "false",
"intentName": "welcome"
},
"fulfillment": {
"speech": "Hello!",
"messages": [
{
"type": 0,
"speech": "Hello!"
},
{
"type": 0,
"speech": "Bye!"
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": ""
}
I need show the black messages.

What rest API can be used to get default values of fields for create issue?

I am using jira rest api's in my application.
I have found the api for getting the meta-data for creating jira issue but that API doesn't return default values of the fields for example :-
This is the request :-
http://kelpie9:8081/rest/api/latest/issue/createmeta?projectKeys=QA&issuetypeNames=Bug&expand=project.issuetypes.fields
the default value of priority field is set to "major" and the description of priority is also customized but the return from api is:-
{
"expand": "projects",
"projects": [
{
"expand": "issuetypes",
"self": "http://kelpie9:8081/rest/api/2/project/QA",
"id": "10010",
"key": "QA",
"name": "QA",
"avatarUrls": {
"16x16": "http://kelpie9:8081/secure/projectavatar?size=small&pid=10010&avatarId=10011",
"48x48": "http://kelpie9:8081/secure/projectavatar?pid=10010&avatarId=10011"
},
"issuetypes": [
{
"expand": "fields",
"self": "http://kelpie9:8081/rest/api/2/issuetype/1",
"id": 1,
"name": "Bug",
"iconUrl": "http://kelpie9:8081/images/icons/bug.gif",
"fields": {
"summary": {
"required": true,
"schema": {
"type": "string",
"system": "summary"
},
"operations": [
"set"
]
},
"timetracking": {
"required": false,
"operations": [ ]
},
"issuetype": {
"required": true,
"schema": {
"type": "issuetype",
"system": "issuetype"
},
"operations": [ ],
"allowedValues": [
{
"id": "1",
"name": "Bug",
"description": "A problem which impairs or prevents the functions of the product.",
"iconUrl": "http://kelpie9:8081/images/icons/bug.gif"
}
]
},
"priority": {
"required": false,
"schema": {
"type": "priority",
"system": "priority"
},
"name": "Priority",
"operations": [
"set"
],
"allowedValues": [
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/1",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_blocker.gif",
"name": "Blocker",
"id": "1"
},
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/2",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_critical.gif",
"name": "Critical",
"id": "2"
},
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/3",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_major.gif",
"name": "Major",
"id": "3"
},
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/4",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_minor.gif",
"name": "Minor",
"id": "4"
},
{
"self": "http://172.19.30.101:18080/rest/api/2/priority/5",
"iconUrl": "http://172.19.30.101:18080/images/icons/priority_trivial.gif",
"name": "Trivial",
"id": "5"
}
]
},
"customfield_10080": {
"required": false,
"schema": {
"type": "array",
"items": "string",
"custom": "com.atlassian.jira.plugin.system.customfieldtypes:labels",
"customId": 10080
},
"operations": [ ]
},
"customfield_10010": {
"required": false,
"schema": {
"type": "array",
"items": "string",
"custom": "com.atlassian.jira.plugin.system.customfieldtypes:labels",
"customId": 10010
},
"operations": [ ]
},
"customfield_10071": {
"required": false,
"schema": {
"type": "array",
"items": "string",
"custom": "com.atlassian.jira.plugin.system.customfieldtypes:textfield",
"customId": 10071
},
"operations": [ ]
}
}
}
]
}
]
}
There is nothing like default value or description in priority field, how will I get those values?