Google Text-to-Speech API 400 error for specific paragraph - google-text-to-speech

I have an integration set up with Google TTS generating audio for a daily Bloomberg email newsletter. It's been working reliably, but I recently received a 400 error for a specific group of sentences:
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT
Sending POST to https://cloud.google.com/text-to-speech/docs/reference/rest/v1/text/synthesize with this payload:
{
"input": {
"text": "Still it hangs together in a rough schematic way, which means you can try it in thecryptomarket. Crypto, particularly decentralized finance, has some key advantages for this, including:\n\n * Weird and fragmented liquidity, so that you can trade with yourself on a futures exchange, and you can move the price of a token a lot on the spot market;\n * A love of mechanical rules and automated markets, so that if your X position spikes from $1 million to $100 million, some decentralized finance platform will say “yup, now it’s worth $100 million, so it’s good collateral for a $40 million loan”; and\n * A presumption of anonymity, so exchanges will let you trade with yourself, and won’t be able to come after you for your losses, since they just have some anonymous wallet addresses."
},
"voice": {
"name": "en-US-Neural2-A",
"languageCode": "en-US"
},
"audioConfig": {
"pitch": -4,
"speakingRate": 1.2,
"audioEncoding": "MP3"
}
}
I've confirmed this behavior is consistent in Google's API explorer, so I think I've isolated the text content itself as the source of the error. I eliminated unescaped characters as a cause by trying a no-symbol version of the text that still failed. API documentation hasn't yielded any clues on allowable characters or other requirements.
The weirdest thing is that the text above works if I delete either the first sentence or the last sentence. Is Google checking the content itself for prohibited phrases or something???
Any other ideas to resolve this error?

I have been able to reproduce this exact same error with multiple AU, UK and US english Neural2 voices using the text you provided. I've also observed this same exact behavior with other random segments of text of my own.
The workaround I've found (and which is working on the text you provided) is to simply use Wavenet voices instead.

Related

Is it not possible to use curl, to use Google Cloud Speech API, to recognize within 10 to 15 minute files?

I'm using REST API with cURL because I need to do something quick and simple, and I'm on a box that I can't start dumping garbage on; i.e. some thick developer SDK.
I started out base64 encoding flac files and initiating speech.syncrecognize.
That eventually failed with:
{
"error": {
"code": 400,
"message": "Request payload size exceeds the limit: 10485760.",
"status": "INVALID_ARGUMENT"
}
}
So okay, you can't send 31,284,578 bytes in the request; have to use Cloud Storage. So, I upload the flac audio file and try again using the file now in Cloud Storage. That fails with:
{
"error": {
"code": 400,
"message": "For audio inputs longer than 1 min, use the 'AsyncRecognize' method.",
"status": "INVALID_ARGUMENT"
}
}
Great, speech.syncrecognize doesn't like the content size; try again with speech.asyncrecognize. That fails with:
{
"error": {
"code": 400,
"message": "For audio inputs longer than 1 min, please use LINEAR16 encoding.",
"status": "INVALID_ARGUMENT"
}
}
Okay, so speech.asyncrecognize can only do LPCM; upload the file in pcm_s16le format and try again. So finally, I get an operation handel:
{
"name": "9174269756763138681"
}
Keep checking it, and eventually it's complete:
{
"name": "9174269756763138681",
"done": true,
"response": {
"#type": "type.googleapis.com/google.cloud.speech.v1beta1.AsyncRecognizeResponse"
}
}
So wait, after all that, with the result now sitting on a queue, there is no REST method to request the result? Someone please tell me that I've missed the glaringly obvious staring me right in the face, and that Google didn't create completely pointless, incomplete, REST API.
So the answer to the question is, No, it is possible to use curl, to use Google Cloud Speech API, to recognize within 10 to 15 minute files... assuming you navigate and conform to a fairly tight set of constraints... at least in beta1.
What is not overtly obvious from the documentation is the result should be returned by the operations.get method... which would have been obvious had any of my attempts actually returned something other than empty results.
The source rate in my files is either 44,100 or 48,000 Hz, and I was setting sample_rate to the source native rate. However, contrary to the documentation which states:
Sample rate in Hertz of the audio data sent in all RecognitionAudio
messages. Valid values are: 8000-48000. 16000 is optimal. For best
results, set the sampling rate of the audio source to 16000 Hz. If
that's not possible, use the native sample rate of the audio source
(instead of re-sampling).
after re-sampling to 16,000 Hz I started to get results with operations.get.
I think it's worth noting that correlation does not imply causation. After re-sampling to 16,000 Hz the files becomes significantly smaller. Thus, I can't prove it's a sample rate issue, and not just the service choking on files over a certain size.
It's also worth noting the documentation refers to the Sample Rate inconsistently. It appears that gRPC API may be expecting sample_rate, and REST API may be expecting sampleRate, according to their respective detailed definitions, in which case the Quickstart may be giving an incorrect example for the REST API.

