Hi.  

I am following up on a thread I posted earlier which seems to have withered -- I am looking for an alternate path.    (Link to original thread is below)

Is there a "No Code" way to add to the email headers that Creatio generates? 

I know there is a way to code the email, but we have so many processes that send out emails, I will have to hire a developer to do this.   (Code is included below for reference, you can see there the header I need to add to the outbound emails)

If we could add "X-Auto-Response-Suppress: All" to the header, we would eliminate most if not all "out of office" responses we get back.

Thanks
Rob

var message = new Terrasoft.Mail.Sender.EmailMessage
{
	// Sender email address.
	From = "Sender@email.com",
	// Recipient email addresses.
	To = new List<string>{ "first@recepient.co", "second@recepient.co" },
	// Copy optional
	Cc = new List<string>{ "first@recepient.co", "second@recepient.co" },
	// Hidden copy optional
	Bcc = new List<string>{ "first@recepient.co", "second@recepient.co" },
	Subject = "Message subject",
	// Email body.
	Body = "Body",
	// Priority, Terrasoft.Mail.Sender.EmailPriority enumeration values.
	Priority = Terrasoft.Mail.Sender.EmailPriority.Normal,
	// Headers you want to add to your email
	HeaderProperties = new List<Mail.Sender.EmailMessageHeader>
	{
		new Mail.Sender.EmailMessageHeader
		{
			Name = "X-Auto-Response-Suppress",
			Value = "All"
		}
	}
};

https://community.creatio.com/questions/add-email-header-x-auto-response-suppress-all

Like 0

Like

2 comments
Best reply

If you used the code approach, you could make a generic process you'd use as a subprocess. Any process that needed to send email could use that one process. However, you'd lose the ability for an easy designer for composing the email in the process and would have to send HTML to the subprocess to use as the body (not an issue with the subprocess route specifically, but an issue with using code to send the email). 

If it worked for you, you could create the emails themselves as message templates. The subprocess would need to process that template as well to generate the body. At leas that way you could use an easy designer to create the messages instead of just forming the HTML.

Ryan

Does not appear to be possible without code. The send email process element doesn't expose any properties for the header. 

If you used the code approach, you could make a generic process you'd use as a subprocess. Any process that needed to send email could use that one process. However, you'd lose the ability for an easy designer for composing the email in the process and would have to send HTML to the subprocess to use as the body (not an issue with the subprocess route specifically, but an issue with using code to send the email). 

If it worked for you, you could create the emails themselves as message templates. The subprocess would need to process that template as well to generate the body. At leas that way you could use an easy designer to create the messages instead of just forming the HTML.

Ryan

Show all comments

Hi.  

We use Creatio to automatically send out emails to users based on certain triggers.  There is typically 50-100 a day -- We then get many "out of office" responses back, which are unnecessary. 

Is there a way to add to the email headers that Creatio generates?  If we could add "X-Auto-Response-Suppress: All" to the header, we would eliminate most if not all "out of office" responses.

Thanks
Rob

 

Like 0

Like

5 comments
Best reply

Hello Rob,

 

You can customize your email sending process using the instructions and examples from the article https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/8.1/platform-customization/classic-ui/emails/sending-emails/overview.

 

If you want to add the header to your email you can it by creating the configuration file of the email and specifying the header there.

 

For example: 

 

var message = new Terrasoft.Mail.Sender.EmailMessage
{
	// Sender email address.
	From = "Sender@email.com",
	// Recipient email addresses.
	To = new List<string>{ "first@recepient.co", "second@recepient.co" },
	// Copy optional
	Cc = new List<string>{ "first@recepient.co", "second@recepient.co" },
	// Hidden copy optional
	Bcc = new List<string>{ "first@recepient.co", "second@recepient.co" },
	Subject = "Message subject",
	// Email body.
	Body = "Body",
	// Priority, Terrasoft.Mail.Sender.EmailPriority enumeration values.
	Priority = Terrasoft.Mail.Sender.EmailPriority.Normal,
	// Headers you want to add to your email
	HeaderProperties = new List<Mail.Sender.EmailMessageHeader>
	{
		new Mail.Sender.EmailMessageHeader
		{
			Name = "X-Auto-Response-Suppress",
			Value = "All"
		}
	}
};

