Hi, 

I’m using the "Handle Template for Email with Macros" user task, but the output still contains the original template with macros untouched. The macros are not being replaced with actual values, and the Body parameter is returning the same template content.

Can you help me understand why the macro fields are not being filled in?

Like 0

Like

1 comments

I Created my own User task which handle all macro which have macro source filled in.

protected override bool InternalExecute(ProcessExecutingContext context) {
			// IMPORTANT: When implementing long-running operations, it is crucial to
			// enable timely and responsive cancellation. To achieve this, ensure that your code is designed to
			// respond appropriately to cancellation requests using the context.CancellationToken mechanism.
			// For more detailed information and examples, please, refer to our documentation.
			if (TemplateCode == Guid.Empty || RecordId == Guid.Empty) {
				isSuccess = false; 
				return true;
			}
 
			var templateEsq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "EmailTemplate");
			var bodyColumn = templateEsq.AddColumn("Body");
			var macroColumn = templateEsq.AddColumn("Object");
			var templateEntity = templateEsq.GetEntity(UserConnection, TemplateCode);
 
			if (templateEntity == null) {
				isSuccess = false;
				return true;
			}
 
			Guid macroSource = templateEntity.GetTypedColumnValue<Guid>("ObjectId");
			string body = templateEntity.GetColumnValue(bodyColumn.Name)?.ToString() ?? "";
 
 
			var macroSourceEsq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "SysSchema");
			var idFilter = macroSourceEsq.CreateFilterWithParameters(FilterComparisonType.Equal, "UId", macroSource);
			macroSourceEsq.Filters.Add(idFilter);
			var schemaNameColumn = macroSourceEsq.AddColumn("Name");
			var macroSourceEntities = macroSourceEsq.GetEntityCollection(UserConnection);
 
			if (macroSourceEntities == null || macroSourceEntities.Count == 0) {
				isSuccess = false;
				return true;
			}
 
			string schemaName = macroSourceEntities[0].GetColumnValue(schemaNameColumn.Name)?.ToString() ?? "";
 
			var macroRegex = new Regex(@"\[#(.*?)#\]");
			var matches = macroRegex.Matches(body);
 
			if (matches.Count == 0) {
				ReturnBody = body;
				isSuccess = false; 
				return true;
			}
 
			var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, schemaName);
			var columnMap = new Dictionary<string, string>(); 
 
			foreach (Match match in matches) {
				var macro = match.Groups[1].Value;
				if (!columnMap.ContainsKey(macro)) {
					var column = esq.AddColumn(macro);
					columnMap[macro] = column.Name;
				}
			}
 
			var entity = esq.GetEntity(UserConnection, RecordId);
			if (entity == null) {
				ReturnBody = body;
				isSuccess = false;
				return true;
			}
 
			var result = body;
			foreach (Match match in matches) {
				var macro = match.Groups[1].Value;
				if (columnMap.TryGetValue(macro, out string esqColumnName)) {
					try {
						var value = entity.GetColumnValue(esqColumnName)?.ToString() ?? "";
						result = result.Replace(match.Value, value);
					} catch (Terrasoft.Common.ItemNotFoundException) {
						try {
							var value = entity.GetColumnValue(esqColumnName + "Id")?.ToString() ?? "";
							result = result.Replace(match.Value, value);
						} catch {
							result = result.Replace(match.Value, "");
						}
					}
				}
			}
 
			ReturnBody = result;
			isSuccess = true;
			return true;
		}
Show all comments

i have my email templates like this

but after i testing send the email, the templates become like this from inbox

it becomes stacked like this
what i do wrong?

Like 0

Like

3 comments

Good day!
 

The thing is that all mail providers have their own rules and styles of displaying templates, so they can adapt them differently. Unfortunately, no template can look exactly the same in all mailers. 

Regarding your problem, you can add a section and columns to the template in place of pictures, this will keep the location of pictures and prevent them from being moved to a new line. You can find an example below in the picture, it should help. 

 

 

Regards,
Anton

hello Anton Starikov, thanks for your answer but in my view the picture you give doesnt show maybe you can resend it? below is the picture you share in my view

 

hello any suggestion i already using section and column like this

best Regards,
Ghifari

Show all comments

Hello,

 