phpmailer error codes for outcome processing

I am building a mailout capability and it is working OK as far as it goes. However, I want to distinguish between various potential (high level) outcomes in order to determine what happens to each message after the current send attempt.
This must be a common requirement so I seem to be missing something pretty obvious, but I can't find anything that addresses it, either here or via Google or on PHPMailer site or .. . Possibly because there are so many questions about specific errors that I just can't find anything useful in all the other results.
At very high level:
Attempt send, and assess resulting error/result. Identify whether this message has been sent, must be retried later, or failed permanently.
- success -> update message status as 'SENT: OK'
- sent, but some issues (e.g. one recipient failed, others processed OK)-> 'SENT: some error'
- failed, due to temporary problem (e.g. connection problem, attachment open) -> 'TRY LATER'
- failed, due to message-specific problem that we should NOT try to resend-> 'FAILED: some error'
As I was unable to find an existing resource with e.g. a table of errors, I spent some time working through the phpmailerException code to try to build one myself, but it's not simple because a) they don't appear to have been designed in terms of this kind of grouping logic, b) it is not easy to uniquely identify a particular error: PHPMailer provides human-friendly messages, which are different in different languages, rather than an identifiable code - given that my solution will need to work across different language installations that's a problem!
Obviously SMTP itself provides a range of errorcodes which I could potentially use for this purpose, but how do I access these via PHPMailer? (This would work for me as I only use SMTP at this point - however, this would NOT work if other message transport like sendmail was used, so I would prefer a PHPMailer solution)
If you want individual result codes for individual address, you really need to send each message separately. If you do get errors on some recipients, they will be listed in the ErrorInfo property - look in the smtpSend function to see how the error string is assembled. I agree that it's not especially easy to parse that info out. The error messages in PHPMailer are generally more for the developer than the end user, so the translations are not that significant. You can get slightly more information about errors if you enable exceptions rather than relying only on return values.

Supporting multiple languages in a REST API

I have a collection of cities for which I'm creating a REST API (my first REST API). Each city has a number of language independent things, such as founding date and population count. Cities also have things that depend on the language, such as the title and a short description. Internally the city documents have this format:
{
"population": 9042,
"name": {
"en": "Berlin",
"nl": "Berlijn",
// ...
},
// ...
}
The users of my API always want to view the city info for a specific language only, and get back something like:
{
"population": 9042,
"name": Berlin,
// ...
}
I've made these accessible via /cities/:id/:language_code, for instance cities/123/en. Now I want to implement listing of cities: GET /cities. There the requested language is also needed. Since this would result in /cities/:language_code, I'm getting the impression putting this at the end of the url is not a good idea, and suspect I'll be better off with /en/cities/...whatever....
How is this typically done in REST APIs? Any big, nicely implemented, API out there that is a good example?
REST API's are based upon HTTP protocol, so they can use the headers, that are traditionaly used to defined the prefered locale.
So I would use a Accept-Language parameter for this.
# Request
GET /cities/.... HTTP/1.1
Host: www.example.org
Accept-Language: en,en-US,fr;q=0.6
Would give :
{
"population": 9042,
"name": Berlin,
// ...
}
It depends on your clients. If the clients are applications, then #Orabîg's answer is 100% correct. If your clients are web browers, though, you should track language as a user preference. The reason is that a user might be using a non-personal machine where the browser is set to a different language, and they may not know how to or be able to change that setting. Rather than forcing them to use an unfamiliar language, you build the preference into your API.
In that case, I would start with the language provided in Accept-Language until the user either identified themself. Once they are passing some identifying token in a header with each request, use that to figure out what language responses should be in.
Just to mention the related article of W3C about using headers for locale determination (not only language that seems be the original case of the question)
The HTTP Accept-Language header was originally only intended to specify the user's language. However, since many applications need to know the locale of the user, common practice has used Accept-Language to determine this information. It is not a good idea to use the HTTP Accept-Language header alone to determine the locale of the user. If you use Accept-Language exclusively, you may handcuff the user into a set of choices not to his liking.
For a first contact, using the Accept-Language value to infer regional settings may be a good starting point, but be sure to allow them to change the language as needed and specify their cultural settings more exactly if necessary. Store the results in a database or a cookie for later visits.
Some of the potential issues include the following:
Many users never change the defaults for Accept-Language. They are
set when the user agent is installed. Unless they are multilingual or
have some other reason to adjust language preferences they may not
even know such settings exist. Hence, the user may not have ever
ratified the Accept-Language setting.
A user agent may send a request
that specifies only a language and not a region, for example you may
not get a header with de-DE, de-CH or de-AT to indicate German as
spoken in Germany, Switzerland or Austria, respectively. On the other
hand, you might only get de indicating a preference for German. If
you were planning to use the region to decide what currency to use
you are now in a bind. Your particular circumstances might allow you
to make assumptions such as "Germany has 83 million people,
Switzerland has 7 million but only 63% speak German, Austria has 8
million, so this user probably uses the Euro. If we're wrong we'll
only offend 4.6% of our German speaking customers or just over 4
million people." Feel free to make such an assumption, if you can
accept the risk. Its a lot simpler to ask the user for more
information. Also, the math gets more difficult for Spanish or
English, for instance.
People borrow machines from friends, they rent
them from internet cafes. In these cases the inferred locale may be
inappropriate, and care should be taken to allow the user to select
the appropriate language and locale from whatever page they are
looking at.
Full article: Accept-Language used for locale setting