Hello,

Are we discussing marketing bulk emails or regular emails sent via Exchange\SMTP?

Oleg Drobina,

Not bulk.  These are individual emails, sent out to a user (or other person) based on some data entry firing a trigger/process.

Thanks.

 

 

Hello Rob,

 

You can customize your email sending process using the instructions and examples from the article https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/8.1/platform-customization/classic-ui/emails/sending-emails/overview.

 

If you want to add the header to your email you can it by creating the configuration file of the email and specifying the header there.

 

For example: 

 

var message = new Terrasoft.Mail.Sender.EmailMessage
{
	// Sender email address.
	From = "Sender@email.com",
	// Recipient email addresses.
	To = new List<string>{ "first@recepient.co", "second@recepient.co" },
	// Copy optional
	Cc = new List<string>{ "first@recepient.co", "second@recepient.co" },
	// Hidden copy optional
	Bcc = new List<string>{ "first@recepient.co", "second@recepient.co" },
	Subject = "Message subject",
	// Email body.
	Body = "Body",
	// Priority, Terrasoft.Mail.Sender.EmailPriority enumeration values.
	Priority = Terrasoft.Mail.Sender.EmailPriority.Normal,
	// Headers you want to add to your email
	HeaderProperties = new List<Mail.Sender.EmailMessageHeader>
	{
		new Mail.Sender.EmailMessageHeader
		{
			Name = "X-Auto-Response-Suppress",
			Value = "All"
		}
	}
};
Show all comments

Hi,
I have a template ready for sending emails in Creatio. The email contains values taken from previously filled fields. Now, I would like to know the steps to send this email automatically when clicking the "Send Email" button.

Can someone guide me on how to configure the process to ensure the pre-filled values from the fields are included when the email is sent? Any help with this would be appreciated!

Could someone guide me on:

  1. How to upload or store the email template in Creatio?
  2. How to configure the button so that clicking it will send the email using the pre-filled template?

Any assistance with this process would be highly appreciated!

I'am using creatio 8.2.2

Thanks in advance!

Like 0

Like

3 comments

Dear Muhammad,

You can find more information on how to work with templates in the following Creatio Academy articles:
https://academy.creatio.com/docs/8.x/creatio-apps/creatio-basics/communications/work-with-message-templates
https://academy.creatio.com/docs/8.x/creatio-apps/products/marketing-tools/email-marketing/classic-ui/email-templates/create-an-email-template

Please note that macros will only appear when the template is opened from its corresponding source object. This means that if you send an email via the Communication panel, only templates with the source set to Activity (or those with no source) will be available — as all emails are stored in the Activity object.

If you'd like to use macros from another object, you'll need to add the MessageComposer element to the page where these macros are intended to be used.

image.png

Have a great day!

Hi Alina Yakovlieva,
 

Thank you for your advice, but I’m still confused to implement it. Can I use the button to trigger the action that runs the business process, where the business process reads data and sends an email, as shown in the image below

config read data

Config send email ( For the 'From' field, it should be filled with the company email (how do I insert the company email?), while for the 'To' field, it should send the email to the value that was previously read.)

and the button

 

 

Muhammad Rizky,

Hello,

So you can use the button to trigger a business process.

For the 'From' field, it should be filled with the company email (how do I insert the company email?)

I see that you have chosen to get the email from the system settings. So to insert the email in the business process you need to fill in the system settings by selecting one of the mailboxes already added to the system:



You also filled in that field correctly if you want that field to be filled with a value from the collection in which you are reading the Gengerate Document. However, I recommend making sure that the sorting condition returns the record you need and the field with the required email:

Show all comments

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