Using Liquid markup to customize comments and email notifications Follow

Comments

48 comments

  • Avatar
    Jennifer Holmes

    hi We have been using liquid markup to customize email responses for a while now and it works very well but I am trying to create a response where there a 2 different responses dependent on 2 different payment type tags . I am struggling to get it to work . Just keeps giving me the else response. Any ideas what I'm doing wrong?

    {% capture tags %}{{ ticket.tags }}{% endcapture %}{% case tag %}
    {% when 'amz' %}
    you will be refunded back to your amazon account
    {% when 'paypal' %}
    you will be refunded back to your paypal
    {% else %}
    you have not been charged
    {% endcase %}

  • Avatar
    Jason Littrell (Edited )

    Hi Jennifer,

    This seems like an easy enough problem, but it's actually somewhat complicated.

    For starters, capturing the "ticket.tags" placeholder is unnecessary. Capture is only used for strings and the "ticket.tags" placeholder is already a string of tags separated by spaces. If you test this after your "endcapture" tag,

    {{tags}}
    {{ticket.tags}}

    you'll see they are the same. If you want to put the tags in an array, instead, use the "assign" tag:

    {% assign tags = ticket.tags | split: " " %}

    This splits the "ticket.tags" string at each space and puts them in your "tags" array.

    Another problem is that your "case" statement is using "tag" instead of your "tags" variable, but even if you change it, you'll still be trying to evaluate the entire string. If your tags contain "amz" and "test", for example, your string will be "amz test" and "when 'amz'" will evaluate as false.

    You can use the "assign" method from above and loop through it with a "for" statement. Based on your example, it would look something like this:

    {% assign tags = ticket.tags | split: " " %}{% for tag in tags %}{% case tag %}
    {% when 'amz' %}
    you will be refunded back to your amazon account
    {% when 'paypal' %}
    you will be refunded back to your paypal
    {% else %}
    you have not been charged
    {% endcase %}{% endfor %}

    Note: in this example, "case tag" works because we assigned the item name in the "for" loop ("for tag in tags"), and the "case" statement is evaluating an individual tag instead of the whole array.

    There are some problems with this approach, though. First, since you are evaluating each tag individually, every tag that is not "amz" or "paypal" will print "you have not been charged". Similarly, if your tags contain "amz" and "paypal", it will print both of the first two statements.

    You can remove the "else" statement from the "for" loop, but then you would need to find a way to fallback to your default string if the "tags" array doesn't contain "amz" or "paypal". One way to do that would be to capture your text as a string variable, then evaluate it after the "for" loop. For example:

    {% assign tags = ticket.tags | split: " " %}
    {% assign refund = "you have not been charged" %}
    {% for tag in tags %}{% case tag %}
    {% when 'amz' %}
    {% assign refund = 'you will be refunded back to your amazon account' %}
    {% when 'paypal' %}
    {% assign refund = 'you will be refunded back to your paypal' %}
    {% endcase %}{% endfor %}
    {{refund}}

    Note: with this code, if your array contains both "amz" and "paypal", your text string will be overwritten by whatever is later in the array.

    The easiest method, though, would be to run an "if" statement on your "tags" array:

    {% assign tags = ticket.tags | split: " " %}
    {% if tags contains 'amz' %}
    you will be refunded back to your amazon account
    {% elsif tags contains 'paypal' %}
    you will be refunded back to your paypal
    {% else %}
    you have not been charged
    {% endif %}

    This will check to see if any items in the array match "amz", then "paypal", then return your default text if both are false. If your array contains both tags, "amz" will return as true first and break the loop.

    You can also forgo the array and just run an "if" statement on the "ticket.tags" string:

    {% if ticket.tags contains 'amz' %}
    you will be refunded back to your amazon account
    {% elsif ticket.tags contains 'paypal' %}
    you will be refunded back to your paypal
    {% else %}
    you have not been charged
    {% endif %}

    The problem here is that any tags that contain "amz" or "paypal" (for example, "notamz" or "notpaypal") will return as true. If you're confident that your tags are unique, though, this is a viable option.

    You're biggest hurdle at this point might be making sure that tickets that have the "amz" tag cannot have the "paypal" tag, and vice versa. Otherwise, make sure that whichever text string you want to default to when both are present is listed first in your "if" statement.

    Hope this helps. Let me know if you have any questions.

  • Avatar
    Joshua Atkin

    I don't believe this works in signatures, is that true? in essence I would like to build a custom signature depending on which organization writes to me and I could do that with Liquid

  • Avatar
    Ilya Dovidovskii

    Can you guys add this functionality to Agent signature? I tried to implement the {% ticket.requester.language %}... in Admin>Settings>Agent>Signature but it always returns the {% else %} section.

  • Avatar
    Jason Littrell

    Ilya,

    The common agent signature supports Liquid markup, but only for the "agent", "current_user", "account", and "dc" placeholder classes. Unfortunately, the "ticket" class isn't supported (more info here). When using Liquid in the signature, the ticket.requester.language placeholder is evaluated as null, so comparison to any other value returns false.

    If you're on the Professional or Enterprise plan, dynamic content will do exactly what you want. On the Team plan, you can build and install an app that would inject an agent signature and localized text when a comment is submitted. This would work because the Data API allows you to pull the requester's locale using ticket.requester.locale(). Aside from those options, I have a vague idea of how you may be able to accomplish this using a unique code in the signature, multiple triggers with language based codes in the notification body, and some Liquid markup directly in your email template. It's all highly theoretical, however, and quite possibly very dangerous. 

  • Avatar
    Sharon Stone

    Hiya,

    I need an email notification sent in a trigger to caption checked boxes within a ticket field range, and am not really clear how to use liquid mark-up for this. For a few of our applications, they have multiple options for access levels so they are check boxes. For example, there is a drop down question "System access required", which when "yes" is selected, several checkboxes appear.

    Can anyone advise how I can use liquid mark-up to only show checked boxes for that question in the email notification? The people getting the emails won't see the full content of the form.

    Thanks!

    Sharon

  • Avatar
    Jason Littrell

    Hi Sharon,

    If I understand your question correctly, you can use the following liquid code to only show checkboxes when your "System access required" field is set to "yes":

    {% if ticket.ticket_field_option_title_<field ID number> == 'yes' %} [checkboxes go here] {% else %} [fallback content goes here] {% endif %}

    Just replace <field ID number> with the id number for the "System access required" field. You can omit the {% else %} tag and fallback content if you want to leave the area blank when "yes" isn't selected. Also, the field option title is case sensitive, so "yes" =/= "Yes".

    Best,

    Jason

  • Avatar
    Jiri Tawski

    Hi, I'm trying to create a trigger with a liquid markup, that would send notifications based on strings in comments.  

    I have 3 triggers that send notifications. All of them are based on condition "comment text does contain the following string. For example


    If ticket 1 comment does contain 1 - send 1
    If ticket 2 comment does contain 2 - send 2
    else send 3

    Is there a solution for that?

    Thanks

  • Avatar
    Jonathan March

    Artem, could you explain more explicitly what you mean by "ticket 1 comment" and "ticket 2 comment" ? A given trigger only operates on one ticket at a time. Or are you hoping to look back at old comments on this ticket?

  • Avatar
    Jiri Tawski

    Jonathan, 

    sorry for confusion, please read as follows:

    — If ticket comment does contain ABC - send 1
    — If ticket  comment does contain DEF - send 2
    — else send 3

  • Avatar
    Jonathan March

    @Artem I have not tested this, but something like this should work:

     

    ```

    {% capture comment %} {{ ticket.latest_comment }} {% endcapture %}

    {% if comment contains "text1" %}

    paragraph 1

    {% elsif comment contains "text2" %}

    paragraph 2

    {% else %}

    paragraph 3

    {% endif %}

    ```

  • Avatar
    Jiri Tawski

    @ Jonathan, 

    it works great. Thank you very much for that snippet. 

     

  • Avatar
    Jacob J Christensen

    I've tried more or less to replicate the Liquid Markup in the second example "Using Liquid markup to support multiple languages in automations, macros, and triggers", but through much trial and error found that the string to indicate locale is not as described in the article or the example.

    Language support is defined by an administrator (on the Localization tab of the Account page) and you use the names (the exact text string) as displayed in the list of languages on that page.

    I found that locale is actually the native language name Danish is 'Dansk', Swedish is 'Svenska', and the almost impossible to guess Finnish is 'Suomi (Finnish)'.

    Please update the article and save some poor bastard hours of frustration.

  • Avatar
    Justin Graves

    Fellow Zendeskers - I just posted a request to try to address some of the same needs as many users have stated in the comments here- namely how to format only a portion (in my case the message section) of an otherwise "unformatted" email template. I used your post here as an example of another Zendesk users with a similar need. I'm trying to drum up support to get the Zendesk developers moving on this idea so I'd like to have you look at my post and give it a thumbs up and leave a comment there so we can bolster the case and show the need for these features.

    Please take a look:

    https://support.zendesk.com/hc/en-us/community/posts/220847487-Add-a-placeholder-for-formatted-comment-values-maybe-comment-value-formatted-

  • Avatar
    Nathan C

    If you're looking for a solution to make email notifications look a little more like "Real emails" Check out the below... i know there have been a lot of people looking for this (including myself)

    http://moometric.com/integrations/zendesk/make-zendesk-tickets-look-like-real-emails/

  • Avatar
    Ferenc Bartha (Edited )

    Any plan to support Jekyl Lib.? - http://jekyllrb.com/docs/plugins/

    So that we could import content into the notification templates?

    eg.: http://stackoverflow.com/questions/15917463/embedding-markdown-in-jekyll-html

    It would be extremely useful, scalable for us. Just image example translations ... if I could dynamically load the notification body based on some parameters from our service, instead of having at least two email notification setup over about 150 triggers. - totally not scalable.

    Like this we could dynamically include the html content of the notifications, including the ZD placeholders ... so things would get pretty scalable, manageable .

    Any thoughts on this?

  • Avatar
    Jack Elver-Fiddimore

    Hi, thanks for this great article. 

    Could you tell me the language property values of Bosnian and Bulgarian? They're both languages supported in Zendesk but I can't find their property values. 

    Thanks. 

  • Avatar
    Jacob J Christensen (Edited )

    Hi Jack,

    I can't validate it myself, but (if those languages are supported in Liquid Markup) I believe that it should be:

    Bosanski

    and

    Български

     

     

  • Avatar
    Jason Littrell (Edited )

    @Jack You can use the "/api/v2/locales/public.json" endpoint to pull up the data. For Bosnian its:

    "url": "https://yapstone.zendesk.com/api/v2/locales/bs.json",
    "id": 1008,
    "locale": "bs",
    "name": "Bosnian",
    "native_name": "bosanski",
    "presentation_name": "Bosnian - bosanski",
    "rtl": false,
    "created_at": "2010-01-11T11:54:03Z",
    "updated_at": "2016-10-27T00:09:14Z",
    "default": false

    And Bulgarian shows:

    "url": "https://yapstone.zendesk.com/api/v2/locales/bg.json",
    "id": 94,
    "locale": "bg",
    "name": "Bulgarian",
    "native_name": "български",
    "presentation_name": "Bulgarian - български",
    "rtl": false,
    "created_at": "2009-07-21T10:51:33Z",
    "updated_at": "2017-02-18T17:32:33Z",
    "default": false

    The "name" value is returned when using the {{ticket.requester.language}} placeholder, while the "locale" value will be returned for {{ticket.requester.locale}}.

    *Edit: for just the languages that your Zendesk instance supports, you can use "/api/v2/locales.json".

  • Avatar
    Jack Elver-Fiddimore

    Thank you Jason and Jacob :) That's awesome. 

  • Avatar
    Colin Campbell

    Is there a way to customize a greeting depending on the time of day for Good morning and Good afternoon?

  • Avatar
    Sarah Seiwert

    Hi - forgive me if my question is very basic. Hopefully, this will be an obvious answer for you! I'm new to liquid macros and I can't seem to get past a problem that's been occurring for me: 

    Background:

    I've been creating macros this way to call a response based on an exam name... 

    {% if ticket.tags contains 'praxis' %}

    {% elsif ticket.tags contains 'lsat' %}

    {% elsif ticket.tags contains 'sat' %}

    {% elsif ticket.tags contains 'act' %}

     

    {% elsif ticket.tags contains 'gre' %}

    {% else %}

    {{ticket.comments_formatted}}

    {% endif %}

    Problem:

    We have a few tags that quite literally have the words sat or act in it, e.g. "detractor" and "satisfaction". To workaround that, I thought rewriting the following commands this way would solve the issue... 

    {% elsif ticket.tag == sat %}

    {% elsif ticket.tag == act %}

    However, this isn't working. Putting in an act exam tag during testing will still call up the SAT response. What am I don't wrong? Thanks for helping this novice out! 

     

  • Avatar
    Jason Littrell

    @Sarah The problem is that the ticket.tags placeholder produces a string so 'contains' will look for any part of the string. To get around this, you can convert it to an array like this:

    {% assign tags = ticket.tags | split: ' ' %}

    Then you would just replace 'ticket.tags' with 'tags' in your first four examples above. For example:

    {% if tags contains 'sat' %}...

    Using 'contains' on an array checks the array for the value you specify, but will not search within individual values. Try it with 'sat' and 'satisfaction' tags, then again without the 'sat' tag and you should get different results.

  • Avatar
    Sam Tilin

    Hey, this is a great post! What I'm wondering is if I can use Liquid markup to change a custom field on the ticket, rather than show/hide text in the email notification. 

    In other words, I'd like to use the {% if comment contains "text1" %} logic to set a checkbox to TRUE on my tickets. Is this possible? 

  • Avatar
    Jason Littrell

    @Sam You can use an HTTP target to accomplish this (see here and here for inspiration). Your best bet, though, is to accomplish this with a trigger. Here's a barebones example of how you could set one up:

  • Avatar
    Sam Tilin

    @Jason Thanks! I'll try those solutions

  • Avatar
    Sarah Seiwert

    Hi @jason, I'm FINALLY getting back to this. Sorry for the delay. So just to be sure, you're saying that the array should be written before the start of the if statement, thus my syntax should appear like this: 

    {% assign tags = ticket.tags | split: '' %}

    {% if tags contains 'praxis' %}

    Message

    {% elsif tags contains 'lsat' %}

    Message

    {% elsif tags contains 'sat' %}

    Message

    {% elsif tags contains 'act' %}

    Message

     {% elsif ticket.tags contains 'gre' %}

    Message

    {% else %}

    Alternative message

    {{ticket.comments_formatted}}

    {% endif %}

    Thanks, just need to be sure since I'll have a lot of macros to modify. 

  • Avatar
    Sarah Seiwert

    I'm posting a different question that I can use some help with. I'm only able to call my response within after {% else %}. I'm just trying to call up a message between two options. I've tried if/else/end, but that didn't work, so I thought this would be a better alternative. Nothing I'm doing is working. :( 

    ++++++++++++++++++++++

    {% if ticket.requester.last_name == ticket.requester.first_name %}Hi there! {% else %}Hi {{ ticket.requester.first_name | capitalize }},{% endif %}

    {% if ticket.tags contains ‘gmat' %}

     

    Message 1

    {% elsif ticket.tags contains 'gre' %}

     

    Message 2

    {% else %}

    Message 3

    {{ticket.comments_formatted}}

    {% endif %}

  • Avatar
    Jason Littrell (Edited )

    @Sarah That's correct. You'll need to assign the "tags" variable first, but also make sure that you're splitting with a space and not just two single quotes (i.e. ' ' and not ''). The latter will split on every character in the tags string.

    I'll have to do some testing, but one thing I noticed in your second question is that the "gmat" if condition starts with an incorrect single quote. It's not clearly visible with this site's font, so this code block might make it easier to see:

    {% if ticket.tags contains ‘gmat' %}

    Liquid doesn't play nice with the smart-style quotes, so replacing it with a standard single quote might make that portion of the code work. 

  • Avatar
    Sarah Seiwert

    Both solutions were spot on, @jason. I especially thank you for catching the incorrect smart-style quote. All is well now!  - SS

     

Please sign in to leave a comment.

Powered by Zendesk