Lesson 13 - Existing Content

Goal

In this lesson we’ll learn how to easily integrate ready-made content into our flow.

Get Started

Instead of printing that our flow has completed, let’s send an email to HR to let them know that the new hire’s email address has been created and notify them as to the status of the new hire’s equipment order. If you’re using a pre-built CLI you’ll have a folder named content that contains all of the ready-made content. If you’ve built the CLI from the source code, you’ll have to get the content mentioned below from the GitHub repository and point to the right location when running the flow.

Ready-Made Operation

We’ll use the send_mail operation which is found in the base/mail folder. All ready-made content begins with a commented explanation of its purpose and its inputs, outputs and results.

Here’s the documentation for the send_mail operation:

########################################################################################################################
#!!
#! @description: This operation sends SMTP email.
#!
#! @input hostname: The hostname or ip address of the SMTP server.
#! @input port: The port of the SMTP service.
#! @input from: From email address.
#! @input to: A delimiter separated list of email address(es) or recipients where the email will be sent.
#! @input cc: Optional - A delimiter separated list of email address(es) or recipients, to be placed in the CC.
#!            Default: ''
#! @input bcc: Optional - A delimiter separated list of email address(es) or recipients, to be placed in the BCC.
#!             Default: ''
#! @input subject: The email subject. If a subject spans on multiple lines, it is formatted to a single one.
#! @input body: The body of the email.
#! @input html_email: The value should be true if the email is in rich text/html format.
#!                    The value should be false if the email is in plain text format.
#!                    Valid values: 'true', 'false'.
#!                    Default: 'true'.
#! @input read_receipt: Optional - The value should be true if read receipt is required, else false.
#!                                 Valid values: 'true', 'false'.
#!                                 Default: 'false'
#! @input attachments: Optional - A delimited separated list of files to attach (must be full path).
#!                     Default: ''
#! @input username: Optional - If SMTP authentication is needed, the username to use.
#!                  Default: ''
#! @input password: Optional - If SMTP authentication is needed, the password to use.
#!                  Default: ''
#! @input character_set: Optional - The character set encoding for the entire email which includes subject, body,
#!                                  attached file name and the attached file.
#!                                  Valid values: 'UTF-8', 'UTF-16', 'UTF-32', 'EUC-JP', 'ISO-2022-JP',
#!                                                'Shift_JIS', 'Windows-31J'.
#!                                  Default: 'UTF-8'
#! @input content_transfer_encoding: Optional - The content transfer encoding scheme (such as 7bit, 8bit, base64,
#!                                              quoted-printable, etc) for the entire email which includes subject,
#!                                              body, attached file name and the attached file.
#!                                              Valid values: 'quoted-printable', 'base64', '7bit',
#!                                                            '8bit', 'binary', 'x-token'.
#!                                              Default: 'base64'
#! @input delimiter: Optional -  A delimiter to separate the email recipients and the attachments.
#!                               Default: ''
#! @input enable_TLS: Optional - Specify if the connection should be TLS enabled or not.
#!                               Default: 'false'
#!
#! @output return_result: That will contain the 'Sent Mail Successfully' if the mail was sent successfully.
#! @output return_code: '0' if success, '-1' otherwise.
#! @output exception: The exception message if the operation goes to failure.
#!
#! @result SUCCESS: Succeeds if mail was sent successfully and the return_code = '0'.
#! @result FAILURE: There was an error while trying to sent the mail and the return code = '-1'.
#!!#
########################################################################################################################

We could get this information by opening the operation from the ready-made content folder or by running inspect on the flow.

inspect <content folder path>/io/cloudslang/base/mail/send_mail.sl

When calling the operation, we’ll need to pass values for all the arguments listed in the documentation that are not optional.

Imports

First, we’ll need to set up an import alias for the new operation since it doesn’t reside where our other operations and subflows do.

imports:
  base: tutorials.base
  mail: io.cloudslang.base.mail

For more information, see imports in the DSL reference.

Step

