I am trying to develop a web application using Watson Conversation service and Watson TTS service. The conversation output is sent to the TTS service for conversion. I am doing this in NodeRED and also i have put a function node between conversation node and TTS node which assigns the payload. After deployment I am only getting the conversational dialog chatbot but not the speech as I am suppose to. Please help me figure out what am I missing?
*PS: I am using HTTP post and HTTP get for this.
I built a flow that works and you will need to install a node that can play audio. The text to speech node does not actually play any sound. It creates an audio file.
Go to the hamburger in the upper right of the node red editor. Look for Palette Manager. look for node-red-contrib-play-audio and install it. I assume you have node-red-bluemix-nodes already.
you will need a node to retrieve the input, I used an inject node for the test.
connect it to your conversation node. Double click it and put the Workspace ID. (it is on the workspace under the three dots in the upper right of each one. Copy that long string into your node. I used the default car tutorial.
connect that to a function node. I then have to move the response from the conversation from msg.payload.output.text[0] to msg.payload like so:
msg.payload = msg.payload.output.text[0];
return msg;
connect that to a text to speech node. Fill in any credentials, pick a voice and click the output to msg.payload. If you forget to do this then the audio node will actually read the text instead of using the text to speech node's voice. The audio node's voice is not great.
connect the play audio node.
That is it. You should have a working voice.
A good way to see what is going on is to use a debug node. This lets you see where content is flowing and drop in functions to redirect the output appropriately for each node.
Copy the code below and go into the hamburger and do an import from clipboard to a new flow. You will need to fill in appropriate passwords and workspace ids but this shows how it is working.
[{
"id": "b7b6d9fc.1997f8",
"type": "tab",
"label": "Flow 2"
}, {
"id": "d0ed4492.045c18",
"type": "inject",
"z": "b7b6d9fc.1997f8",
"name": "",
"topic": "",
"payload": "play the radio",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"x": 159.5,
"y": 122,
"wires": [
["dc33249.3227bd8"]
]
}, {
"id": "dc33249.3227bd8",
"type": "watson-conversation-v1",
"z": "b7b6d9fc.1997f8",
"name": "",
"workspaceid": "",
"multiuser": false,
"context": true,
"default-endpoint": true,
"service-endpoint": "https://gateway.watsonplatform.net/conversation/api",
"x": 383.5,
"y": 121,
"wires": [
["d3c07b87.22f9c8"]
]
}, {
"id": "711b8067.a1c7",
"type": "debug",
"z": "b7b6d9fc.1997f8",
"name": "",
"active": true,
"console": "false",
"complete": "true",
"x": 751.5,
"y": 200,
"wires": []
}, {
"id": "9826b891.eb02b8",
"type": "watson-text-to-speech",
"z": "b7b6d9fc.1997f8",
"name": "",
"lang": "en-US",
"langhidden": "en-US",
"langcustom": "NoCustomisationSetting",
"langcustomhidden": "",
"voice": "en-US_MichaelVoice",
"voicehidden": "",
"format": "audio/wav",
"password": "",
"payload-response": true,
"default-endpoint": true,
"service-endpoint": "https://stream.watsonplatform.net/text-to-speech/api",
"x": 757.5,
"y": 64,
"wires": [
["ccf6f5a7.700508"]
]
}, {
"id": "d3c07b87.22f9c8",
"type": "function",
"z": "b7b6d9fc.1997f8",
"name": "",
"func": "msg.payload = msg.payload.output.text[0];\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 561.5,
"y": 120,
"wires": [
["9826b891.eb02b8", "711b8067.a1c7"]
]
}, {
"id": "ccf6f5a7.700508",
"type": "play audio",
"z": "b7b6d9fc.1997f8",
"name": "",
"voice": "0",
"x": 963.5,
"y": 64,
"wires": []
}]
Here is a link to a sample flow that uses Text to Speech on an HTML page. Take that as your starter, and add in Conversation.
https://github.com/watson-developer-cloud/node-red-labs/tree/master/basic_examples/text_to_speech
you need to provide more information about your problem.
anyway, one thing I've noticed is that text to speech generates a 44khz audio file. If you're running it locally in a RPI using some USB dongle, for example, it may not be able to play because it support by default 22Khz audio. So being able to play it locally also depends on the hardware and how the sound is configured in it.
Related
Is there an easy way to obtain the geolocation data of an autocomplete reply?
Currently only text is returned in a query. How would one read the GPS coordinates for an entry?
https://autocomplete.search.hereapi.com/v1/autocomplete?apiKey=xxx&q=k%C3%B6ln%20&in=countryCode:DEU&lang=de&limit=20&resultType=city,postalCode
{
"title": "Deutschland, Köln, Anschlussstelle Köln-Messe",
"id": "here:af:street:kXSoQ5Ilp2fEnS-ifyMsXD",
"resultType": "street",
"address": {
"label": "Anschlussstelle Köln-Messe, 50679 Köln, Deutschland",
"countryCode": "DEU",
"countryName": "Deutschland",
"stateCode": "NW",
"state": "Nordrhein-Westfalen",
"countyCode": "K",
"county": "Köln",
"city": "Köln",
"street": "Anschlussstelle Köln-Messe",
"postalCode": "50679"
},
"highlights": {
"title": [
{
"start": 35,
"end": 39
}
],
"address": {
"label": [
{
"start": 16,
"end": 20
}
],
"street": [
{
"start": 16,
"end": 20
}
]
}
}
},
The idea of autocomplete is to provide key-by-key input completion for the end user. We believe the end user can decide based on the text response and does not need to show the position on the map. Only for the result that the user clicks on a lookup needs to be requested from the application which then shows the complete address including position.
So to get the geolocation, you need to use lookup endpoint while the user clicks, e.g: https://lookup.search.hereapi.com/v1/lookup?id=here:af:street:kXSoQ5Ilp2fEnS-ifyMsXD&apiKey={{YOUR_API_KEY}}
In addition, you can evalaute the autosuggestion endpoint (which contains the position info) and see if it can meet your requirement: https://developer.here.com/documentation/geocoding-search-api/dev_guide/topics/endpoint-autosuggest-brief.html
According to this Map Provider Configuration Changes, I use this configuration to add HERE maps in GeoMap:
var oMapConfig = {
"MapProvider": [{
"name": "HEREMAPS",
"type": "HERETerrainMap",
"description": "",
"tileX": "256",
"tileY": "256",
"maxLOD": "20",
"copyright": "Tiles Courtesy of HERE Maps",
"Source": [{
"id": "s1",
"url": "https://1.base.maps.cit.api.here.com/maptile/2.1/maptile/newest/reduced.day/{LOD}/{X}/{Y}/256/png8?app_id=MY_ID&app_code=MY_CODE"
}, {
"id": "s2",
"url": "https://2.base.maps.cit.api.here.com/maptile/2.1/maptile/newest/reduced.day/{LOD}/{X}/{Y}/256/png8?app_id=MY_ID&app_code=MY_CODE"
}
]
}],
"MapLayerStacks": [{
"name": "DEFAULT",
"MapLayer": {
"name": "layer1",
"refMapProvider": "HEREMAPS",
"opacity": "1.0",
"colBkgnd": "RGB(255,255,255)"
}
}]
};
this.oMap.setMapConfiguration(oMapConfig);
this.oMap.setRefMapLayerStack("DEFAULT");
But my map is in black and white style:
What I want is standard map:
In Configuring HERE (formerly Nokia, NAVTEQ) maps, new server URL is provided, I've tried this, but not working.
{
"id": "s1",
"url": http://1.maps.nlp.nokia.com/maptile/2.1/maptile/newest/normal.day/{LOD}/{X}/{Y}/256/png?app_id=YOUR_APP_ID&app_code=YOUR_APP_CODE"
}, {
"id": "s2",
"url": "http://2.maps.nlp.nokia.com/maptile/2.1/maptile/newest/normal.day/{LOD}/{X}/{Y}/256/png?app_id=MY_APP_ID&app_code=MY_APP_CODE"
}
And failed to find MapProvider configuration documentation in setMapConfiguration of GeoMap
Just change reduced.day to normal.day in your map URL, and you'll get colored map:)
edit:
Please refer to https://developer.here.com/documentation/map-tile/topics/examples.html for detailed APIs
As I don't know why suggested, using Postman.
Per docs, have succesfully POSTed the configuration to facebook APIs:
which is not supposed to be anyways locale specific. Even I don't see here
Localization: Developers can now provide text in multiple languages (or entirely different menus) for each local your bot's users may come from.
Like my brother, I have tried almost everything so far
This looks like some crazy bug. Is there some work around to add a simplest persistent menu?
Wasted 2 hours on this issue. Until I realised you have to delete the conversation then refresh facebook with ignore cache (ctrl+shift+r in chrome) and then it will show.
The FB API document states that the API link to hit for applying persistent menu to the page specific bot is:
https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<PAGE_ACCESS_TOKEN>
Notice the me after version number i.e v2.6 in this specific case. However, this did not worked for a lot of people
There is small change in the API link to hit:
graph.facebook.com/v2.6/Page ID/messenger_profile?access_token=PAGE ACCESS TOKEN
Notice that me is replaced with the fb Page Id.
And the sample payload can still be the same:
{
"get_started": {
"payload": "Get started"
},
"persistent_menu": [
{
"locale": "default",
"composer_input_disabled": false,
"call_to_actions": [
{
"title": "Stop notifications",
"type": "nested",
"call_to_actions": [
{
"title": "For 1 week",
"type": "postback",
"payload": "For_1_week"
},
{
"title": "For 1 month",
"type": "postback",
"payload": "For_1_month"
},
{
"title": "For 1 year",
"type": "postback",
"payload": "For_1_year"
}
]
},
{
"title": "fresh jobs",
"type": "postback",
"payload": "fresh jobs"
},
{
"title": "More",
"type": "nested",
"call_to_actions": [
{
"title": "like us",
"type": "web_url",
"url": "https://www.facebook.com/nordible/"
},
{
"title": "blog",
"type": "web_url",
"url": "http://xameeramir.github.io/"
}
]
}
]
}
]
}
Notice that it is mandatory to configure get_started button before setting up the persistent_menu.
I am trying to use Mapbox to calculate the duration between two locations however the examples here are incomplete (at least with my limited experience). I would like to connect to this API using server-side Java, however I can't even get a basic example working in javaScript, Python or simply in the address bar in my browser.
I can get an example working in my browser using this url and substituting in my API key:
https://api.mapbox.com/geocoding/v5/mapbox.places/Chester.json?country=us&access_token=pk.my-token-value
However I can't get a similar example working with the distance API. The best I can manage is something like this:
https://api.mapbox.com/distances/v1/driving/[13.41894,52.50055],[14.10293,52.50055]&access_token=pk.my-token-value.
But I have no idea how to format my coordinates as I can't find a single example.
Has anyone been able to get this working. Ideally in Java, but client-side JavaScript or a valid url would be a great start.
I should also add that I can't get the JavaScript or Python ones working as they rely on external librarys that aren't referenced anywhere in the documentation!.
Thanks in advance.
Looks like you can provide a list of 2 or more semi-colon separated coordinates:
https://api.mapbox.com/optimized-trips/v1/mapbox/driving/13.41894,52.50055;14.10293,52.50055?access_token=pk.your_token
returns:
{
"code":"Ok",
"waypoints":[
{"distance":9.0352511932471,"name":"","location":[13.418991,52.500625],"waypoint_index":0,"trips_index":0},
{"distance":91.0575241567836,"name":"Berliner Chaussee","location":[14.103096,52.499738],"waypoint_index":1,"trips_index":0}
],
"trips":
[
{"geometry":"}_m_Iu{{pA}ZuQ}Iad#}cAk^jr#etOdE_iGtTqoAxBkoGnOkiCjR_s#wJ_v#b#}aN|aBogRyVucBiEw_C~r#_eB`Fc`NtP_bAshBorHa#}dCkOe~AmPmrGlPlrGjOd~A`#|dCrhBnrHuP~aAaFb`N_s#~dBhEv_CxVtcBkbBbeRo#l`NzJ`z#mRpr#qOpjCwBpnGoT~lAeEdkGsr#jtOtp#dQ~UjTtDfZf]jS",
"legs":[
{"summary":"","weight":4198.3,"duration":3426.4,"steps":[],"distance":49487},
{"summary":"","weight":7577.8,"duration":3501.3,"steps":[],"distance":49479.7}
],
"weight_name":"routability",
"weight":11776.1,
"duration":6927.700000000001,
"distance":98966.7}
]
}
I don't know if this is better now, but I had to work through it right now and can give you this example
curl "https://api.mapbox.com/directions-matrix/v1/mapbox/driving/9.51416,54.47004;13.5096410,50.0716190;6.8614070,48.5206360;14.1304840,51.0856060?sources=0&access_token={token}"`
This will return the following json for driving durations. I made use of the sources attribute, which is my search lng/lat and all other points are places in my database.
{
"code": "Ok",
"durations": [
[0.0, 29407.9, 34504.7, 24163.5]
],
"destinations": [{
"distance": 131.946157371,
"name": "",
"location": [9.514914, 54.468939]
}, {
"distance": 34.636975593,
"name": "",
"location": [13.509868, 50.071344]
}, {
"distance": 295.206928933,
"name": "",
"location": [6.863566, 48.52287]
}, {
"distance": 1186.975749670,
"name": "",
"location": [14.115694, 51.080408]
}],
"sources": [{
"distance": 131.946157371,
"name": "",
"location": [9.514914, 54.468939]
}]
}
Adding the annotations=distance parameter to the url will return the distances instead of the durations if you need that.
{
"code": "Ok",
"distances": [
[0.0, 738127.3, 902547.6, 616060.8] // distances in meters
],
"destinations": [{ // destinations including the source
"distance": 131.946157371, // result 0
"name": "",
"location": [9.514914, 54.468939]
}, {
"distance": 34.636975593, // result 1
"name": "",
"location": [13.509868, 50.071344]
}, {
"distance": 295.206928933, // result 2
"name": "",
"location": [6.863566, 48.52287]
}, {
"distance": 1186.975749670, // result 3
"name": "",
"location": [14.115694, 51.080408]
}],
"sources": [{ // source where we start from
"distance": 131.946157371,
"name": "",
"location": [9.514914, 54.468939]
}]
}
I wasn't able to find anything fitting in HTTP API documentation.
As I know, there's some tracks popping out in SC widget after current track is finished, therefore there is some related tracks functionality in SC itself, yet can we access it via API?
I.e get a list of tracks, related to given track's id.
Disclaimer: This is an undocumented endpoint and is subject to change at anytime by SoundCloud.
There is an undocumented endpoint that allows you to access a track's related sounds:
HTTP GET: https://api.soundcloud.com/tracks/[TRACK_ID]/related?client_id=[YOUR_CLIENT_ID]
You didn't specify a language, so i'm just going to give a high-level overview on how to use the endpoint.
First, get your track URL. I'll use this one as an example: https://soundcloud.com/msmrsounds/ms-mr-hurricane-chvrches-remix
Then hit the resolve endpoint to get the track_id.
HTTP GET: https://api.soundcloud.com/resolve.json?url=https%3A%2F%2Fsoundcloud.com%2Fmsmrsounds%2Fms-mr-hurricane-chvrches-remix&client_id=[YOUR_CLIENT_ID]
Response:
{
"status": "302 - Found",
"location": "https://api.soundcloud.com/tracks/90787841.json?client_id=[YOUR_CLIENT_ID]"
}
Next, hit the related endpoint with your track_id.
HTTP GET: https://api.soundcloud.com/tracks/90787841/related?client_id=[YOUR_ClIENT_ID]
The full response will give you up to 50 related tracks. The response is too large to post, but it's just an array of tracks.
[
{
"kind": "track",
"id": 112741336,
"created_at": "2013/09/27 09:40:29 +0000",
"user_id": 59817646,
"duration": 215896,
"commentable": true,
"state": "finished",
"original_content_size": 38068298,
"last_modified": "2015/04/04 20:17:24 +0000",
"sharing": "public",
"tag_list": "CHVRCHES Whitney Houston Zane Lowe",
"permalink": "chvrches-its-not-right-but-its",
"streamable": true,
"embeddable_by": "all",
"downloadable": false,
"purchase_url": null,
"label_id": null,
"purchase_title": null,
"genre": "Electronic",
"title": "CHVRCHES - It's Not Right But It's Okay (Whitney Houston Cover)",
"description": "CHVRCHES - It's Not Right But It's OK (Whitney Houston Cover) from Zane's Live Sessions",
"label_name": "",
"release": "",
"track_type": "recording",
"key_signature": "",
"isrc": "",
"video_url": null,
"bpm": null,
"release_year": null,
"release_month": null,
"release_day": null,
"original_format": "wav",
"license": "all-rights-reserved",
"uri": "https://api.soundcloud.com/tracks/112741336",
"user": {
"id": 59817646,
"kind": "user",
"permalink": "uknewmusic",
"username": "UKNewMusic",
"last_modified": "2013/09/27 09:38:04 +0000",
"uri": "https://api.soundcloud.com/users/59817646",
"permalink_url": "http://soundcloud.com/uknewmusic",
"avatar_url": "https://a1.sndcdn.com/images/default_avatar_large.png"
},
"permalink_url": "http://soundcloud.com/uknewmusic/chvrches-its-not-right-but-its",
"artwork_url": "https://i1.sndcdn.com/artworks-000058757165-6tnuep-large.jpg",
"waveform_url": "https://w1.sndcdn.com/XkEffI5hwjZ7_m.png",
"stream_url": "https://api.soundcloud.com/tracks/112741336/stream",
"playback_count": 680326,
"download_count": 0,
"favoritings_count": 9241,
"comment_count": 199,
"attachments_uri": "https://api.soundcloud.com/tracks/112741336/attachments",
"policy": "ALLOW"
},
{ ...
}
]