What are the requirements for the event name?

I've written an app to publish some events via the open graph api to facebook. For most of the events this works fine. But some events facebook denies:
"OAuthException: (#100) Invalid event name specified: event_info-name"
I searched the facebook doc but I couldn't find a detailed description how the link has to look alike. I convert it to utf8 with utf8_encode (PHP). I guess that the string length is limited. If so: How long can the string be? Are there some other restrictions?
Thanks, Michael
I created events with different name lengths an it seems that the max event name size is 74 characters (one with a length of 75 or more throws the "(#100) Invalid event name specified").
I think the characters in the name are pretty flexible. My titles had " and ' among others and showed up fine, without encoding, on the event page.
What events do you have coded for your application in the application settings See: https://developers.facebook.com/apps/{YOUR_APP_ID}/opengraph
I get the same error, but there appears to be STOP keywords but not sure where they are. If anyone is getting this error you might also want to look at Facebook Graph Error (#100) Invalid event name specified: event_info-name
As of January 2015 there's no character limit for event names. There's been a torrent of troll events here in Poland where people copypasted whole 100k character long books or pi number with 100k or so decimal places. The names were cut short in the event pages but in notifications page the whole names are displayed, cluttering it into oblivion.

How does the email header field 'thread-index' work?

I was wondering if anyone knew how the thread-index field in email headers work?
Here's a simple chain of emails thread indexes that I messaged myself with.
Email 1 Thread-Index: AcqvbpKt7QRrdlwaRBKmERImIT9IDg==
Email 2 Thread-Index: AcqvbpjOf+21hsPgR4qZeVu9O988Eg==
Email 3 Thread-Index: Acqvbp3C811djHLbQ9eTGDmyBL925w==
Email 4 Thread-Index: AcqvbqMuifoc5OztR7ei1BLNqFSVvw==
Email 5 Thread-Index: AcqvbqfdWWuz4UwLS7arQJX7/XeUvg==
I can't seem to say with certainty how I can link these emails together. Normally, I would use the in-reply-to field or references field, but I recently found that Blackberrys do NOT include these fields. The only include Thread-Index field.
They are base64 encoded Conversation Index values. No need to reverse engineer them as they are documented by Microsoft on e.g. http://msdn.microsoft.com/en-us/library/ms528174(v=exchg.10).aspx and more detailed on http://msdn.microsoft.com/en-us/library/ee202481(v=exchg.80).aspx
Seemingly the indexes in your example doesn't represent the same conversation, which probably means that the software that sent the mails wasn't able to link them together.
EDIT: Unfortunately I don't have enough reputation to add a comment, but adamo is right that it contains a timestamp - a somewhat esoteric encoded partial FILETIME. But it also contains a GUID, so it is pretty much guarenteed to be unique for that mail (of course the same mail can exist in multiple copies).
There's a good analysis of how exactly this non-standard "Thread-Index" header appears to be used, in this post and links therefrom, including this pdf (a paper presented at the CEAS 2006 conference) and this follow-up, which includes a comment on the issue from the evolution source code (which seems to reflect substantial reverse-engineering of this undocumented header).
Executive summary: essentially, the author eventually gives up on using this header and recommends and shows a different approach, which is also implemented in the c-client library, part of the UW IMAP Toolkit open source package (which is not for IMAP only -- don't let the name fool you, it also works for POP, NNTP, local mailboxes, &c).
I wouldn't be surprised if there are mail clients out there which would not be able to link Blackberry's mails to their threads. The Thread-Index header appears to be a Microsoft extension.
Either way, Novell Evolution implements this. Take a look at this short description of how they do it, or this piece of code that finds the thread parent of a given message.
I assume that, because the lengths of the Thread-Index headers in your example are all the same, these messages were all thread starts? Strange that they're only 22-bytes, though I suppose you could try applying the 5-bytes-per-message rule to them and see if it works for you.
If you are interested in parsing the Thread-Index in C# please take a look at this post
http://forum.rebex.net/questions/3841/how-to-interprete-thread-index-header
The snippet you will find there will let you parse the Thread-Index and retrieve the Thread GUID and message DateTime. There is a problem however, it does not work for all Thread-Indexes out there. Question is why do some Thread-Indexes generate invalid DateTime and what to do to support all of them???