Then, all we really need to do is create a step in our flow that will call the send_mail operation. Let’s put it right after the print_finish operation. We need to pass a host, port, from, to, subject and body. You’ll need to substitute the values in angle brackets (<>) to work for your email host. Notice that the body value is taken directly from the print_finish step with two slight changes. First, we turned the \n into a <br> since the html_email input defaults to true. Second, we added the temporary password published by the create_email_address step.

- send_mail:
    do:
      mail.send_mail:
        - hostname: "<host>"
        - port: "<port>"
        - from: "<from>"
        - to: "<to>"
        - subject: "${'New Hire: ' + first_name + ' ' + last_name}"
        - body: >
            ${'Created address: ' + address + ' for: ' + first_name + ' ' + last_name + '<br>' +
            'Missing items: ' + all_missing + ' Cost of ordered items: ' + str(total_cost) + '<br>' +
            'Temporary password: ' + password}
    navigate:
      - FAILURE: FAILURE
      - SUCCESS: SUCCESS

Run It

We can save the files, run the flow and check that an email was sent with the proper information.

run --f <folder path>/tutorials/hiring/new_hire.sl --cp <folder path>/tutorials,<content folder path>/io/cloudslang/base --i first_name=john,last_name=doe

Download the Code

Lesson 13 - Complete code

Up Next

In the next lesson we’ll see how to use system properties to send values to input variables.

New Code - Complete

new_hire.sl

namespace: tutorials.hiring

imports:
  base: tutorials.base
  mail: io.cloudslang.base.mail

flow:
  name: new_hire

  inputs:
    - first_name
    - middle_name:
        required: false
    - last_name
    - all_missing:
        default: ""
        required: false
        private: true
    - total_cost:
        default: '0'
        private: true
    - order_map:
        default: '{"laptop": 1000, "docking station": 200, "monitor": 500, "phone": 100}'

  workflow:
    - print_start:
        do:
          base.print:
            - text: "Starting new hire process"
        navigate:
          - SUCCESS: create_email_address

    - create_email_address:
        loop:
          for: attempt in range(1,5)
          do:
            create_user_email:
              - first_name
              - middle_name
              - last_name
              - attempt: ${str(attempt)}
          publish:
            - address
            - password
          break:
            - CREATED
            - FAILURE
        navigate:
          - CREATED: get_equipment
          - UNAVAILABLE: print_fail
          - FAILURE: print_fail

    - get_equipment:
        loop:
          for: item, price in eval(order_map)
          do:
            order:
              - item
              - price: ${str(price)}
              - missing: ${all_missing}
              - cost: ${total_cost}
          publish:
            - all_missing: ${missing + not_ordered}
            - total_cost: ${str(int(cost) + int(spent))}
          break: []
        navigate:
          - AVAILABLE: check_min_reqs
          - UNAVAILABLE: check_min_reqs

    - check_min_reqs:
        do:
          base.contains:
            - container: ${all_missing}
            - sub: 'laptop'
        navigate:
          - DOES_NOT_CONTAIN: print_finish
          - CONTAINS: print_warning

    - print_warning:
        do:
          base.print:
            - text: >
                ${first_name + ' ' + last_name +
                ' did not receive all the required equipment'}
        navigate:
          - SUCCESS: print_finish

    - print_finish:
        do:
          base.print:
            - text: >
                ${'Created address: ' + address + ' for: ' + first_name + ' ' + last_name + '\n' +
                'Missing items: ' + all_missing + ' Cost of ordered items: ' + total_cost}
        navigate:
          - SUCCESS: send_mail

    - send_mail:
       do:
         mail.send_mail:
           - hostname: "<host>"
           - port: "<port>"
           - from: "<from>"
           - to: "<to>"
           - subject: "${'New Hire: ' + first_name + ' ' + last_name}"
           - body: >
               ${'Created address: ' + address + ' for: ' + first_name + ' ' + last_name + '<br>' +
               'Missing items: ' + all_missing + ' Cost of ordered items: ' + total_cost + '<br>' +
               'Temporary password: ' + password}
       navigate:
         - FAILURE: FAILURE
         - SUCCESS: SUCCESS

    - on_failure:
      - print_fail:
          do:
            base.print:
              - text: "${'Failed to create address for: ' + first_name + ' ' + last_name}"