TMS FNC Cloud Translation Guides
TTMSFNCCloudTranslation translates text and detects languages through a
cloud translation provider. One component covers every supported provider:
you set Service and APIKey, and Translate, Detect and
GetSupportedLanguages behave the same way regardless of which one is
selected. That makes the provider a configuration choice rather than a code
choice — useful when pricing, regional data residency or language coverage
decides it. This page covers selecting and authenticating a provider, the
Microsoft-specific endpoint and region settings, translating and detecting,
and combining the two.
Supported services
Service takes a TTMSFNCCloudTranslationService value:
| Value | Provider | Credentials |
|---|---|---|
tsGoogle |
Google Cloud Translation | APIKey |
tsMicrosoft |
Microsoft Translator | APIKey, plus ServiceEndPoint / ServiceRegion for a regional resource |
tsDeepL |
DeepL | APIKey |
Important
The IBM Translator service API was removed. There is no longer an IBM
value in TTMSFNCCloudTranslationService, so code or a stored setting that
selected it must be migrated to one of the three services above, with that
provider's own API key. See
Release notes for the version this happened in.
Because the provider is usually a stored setting rather than a literal, map it in one place and handle the retired IBM value explicitly instead of letting it fall through to a default:
function TForm1.ApplyTranslationService(const AConfiguredService: string): Boolean;
begin
Result := True;
// ServiceEndPoint and ServiceRegion are Microsoft-only, so clear them
// before selecting another provider.
TMSFNCCloudTranslation1.ServiceEndPoint := '';
TMSFNCCloudTranslation1.ServiceRegion := '';
if SameText(AConfiguredService, 'Google') then
TMSFNCCloudTranslation1.Service := tsGoogle
else if SameText(AConfiguredService, 'DeepL') then
TMSFNCCloudTranslation1.Service := tsDeepL
else if SameText(AConfiguredService, 'Microsoft') then
begin
TMSFNCCloudTranslation1.Service := tsMicrosoft;
TMSFNCCloudTranslation1.ServiceRegion := 'westeurope';
end
else if SameText(AConfiguredService, 'IBM') then
begin
// The IBM Translator service API was removed, so
// TTMSFNCCloudTranslationService no longer has an IBM value: an old
// stored setting has to be migrated to a supported service, with its
// own APIKey.
TMSFNCCloudTranslation1.Service := tsGoogle;
TMSFNCCloudTranslation1.APIKey := '';
ShowMessage('The IBM translation service is no longer available. ' +
'Select another provider and enter its API key.');
Result := False;
end
else
Result := False;
end;
Microsoft Translator endpoints and regions
Google and DeepL are reached on a single global host, but a Microsoft Translator resource may be global or regional, and a regional one rejects requests that do not name its region. Two properties cover this:
| Property | Effect when set | Effect when empty |
|---|---|---|
ServiceEndPoint |
Used as the request host, for a custom or regional resource | Falls back to the global https://api.cognitive.microsofttranslator.com |
ServiceRegion |
Sent as the Ocp-Apim-Subscription-Region header |
The header is omitted entirely |
Both apply to Translate, Detect and GetSupportedLanguages alike. A
regional key used without ServiceRegion typically fails authentication, so
set the region whenever the resource was not created as global.
procedure TForm1.ConfigureMicrosoftTranslator;
begin
TMSFNCCloudTranslation1.Service := tsMicrosoft;
TMSFNCCloudTranslation1.APIKey := 'your-translator-subscription-key';
// ServiceEndPoint replaces the global host. Leave it empty to use
// https://api.cognitive.microsofttranslator.com; set it when the resource
// was created with a custom or regional endpoint.
TMSFNCCloudTranslation1.ServiceEndPoint := 'https://my-translator.cognitiveservices.azure.com';
// ServiceRegion is sent as the Ocp-Apim-Subscription-Region header, which a
// regional (non-global) resource requires. An empty value omits the header.
TMSFNCCloudTranslation1.ServiceRegion := 'westeurope';
TMSFNCCloudTranslation1.OnTranslate := TranslationDone;
TMSFNCCloudTranslation1.Translate('Good morning', 'nl');
end;
procedure TForm1.TranslationDone(Sender: TObject;
const ARequest: TTMSFNCCloudTranslationRequest;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
if not ARequestResult.Success then
begin
// A 401 here usually means the key is regional but ServiceRegion is empty.
ShowMessage('Translation failed: ' + ARequestResult.ResultString);
Exit;
end;
if ARequest.Translations.Count > 0 then
Edit1.Text := ARequest.Translations[0].TranslatedText;
end;
Translating and detecting
Translate accepts a single string or a TStringList for a batch, plus the
target language code. Detect reports the language of a string without
translating it. GetSupportedLanguages fills SupportedLanguages with the
codes the selected provider accepts, named in the language you pass.
Each method reports either through its event — OnTranslate, OnDetect,
OnGetSupportedLanguages — or through an optional callback argument, which
keeps a multi-step flow in one place. Results arrive on the
TTMSFNCCloudTranslationRequest: Translations[i].TranslatedText alongside
SourceText and SourceLanguage, and Detections[i].SourceLanguage. Always
check ARequestResult.Success first, and read
ARequestResult.ResultString for the provider's error detail.
Combining detection and translation
Detecting first lets you skip the translation call when the text is already in the target language, which saves a request per item on a large batch. The callback overloads chain the two steps without splitting the logic across two event handlers:
{ FPendingText is a private string field on the form, holding the text
between the Detect and the Translate step. }
procedure TForm1.TranslateIfNeeded(const AText: string);
begin
// A regional Microsoft resource needs both the endpoint and the region, and
// both apply to the Detect call as much as to Translate.
TMSFNCCloudTranslation1.Service := tsMicrosoft;
TMSFNCCloudTranslation1.APIKey := 'your-translator-subscription-key';
TMSFNCCloudTranslation1.ServiceEndPoint := 'https://my-translator.cognitiveservices.azure.com';
TMSFNCCloudTranslation1.ServiceRegion := 'westeurope';
FPendingText := AText;
// The callback overload keeps the two steps together instead of splitting
// them across OnDetect and OnTranslate.
TMSFNCCloudTranslation1.Detect(AText,
procedure(const ARequest: TTMSFNCCloudTranslationRequest;
const ARequestResult: TTMSFNCCloudBaseRequestResult)
begin
if not ARequestResult.Success or (ARequest.Detections.Count = 0) then
Exit;
Label1.Text := 'Detected: ' + ARequest.Detections[0].SourceLanguage;
// Nothing to do when the text is already in the target language.
if SameText(ARequest.Detections[0].SourceLanguage, 'nl') then
begin
Edit1.Text := FPendingText;
Exit;
end;
TMSFNCCloudTranslation1.Translate(FPendingText, 'nl',
procedure(const ATransRequest: TTMSFNCCloudTranslationRequest;
const ATransResult: TTMSFNCCloudBaseRequestResult)
begin
if ATransResult.Success and (ATransRequest.Translations.Count > 0) then
Edit1.Text := ATransRequest.Translations[0].TranslatedText;
end);
end);
end;
Common mistakes
- Selecting a retired provider. IBM Translator is gone; a stored
'IBM'setting must be migrated rather than defaulted silently. - Leaving
ServiceRegionempty for a regional Microsoft key. TheOcp-Apim-Subscription-Regionheader is then omitted and the request fails authentication. - Leaving
ServiceEndPointorServiceRegionset after switching provider. They are Microsoft-only; clear them when selectingtsGoogleortsDeepL. - Reading the result after the method returns.
TranslateandDetectreturn before the provider answers, so the data is only available in the event or callback. TheTStringListyou pass is copied internally, so freeing it right after the call is safe — the result is not. - Assuming every provider accepts the same language codes. Call
GetSupportedLanguagesand validate the target code againstSupportedLanguagesafter changingService.
See also
- TTMSFNCCloudTranslation — full class reference
- Get started
- Release notes