Mandrill API mis-reports bad formats - google-analytics

As specified in the documentation, I have to send arrays for google_analytics_domains and google_analytics_campaign fields.
http://mandrillapp.com/api/docs/messages.html#method=send
But mandrill generates a link with a wrong utm_campaign (Google analytics doesn't like the [0] part) :
utm_campaign[0]=test_campaign
I tried to send strings instead of arrays but the mandrallapi kicks me out (Please enter an array)... Did i miss something ? Thanks for your help !
Here is a request example with mandrillapp:
{
"key":"apikey",
"message":{
"html":"example html",
"text":"example text",
"subject":"example subject",
"from_email":"from_email#example.com",
"from_name":"example from_name",
"to":[
{
"email":"email#example.com",
"name":"example name"
}
],
"headers":{
"...":"..."
},
"track_opens":true,
"track_clicks":true,
"auto_text":true,
"url_strip_qs":true,
"bcc_address":"bcc_address#example.com",
"merge":true,
"global_merge_vars":[
{
"name":"example name",
"content":"example content"
}
],
"merge_vars":[
{
"rcpt":"rcpt#example.com",
"vars":[
{
"name":"example name",
"content":"example content"
}
]
}
],
"tags":[
"example tags[]"
],
"google_analytics_domains":[
"..."
],
"google_analytics_campaign":[
"..."
],
"metadata":[
"..."
],
"attachments":[
{
"type":"example type",
"name":"example name",
"content":"example content"
}
]
}
}

Related

Send push notification title to its invocation intent in Actions on Google

I'm sending push notifications in Actions on Google (ref this official documentation).
So once I send the notification I'm sending title in it. So it looks like this, where A Very Happy Birthday, Jay Patel is the title that I've sent.
So once I click on the notification, it opens Google Assistant and invokes the intent (configured in this step), but it doesn't specify any contexts or other data regarding that notification so I'm not getting a person name that I've specified in title or any other data.
I want to know, is there anyway so that I can pass some data(title or any other data of notification) to the invocation intent when a
person taps on the notification?
I'm getting this json response in my webhook when a person taps on the notification
{
"responseId":"e2de9045-b415-kr45-be96-1a35779abcde",
"queryResult":{
"queryText":"intent:send_push",
"parameters":{
},
"allRequiredParamsPresent":true,
"fulfillmentText":"Latest update is here!",
"fulfillmentMessages":[
{
"text":{
"text":[
"Latest update is here!"
]
}
}
],
"intent":{
"name":"projects/happierwork-bot/agent/intents/d1f4c032-28cf-4906-a393-6f2a612c0496",
"displayName":"send_push"
},
"intentDetectionConfidence":1.0,
"languageCode":"en-in"
},
"originalDetectIntentRequest":{
"source":"google",
"version":"2",
"payload":{
"user":{
"userId":"my_id",
"accessToken":"my_token",
"permissions":[
"UPDATE"
],
"locale":"en-IN",
"lastSeen":"2018-10-09T05:57:18Z"
},
"conversation":{
"conversationId":"ABwppHE7XKXDdjfjSRPF_OCVttGKMavfasdffngesQEI2Jy11Q8fp8lNXgpgGtFe7KCxK3WWey-1ColL7",
"type":"NEW"
},
"inputs":[
{
"intent":"send_push",
"rawInputs":[
{
"inputType":"URL",
"url":"bot_url?intent=send_push"
}
],
"arguments":[
{
"name":"UPDATES",
"boolValue":true
}
]
}
],
"surface":{
"capabilities":[
{
"name":"actions.capability.WEB_BROWSER"
},
{
"name":"actions.capability.AUDIO_OUTPUT"
},
{
"name":"actions.capability.SCREEN_OUTPUT"
},
{
"name":"actions.capability.MEDIA_RESPONSE_AUDIO"
}
]
},
"isInSandbox":true,
"availableSurfaces":[
{
"capabilities":[
{
"name":"actions.capability.WEB_BROWSER"
},
{
"name":"actions.capability.AUDIO_OUTPUT"
},
{
"name":"actions.capability.SCREEN_OUTPUT"
}
]
}
]
}
},
"session":"projects/myproject-bot/agent/sessions/ABwppHE7XKXDdjfjSRPF_OCVtasdffagbKiGKA9sCsQEI2Jy11Q8fp8lNXgpgGtFe7KCxK3WWey-1ColL7"
}
You can supply argument data using the argument field of the push message target.
Please view the reference for more detail:
https://actions-on-google.github.io/actions-on-google-nodejs/2.12.0/interfaces/_service_actionssdk_api_v2_.googleactionsv2custompushmessagetarget.html

alexa - audioPlayer.Play issue displaying content on Echo Show Now Playing screen

I am having issues understanding how to display images on the Echo Show inside the audioPlayer 'Now Playing' screen.
I am currently playing an audio file and want to display an image on the 'Now Playing' screen. The closest I have been able to get is the following code which displays the image and title just before the audio starts, but then disappears immediately and the Echo Show goes to the 'Now Playing' screen with no background image and no metadata. I feel I'm close, but just cannot understand how to update the 'Now Playing' screen, rather than the screen that comes immediately before it.
This is part of the code (which works as per above):
var handlers = {
'LaunchRequest': function() {
this.emit('PlayStream');
},
'PlayStream': function() {
let builder = new Alexa.templateBuilders.BodyTemplate1Builder();
let template = builder.setTitle('Test Title')
.setBackgroundImage(makeImage('https://link_to_my_image.png'))
.setTextContent(makePlainText('Test Text'))
.build();
this.response.speak('OK.').
audioPlayerPlay(
'REPLACE_ALL',
stream.url,
stream.url,
null,
0)
.renderTemplate(template);
this.emit(':responseReady');
}
I have been looking at this page https://developer.amazon.com/docs/custom-skills/audioplayer-interface-reference.html but cannot understand how to convert the structure of what is on that page into my code. I assume that, from the code on the page :
{
"type": "AudioPlayer.Play",
"playBehavior": "valid playBehavior value such as ENQUEUE",
"audioItem": {
"stream": {
"url": "https://url-of-the-stream-to-play",
"token": "opaque token representing this stream",
"expectedPreviousToken": "opaque token representing the previous stream",
"offsetInMilliseconds": 0
},
"metadata": {
"title": "title of the track to display",
"subtitle": "subtitle of the track to display",
"art": {
"sources": [
{
"url": "https://url-of-the-album-art-image.png"
}
]
},
"backgroundImage": {
"sources": [
{
"url": "https://url-of-the-background-image.png"
}
]
}
}
}
}
I somehow need to get this part :
"metadata": {
"title": "title of the track to display",
"subtitle": "subtitle of the track to display",
"art": {
"sources": [
{
"url": "https://url-of-the-album-art-image.png"
}
]
},
Into this block of my code :
audioPlayerPlay(
'REPLACE_ALL',
streamInfo.url,
streamInfo.url,
null,
0)
.renderTemplate(template);
(and could probably lose the .renderTemplate(template); part as it only flashes up briefly before the 'Now Playing' screen loads anyway.
Any ideas on how to achieve this?
Thanks!
Update :
I have added the following to index.js:
var metadata = {
title: "title of the track to display",
subtitle: "subtitle of the track to display",
art: {
sources: {
url: "https://url-of-the-album-art-image.png"
}
}
};
And modified the audioPlayer as follows :
audioPlayerPlay(
'REPLACE_ALL',
stream.url,
stream.url,
null,
0,
metadata)
.renderTemplate(template);
And modified the responseBuilder.js as indicated:
audioPlayerPlay(behavior, url, token, expectedPreviousToken, offsetInMilliseconds, metadata) {
const audioPlayerDirective = {
type : DIRECTIVE_TYPES.AUDIOPLAYER.PLAY,
playBehavior: behavior,
audioItem: {
stream: {
url: url,
token: token,
expectedPreviousToken: expectedPreviousToken,
offsetInMilliseconds: offsetInMilliseconds,
metadata : metadata
}
}
};
this._addDirective(audioPlayerDirective);
return this;
}
But I'm still not getting anything displayed on the 'Now Playing' screen.
For some reason the Echo Show is not updating in realtime and needs to be rebooted before it will show whatever is passed in the metadata variable, which is why I wasn't seeing any results.
Simply passing a variable as such works fine. I just need to find out why the content gets stuck on the 'Now Playing' screen and requires a reboot to work.
var "metadata": {
"title": "title of the track to display",
"subtitle": "subtitle of the track to display",
"art": {
"sources": [
{
"url": "https://url-of-the-album-art-image.png"
}
]
},
Just define your metadata as below. And pass it as a 6th argument to audioPlayerPlay;
"metadata": {
"title": "title of the track to display",
"subtitle": "subtitle of the track to display",
"art": {
"sources": [
{
"url": "https://url-of-the-album-art-image.png"
}
]
},
audioPlayerPlay(
'REPLACE_ALL',
streamInfo.url,
streamInfo.url,
null,
0,metadata)
P.S. For this to work properly, You have to modify your node modules which you ll be zipping and uploading to lambda.
steps -
Go to your node_modules\alexa-sdk\lib and open responseBuilder file in it. And modify the code as follows-
audioPlayerPlay(behavior, url, token, expectedPreviousToken, offsetInMilliseconds, **metadata**) {
const audioPlayerDirective = {
type : DIRECTIVE_TYPES.AUDIOPLAYER.PLAY,
playBehavior: behavior,
audioItem: {
stream: {
url: url,
token: token,
expectedPreviousToken: expectedPreviousToken,
offsetInMilliseconds: offsetInMilliseconds
},
**metadata : metadata**
}
};
this._addDirective(audioPlayerDirective);
return this;
}
P.S. - The node module modifications required only if you are using alexa-sdk version 1.
I know it's been years since this question was originally posted, but for those like me who stumble upon this now, make sure you use a unique token in the play directive because metadata is cached using that token.
See the yellow Important note in the following section https://developer.amazon.com/en-US/docs/alexa/custom-skills/audioplayer-interface-reference.html#images
Important: The metadata for a given audio stream is identified by the
audioItem.stream.token included in the Play directive. Note that the
metadata associated with a particular audioItem.stream.token may be
cached in the Alexa service for up to five days, so changes to the
metadata (such as a different image, or a change to the title text)
may not be reflected immediately on the device. For instance, you may
notice this when testing if you experiment with different images or
title text for the same audio stream. You can send a new Play
directive with a different audioItem.stream.token to clear the cache.
And an example payload with a token:
{
"type": "AudioPlayer.Play",
"playBehavior": "valid playBehavior value such as ENQUEUE",
"audioItem": {
"stream": {
"url": "https://cdn.example.com/url-of-the-stream-to-play",
"token": "opaque token representing this stream",
"expectedPreviousToken": "opaque token representing the previous stream",
"offsetInMilliseconds": 0,
"captionData":{
"content": "WEBVTT\n\n00:00.000 --> 00:02.107\n<00:00.006>My <00:00.0192>Audio <00:01.232>Captions.\n",
"type": "WEBVTT"
}
},
"metadata": {
"title": "title of the track to display",
"subtitle": "subtitle of the track to display",
"art": {
"sources": [
{
"url": "https://cdn.example.com/url-of-the-album-art-image.png"
}
]
},
"backgroundImage": {
"sources": [
{
"url": "https://cdn.example.com/url-of-the-background-image.png"
}
]
}
}
}
}

API Gateway and DynamoDB PutItem for String Set

I can't seem to find how to correctly call PutItem for a StringSet in DynamoDB through API Gateway. If I call it like I would for a List of Maps, then I get objects returned. Example data is below.
{
"eventId": "Lorem",
"eventName": "Lorem",
"companies": [
{
"companyId": "Lorem",
"companyName": "Lorem"
}
],
"eventTags": [
"Lorem",
"Lorem"
]
}
And my example template call for companies:
"companies" : {
"L": [
#foreach($elem in $inputRoot.companies) {
"M": {
"companyId": {
"S": "$elem.companyId"
},
"companyName": {
"S": "$elem.companyName"
}
}
} #if($foreach.hasNext),#end
#end
]
}
I've tried to call it with String Set listed, but it errors out still and tells me that "Start of structure or map found where not expected" or that serialization failed.
"eventTags" : {
"SS": [
#foreach($elem in $inputRoot.eventTags) {
"S":"$elem"
} #if($foreach.hasNext),#end
#end
]
}
What is the proper way to call PutItem for converting an array of strings to a String Set?
If you are using JavaScript AWS SDK, you can use document client API (docClient.createSet) to store the SET data type.
docClient.createSet - converts the array into SET data type
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName:table,
Item:{
"yearkey": year,
"title": title
"product" : docClient.createSet(['milk','veg'])
}
};

Google Analytics: Filter by custom dimension

I'm using the enhanced ecommerce tracking from Google Analytics to send data like this in JS to GA:
ga("ec:addImpression", {
brand: null,
dimension2: "shop123",
id: 1,
list: "Search",
name: "Product 123",
position: 1
});
ga("send", "pageview");
Then, I use the Reporting API to generate some charts. Here, I want to filter by my custom dimension dimension2. The request looks like this:
{
"reportRequests":[
{
"dateRanges":[
{
"startDate":"2016-10-17",
"endDate":"2016-11-16"
}
],
"viewId":"132093148",
"metrics":[
{
"expression":"ga:productListViews"
}
],
"dimensions":[
{
"name":"ga:date"
},
{
"name":"ga:dimension2"
}
],
"dimensionFilterClauses":[
{
"filters":[
{
"dimension_name":"ga:dimension2",
"operator":"EXACT",
"expressions":[
"shop123"
]
}
]
}
]
}
]
}
However, this returns no results:
{
"reports":[
{
"columnHeader":{
"dimensions":[
"ga:date",
"ga:dimension2"
],
"metricHeader":{
"metricHeaderEntries":[
{
"name":"ga:productListViews",
"type":"INTEGER"
}
]
}
},
"data":{
"totals":[
{
"values":[
"0"
]
}
]
}
}
]
}
But when I remove the dimensionFilterClauses I get all the results, of course not filtered by dimension2.
Did I anything wrong when filtering for that dimension?
Change your string dimension_name for dimensionName and try.
As you can see in the examples: https://developers.google.com/analytics/devguides/reporting/core/v4/samples
"dimensionFilter":
{
"dimensionName":"ga:browser",
"operator":"EXACT",
"expressions":["Safari"]
}

Firebase database modeling

I'm starting out using firebase and even though I've spent 2 days on firebase db and nosql I'm still not sure if I'm on the right track.
I'm working on a fairly simple usecase/dataset:
I have content-items (title, coordinates, ...) which can be attributed to subcategories. Subcategories are attributed to categories.
Sound simple? Ok, I created the following:
{
"contentitems": {
"item1": {
"title": "i am a content item",
"coordinates": ""
},
"item2": { ... },
"item3": { ... }
},
"subcategories": {
"sc1": {
"title": "i am a subcategory",
"contentitems": {
"item1" : true,
"item2" : true
}
},
"sc2": {
"title": "i am another subcategory",
"contentitems": {
"item1" : true,
"item134" : true
}
},
"sc3": { ... }
},
"categories": {
"c1": {
"title" : "i am a cateogry,
"subcategories": {
"sc1" : true,
"sc2" : true
},
},
"c2": { ... },
"c3": { ... }
}
}
As far as I can tell this should be fine for the following usecase (in an app):
I click on a category from the categories list and open a list with all related subcategories. When I click on a subcategory I open a list with all related content-items.
Is this correct? Are there any pitfalls I can't see at the moment? Am I completly off?
2n part of my question:
How can I achieve a geolocation search with a bounding box? Do I have to create another 'table' called geocoordinates like this:
"geocoordinates": {
"coords" : {
lat: "45",
lon: "44"
}
}
How can I get all data within the bounding box?

Resources