I've created a set of new email templates that include both standard and custom macros sourced from macros in related objects. To share these templates with my colleagues, I’ve attached the email templates to my current package using an EmailTemplate data file. However, the custom macros within these templates aren't being included; my colleagues are seeing only the email template itself without the custom macros in their message templates.

 

When I attempt to bind the macros using an "EmailTemplateMacros" data file, I’m only given the option to include basic macros—none of the custom macros from pre-defined objects appear. Does anyone know how to properly bind these custom macros to the email templates so they appear for others?

 

Thank you!

n.b. some of the basic macros that I am able to join seem to be generic fields, not the fields I want to bind - see below...

 

Like 3

Like

2 comments

Greetings!
 


The data is stored in the object—EmailTemplate.


Please check, on the dev site where the template was originally created and the data was bound, that you have bound the TemplateConfig and ConfigType columns to this data, and if you have checked the “Forced Update” checkbox for these columns

Regards,
Orkhan

Orkhan,

Thank you!

Show all comments

I have created a signal-based Business Process that fires on modifying the data in Opportunity.

 

To Read the Email Template I write the following code:

using System;
	using System.Collections.Generic;
	using System.Linq;
	using Newtonsoft.Json;
	using Terrasoft.Common;
	using Terrasoft.Configuration;
	using Terrasoft.Configuration.Utils;
	using Terrasoft.Core;
	using Terrasoft.Core.Configuration;
	using Terrasoft.Core.DB;
	using Terrasoft.Core.Entities;
	using Terrasoft.Core.OperationLog;
	using SystemSettings = Terrasoft.Core.Configuration.SysSettings;
 
 
	public class EmailTemplateManager
	{
 
		private UserConnection _userConnection;
		private MacrosHelperService _macrosService;
		private readonly Dictionary<Guid, Entity> _cachedTemplates = new Dictionary<Guid, Entity>();
 
		public EmailTemplateManager(UserConnection userConnection) : base() {
			_userConnection = userConnection;
			MacrosHelperV2 macrosHelper = new GlobalMacrosHelper();
			macrosHelper.UserConnection = userConnection;
			_macrosService = new MacrosHelperService(macrosHelper, userConnection);
		}
 
		public string GetEmailTemplateSchemaName() {
			return _userConnection.GetFeatureState("EmailMessageMultiLanguage") == 0
				? "EmailTemplate"
				: "EmailTemplateLang";
		}
 
		public string GetTemplateBody(Guid recordId, Guid templateId) {
			var template = GetTemplate(templateId);
			if(template != null) {
				var schemaName = GetSchemaNameFromId(template.GetTypedColumnValue<Guid>("ObjectId"));
				var body = this.GetTemplateBody(new MacrosHelperServiceRequest
				{
					EntityId = recordId,
					EntityName = schemaName,
					TemplateId = templateId
				});
				return body;
			}
			return string.Empty;
		}
 
		public string GetTemplateBody(MacrosHelperServiceRequest request) {
			MacrosHelperServiceResponse template = null;
			string body = string.Empty;
			if (_userConnection.GetIsFeatureEnabled("EmailMessageMultiLanguageV2")) {
				template = _macrosService.GetMultiLanguageTextTemplate(request);
				body = template.TextTemplate;
			} else {
				template = _macrosService.GetMultiLanguageTextTemplate(request);
				body = template.TextTemplate;
			}
			return body;
		}
 
		public string GetTemplateSubject(MacrosHelperServiceRequest request) {
			MacrosHelperServiceResponse template = _macrosService.GetMultiLanguageTextTemplate(request);
			string title = template.SubjectTemplate;
			return title;
		}
 
		private bool IsNeedChangeMacrosCulture() {
			return _userConnection.GetIsFeatureEnabled("UseMacrosAdditionalParameters")
				&& _userConnection.GetIsFeatureEnabled("EmailMessageMultiLanguageV2");
		}
 
		public string GetTemplateSubject(Guid recordId, Guid templateId) {
			var template = GetTemplate(templateId);
			if(template != null) {
				var schemaName = GetSchemaNameFromId(template.GetTypedColumnValue<Guid>("ObjectId"));
				return GetTemplateSubject(new MacrosHelperServiceRequest
				{
					EntityId = recordId,
					EntityName = schemaName,
					TemplateId = templateId
				});
			}
			return string.Empty;
		}
 
		private string GetSchemaNameFromId(Guid objectId) {
			if(objectId != Guid.Empty) {
				var selectQuery  = new Select(_userConnection)
								.Column("Name")
								.From("SysSchema")
								.Where("UId")
									.IsEqual(Column.Parameter(objectId)) as Select;
 
				return selectQuery.ExecuteScalar<string>();
			}
			return string.Empty;
		}
 
		public Entity GetTemplate(Guid id) {
			Entity template;
			if (_cachedTemplates.ContainsKey(id)) {
				template = _cachedTemplates[id];
			} else {
				var esq = new EntitySchemaQuery(_userConnection.EntitySchemaManager, GetEmailTemplateSchemaName());
				esq.AddColumn("Object");
				esq.AddColumn("Subject");
				esq.AddColumn("Body");
				esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "Id", id));
				template = esq.GetEntity(_userConnection, id);
				_cachedTemplates.Add(id, template);
			}
			return template;
		}	
	}

 

