Skip to content

Commit b70ce94

Browse files
authored
21 automatically translate for new translations (#22)
1 parent bf5506e commit b70ce94

15 files changed

Lines changed: 453 additions & 347 deletions

functions/package-lock.json

Lines changed: 151 additions & 136 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

functions/src/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {Firestore, getFirestore} from 'firebase-admin/firestore';
44
import {getStorage, Storage} from 'firebase-admin/storage';
55
import {Auth, getAuth} from 'firebase-admin/auth';
66
import {TranslationServiceClient} from '@google-cloud/translate';
7+
import {FIREBASE_CONFIG, FirebaseConfig} from './models/firebase.model';
78

89
// BATCH OPERATION
910
export const BATCH_MAX = 500;
@@ -39,3 +40,5 @@ export const SUPPORT_LOCALES = new Set([
3940
"th", "tk", "tl", "tr", "tt", "ug", "uk", "ur", "uz", "vi", "xh", "yi", "yo", "zh", "zh-TW", "zu"
4041
]
4142
)
43+
44+
export const firebaseConfig: FirebaseConfig = JSON.parse(process.env[FIREBASE_CONFIG] || '')

functions/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export {onSpaceDelete} from './spaces';
44

55
export {translate} from './translate'
66

7-
export {translationsPublish, translationsExport, translationsImport} from './translations';
7+
export {translationsPublish, translationsExport, translationsImport, onTranslationCreate} from './translations';
88

99
export {onAuthUserCreate, onUserUpdate, userInvite, onUserDelete, usersSync} from './users';
1010

functions/src/models/translations.model.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {Timestamp} from 'firebase-admin/firestore';
22

3-
export type TranslationLocale = { [key: string]: string }
3+
export type TranslationLocale = { [key: string]: string }
44

55
export enum TranslationType {
66
STRING = 'STRING',
@@ -9,13 +9,14 @@ export enum TranslationType {
99
}
1010

1111
export interface Translation {
12-
name: string;
13-
type: TranslationType;
14-
locales: { [key: string]: string };
12+
name: string
13+
type: TranslationType
14+
locales: { [key: string]: string }
1515
labels?: string[]
16-
description?: string;
17-
createdOn: Timestamp;
18-
updatedOn: Timestamp;
16+
translate?: boolean
17+
description?: string
18+
createdOn: Timestamp
19+
updatedOn: Timestamp
1920
}
2021

2122
export interface TranslationExportImport {

functions/src/translate.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import {https, logger} from 'firebase-functions';
22
import {SecurityUtils} from './utils/security-utils';
3-
import {ROLE_ADMIN, ROLE_EDIT, ROLE_WRITE, SUPPORT_LOCALES, translationService} from './config';
4-
import {FIREBASE_CONFIG, FirebaseConfig} from './models/firebase.model';
3+
import {
4+
firebaseConfig,
5+
ROLE_ADMIN,
6+
ROLE_EDIT,
7+
ROLE_WRITE,
8+
SUPPORT_LOCALES,
9+
translationService
10+
} from './config';
511
import {TranslateData} from './models/translate.model';
612
import {protos} from '@google-cloud/translate';
713

@@ -12,7 +18,6 @@ export const translate = https.onCall(async (data: TranslateData, context) => {
1218
if (!(SUPPORT_LOCALES.has(data.sourceLocale) && SUPPORT_LOCALES.has(data.targetLocale))) throw new https.HttpsError('invalid-argument', 'Unsupported language');
1319

1420

15-
const firebaseConfig: FirebaseConfig = JSON.parse(process.env[FIREBASE_CONFIG] || '')
1621
const projectId = firebaseConfig.projectId
1722
let locationId; //firebaseConfig.locationId || 'global'
1823
if (firebaseConfig.locationId && firebaseConfig.locationId.startsWith('us-')) {
@@ -31,8 +36,6 @@ export const translate = https.onCall(async (data: TranslateData, context) => {
3136
};
3237

3338
try {
34-
35-
// Run request
3639
const [responseTranslateText] = await translationService.translateText(request);
3740

3841
if (responseTranslateText.translations && responseTranslateText.translations.length > 0) {

functions/src/translations.ts

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1-
import {https, logger} from 'firebase-functions';
1+
import {firestore, https, logger} from 'firebase-functions';
22
import {SecurityUtils} from './utils/security-utils';
3-
import {BATCH_MAX, bucket, firestoreService, ROLE_ADMIN, ROLE_WRITE} from './config';
3+
import {
4+
BATCH_MAX,
5+
bucket,
6+
firebaseConfig,
7+
firestoreService,
8+
ROLE_ADMIN,
9+
ROLE_WRITE,
10+
SUPPORT_LOCALES,
11+
translationService
12+
} from './config';
413
import {Space} from './models/space.model';
514
import {
615
PublishTranslationsData,
@@ -13,6 +22,7 @@ import {
1322
} from './models/translations.model';
1423
import {FieldValue, QuerySnapshot, Timestamp, WriteBatch} from 'firebase-admin/firestore';
1524
import axios from 'axios';
25+
import {protos} from '@google-cloud/translate';
1626

1727
// Publish
1828
export const translationsPublish = https.onCall(async (data: PublishTranslationsData, context) => {
@@ -223,7 +233,6 @@ export const translationsImport = https.onCall(async (data: TranslationsImportDa
223233
// add label
224234
update.labels = value.locales
225235
}
226-
logger.info('sdgsdg')
227236
if (Object.getOwnPropertyNames(update).length > 1) {
228237
batches[batchIdx].update(firestoreService.doc(`spaces/${data.spaceId}/translations/${oid}`), update);
229238
totalChanges++;
@@ -265,3 +274,59 @@ export const translationsImport = https.onCall(async (data: TranslationsImportDa
265274
throw new https.HttpsError('not-found', 'Space not found');
266275
}
267276
});
277+
278+
export const onTranslationCreate = firestore.document('spaces/{spaceId}/translations/{translationId}')
279+
.onCreate(async (snapshot, context) => {
280+
logger.info(`[Translation::onCreate] id='${snapshot.id}' eventId='${context.eventId}'`);
281+
const spaceId: string = context.params['spaceId'];
282+
// const translationId: string = context.params.translationId
283+
284+
const spaceSnapshot = await firestoreService.doc(`spaces/${spaceId}`).get();
285+
286+
const space = spaceSnapshot.data() as Space;
287+
// is incoming locale supporting translation ?
288+
if (!SUPPORT_LOCALES.has(space.localeFallback.id)) return;
289+
290+
const translation = snapshot.data() as Translation;
291+
const localeValue = translation.locales[space.localeFallback.id]
292+
293+
const projectId = firebaseConfig.projectId
294+
let locationId; //firebaseConfig.locationId || 'global'
295+
if (firebaseConfig.locationId && firebaseConfig.locationId.startsWith('us-')) {
296+
locationId = 'us-central1'
297+
} else {
298+
locationId = 'global'
299+
}
300+
301+
const update: any = {
302+
translate: FieldValue.delete(),
303+
updatedOn: FieldValue.serverTimestamp(),
304+
};
305+
306+
for (const locale of space.locales) {
307+
// skip already filled data
308+
if (locale.id === space.localeFallback.id) continue;
309+
// skip unsupported locale
310+
if (!SUPPORT_LOCALES.has(locale.id)) continue;
311+
312+
const request: protos.google.cloud.translation.v3.ITranslateTextRequest = {
313+
parent: `projects/${projectId}/locations/${locationId}`,
314+
contents: [localeValue],
315+
mimeType: 'text/plain',
316+
sourceLanguageCode: space.localeFallback.id,
317+
targetLanguageCode: locale.id,
318+
};
319+
try {
320+
const [responseTranslateText] = await translationService.translateText(request);
321+
if (responseTranslateText.translations && responseTranslateText.translations.length > 0) {
322+
update[`locales.${locale.id}`] = responseTranslateText.translations[0].translatedText;
323+
}
324+
} catch (e) {
325+
logger.error(e)
326+
}
327+
}
328+
logger.info(`[Translation::onCreate] Update : ${JSON.stringify(update)}`)
329+
await snapshot.ref.update(update)
330+
331+
return
332+
});

0 commit comments

Comments
 (0)