Merged PR 635: アカウント登録完了通知 [U-101] の実装
## 概要 [Task3301: アカウント登録完了通知 [U-101] の実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3301) - アカウント登録完了(認証完了)後にメール送信をする機能を追加しました。 - 合わせてテスト修正をしています。 ## レビューポイント - テンプレートの適用は適切でしょうか。 - テスト修正で対象Sendgridメソッドを上書きしていますが対応として不自然な点はないでしょうか? ## UIの変更 - なし ## 動作確認状況 - ローカルで確認
This commit is contained in:
parent
11aa73f190
commit
b2fef69ea9
4
dictation_client/.vscode/settings.json
vendored
4
dictation_client/.vscode/settings.json
vendored
@ -27,8 +27,8 @@
|
||||
"debug.javascript.usePreview": false,
|
||||
"editor.copyWithSyntaxHighlighting": false,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.stylelint": "explicit"
|
||||
"source.fixAll.eslint": true,
|
||||
"source.fixAll.stylelint": true
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
|
||||
2
dictation_server/.vscode/settings.json
vendored
2
dictation_server/.vscode/settings.json
vendored
@ -1,7 +1,7 @@
|
||||
{
|
||||
"terminal.integrated.shell.linux": "/bin/bash",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"eslint.format.enable": false,
|
||||
"[javascript]": {
|
||||
|
||||
@ -92,6 +92,11 @@ export const overrideSendgridService = <TService>(
|
||||
text: string,
|
||||
html: string,
|
||||
) => Promise<void>;
|
||||
sendMailWithU101?: (
|
||||
context: Context,
|
||||
customerMail: string,
|
||||
customerAccountName: string,
|
||||
) => Promise<void>;
|
||||
},
|
||||
): void => {
|
||||
// テストコードでのみ許される強引な方法でprivateメンバ変数の参照を取得
|
||||
@ -113,6 +118,20 @@ export const overrideSendgridService = <TService>(
|
||||
});
|
||||
}
|
||||
|
||||
if (overrides.sendMailWithU101) {
|
||||
Object.defineProperty(obj, obj.sendMailWithU101.name, {
|
||||
value: overrides.sendMailWithU101,
|
||||
writable: true,
|
||||
});
|
||||
} else {
|
||||
Object.defineProperty(obj, obj.sendMailWithU101.name, {
|
||||
value: async () => {
|
||||
return;
|
||||
},
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (overrides.createMailContentFromEmailConfirm) {
|
||||
Object.defineProperty(obj, obj.createMailContentFromEmailConfirm.name, {
|
||||
value: overrides.createMailContentFromEmailConfirm,
|
||||
|
||||
@ -18,6 +18,7 @@ import {
|
||||
} from '../../../common/types/sort';
|
||||
import { AdB2cUser } from '../../../gateways/adb2c/types/types';
|
||||
import { ADB2C_SIGN_IN_TYPE } from '../../../constants';
|
||||
import { AccountsRepositoryService } from '../../../repositories/accounts/accounts.repository.service';
|
||||
|
||||
export type SortCriteriaRepositoryMockValue = {
|
||||
updateSortCriteria: SortCriteria | Error;
|
||||
@ -80,6 +81,8 @@ export const makeUsersServiceMock = async (
|
||||
})
|
||||
.useMocker((token) => {
|
||||
switch (token) {
|
||||
case AccountsRepositoryService:
|
||||
return {};
|
||||
case UsersRepositoryService:
|
||||
return makeUsersRepositoryMock(usersRepositoryMockValue);
|
||||
case LicensesRepositoryService:
|
||||
|
||||
@ -8,9 +8,11 @@ import { LicensesRepositoryModule } from '../../repositories/licenses/licenses.r
|
||||
import { UsersController } from './users.controller';
|
||||
import { UsersService } from './users.service';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { AccountsRepositoryModule } from '../../repositories/accounts/accounts.repository.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
AccountsRepositoryModule,
|
||||
UsersRepositoryModule,
|
||||
LicensesRepositoryModule,
|
||||
SortCriteriaRepositoryModule,
|
||||
|
||||
@ -94,6 +94,12 @@ describe('UsersService.confirmUser', () => {
|
||||
});
|
||||
|
||||
const service = module.get<UsersService>(UsersService);
|
||||
overrideSendgridService(service, {
|
||||
sendMailWithU101: async () => {
|
||||
return;
|
||||
},
|
||||
});
|
||||
|
||||
// account id:1, user id: 2のトークン
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
@ -141,6 +147,11 @@ describe('UsersService.confirmUser', () => {
|
||||
if (!module) fail();
|
||||
const token = 'invalid.id.token';
|
||||
const service = module.get<UsersService>(UsersService);
|
||||
overrideSendgridService(service, {
|
||||
sendMailWithU101: async () => {
|
||||
return;
|
||||
},
|
||||
});
|
||||
const context = makeContext(`uuidv4`, 'requestId');
|
||||
await expect(service.confirmUser(context, token)).rejects.toEqual(
|
||||
new HttpException(makeErrorResponse('E000101'), HttpStatus.BAD_REQUEST),
|
||||
@ -175,6 +186,11 @@ describe('UsersService.confirmUser', () => {
|
||||
email_verified: false,
|
||||
});
|
||||
const service = module.get<UsersService>(UsersService);
|
||||
overrideSendgridService(service, {
|
||||
sendMailWithU101: async () => {
|
||||
return;
|
||||
},
|
||||
});
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
const context = makeContext(`uuidv4`, 'requestId');
|
||||
@ -187,6 +203,11 @@ describe('UsersService.confirmUser', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<UsersService>(UsersService);
|
||||
overrideSendgridService(service, {
|
||||
sendMailWithU101: async () => {
|
||||
return;
|
||||
},
|
||||
});
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
const context = makeContext(`uuidv4`, 'requestId');
|
||||
|
||||
@ -33,7 +33,6 @@ import {
|
||||
UserNotFoundError,
|
||||
} from '../../repositories/users/errors/types';
|
||||
import {
|
||||
ADB2C_SIGN_IN_TYPE,
|
||||
LICENSE_EXPIRATION_THRESHOLD_DAYS,
|
||||
MANUAL_RECOVERY_REQUIRED,
|
||||
OPTION_ITEM_VALUE_TYPE_NUMBER,
|
||||
@ -51,6 +50,7 @@ import {
|
||||
} from '../../repositories/licenses/errors/types';
|
||||
import { AccountNotFoundError } from '../../repositories/accounts/errors/types';
|
||||
import { getUserNameAndMailAddress } from '../../gateways/adb2c/utils/utils';
|
||||
import { AccountsRepositoryService } from '../../repositories/accounts/accounts.repository.service';
|
||||
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
@ -58,6 +58,7 @@ export class UsersService {
|
||||
private readonly mailFrom: string;
|
||||
private readonly appDomain: string;
|
||||
constructor(
|
||||
private readonly accountsRepository: AccountsRepositoryService,
|
||||
private readonly usersRepository: UsersRepositoryService,
|
||||
private readonly licensesRepository: LicensesRepositoryService,
|
||||
private readonly sortCriteriaRepository: SortCriteriaRepositoryService,
|
||||
@ -98,6 +99,24 @@ export class UsersService {
|
||||
context,
|
||||
userId,
|
||||
);
|
||||
|
||||
try {
|
||||
const { company_name: companyName } =
|
||||
await this.accountsRepository.findAccountById(
|
||||
context,
|
||||
decodedToken.accountId,
|
||||
);
|
||||
|
||||
// アカウント認証が完了した旨をメール送信する
|
||||
await this.sendgridService.sendMailWithU101(
|
||||
context,
|
||||
decodedToken.email,
|
||||
companyName,
|
||||
);
|
||||
} catch (e) {
|
||||
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
|
||||
// メール送信に関する例外はログだけ出して握りつぶす
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
|
||||
if (e instanceof Error) {
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
DEALER_NAME,
|
||||
LICENSE_QUANTITY,
|
||||
PO_NUMBER,
|
||||
TOP_URL,
|
||||
} from '../../templates/constants';
|
||||
|
||||
@Injectable()
|
||||
@ -21,6 +22,8 @@ export class SendGridService {
|
||||
private readonly mailFrom: string;
|
||||
private readonly templateEmailVerifyHtml: string;
|
||||
private readonly templateEmailVerifyText: string;
|
||||
private readonly templateU101Html: string;
|
||||
private readonly templateU101Text: string;
|
||||
private readonly templateU105Html: string;
|
||||
private readonly templateU105Text: string;
|
||||
private readonly templateU106Html: string;
|
||||
@ -48,6 +51,15 @@ export class SendGridService {
|
||||
'utf-8',
|
||||
);
|
||||
|
||||
this.templateU101Html = readFileSync(
|
||||
path.resolve(__dirname, `../../templates/template_U_101.html`),
|
||||
'utf-8',
|
||||
);
|
||||
this.templateU101Text = readFileSync(
|
||||
path.resolve(__dirname, `../../templates/template_U_101.txt`),
|
||||
'utf-8',
|
||||
);
|
||||
|
||||
this.templateU105Html = readFileSync(
|
||||
path.resolve(__dirname, `../../templates/template_U_105.html`),
|
||||
'utf-8',
|
||||
@ -178,6 +190,46 @@ export class SendGridService {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* U-101のテンプレートを使用したメールを送信する
|
||||
* @param context
|
||||
* @param customerMail アカウント登録を行った管理者ユーザーのメールアドレス
|
||||
* @param customerAccountName アカウント登録した会社名
|
||||
* @returns mail with u101
|
||||
*/
|
||||
async sendMailWithU101(
|
||||
context: Context,
|
||||
customerMail: string,
|
||||
customerAccountName: string,
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU101.name}`,
|
||||
);
|
||||
try {
|
||||
const subject = 'Account Registered Notification [U-101]';
|
||||
const html = this.templateU101Html
|
||||
.replaceAll(CUSTOMER_NAME, customerAccountName)
|
||||
.replaceAll(TOP_URL, this.appDomain);
|
||||
const text = this.templateU101Text
|
||||
.replaceAll(CUSTOMER_NAME, customerAccountName)
|
||||
.replaceAll(TOP_URL, this.appDomain);
|
||||
|
||||
await this.sendMail(
|
||||
context,
|
||||
[customerMail],
|
||||
[],
|
||||
this.mailFrom,
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
);
|
||||
} finally {
|
||||
this.logger.log(
|
||||
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU101.name}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* U-105のテンプレートを使用したメールを送信する
|
||||
* @param context
|
||||
|
||||
@ -2,3 +2,4 @@ export const CUSTOMER_NAME = '$CUSTOMER_NAME$';
|
||||
export const DEALER_NAME = '$DEALER_NAME$';
|
||||
export const LICENSE_QUANTITY = '$LICENSE_QUANTITY$';
|
||||
export const PO_NUMBER = '$PO_NUMBER$';
|
||||
export const TOP_URL = '$TOP_URL$';
|
||||
|
||||
128
dictation_server/src/templates/template_U_101.html
Normal file
128
dictation_server/src/templates/template_U_101.html
Normal file
@ -0,0 +1,128 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Account Registered Notification [U-101]</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h3><English></h3>
|
||||
<p>Dear $CUSTOMER_NAME$,</p>
|
||||
<p>
|
||||
Thank you for choosing ODMS Cloud. Your account has been successfully
|
||||
registered.
|
||||
</p>
|
||||
<p>
|
||||
We have granted [100] trial licenses to your account which is valid for
|
||||
30 days. During the trial, you can try all the features of ODMS Cloud.
|
||||
</p>
|
||||
<p>
|
||||
If you wish to continue using ODMS Cloud after the trial period has
|
||||
expired, please contact an authorized OM SYSTEM audio dealer to purchase
|
||||
annual licenses. Various settings including dealer selection can be
|
||||
configured within ODMS Cloud under the Account tab.
|
||||
</p>
|
||||
<p>
|
||||
Please log in to ODMS Cloud to configure your user setting and and
|
||||
verify the license expiration date.<br />
|
||||
URL: $TOP_URL$
|
||||
</p>
|
||||
<p>
|
||||
After you have selected a dealer, to request the number of licenses
|
||||
please select Subscription tab. Licenses issued by dealers will be
|
||||
stored in your license Inventory.
|
||||
</p>
|
||||
<p>
|
||||
If you need assistance with ODMS Cloud, please contact your selected
|
||||
approved OM SYSTEM audio dealer directly.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you have received this e-mail in error, please delete this e-mail
|
||||
from your system.<br />
|
||||
This is an automatically generated e-mail and this mailbox is not
|
||||
monitored. Please do not reply.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3><Deutsch></h3>
|
||||
<p>Sehr geehrte(r) $CUSTOMER_NAME$,</p>
|
||||
<p>
|
||||
Vielen Dank, dass Sie sich für ODMS Cloud entschieden haben. Ihr Konto
|
||||
wurde erfolgreich registriert.
|
||||
</p>
|
||||
<p>
|
||||
Wir haben Ihrem Konto [100] Testlizenzen gewährt, die 30 Tage gültig
|
||||
sind. Während der Testversion können Sie alle Funktionen von ODMS Cloud
|
||||
ausprobieren.
|
||||
</p>
|
||||
<p>
|
||||
Wenn Sie ODMS Cloud nach Ablauf des Testzeitraums weiterhin nutzen
|
||||
möchten, wenden Sie sich bitte an einen autorisierten OM
|
||||
SYSTEM-Audiohändler, um Jahreslizenzen zu erwerben. Verschiedene
|
||||
Einstellungen, einschließlich der Händlerauswahl, können in der ODMS
|
||||
Cloud auf der Registerkarte „Konto“ konfiguriert werden.
|
||||
</p>
|
||||
<p>
|
||||
Bitte melden Sie sich bei ODMS Cloud an, um Ihre Benutzereinstellungen
|
||||
zu konfigurieren und das Ablaufdatum der Lizenz zu überprüfen.<br />
|
||||
URL: $TOP_URL$
|
||||
</p>
|
||||
<p>
|
||||
Nachdem Sie einen Händler ausgewählt haben, wählen Sie bitte die
|
||||
Registerkarte „Abonnement“ aus, um die Anzahl der Lizenzen anzufordern.
|
||||
Von Händlern ausgestellte Lizenzen werden in Ihrem Lizenzbestand
|
||||
gespeichert.
|
||||
</p>
|
||||
<p>
|
||||
Wenn Sie Hilfe mit ODMS Cloud benötigen, wenden Sie sich bitte direkt an
|
||||
Ihren ausgewählten zugelassenen OM SYSTEM-Audiohändler.
|
||||
</p>
|
||||
<p>
|
||||
Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie
|
||||
diese E-Mail bitte aus Ihrem System.<br />
|
||||
Dies ist eine automatisch generierte E-Mail und dieses Postfach wird
|
||||
nicht überwacht. Bitte nicht antworten.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3><Français></h3>
|
||||
<p>Chère/Cher $CUSTOMER_NAME$,</p>
|
||||
<p>
|
||||
Merci d'avoir choisi ODMS Cloud. Votre compte a été enregistré avec
|
||||
succès.
|
||||
</p>
|
||||
<p>
|
||||
Nous avons accordé [100] licences d'essai à votre compte, valables 30
|
||||
jours. Pendant la période d'essai, vous pouvez essayer toutes les
|
||||
fonctionnalités d'ODMS Cloud.
|
||||
</p>
|
||||
<p>
|
||||
Si vous souhaitez continuer à utiliser ODMS Cloud après l'expiration de
|
||||
la période d'essai, veuillez contacter un concessionnaire audio agréé OM
|
||||
SYSTEM pour acheter des licences annuelles. Divers paramètres, y compris
|
||||
la sélection du concessionnaire, peuvent être configurés dans ODMS Cloud
|
||||
sous l'onglet Compte.
|
||||
</p>
|
||||
<p>
|
||||
Veuillez vous connecter à ODMS Cloud pour configurer vos paramètres
|
||||
utilisateur et vérifier la date d'expiration de la licence.<br />
|
||||
URL: $TOP_URL$
|
||||
</p>
|
||||
<p>
|
||||
Après avoir sélectionné un concessionnaire, pour demander le nombre de
|
||||
licences, veuillez sélectionner l'onglet Abonnement. Les licences
|
||||
délivrées par les concessionnaires seront stockées dans votre inventaire
|
||||
de licences.
|
||||
</p>
|
||||
<p>
|
||||
Si vous avez besoin d'aide avec ODMS Cloud, veuillez contacter
|
||||
directement votre concessionnaire audio OM SYSTEM agréé sélectionné.
|
||||
</p>
|
||||
<p>
|
||||
Si vous avez reçu cet e-mail par erreur, veuillez supprimer cet e-mail
|
||||
de votre système.<br />
|
||||
Il s'agit d'un e-mail généré automatiquement et cette boîte aux lettres
|
||||
n'est pas surveillée. Merci de ne pas répondre.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
59
dictation_server/src/templates/template_U_101.txt
Normal file
59
dictation_server/src/templates/template_U_101.txt
Normal file
@ -0,0 +1,59 @@
|
||||
<English>
|
||||
|
||||
Dear $CUSTOMER_NAME$,
|
||||
|
||||
Thank you for choosing ODMS Cloud. Your account has been successfully registered.
|
||||
|
||||
We have granted [100] trial licenses to your account which is valid for 30 days. During the trial, you can try all the features of ODMS Cloud.
|
||||
|
||||
If you wish to continue using ODMS Cloud after the trial period has expired, please contact an authorized OM SYSTEM audio dealer to purchase annual licenses. Various settings including dealer selection can be configured within ODMS Cloud under the Account tab.
|
||||
|
||||
Please log in to ODMS Cloud to configure your user setting and and verify the license expiration date.
|
||||
URL: $TOP_URL$
|
||||
|
||||
After you have selected a dealer, to request the number of licenses please select Subscription tab. Licenses issued by dealers will be stored in your license Inventory.
|
||||
|
||||
If you need assistance with ODMS Cloud, please contact your selected approved OM SYSTEM audio dealer directly.
|
||||
|
||||
If you have received this e-mail in error, please delete this e-mail from your system.
|
||||
This is an automatically generated e-mail and this mailbox is not monitored. Please do not reply.
|
||||
|
||||
<Deutsch>
|
||||
|
||||
Sehr geehrte(r) $CUSTOMER_NAME$,
|
||||
|
||||
Vielen Dank, dass Sie sich für ODMS Cloud entschieden haben. Ihr Konto wurde erfolgreich registriert.
|
||||
|
||||
Wir haben Ihrem Konto [100] Testlizenzen gewährt, die 30 Tage gültig sind. Während der Testversion können Sie alle Funktionen von ODMS Cloud ausprobieren.
|
||||
|
||||
Wenn Sie ODMS Cloud nach Ablauf des Testzeitraums weiterhin nutzen möchten, wenden Sie sich bitte an einen autorisierten OM SYSTEM-Audiohändler, um Jahreslizenzen zu erwerben. Verschiedene Einstellungen, einschließlich der Händlerauswahl, können in der ODMS Cloud auf der Registerkarte „Konto“ konfiguriert werden.
|
||||
|
||||
Bitte melden Sie sich bei ODMS Cloud an, um Ihre Benutzereinstellungen zu konfigurieren und das Ablaufdatum der Lizenz zu überprüfen.
|
||||
URL: $TOP_URL$
|
||||
|
||||
Nachdem Sie einen Händler ausgewählt haben, wählen Sie bitte die Registerkarte „Abonnement“ aus, um die Anzahl der Lizenzen anzufordern. Von Händlern ausgestellte Lizenzen werden in Ihrem Lizenzbestand gespeichert.
|
||||
|
||||
Wenn Sie Hilfe mit ODMS Cloud benötigen, wenden Sie sich bitte direkt an Ihren ausgewählten zugelassenen OM SYSTEM-Audiohändler.
|
||||
|
||||
Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
|
||||
Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
|
||||
|
||||
<Français>
|
||||
|
||||
Chère/Cher $CUSTOMER_NAME$,
|
||||
|
||||
Merci d'avoir choisi ODMS Cloud. Votre compte a été enregistré avec succès.
|
||||
|
||||
Nous avons accordé [100] licences d'essai à votre compte, valables 30 jours. Pendant la période d'essai, vous pouvez essayer toutes les fonctionnalités d'ODMS Cloud.
|
||||
|
||||
Si vous souhaitez continuer à utiliser ODMS Cloud après l'expiration de la période d'essai, veuillez contacter un concessionnaire audio agréé OM SYSTEM pour acheter des licences annuelles. Divers paramètres, y compris la sélection du concessionnaire, peuvent être configurés dans ODMS Cloud sous l'onglet Compte.
|
||||
|
||||
Veuillez vous connecter à ODMS Cloud pour configurer vos paramètres utilisateur et vérifier la date d'expiration de la licence.
|
||||
URL: $TOP_URL$
|
||||
|
||||
Après avoir sélectionné un concessionnaire, pour demander le nombre de licences, veuillez sélectionner l'onglet Abonnement. Les licences délivrées par les concessionnaires seront stockées dans votre inventaire de licences.
|
||||
|
||||
Si vous avez besoin d'aide avec ODMS Cloud, veuillez contacter directement votre concessionnaire audio OM SYSTEM agréé sélectionné.
|
||||
|
||||
Si vous avez reçu cet e-mail par erreur, veuillez supprimer cet e-mail de votre système.
|
||||
Il s'agit d'un e-mail généré automatiquement et cette boîte aux lettres n'est pas surveillée. Merci de ne pas répondre.
|
||||
Loading…
x
Reference in New Issue
Block a user