How do I send customer data from twilio to stripe? - stripe-payments

I'm using Twilio to allow my customers to pay automatically over the phone via to stripe. I followed this tutorial: Is there a way to enter dollars/cents via DTMF?
The issue I'm running into is how do I send the "phone number" as a "customer" into stripe? The reason I want this is to be able to see who bought what and how many times etc. Currently, they are all coming into stripe as unknown/guest.
My only success has been (I'm using the studio) entering {{trigger.call.From}} into the "payment description". That still doesn't solve the issue fully though.
Any help would be greatly appreciated!
Here is my flow code:
{
"description": "A New Flow",
"states": [
{
"name": "Trigger",
"type": "trigger",
"transitions": [
{
"next": "received_message_forward",
"event": "incomingMessage"
},
{
"next": "gather_1",
"event": "incomingCall"
},
{
"event": "incomingConversationMessage"
},
{
"event": "incomingRequest"
},
{
"event": "incomingParent"
}
],
"properties": {
"offset": {
"x": 0,
"y": 0
}
}
},
{
"name": "gather_1",
"type": "gather-input-on-call",
"transitions": [
{
"next": "function_1",
"event": "keypress"
},
{
"event": "speech"
},
{
"next": "gather_1",
"event": "timeout"
}
],
"properties": {
"voice": "man",
"speech_timeout": "auto",
"offset": {
"x": 30,
"y": 270
},
"loop": 1,
"finish_on_key": "#",
"say": "Welcome and thank you for calling the donation line. Please enter the amount you wish to donate, then press pound. To enter with cents use the star key. for example to enter $18.50, press one eight star five zero.",
"language": "en-US",
"stop_gather": true,
"gather_language": "en",
"profanity_filter": "true",
"timeout": 5
}
},
{
"name": "function_1",
"type": "run-function",
"transitions": [
{
"next": "confirm_donation_amount",
"event": "success"
},
{
"event": "fail"
}
],
"properties": {
"offset": {
"x": -60,
"y": 530
},
"parameters": [
{
"value": "{{widgets.gather_1.Digits}}",
"key": "amount"
}
],
"url": "https://sand-pointer-5043.twil.io/pay_from_exchange"
}
},
{
"name": "say_play_2",
"type": "say-play",
"transitions": [
{
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": -60,
"y": 840
},
"loop": 1,
"say": "You entered ${{widgets.function_1.body}}",
"language": "en-US"
}
},
{
"name": "pay_1",
"type": "capture-payments",
"transitions": [
{
"next": "say_play_3",
"event": "success"
},
{
"next": "say_play_4",
"event": "maxFailedAttempts"
},
{
"next": "say_play_4",
"event": "providerError"
},
{
"next": "say_play_4",
"event": "payInterrupted"
},
{
"next": "say_play_4",
"event": "hangup"
},
{
"next": "say_play_4",
"event": "validationError"
}
],
"properties": {
"security_code": true,
"offset": {
"x": -70,
"y": 1140
},
"max_attempts": 2,
"payment_connector": "",
"payment_amount": "{{widgets.function_1.body}}",
"description": "{{trigger.call.From}} via Twilio",
"currency": "usd",
"language": "en-US",
"postal_code": "false",
"payment_token_type": "reusable",
"timeout": 5,
"valid_card_types": [
"visa",
"master-card",
"amex",
"discover"
]
}
},
{
"name": "say_play_3",
"type": "say-play",
"transitions": [
{
"next": "send_success_message_1",
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": -185,
"y": 1433
},
"loop": 1,
"say": "Your donation of ${{widgets.function_1.body}} was successful, Thank you.",
"language": "en-US"
}
},
{
"name": "say_play_4",
"type": "say-play",
"transitions": [
{
"next": "send_fail_message_1",
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": 190,
"y": 1456
},
"loop": 1,
"say": "There was an error with your donation. Please verify your details and call back to try again. Thanks!",
"language": "en-US"
}
},
{
"name": "send_success_message_1",
"type": "send-message",
"transitions": [
{
"event": "sent"
},
{
"event": "failed"
}
],
"properties": {
"offset": {
"x": -100,
"y": 1700
},
"service": "{{trigger.message.InstanceSid}}",
"channel": "{{trigger.message.ChannelSid}}",
"from": "{{flow.channel.address}}",
"to": "{{contact.channel.address}}",
"body": "Your donation of ${{widgets.function_1.body}} was successful, Thank you!."
}
},
{
"name": "send_fail_message_1",
"type": "send-message",
"transitions": [
{
"event": "sent"
},
{
"event": "failed"
}
],
"properties": {
"offset": {
"x": 250,
"y": 1700
},
"service": "{{trigger.message.InstanceSid}}",
"channel": "{{trigger.message.ChannelSid}}",
"from": "{{flow.channel.address}}",
"to": "{{contact.channel.address}}",
"body": "There was an error with your donation. Please verify your details and call back to try again. Thanks!"
}
},
{
"name": "confirm_donation_amount",
"type": "gather-input-on-call",
"transitions": [
{
"next": "split_2",
"event": "keypress"
},
{
"event": "speech"
},
{
"next": "confirm_donation_amount",
"event": "timeout"
}
],
"properties": {
"number_of_digits": 1,
"speech_timeout": "auto",
"offset": {
"x": 420,
"y": 530
},
"loop": 1,
"finish_on_key": "#",
"say": "You entered ${{widgets.function_1.body}}. Press 1 to confirm, or press 2 to enter a different amount.",
"stop_gather": true,
"gather_language": "en",
"profanity_filter": "true",
"timeout": 5
}
},
{
"name": "split_2",
"type": "split-based-on",
"transitions": [
{
"next": "confirm_donation_amount",
"event": "noMatch"
},
{
"next": "pay_1",
"event": "match",
"conditions": [
{
"friendly_name": "If value equal_to 1",
"arguments": [
"{{widgets.confirm_donation_amount.Digits}}"
],
"type": "equal_to",
"value": "1"
}
]
},
{
"next": "gather_1",
"event": "match",
"conditions": [
{
"friendly_name": "If value equal_to 2",
"arguments": [
"{{widgets.confirm_donation_amount.Digits}}"
],
"type": "equal_to",
"value": "2"
}
]
}
],
"properties": {
"input": "{{widgets.confirm_donation_amount.Digits}}",
"offset": {
"x": 430,
"y": 800
}
}
},
{
"name": "received_message_forward",
"type": "send-message",
"transitions": [
{
"event": "sent"
},
{
"event": "failed"
}
],
"properties": {
"offset": {
"x": -300,
"y": 250
},
"service": "{{trigger.message.InstanceSid}}",
"channel": "{{trigger.message.ChannelSid}}",
"from": "{{flow.channel.address}}",
"to": "{{contact.channel.address}}",
"body": "Thanks for texting the Donation line. To donate, please call us on this same number. We do not accept donations via text."
}
}
],
"initial_state": "Trigger",
"flags": {
"allow_concurrent_calls": true
}
}
Here is the function:
exports.handler = function(context, event, callback) {
const amount = event.amount;
const convert = amount.replace('*', '.');
callback(null, convert);
};

Related

Need to get data from fixture JSON

I am struggling hard since yesterday getting the data from JSON, I don't understand why the fixture is not accessible. When I tried to get the ID, it gives me an error saying id isn't defined.
This gives me an error saying ID is not defined:
res.send(data.response["fixture"].id)
This code returns nothing:
res.send(data.response.fixture);
This code gives me the JSON data:
res.send(data.response
My JSON data:
// 20220714200426
// http://localhost:9090/
[
{
"fixture": {
"id": 822924,
"referee": "Jhon Alexander Hinestroza Romana, Colombia",
"timezone": "UTC",
"date": "2022-07-15T01:10:00+00:00",
"timestamp": 1657847400,
"periods": {
"first": 1657847400,
"second": 1657851000
},
"venue": {
"id": 375,
"name": "Estadio Manuel Murillo Toro",
"city": "Ibagué"
},
"status": {
"long": "Second Half",
"short": "2H",
"elapsed": 90
}
},
"league": {
"id": 239,
"name": "Primera A",
"country": "Colombia",
"logo": "https://media.api-sports.io/football/leagues/239.png",
"flag": "https://media.api-sports.io/flags/co.svg",
"season": 2022,
"round": "Clausura - 2"
},
"teams": {
"home": {
"id": 1142,
"name": "Deportes Tolima",
"logo": "https://media.api-sports.io/football/teams/1142.png",
"winner": true
},
"away": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png",
"winner": false
}
},
"goals": {
"home": 2,
"away": 0
},
"score": {
"halftime": {
"home": 0,
"away": 0
},
"fulltime": {
"home": null,
"away": null
},
"extratime": {
"home": null,
"away": null
},
"penalty": {
"home": null,
"away": null
}
},
"events": [
{
"time": {
"elapsed": 1,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": 13398,
"name": "Y. Congo"
},
"assist": {
"id": null,
"name": null
},
"type": "Card",
"detail": "Yellow Card",
"comments": null
},
{
"time": {
"elapsed": 26,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": 13592,
"name": "T. Gutierrez"
},
"assist": {
"id": null,
"name": null
},
"type": "Card",
"detail": "Yellow Card",
"comments": null
},
{
"time": {
"elapsed": 27,
"extra": null
},
"team": {
"id": 1142,
"name": "Deportes Tolima",
"logo": "https://media.api-sports.io/football/teams/1142.png"
},
"player": {
"id": 13304,
"name": "B. Rovira"
},
"assist": {
"id": null,
"name": null
},
"type": "Card",
"detail": "Yellow Card",
"comments": null
},
{
"time": {
"elapsed": 40,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": 13592,
"name": "T. Gutierrez"
},
"assist": {
"id": null,
"name": null
},
"type": "Card",
"detail": "Red Card",
"comments": null
},
{
"time": {
"elapsed": 56,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": null,
"name": "O. Acosta"
},
"assist": {
"id": null,
"name": null
},
"type": "Card",
"detail": "Yellow Card",
"comments": null
},
{
"time": {
"elapsed": 59,
"extra": null
},
"team": {
"id": 1142,
"name": "Deportes Tolima",
"logo": "https://media.api-sports.io/football/teams/1142.png"
},
"player": {
"id": 283830,
"name": "L. Riascos"
},
"assist": {
"id": null,
"name": null
},
"type": "Card",
"detail": "Yellow Card",
"comments": null
},
{
"time": {
"elapsed": 61,
"extra": null
},
"team": {
"id": 1142,
"name": "Deportes Tolima",
"logo": "https://media.api-sports.io/football/teams/1142.png"
},
"player": {
"id": 13348,
"name": "L. Miranda"
},
"assist": {
"id": null,
"name": null
},
"type": "Var",
"detail": "Goal Disallowed - offside",
"comments": null
},
{
"time": {
"elapsed": 64,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": 10328,
"name": "Y. Gonzalez"
},
"assist": {
"id": null,
"name": "O. Acosta"
},
"type": "subst",
"detail": "Substitution 1",
"comments": null
},
{
"time": {
"elapsed": 66,
"extra": null
},
"team": {
"id": 1142,
"name": "Deportes Tolima",
"logo": "https://media.api-sports.io/football/teams/1142.png"
},
"player": {
"id": 6632,
"name": "A. Renteria"
},
"assist": {
"id": 13348,
"name": "L. Miranda"
},
"type": "subst",
"detail": "Substitution 1",
"comments": null
},
{
"time": {
"elapsed": 69,
"extra": null
},
"team": {
"id": 1142,
"name": "Deportes Tolima",
"logo": "https://media.api-sports.io/football/teams/1142.png"
},
"player": {
"id": 13596,
"name": "M. Rangel"
},
"assist": {
"id": 13298,
"name": "J. Lucumi"
},
"type": "Goal",
"detail": "Normal Goal",
"comments": null
},
{
"time": {
"elapsed": 70,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": 59887,
"name": "A. Gutierrez"
},
"assist": {
"id": null,
"name": null
},
"type": "Card",
"detail": "Yellow Card",
"comments": null
},
{
"time": {
"elapsed": 72,
"extra": null
},
"team": {
"id": 1142,
"name": "Deportes Tolima",
"logo": "https://media.api-sports.io/football/teams/1142.png"
},
"player": {
"id": 13298,
"name": "J. Lucumi"
},
"assist": {
"id": 6632,
"name": "A. Renteria"
},
"type": "Goal",
"detail": "Normal Goal",
"comments": null
},
{
"time": {
"elapsed": 78,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": 31691,
"name": "A. Vuletich"
},
"assist": {
"id": 51135,
"name": "H. Mosquera"
},
"type": "subst",
"detail": "Substitution 2",
"comments": null
},
{
"time": {
"elapsed": 78,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": 200150,
"name": "J. C. Caldera Alvis"
},
"assist": {
"id": 51165,
"name": "A. Rodriguez"
},
"type": "subst",
"detail": "Substitution 3",
"comments": null
},
{
"time": {
"elapsed": 82,
"extra": null
},
"team": {
"id": 1127,
"name": "Deportivo Cali",
"logo": "https://media.api-sports.io/football/teams/1127.png"
},
"player": {
"id": 200150,
"name": "J. C. Caldera Alvis"
},
"assist": {
"id": null,
"name": null
},
"type": "Card",
"detail": "Yellow Card",
"comments": null
},
{
"time": {
"elapsed": 84,
"extra": null
},
"team": {
"id": 1142,
"name": "Deportes Tolima",
"logo": "https://media.api-sports.io/football/teams/1142.png"
},
"player": {
"id": 59758,
"name": "A. Melendez"
},
"assist": {
"id": 35757,
"name": "Y. Orozco"
},
"type": "subst",
"detail": "Substitution 2",
"comments": null
}
]
},
{
"fixture": {
"id": 896998,
"referee": null,
"timezone": "UTC",
"date": "2022-07-15T02:00:00+00:00",
"timestamp": 1657850400,
"periods": {
"first": 1657850400,
"second": 1657854000
},
"venue": {
"id": 1087,
"name": "Estadio Universitario de Nuevo León",
"city": "San Nicolás de los Garza"
},
"status": {
"long": "Second Half",
"short": "2H",
"elapsed": 46
}
},
"league": {
"id": 927,
"name": "World Cup - Women - Qualification Concacaf",
"country": "World",
"logo": "https://media.api-sports.io/football/leagues/927.png",
"flag": null,
"season": 2022,
"round": "Semi-finals"
},
"teams": {
"home": {
"id": 1717,
"name": "Canada W",
"logo": "https://media.api-sports.io/football/teams/1717.png",
"winner": true
},
"away": {
"id": 1785,
"name": "Jamaica W",
"logo": "https://media.api-sports.io/football/teams/1785.png",
"winner": false
}
},
"goals": {
"home": 1,
"away": 0
},
"score": {
"halftime": {
"home": 1,
"away": 0
},
"fulltime": {
"home": null,
"away": null
},
"extratime": {
"home": null,
"away": null
},
"penalty": {
"home": null,
"away": null
}
},
"events": [
{
"time": {
"elapsed": 10,
"extra": null
},
"team": {
"id": 1785,
"name": "Jamaica W",
"logo": "https://media.api-sports.io/football/teams/1785.png"
},
"player": {
"id": null,
"name": "C. Swaby"
},
"assist": {
"id": null,
"name": "J. C. Pelaia-Hylton"
},
"type": "subst",
"detail": "Substitution 1",
"comments": null
},
{
"time": {
"elapsed": 18,
"extra": null
},
"team": {
"id": 1717,
"name": "Canada W",
"logo": "https://media.api-sports.io/football/teams/1717.png"
},
"player": {
"id": null,
"name": "J. Fleming"
},
"assist": {
"id": null,
"name": null
},
"type": "Goal",
"detail": "Normal Goal",
"comments": null
}
]
},
{
"fixture": {
"id": 868553,
"referee": null,
"timezone": "UTC",
"date": "2022-07-15T02:05:00+00:00",
"timestamp": 1657850700,
"periods": {
"first": 1657850700,
"second": null
},
"venue": {
"id": 1844,
"name": "Estadio Olímpico Carlos Iturralde Rivero",
"city": "Mérida"
},
"status": {
"long": "Halftime",
"short": "HT",
"elapsed": 45
}
},
"league": {
"id": 263,
"name": "Ascenso MX",
"country": "Mexico",
"logo": "https://media.api-sports.io/football/leagues/263.png",
"flag": "https://media.api-sports.io/flags/mx.svg",
"season": 2022,
"round": "Apertura - 3"
},
"teams": {
"home": {
"id": 2311,
"name": "Venados FC",
"logo": "https://media.api-sports.io/football/teams/2311.png",
"winner": true
},
"away": {
"id": 2308,
"name": "Celaya",
"logo": "https://media.api-sports.io/football/teams/2308.png",
"winner": false
}
},
"goals": {
"home": 2,
"away": 1
},
"score": {
"halftime": {
"home": 2,
"away": 1
},
"fulltime": {
"home": null,
"away": null
},
"extratime": {
"home": null,
"away": null
},
"penalty": {
"home": null,
"away": null
}
},
"events": [
{
"time": {
"elapsed": 11,
"extra": null
},
"team": {
"id": 2308,
"name": "Celaya",
"logo": "https://media.api-sports.io/football/teams/2308.png"
},
"player": {
"id": null,
"name": "D. Gonzalez"
},
"assist": {
"id": null,
"name": null
},
"type": "Goal",
"detail": "Normal Goal",
"comments": null
},
{
"time": {
"elapsed": 17,
"extra": null
},
"team": {
"id": 2311,
"name": "Venados FC",
"logo": "https://media.api-sports.io/football/teams/2311.png"
},
"player": {
"id": null,
"name": "M. Perez"
},
"assist": {
"id": null,
"name": null
},
"type": "Goal",
"detail": "Normal Goal",
"comments": null
},
{
"time": {
"elapsed": 36,
"extra": null
},
"team": {
"id": 2311,
"name": "Venados FC",
"logo": "https://media.api-sports.io/football/teams/2311.png"
},
"player": {
"id": 36091,
"name": "M. Perez"
},
"assist": {
"id": null,
"name": null
},
"type": "Goal",
"detail": "Normal Goal",
"comments": null
}
]
}
]
My Node.js code:
const express = require('express');
const Router = express.Router();//router will be used now to route
require('dotenv').config();
const fetch = require('cross-fetch');
const axios = require('axios');
const request = require('request');
const endpoint = 'fixtures';
Router.get('/', (req, res) => {
var options = {
method: 'GET',
url: `https://v3.football.api-sports.io/${endpoint}`,
qs: {live: 'all'},
headers: {
'x-rapidapi-host': 'v3.football.api-sports.io',
'x-rapidapi-key': `${process.env.API_KEY}`
}
};
request(options, function (error, resp, body) {
if (error) throw new Error(error);
const data = JSON.parse(body);
res.send(data.response);
});
})
module.exports = Router;
What I want is to access fixture ID and all other keys as well but I am not able to reach the fixture. Can anyone able to guide me on what's wrong I am doing?
From the json data response body above, data.response is an array of objects of multiple fixtures. So, data.response.fixture would always return undefined. To access a particular fixture, depending on what you want to do to with, you'd have to access the index of the response first. As such:
console.log(data.response[0].fixture)
this should return:
"fixture": {
"id": 822924,
"referee": "Jhon Alexander Hinestroza Romana, Colombia",
"timezone": "UTC",
"date": "2022-07-15T01:10:00+00:00",
"timestamp": 1657847400,
"periods": {
"first": 1657847400,
"second": 1657851000
},
"venue": {
"id": 375,
"name": "Estadio Manuel Murillo Toro",
"city": "Ibagué"
},
"status": {
"long": "Second Half",
"short": "2H",
"elapsed": 90
}
}
To access its id:
console.log(data.response[0].fixture.id)
The important thing is to access the properties through the array index of the element you want.

Shopware6 API integrity constraints on nested entities

Tested on Shopware 6.3.5.1:
I'm trying to create a product via API together with its parent. That is necessary, because I can only iterate over variants in the other system.
As far as I can tell there's no conflict with the IDs or duplicates. Neither the product nor its parent already exist.
But when I do this:
POST https://somedomain.de/api/v3/_action/sync
Content-Type: application/json
Accept: application/json
Authorization: Bearer {{auth_token}}
{
"7508d64f832fb06b8f82f78963b280ab": {
"action": "upsert",
"entity": "product",
"payload": [
{
"id": "7508d64f832fb06b8f82f78963b280ab",
"__code": "1111111189",
"stock": 99,
"taxId": "d390c2f211144543845dbf76fa69d17a",
"cmsPageId": null,
"deliveryTimeId": null,
"manufacturerId": null,
"visibilities": [
{
"id": "e24f994426246015347bba784ac69a97",
"productId": "7508d64f832fb06b8f82f78963b280ab",
"salesChannelId": "8e7c11e2540b4c71b521d5a59920e142",
"visibility": 30
}
],
"unitId": null,
"price": [
{
"currencyId": "b7d2554b0ce847cd82f3ac9bd1c0dfca",
"net": 25,
"gross": 29.75,
"linked": true
}
],
"productNumber": "1111111189",
"coverId": null,
"translations": {
"ce1df85b5f1c4eedbc532cbd34c57df6": {
"name": "Converse black",
"description": "Converse black"
},
"2fbb5fe2e29a4d70aa5854ce7ce3e20b": {
"name": "Converse black",
"description": "Converse black"
}
},
"categories": [
{
"id": "e90cf50735a0d6f69b2dbf599caa4954"
},
{
"id": "a5b4753f41c8f4bedba1bf5954c961cb"
}
],
"properties": [
{
"id": "a01a0380ca3c61428c26a231f0e49a09"
}
],
"media": [
{
"id": "cb9a886400616c215a588b13cb7c662b",
"mediaId": "a7aabb5ff4dc3c99ba45724ec7477ffe"
}
],
"parent": {
"id": "7a788255eab96bf51002829b3a6becf2",
"__code": "1111111189",
"stock": 99,
"taxId": "d390c2f211144543845dbf76fa69d17a",
"cmsPageId": null,
"deliveryTimeId": null,
"manufacturerId": null,
"visibilities": [
{
"id": "8d5a7e2b2c02986a924eaf3d9504413c",
"productId": "7a788255eab96bf51002829b3a6becf2",
"salesChannelId": "8e7c11e2540b4c71b521d5a59920e142",
"visibility": 30
}
],
"unitId": null,
"price": [
{
"currencyId": "b7d2554b0ce847cd82f3ac9bd1c0dfca",
"net": 25,
"gross": 29.75,
"linked": true
}
],
"productNumber": "converseblack",
"coverId": null,
"translations": {
"ce1df85b5f1c4eedbc532cbd34c57df6": {
"name": "Converse black",
"description": "Converse black"
},
"2fbb5fe2e29a4d70aa5854ce7ce3e20b": {
"name": "Converse black",
"description": "Converse black"
}
},
"categories": [
{
"id": "e90cf50735a0d6f69b2dbf599caa4954"
},
{
"id": "a5b4753f41c8f4bedba1bf5954c961cb"
}
],
"properties": [
{
"id": "a01a0380ca3c61428c26a231f0e49a09"
}
],
"media": [
{
"id": "cb9a886400616c215a588b13cb7c662b",
"mediaId": "a7aabb5ff4dc3c99ba45724ec7477ffe"
}
],
"configuratorSettings": [
{
"optionId": "a01a0380ca3c61428c26a231f0e49a09",
"id": "db3787abb8d6372e1997c144031ef1e2"
}
]
},
"parentId": "7a788255eab96bf51002829b3a6becf2",
"options": [
{
"id": "a01a0380ca3c61428c26a231f0e49a09"
}
]
}
]
}
}
I get as a response that the integrity constraint productId X saleschannelId in visibilities gets violated:
{
"success": false,
"data": {
"7508d64f832fb06b8f82f78963b280ab": {
"result": [
{
"entities": [],
"errors": [
{
"code": "0",
"status": "500",
"title": "Internal Server Error",
"detail": "An exception occurred while executing 'INSERT INTO `product_visibility` (`id`, `product_id`, `product_version_id`, `sales_channel_id`, `visibility`, `created_at`) VALUES (?, ?, ?, ?, ?, ?)' with params [\"\\x8d\\x5a\\x7e\\x2b\\x2c\\x02\\x98\\x6a\\x92\\x4e\\xaf\\x3d\\x95\\x04\\x41\\x3c\", \"\\x7a\\x78\\x82\\x55\\xea\\xb9\\x6b\\xf5\\x10\\x02\\x82\\x9b\\x3a\\x6b\\xec\\xf2\", \"\\x0f\\xa9\\x1c\\xe3\\xe9\\x6a\\x4b\\xc2\\xbe\\x4b\\xd9\\xce\\x75\\x2c\\x34\\x25\", \"\\x8e\\x7c\\x11\\xe2\\x54\\x0b\\x4c\\x71\\xb5\\x21\\xd5\\xa5\\x99\\x20\\xe1\\x42\", 30, \"2021-02-22 11:36:18.099\"]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'zx\\x82U\\xEA\\xB9k\\xF5\\x10\\x02\\x82\\x9B:k\\xEC\\xF2-\\x0F\\xA9\\x1C\\x...' for key 'uniq.product_id__sales_channel_id'"
}
]
}
],
"extensions": []
}
},
"extensions": []
}
I just figured out, that it's possible to extract the nested entities into separate actions (that works):
{
"7508d64f832fb06b8f82f78963b280ab": {
"action": "upsert",
"entity": "product",
"payload": [
{
"id": "7508d64f832fb06b8f82f78963b280ab",
"__code": "1111111189",
"stock": 99,
"taxId": "d390c2f211144543845dbf76fa69d17a",
"cmsPageId": null,
"deliveryTimeId": null,
"manufacturerId": null,
"unitId": null,
"price": [
{
"currencyId": "b7d2554b0ce847cd82f3ac9bd1c0dfca",
"net": 25,
"gross": 29.75,
"linked": true
}
],
"productNumber": "1111111189",
"coverId": null,
"translations": {
"ce1df85b5f1c4eedbc532cbd34c57df6": {
"name": "Converse black",
"description": "Converse black"
},
"2fbb5fe2e29a4d70aa5854ce7ce3e20b": {
"name": "Converse black",
"description": "Converse black"
}
},
"categories": [
{
"id": "e90cf50735a0d6f69b2dbf599caa4954"
},
{
"id": "a5b4753f41c8f4bedba1bf5954c961cb"
}
],
"properties": [
{
"id": "a01a0380ca3c61428c26a231f0e49a09"
}
],
"media": [
{
"id": "cb9a886400616c215a588b13cb7c662b",
"mediaId": "a7aabb5ff4dc3c99ba45724ec7477ffe"
}
],
"parent": {
"id": "7a788255eab96bf51002829b3a6becf2",
"__code": "1111111189",
"stock": 99,
"taxId": "d390c2f211144543845dbf76fa69d17a",
"cmsPageId": null,
"deliveryTimeId": null,
"manufacturerId": null,
"unitId": null,
"price": [
{
"currencyId": "b7d2554b0ce847cd82f3ac9bd1c0dfca",
"net": 25,
"gross": 29.75,
"linked": true
}
],
"productNumber": "converseblack",
"coverId": null,
"translations": {
"ce1df85b5f1c4eedbc532cbd34c57df6": {
"name": "Converse black",
"description": "Converse black"
},
"2fbb5fe2e29a4d70aa5854ce7ce3e20b": {
"name": "Converse black",
"description": "Converse black"
}
},
"categories": [
{
"id": "e90cf50735a0d6f69b2dbf599caa4954"
},
{
"id": "a5b4753f41c8f4bedba1bf5954c961cb"
}
],
"properties": [
{
"id": "a01a0380ca3c61428c26a231f0e49a09"
}
],
"media": [
{
"id": "cb9a886400616c215a588b13cb7c662b",
"mediaId": "a7aabb5ff4dc3c99ba45724ec7477ffe"
}
],
"configuratorSettings": [
{
"optionId": "a01a0380ca3c61428c26a231f0e49a09",
"id": "db3787abb8d6372e1997c144031ef1e2"
}
]
},
"parentId": "7a788255eab96bf51002829b3a6becf2",
"options": [
{
"id": "a01a0380ca3c61428c26a231f0e49a09"
}
]
}
]
},
"e24f994426246015347bba784ac69a97": {
"action": "upsert",
"entity": "product_visibility",
"payload": [
{
"id": "e24f994426246015347bba784ac69a97",
"productId": "7508d64f832fb06b8f82f78963b280ab",
"salesChannelId": "8e7c11e2540b4c71b521d5a59920e142",
"visibility": 30
}
]
},
"8d5a7e2b2c02986a924eaf3d9504413c": {
"action": "upsert",
"entity": "product_visibility",
"payload": [
{
"id": "8d5a7e2b2c02986a924eaf3d9504413c",
"productId": "7a788255eab96bf51002829b3a6becf2",
"salesChannelId": "8e7c11e2540b4c71b521d5a59920e142",
"visibility": 30
}
]
}
}

Received an invalid_authentication error when querying a Foursquare venue

I am trying to query for details of venues using the Foursquare venues
API, but i received a "invalid_auth" error
VENUE_ID='54ea41ad498e9a11e9e13308'
VERSION = '20190823'
venueurl = 'https://api.foursquare.com/v2/venues/{}&client_id={}&client_secret={}&v={}'.format(VENUE_ID, CLIENT_ID, CLIENT_SECRET, VERSION)
venueresults = requests.get(venueurl).json()
venueresults
This is the error i received.
{'meta': {'code': 400, 'errorType': 'invalid_auth', 'errorDetail':
'Missing access credentials. See
https://developer.foursquare.com/docs/api/configuration/authentication
for details.', 'requestId': '5d613b698afbe000358acf53'},
'response': {}}
I expect to receive a response as shown below (shortened as the
response is too long.
https://foursquare.com/developers/explore#req=venues%2F54ea41ad498e9a11e9e13308
{ "meta": { "code": 200 "requestId": "5d613941075a420023f41750" }
"notifications": [ { "type": "notificationTray" "item": {
"unreadCount": 0 } } ] "response": { "venue": { "id":
"54ea41ad498e9a11e9e13308" "name": "Roselle Desserts" "contact": {
"phone": "+14163688188" "formattedPhone": "+1 416-368-8188" "twitter":
"roselle_to" } "location": { "address": "362 King St E" "crossStreet":
"Trinity St" "lat": 43.653446723052674 "lng": -79.3620167174383
"labeledLatLngs": [ { "label": "display" "lat": 43.653446723052674
"lng": -79.3620167174383 } ] "postalCode": "M5A 1K9" "cc": "CA"
"city": "Toronto" "state": "ON" "country": "Canada"
"formattedAddress": [ "362 King St E (Trinity St)" "Toronto ON M5A
1K9" "Canada" ] } "canonicalUrl":
"https://foursquare.com/v/roselle-desserts/54ea41ad498e9a11e9e13308"
"categories": [ { "id": "4bf58dd8d48988d16a941735" "name": "Bakery"
"pluralName": "Bakeries" "shortName": "Bakery" "icon": { "prefix":
"https://ss3.4sqi.net/img/categories_v2/food/bakery_" "suffix": ".png"
} "primary": true } { "id": "4bf58dd8d48988d1d0941735" "name":
"Dessert Shop" "pluralName": "Dessert Shops" "shortName": "Desserts"
"icon": { "prefix":
"https://ss3.4sqi.net/img/categories_v2/food/dessert_" "suffix":
".png" } } { "id": "4bf58dd8d48988d1c9941735" "name": "Ice Cream Shop"
"pluralName": "Ice Cream Shops" "shortName": "Ice Cream" "icon": {
"prefix": "https://ss3.4sqi.net/img/categories_v2/food/icecream_"
"suffix": ".png" } } ] "verified": false "stats": { "tipCount": 15
"usersCount": 674 "checkinsCount": 561 "visitsCount": 1203 } "url":
"http://www.roselleto.com" "price": { "tier": 1 "message": "Cheap"
"currency": "$" } "likes": { "count": 45 "groups": [ { "type":
"others" "count": 45 "items": [ ] } ] "summary": "45 Likes" } "like":
false "dislike": false "ok": false "rating": 8.8 "ratingColor":
"73CF42" "ratingSignals": 54 "allowMenuUrlEdit": true "beenHere": {
"count": 0 "unconfirmedCount": 0 "marked": false
"lastCheckinExpiredAt": 0 } "specials": { "count": 0 "items": [ ] }
"photos": { "count": 39 "groups": [ { "type": "checkin" "name":
"Friends' check-in photos" "count": 0 "items": [ ] } { "type": "venue"
"name": "Venue photos" "count": 39 "items": [ "0": { "id":
"5d59a14744209c00089c596b" "createdAt": 1566155079 "source": { "name":
"Swarm for iOS" "url": "https://www.swarmapp.com"
etc
I have found the answer, a "?" instead of "&" is required after the venue_id
'https://api.foursquare.com/v2/venues/{}?client_id={}&client_secret={}&v={}'.format(VENUE_ID, CLIENT_ID, CLIENT_SECRET, VERSION)
Refer to the Q&A below:
Authentication error in nested API request

Copyindex in deploying dashboard resources Azure ARM

I am deploying a custom Azure Dashboard with a tile that makes use of a resource.
To call the resource I use following code
"[resourceId(parameters('analysisServiceResourceGroup'), '/Microsoft.AnalysisServices/servers', parameters('analysisServiceName'))]"
But in one of the tiles I need multiple resources so I tried something out to make a parameter file with following value
"analysisService": {
"value": [
{
"ResourceGroup": "RG",
"Name": "analysis1",
"Color": "#47BDF5"
},
{
"ResourceGroup": "RG",
"Name": "analysis2",
"Color": "#7E58FF"
},
{
"ResourceGroup": "RG",
"Name": "analysis3",
"Color": "#EB9371"
}
]
},
In my dashboard template i use following code to get the name and resource group.
"resourceId": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
The problem I got at the moment my copy object is not placed in the right place. I got this error
'The template function 'copyIndex' is not expected at this location. The function can only be used in a resource with copy specified. Please see https://aka.ms/arm-copy for usage details.'"
This says that my copy index block is not used in the right resource bracelet but I don't know where i can place this copy Index , tried to put this in every possible place where the copy index can access this but nothing works does anyone know what I do wrong or what I do wrong. It may be possible that copyindex doesn't work inside a dashboard resource.
Code
"12": {
"position": {
"x": 12,
"y": 9,
"colSpan": 6,
"rowSpan": 4
},
"metadata": {
"inputs": [
{
"name": "sharedTimeRange",
"isOptional": true
},
{
"name": "options",
"value": {
"charts": [
{
"metrics": [
{
"name": "CurrentUserSessions",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
},
"aggregationType": 1,
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
}
],
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"visualization": {
"chartType": 2,
"legend": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axis": {
"x": {
"isVisible": true,
"axisType": 2,
"min": 1546508634047,
"max": 1546595034047
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"timeBrushEnable": false
},
"itemDataModel": {
"id": "3464BA29-9AF2-4EAE-9CF4-A246059DDF46",
"chartHeight": 1,
"metrics": [
{
"id": {
"resourceDefinition": {
"id": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
},
"name": {
"id": "CurrentUserSessions",
"displayName": "Current User Sessions"
},
"namespace": {
"name": "microsoft.analysisservices/servers"
}
},
"metricAggregation": 4,
"color": "[parameters('analysisService')[copyIndex()].Color]"
,
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
}
],
"priorPeriod": false,
"horizontalBars": true,
"showOther": false,
"aggregation": 1,
"palette": "multiColor",
"jsonDefinitionId": "59DCE403-7D8D-4E9F-9CDA-7AE7AC9D9220",
"version": {
"major": 1,
"minor": 0,
"build": 0
},
"filters": {
"filterType": 0,
"id": "C81486BB-3934-48C7-9251-A4EE633DB2BB",
"OperandFilters": [],
"LogicalOperator": 0
},
"yAxisOptions": {
"options": 1
},
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"titleKind": "Auto",
"visualization": {
"chartType": 2,
"legend": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axis": {
"x": {
"isVisible": true,
"axisType": 2,
"min": 1546508634047,
"max": 1546595034047
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"timeBrushEnable": false
}
}
}
],
"v2charts": true,
"version": 1
},
"isOptional": true
}
],
"type": "Extension/HubsExtension/PartType/MonitorChartPart",
"settings": {
"content": {
"options": {
"charts": [
{
"metrics": [
{
"name": "CurrentUserSessions",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
},
"aggregationType": 1
,
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
}
],
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"visualization": {
"chartType": 2,
"legend": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axis": {
"x": {
"isVisible": true,
"axisType": 2,
"min": 1546508634047,
"max": 1546595034047
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"timeBrushEnable": false
},
"itemDataModel": {
"id": "3464BA29-9AF2-4EAE-9CF4-A246059DDF46",
"chartHeight": 1,
"metrics": [
{
"id": {
"resourceDefinition": {
"id": "[resourceId(parameters('analysisService')[copyIndex()].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex()].Name)]"
},
"name": {
"id": "CurrentUserSessions",
"displayName": "Current User Sessions"
},
"namespace": {
"name": "microsoft.analysisservices/servers"
}
},
"metricAggregation": 4,
"color": "[parameters('analysisService')[copyIndex()].Color]"
,
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
}
],
"priorPeriod": false,
"horizontalBars": true,
"showOther": false,
"aggregation": 1,
"palette": "multiColor",
"jsonDefinitionId": "59DCE403-7D8D-4E9F-9CDA-7AE7AC9D9220",
"version": {
"major": 1,
"minor": 0,
"build": 0
},
"filters": {
"filterType": 0,
"id": "C81486BB-3934-48C7-9251-A4EE633DB2BB",
"OperandFilters": [],
"LogicalOperator": 0
},
"yAxisOptions": {
"options": 1
},
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"titleKind": "Auto",
"visualization": {
"chartType": 2,
"legend": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axis": {
"x": {
"isVisible": true,
"axisType": 2,
"min": 1546508634047,
"max": 1546595034047
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"timeBrushEnable": false
}
},
"disablePinning": true
}
],
"v2charts": true,
"version": 1
}
}
}
}
},
"copy": {
"name": "AnalysisServiceCopy",
"count": "[length(parameters('analysisService'))]"
},
so, as a general rule, you can only use copy loop to create arrays, not object, so to construct you metrics array you would do something like this:
"charts": [
{
"copy": [
{
"name": "metrics",
"count": "[length(parameters('analysisService'))]",
"input": {
"name": "CurrentUserSessions",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex('metrics')].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex('metrics')].Name)]"
},
"aggregationType": 1
}
}
],
"title": "Avg Current User Sessions for analysis1, analysis1, and analysis1",
"visualization": { redacted for brievity },
"itemDataModel": { redacted for brievity },
"disablePinning": true
}
],
you would need to do this everywhere you need to construct an array. as a workaround (if they are identical) you can use the same construct to create a variable and use that variable:
"variables": {
"copy": [
{
"name": "metrics",
"count": "[length(parameters('analysisService'))]",
"input": {
"name": "CurrentUserSessions",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex('metrics')].ResourceGroup, '/Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex('metrics')].Name)]"
},
"aggregationType": 1
}
}
],
}
the above will create a variable called "metrics" which you can use anywhere in the template like so:
"[variables('metrics')]"
#4c74356b41
I tried it like this , I directly get an green error line beneath copy that this varbiable never is used.
"variables": {
"copy": [
{
"name": "metrics",
"count": "[length(parameters('analysisService'))]",
"input": {
"name": "qpu_metric",
"resourceMetadata": {
"resourceId": "[resourceId(parameters('analysisService')[copyIndex('metrics')].ResourceGroup, 'Microsoft.AnalysisServices/servers', parameters('analysisService')[copyIndex('metrics')].Name)]"
},
"aggregationType": 1
}
}
]
},
In my code I call the variable like this
"charts": [
{
"metrics" : "[variables('metrics')]",
"title": "Avg QPU",
"visualization": {

Adaptive Cards doesn't work in MBF's Emulator running in Ubuntu 16.04

I am trying to implement AdaptiveCard into one of my dialogs using node.js. However once I run the emulator I get the following message instead of rendered AdaptiveCard:
[File of type 'application/vnd.microsoft.card.adaptive'].
Can anyone tell me what can be the problem?
I am running on Ubuntu 16.04, MBF Emulator v.3.5.31-alpha, microsoft-adaptivecards v.0.6.1.
Here is code from inside of one of my dialogs:
var msg = new builder.Message(session)
.addAttachment({
contentType: "application/vnd.microsoft.card.adaptive",
content: {
type: "AdaptiveCard",
body: [
{
"type": "TextBlock",
"text": msg_text,
},
{
"type": "Input.ChoiceSet",
"id": "myColor4",
"isMultiSelect": true,
"value": "1",
"style": "expanded",
"choices": [
{
"title": "Red",
"value": "1",
"isSelected": true
},
{
"title": "Green",
"value": "2"
},
{
"title": "Blue",
"value": "3",
"isSelected": true
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Sent",
"data": {
"myProperty": 12
}
}
],
}
});
session.send(msg);
This is detailed response, it contains all elements of the AdaptiveCard that I declared(but still it does not render):
{
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "What color do you want?"
},
{
"type": "Input.ChoiceSet",
"id": "myColor4",
"isMultiSelect": true,
"value": "1",
"style": "expanded",
"choices": [
{
"title": "Red",
"value": "1",
"isSelected": true
},
{
"title": "Green",
"value": "2"
},
{
"title": "Blue",
"value": "3",
"isSelected": true
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Sent",
"data": {
"myProperty": 12
}
}
]
}
}
],
"locale": "en-US",
"localTimestamp": "2017-09-17T19:21:17+02:00",
"from": {
"id": "default-bot",
"name": "Bot"
},
"recipient": {
"id": "default-user"
},
"inputHint": "acceptingInput",
"id": "heam84b9dn5b",
"replyToId": "71j1d6mbmk3l",
"channelId": "emulator",
"timestamp": "2017-09-17T17:21:17.379Z",
"conversation": {
"id": "fdikc23llm5"
}
}

Resources