Google Cloud Translation v3 translates text between more than a hundred languages and can detect the language of a piece of text for you. The service is exposed over gRPC, and sgcWebSockets Enterprise ships a typed Translation gRPC client built on TsgcGRPCClient. Instead of hand-assembling Protocol Buffers, you fill in a request object, call one method, and read the translated text straight off a typed response. This post walks through how it works and shows the actual Delphi code from the bundled demo.
How it works
gRPC is Protocol Buffers framed over HTTP/2, so the Translation client sits on top of the sgcWebSockets HTTP/2 stack. You create a TsgcHTTP2Client pointed at translate.googleapis.com on port 443 with TLS, assign it to a TsgcGRPCClient, and the gRPC component does the message framing, headers and stream handling for you.
The Translation unit sgcGRPC_Google_Translation adds the typed message classes that mirror the v3 API: TsgcGRPCTranslationTranslateTextRequest and ...TranslateTextResponse for translation, the DetectLanguage pair for language detection, and the GetSupportedLanguages pair for listing languages. Each request exposes a ToBytes method that serializes it to protobuf, and each response exposes a LoadFromBytes method that parses the reply. You pass those bytes to the gRPC client's Call method and read the result back.
Authentication
Cloud Translation requires a Google service-account token. The demo authenticates with a service-account JSON key (client email, private key id, private key and project id) and obtains a Bearer token, which is then added as gRPC metadata so it travels on every call.
GetGRPCClient.DefaultMetadata.Clear;
GetGRPCClient.DefaultMetadata.Add('authorization', 'Bearer ' + FToken);
One detail worth noting: a self-signed service-account JWT is audience-bound, so the token has to target the Translation endpoint to be accepted by translate.googleapis.com. The demo sets JWT.API_Endpoint to https://translate.googleapis.com/ before requesting the token.
Setting up the client
The HTTP/2 transport and the gRPC client are wired together once. The Translation service expects protobuf on the wire, so the channel content type is grpcProto.
uses
sgcHTTP2_Client, sgcGRPC_Types, sgcGRPC_Client,
sgcGRPC_Google_Translation;
FHTTP2Client := TsgcHTTP2Client.Create(nil);
FHTTP2Client.Host := 'translate.googleapis.com';
FHTTP2Client.Port := 443;
FHTTP2Client.TLS := True;
FGRPCClient := TsgcGRPCClient.Create(nil);
FGRPCClient.Client := FHTTP2Client;
FGRPCClient.ChannelOptions.ContentType := grpcProto;
FGRPCClient.ChannelOptions.Compression := grpcNoCompression;
Translating text
To translate, fill in a TsgcGRPCTranslationTranslateTextRequest: set the Parent resource path, add one or more strings to Contents, set the source and target language codes and the MIME type. Serialize it with ToBytes and pass it to Call with the fully qualified service name and method. The parent path follows the v3 form projects/<project-id>/locations/global.
var
oRequest: TsgcGRPCTranslationTranslateTextRequest;
oResponse: TsgcGRPCResponse;
begin
oRequest := TsgcGRPCTranslationTranslateTextRequest.Create;
try
oRequest.Parent := 'projects/' + txtProjectId.Text + '/locations/global';
oRequest.Contents.Add(txtSourceText.Text);
oRequest.SourceLanguageCode := txtSourceLang.Text; // e.g. 'en'
oRequest.TargetLanguageCode := txtTargetLang.Text; // e.g. 'es'
oRequest.MimeType := 'text/plain';
oResponse := GetGRPCClient.Call
('google.cloud.translation.v3.TranslationService', 'TranslateText',
oRequest.ToBytes);
finally
oRequest.Free;
end;
end;
The reply comes back as a TsgcGRPCResponse. When StatusCode is grpcOK, load the raw Data bytes into a typed response and read each translation. Each Translation carries the TranslatedText and, when the source language was auto-detected, the DetectedLanguageCode.
var
oResponse: TsgcGRPCTranslationTranslateTextResponse;
i: Integer;
begin
oResponse := TsgcGRPCTranslationTranslateTextResponse.Create;
try
oResponse.LoadFromBytes(aData);
for i := 0 to oResponse.TranslationCount - 1 do
begin
DoLog('Translated: ' + oResponse.Translation(i).TranslatedText);
if oResponse.Translation(i).DetectedLanguageCode <> '' then
DoLog('Detected: ' + oResponse.Translation(i).DetectedLanguageCode);
end;
finally
oResponse.Free;
end;
end;
Detecting the language
When you do not know the source language, leave the translation aside and call DetectLanguage. Build a TsgcGRPCTranslationDetectLanguageRequest with the parent path and the Content to inspect, then read the candidate languages back, each with a LanguageCode and a Confidence value.
oRequest := TsgcGRPCTranslationDetectLanguageRequest.Create;
try
oRequest.Parent := GetParentPath;
oRequest.Content := txtSourceText.Text;
oRequest.MimeType := 'text/plain';
oResponse := GetGRPCClient.Call
('google.cloud.translation.v3.TranslationService', 'DetectLanguage',
oRequest.ToBytes);
finally
oRequest.Free;
end;
Parsing the detection response gives you the language code and a confidence score for each candidate.
oResponse := TsgcGRPCTranslationDetectLanguageResponse.Create;
try
oResponse.LoadFromBytes(aData);
for i := 0 to oResponse.LanguageCount - 1 do
DoLog('Language: ' + oResponse.Language(i).LanguageCode +
' (confidence: ' + FloatToStr(oResponse.Language(i).Confidence) + ')');
finally
oResponse.Free;
end;
Listing supported languages
The third operation, GetSupportedLanguages, returns every language the service supports. Set DisplayLanguageCode to the language you want the display names in, and each entry comes back with a LanguageCode and a human-readable DisplayName, along with flags for whether it can be used as a source or target.
oRequest := TsgcGRPCTranslationGetSupportedLanguagesRequest.Create;
try
oRequest.Parent := GetParentPath;
oRequest.DisplayLanguageCode := 'en';
oResponse := GetGRPCClient.Call
('google.cloud.translation.v3.TranslationService',
'GetSupportedLanguages', oRequest.ToBytes);
finally
oRequest.Free;
end;
Availability
The Translation gRPC client is part of the sgcWebSockets Enterprise edition and runs on Windows, macOS, Linux, iOS and Android, across Delphi and C++Builder. A complete, ready-to-run sample with service-account loading and all three operations is in Demos\21.GRPC\12.Translation, and the underlying gRPC client is documented on the gRPC Client product page.
Questions or feedback? Get in touch. You will get a reply from the people who wrote the code.