To call this class in the Business Process I used this code:

try{
 
	var userConnection = GetUserConnection();
	var emailManager = new EmailTemplateManager(userConnection);
	var templateId = Get<Guid>("TemplateId");
	var recordId = Get<Guid>("RecordId");
	var subject = emailManager.GetTemplateSubject(recordId, templateId);
	var body = emailManager.GetTemplateBody(recordId, templateId);
	Set<String>("Body", body);
	Set<String>("Subject", subject);
}
catch(Exception ex){
	Set<String>("Subject", ex.Message);
	Set<String>("Body", ex.StackTrace);
}
return true;

 

 

To get the UserConnection in the background I used this Code:

private UserConnection GetUserConnection(){
	return Get<UserConnection>("UserConnection");
}

 

Here is the error I get:

Error Message: Error creating an instance of the "Terrasoft.Configuration.ILanguageIterator" class 

Stack Trace:   at Terrasoft.Core.Factories.ClassFactory.GetInstance[T](Func`1 action)
  at Terrasoft.Configuration.MLangContentFactory.GetContentKit(String iteratorTagName, String storeTagName)
  at QTECX.Email.EmailTemplateManager.GetTemplateSubject(String schemaName, Guid recordId, Guid tplId)
  at QTECX.Email.EmailTemplateManager.GetTemplateSubject(Guid recordId, Guid templateId)
  at Terrasoft.Core.Process.QTXTestEmailProcessMethodsWrapper.ScriptTask1Execute(ProcessExecutingContext context)

 

 

Like 0

Like

6 comments

I created the very same business process and manually specified RecordId (Id is a random Opportunity record) as 

 

new Guid("6344D6CE-F889-4361-83F2-9CD71DBD6300")

 

and TemplateId (Id is a random email template) as

 

new Guid("8F5C1959-25E0-45BC-A62D-04B516502A82")

 

in the process parameters and didn't get the error you received (checked the application logs dicrectly, BusinessProcess.log, Common.log and the Error.log files). Both the EmailTemplateManager class and the business process were created in the Custom package.

 

So the assumption is that either both the business process and the class on your end are created in an assembly package (or in separate packages, one of which is an assembly package) or the issue is in the parameters that the business process receives. Tested everything in the full bundle 8.1.4 application.

But we have to use this code in the Creatio 7.16 Version and it returns this error.

Syed Ali Hassan Shah,

You can order a trial site of 8.1.4 and check the suggested solution. If it works, please update the application to the newest version.

Anhelina,

We can not update the site to the latest version there are many complications in it Creatio Team already tried it once but didn't work out. Can you please suggest a solution for Version 7.16

Is there any update on the solution for Version 7.16?

Any update on this?

Show all comments

Hi, 

I'd like to know if it's possible, in the email of a marketing campaign, to put buttons in the template that allow you to generate the corresponding leads on Creatio.  

 

For example: 

  • Having two Call to Actions: ‘I'm Interested’ and ‘I'm Not Interested’. When the person receives the email, clicking on the ‘I'm interested’ CTA generates a lead in Creatio and the person should not be redirected to another link. The main objective is to capture the customer's behaviour in the email so that the campaign can then generate the flow based on that behaviour.
  •  

Currently, Call To Actions only work when they redirect to a link. But the aim is just to capture the click without opening another page for the contact person.

 

 

Does anyone know if this is possible?

 

Like 0

Like

1 comments

It's not possible to embed buttons in an email that perform actions without opening a page. Email clients do not allow an email to contain any sort of embedded code to do anything since that would be a security risk. This is a limitation of email itself, not specific to Creatio.

The only option is for the buttons to launch a webpage, passing any values to it, such as Contact or other relevant info Id values. The launched webpage it what performs the actual actions.

Ryan

Show all comments

Dear colleagues,

 

How can AVOID this? The link to an object in dev is "https://dev-XXXXX.creatio.com/Navigation/Navigation.aspx?schemaName=Ndo…]" and in TESTING or production, when deploy packages remains https://dev-XXXXX.creatio.com, when it must be https://pre-XXXXX.creatio.com or https://XXXXX.creatio.com

 

Some idea, how to solve this?

Like 0

Like

1 comments

Hello!

 

Please create a separate case for Support Team support@creatio.com  and we will analyze it deeply. 

Show all comments

Dears

 

Due those schemas usually have the EmailBody binded and this is a large string is very difficult to found the name of the binded templates, this is due Creatio show its names centered in the row where they are.

 

Suggestion, could export the data binded in those schemas or select which columns to see (not binded ones),

 

For example see the image

Thanks

3 comments

Good Idea!

 

Although I do have a strong technical background, I would prefer a more user-friendly "no-code-way" of creating data bindings.

 

I like the flexibility of the existing data binding feature, but it would be awesome for a lot of people to have the functionality to select what they want to bind and the system does the heavy lifting and generates the technically necessary data bindings.

 

For instance, if the element that should be bound to the package is an email template, then you would just select the template and the system creates the bindings for you. The same applies to workplaces, dashboards, reports (incl. reports table and the word template), lookups (including their manager), etc.

Robert Pordes,

 



Yes please !



Very well put. For a nocode tool, there still a lot to be implemented. A lot of great new stuff with Freedom UI but still quite some things missing for it to be truely nocode.



Cheers,



Damien

 

Hello,

 

Thank you for your suggestion, we have registered this idea for our R&D team and such functionality may appear in future.

Show all comments

If you save message template blocks in either user templates and/or bulk messages, and you need to change a saved block, the changes do not automatically cascade down the templates that use that block. You have to manually open each item and drag and drop the new block into place and delete the old one. This can get extensive when you have 100s of templated messages in use. There should be a save and save as option, where save overwrites the existing block and cascades the changes to any template that currently uses it. 

1 comments

That would save soooo much time ! (= massive added value)

Show all comments

Hello, 

 

I would like to set an upper limit on the size of an image that gets sent in an email. The image being sent is a variable in a form using the [#ImageName#] syntax. 

 

I have tried styling the element in div and img tags, but I think that this variable syntax does not respect styles.  

 

How can I style an image in an email template? 

 

Thanks!

Like 0

Like

1 comments

Hello,

 

Unfortunately, the logic of inserting an image through a macro into a letter template is not implemented in Creatio.

I am broadcasting your wish to the development team to consider the possibility of adding similar logic in future versions.

Show all comments

Hi Team,

 

We have a query regarding users having permissions to creating email templates in the Message Template section rather than admin creating email templates

 

Currently, only administrators have the ability to create email templates, select macro sources, and add macros while creating templates. However, the enquiry is whether the sales team would have the capability to create their own email templates for future use when communicating with customers rather than reaching out to admin for creating the email templates.

 

Is there a specific permission or access level that can be granted to normal users, specifically those in the sales team with a sales team license, which would allow them to create, save, and utilize their own email templates within the system? This would streamline our communication processes and empower our sales team to personalize their interactions with customers more effectively.

 

For now they are getting the below error while trying to create a email template :

Thanks for the help in advance!

 

Regards,

Mayan

 

Like 0

Like

1 comments

Hello,

for resolving this specific error you would need to give permission for operation by the code "CanManageLookups" in Operation permissions view in System designer. Not sure if users need more permissions to create templates but if its the only error occuring that could resolve it

Show all comments