Skip to Content
Technical Articles
Author's profile photo Mohit Sharma

Object Oriented way of sending an email from ABAP side.

Introduction

The history of email extends over more than 50 years, entailing an evolving set of technologies. Early dedicated machines and networks for sending text messages existed in the form of the telegraph, Telex and AUTODIN.

There can exist some scenarios in  SAP, where we are suppose to send email to someone with/without attachment.

To send an email from ABAP, you can use the function module “SO_NEW_DOCUMENT_SEND_API1”, but in this blog post you will learn how to send an email using object oriented way. Though approach has also become old now, but still it would be good, if we revise it 😛 .

Requirement

Suppose we want to see a simple email like below in SAP:

But, lets first understand that how a simple HTML page looks like: (you can create a simple HTML file with extension “.html”, I saved the file with the name “simple.html”).

<!DOCTYPE html>
 <html>
  <body>
   Hi Dear
   <p> Content Section! </p>
  </body>
 </html>

If you open the above html file, the output looks like:

Similarly we will also create the email referring the above html code.

Steps

Lets achieve 🙂

  1. Create an executable local test program from SE38.
  2. Understand and refer the below code as per your requirement.
*&---------------------------------------------------------------------*
*& Data Declaration
*&---------------------------------------------------------------------*
DATA : lo_mime_helper TYPE REF TO cl_gbt_multirelated_service,
       lo_bcs         TYPE REF TO cl_bcs,
       lo_doc_bcs     TYPE REF TO cl_document_bcs,
       lo_recipient   TYPE REF TO if_recipient_bcs,
       lt_soli        TYPE TABLE OF soli,
       ls_soli        TYPE soli,
       lv_status      TYPE bcs_rqst.

*&---------------------------------------------------------------------*
*& Creation of the mail
*&---------------------------------------------------------------------*

" Create the main object of the mail.
CREATE OBJECT lo_mime_helper.

" Create the mail content.-----"CLASSIC WAY"
*ls_soli-line = '<!DOCTYPE html PUBLIC “-//IETF//DTD HTML 5.0//EN">'.
*APPEND ls_soli TO lt_soli.

*ls_soli-line = '<HTML>'.
*APPEND ls_soli TO lt_soli.

*ls_soli-line = '<BODY>'.
*APPEND ls_soli TO lt_soli.

*ls_soli-line = 'Hi Dear,<P>Content Section!</P>'.
*APPEND ls_soli TO lt_soli.

*ls_soli-line = '</BODY>'.
*APPEND ls_soli TO lt_soli.

*ls_soli-line = '</HTML>'.
*APPEND ls_soli TO lt_soli.

" Create the mail content.-----"NEW WAY"
DATA(string) = '<!DOCTYPE html PUBLIC “-//IETF//DTD HTML 5.0//EN">'
            && '<HTML><BODY>Hi Dear,<P>Content Section!</P></BODY></HTML>'.

lt_soli = CL_DOCUMENT_BCS=>STRING_TO_SOLI( string ).

" Set the HTML body of the mail
CALL METHOD lo_mime_helper->set_main_html
  EXPORTING
    content     = lt_soli
    description = 'Test Email'.

* Set the subject of the mail.
lo_doc_bcs = cl_document_bcs=>create_from_multirelated(
                i_subject          = 'Subject of our email'
                i_importance       = '9'                " 1~High Priority  5~Average priority 9~Low priority
                i_multirel_service = lo_mime_helper ).

lo_bcs = cl_bcs=>create_persistent( ).

lo_bcs->set_document( i_document = lo_doc_bcs ).

* Set the email address
lo_recipient = cl_cam_address_bcs=>create_internet_address(
                  i_address_string =  'test@test12.com' ).

lo_bcs->add_recipient( i_recipient = lo_recipient ).

* Change the status.
lv_status = 'N'.
CALL METHOD lo_bcs->set_status_attributes
  EXPORTING
    i_requested_status = lv_status.

*&---------------------------------------------------------------------*
*& Send the email
*&---------------------------------------------------------------------*
TRY.
  lo_bcs->send( ).
  COMMIT WORK.
CATCH cx_bcs INTO DATA(lx_bcs).
  ROLLBACK WORK.
ENDTRY.

3. Now, execute the above program and go to the transaction SOST, you can see an email against your name as below:

4. Now if you will display the email above, you can see your email as expected 🙂

Note

You can use, email templates as well, which will help you to avoid hard-coding of email content and subjects.

Please find the link below

https://blogs.sap.com/2019/10/12/e-mail-templates-in-s4-hana/

Conclusion

Yes!! In this way we can send a simple email having a subject and a content body with the above piece of code.

 

It would be very helpful in improving and adding more points to this blog post, if you can share your experiences in case you worked or explored with this approach.

In my next blog post, I will try to touch a new add on with the above approach.

For any issues, improvements, additions or any other concerns, please feel free to contact me.

I look forward for your feedback and suggestions.

Keep learning!! Keep improving!!

Assigned Tags

      21 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo S Nalluri
      S Nalluri

      Appreciate your efforts, Small suggestion – Add TRY…CATCH…ENDTRY block

      Author's profile photo Mohit Sharma
      Mohit Sharma
      Blog Post Author

      Thanks S Nalluri for your appreciation; Regarding exception handling, I will surely add that soon as well. 🙂

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Yes, your sy-subrc check isn't useful.

       

      Author's profile photo Sandra Rossi
      Sandra Rossi

      It’s sad that ABAP gurus promoted BCS for 15 years, as SAP did, and that people still use this old function module (and other old-fashioned ones).

      There are also demo programs provided in every ABAP system, prefixed BCS_EXAMPLE_*.

      I’m interested by your “add on”, I don’t know what it is, but if it solves the main issue which is, according to me, that a text or binary document needs to be passed via an internal table instead of string/xstring (many other old “APIs” use internal tables too, unfortunately), which leads to frequent errors like the actual length of the document being “corrupted” (error with PDF files especially), I would be happy!

       

      Author's profile photo Mohit Sharma
      Mohit Sharma
      Blog Post Author

      Thanks Sandra Rossi for your feedback.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      It's chilling that the 2006 blog title Unknown Thus Unloved remains somewhat accurate to this day.

      Author's profile photo Michelle Crapo
      Michelle Crapo

      I usually just use class CL_DOCUMENT_BCS.

      A quick suggestion for a project, use GITHUB.  Blog and then point people to your project.

      Author's profile photo Mohit Sharma
      Mohit Sharma
      Blog Post Author
      Hi Michelle Crapo, thanks for your feedback.
      I just created a GITHUB repository, will try to explore that as well 🙂
      Author's profile photo Michelle Crapo
      Michelle Crapo

      Very cool.  Now the blogs to get the people there and helping out.

      Thank you!

      Author's profile photo Prabhjot Bhatia
      Prabhjot Bhatia

      I published a blog based on email templates which will help to avoid Hardcoding of email content and subjects.

      You can try to integrate in your program.

      https://blogs.sap.com/2019/10/12/e-mail-templates-in-s4-hana/

      Author's profile photo Mohit Sharma
      Mohit Sharma
      Blog Post Author

      Thanks Prabhjot, Its an excellent blog. 🙂
      I will try it; at the meantime instead, I will add the link of your blog to present as a good practice. Thanks!!

      Author's profile photo Mark Wagener
      Mark Wagener

      Hi,

      nice blog! I create a send_mail method using cl_bcs framework myself like this:

      *----------------------------------------------------------------------*
      * CLASS-DEFINITIONS                                                    *
      *----------------------------------------------------------------------*
        data: o_send_request       type ref to cl_bcs.
        data: o_document           type ref to cl_document_bcs.
        data: o_sender             type ref to if_sender_bcs. "cl_sapuser_bcs.
        data: o_recipient          type ref to if_recipient_bcs.
        data: exception_info type ref to if_os_exception_info,    "#EC NEEDED
              bcs_exception  type ref to cx_bcs.
      
      *----------------------------------------------------------------------*
      * INTERNAL TABLES                                                      *
      *----------------------------------------------------------------------*
        data: l_mailtext type soli_tab.
        data: l_mailhex  type solix_tab.
        data: iaddsmtp   type bapiadsmtp_t.
        data: ireturn    type bapiret2_t.
      
      *----------------------------------------------------------------------*
      * FIELD-SYMBOLS                                                        *
      *----------------------------------------------------------------------*
      
      *FIELD-SYMBOLS: <fs_iaddsmtp> TYPE bapiadsmtp.
      
      *----------------------------------------------------------------------*
      * VARIABLES                                                            *
      *----------------------------------------------------------------------*
        data: mail_line  like line of l_mailtext.
        data: mailx_line like line of l_mailhex.
        data: bapiadsmtp         type bapiadsmtp.
      
        class cl_cam_address_bcs definition load.
        class cl_abap_char_utilities definition load.
      
        try.
      * Create persistent send request
            o_send_request = cl_bcs=>create_persistent( ).
      
            data: first(1) type c.
            clear first.
            data: documents_line type line of zov_t_mail_documents.
      
            loop at pi_t_documents into documents_line.
              if first is initial.
                move 'X' to first.
      * Build the Main Document
                if documents_line-content_hex[] is initial.
                  o_document = cl_document_bcs=>create_document(
                                      i_type    = documents_line-type
                                      i_text    = documents_line-content_text
                                      i_subject = documents_line-subject ).
                else.
                  o_document = cl_document_bcs=>create_document(
                                      i_type    = documents_line-type
                                      i_hex     = documents_line-content_hex
                                      i_subject = documents_line-subject ).
                endif.
              else.
                if documents_line-content_hex[] is initial.
      * Add Attachment
                  call method o_document->add_attachment
                    exporting
                      i_attachment_type    = documents_line-type
                      i_attachment_subject = documents_line-subject
                      i_att_content_text   = documents_line-content_text
                      i_attachment_header  = documents_line-attachment_header.
                else.
                  call method o_document->add_attachment
                    exporting
                      i_attachment_type    = documents_line-type
                      i_attachment_subject = documents_line-subject
                      i_att_content_hex    = documents_line-content_hex
                      i_attachment_header  = documents_line-attachment_header.
                endif.
              endif.
            endloop.
      
      
      * Add document to send request
            call method o_send_request->set_document( o_document ).
      
      * Get sender object
            if pi_sender_addr is not initial.
              o_sender =  cl_cam_address_bcs=>create_internet_address( pi_sender_addr ).
            elseif pi_sender is not  initial.
              o_sender = cl_sapuser_bcs=>create( pi_sender ).
            else.
              o_sender = cl_sapuser_bcs=>create( sy-uname ).
            endif.
      
      * Add sender
            call method o_send_request->set_sender
              exporting
                i_sender = o_sender.
      
      
            data: recipients_line like line of pi_t_recipients.
            loop at pi_t_recipients into recipients_line.
      
              o_recipient = cl_cam_address_bcs=>create_internet_address( recipients_line-c_address ).
      * Add recipient with its respective attributes to send request
              call method o_send_request->add_recipient
                exporting
                  i_recipient  = o_recipient
                  i_express    = recipients_line-i_express
                  i_copy       = recipients_line-i_copy
                  i_blind_copy = recipients_line-i_blind_copy
                  i_no_forward = recipients_line-i_no_forward.
      
            endloop.
      
      * Set that you don't need a Return Status E-mail
            data: status_mail type bcs_stml.
            status_mail = pi_requested_status.
            call method o_send_request->set_status_attributes
              exporting
                i_requested_status = pi_requested_status
                i_status_mail      = status_mail.
      
      * set send immediately flag
            o_send_request->set_send_immediately( 'X' ).
      
      * set long status (longer than 50 characters, see note 698087)
            if pi_long_subject is not initial.
              o_send_request->set_message_subject( pi_long_subject ).
            endif.
      
      * Send document
            call method o_send_request->send( ).
      
            if pi_commit = abap_true.
              commit work and wait.
            endif.
      
          catch cx_bcs into bcs_exception.
            raise exception bcs_exception.
      
        endtry.

      Signature:

       class-methods SEND_MAIL
          importing
            !PI_REQUESTED_STATUS type BCS_RQST default 'E'
            !PI_T_DOCUMENTS type ZOV_T_MAIL_DOCUMENTS
            !PI_T_RECIPIENTS type ZOV_T_MAIL_RECIPIENTS
            !PI_COMMIT type OS_BOOLEAN
            !PI_SENDER type SYUNAME optional
            !PI_LONG_SUBJECT type STRING optional
            !PI_SENDER_ADDR type WRB_AD_SMTPADR optional
          raising
            CX_BCS .

      You can attach files and overcome the limitation of 50 characters in the subject (in SOST the short subject is displayed).

      Best regards,

      Mark

      Author's profile photo Mohit Sharma
      Mohit Sharma
      Blog Post Author

      Thanks Mark, it indeed is a good way too 🙂

      Author's profile photo Matthew Billingham
      Matthew Billingham

      You should also make your code compliant with the published SAP guidelines on variable naming (and also part of the clean coding project).

      Stop using Hungarian notation! 🙂

      Other than that, it's good to promote this 15 year old knowledge, as people still insist on using the function modules. Maybe one day they'll learn how to use hashed tables... :-p

      Author's profile photo Mohit Sharma
      Mohit Sharma
      Blog Post Author

      Thanks Matthew for your feedback 🙂

      Author's profile photo jagadeesh kenguva
      jagadeesh kenguva

      Hello Mohit,

      I have tried the same procedure that you have shown with simple mail body(HTML content). But in SOST it shows error like 'Currently no delivery to Recipient'.

       

      I can send mail of body type 'RAW', but not HTM.

      I have tried following two ways. But still it is not working

      1. DATA(lref_documentcl_document_bcs=>create_document(
      i_type     'HTM'
      i_text     lt_body
      i_subject  'Testing(html)'
      i_importance '1'
      ).

      2. lo_doc_bcs cl_document_bcs=>create_from_multirelated(
      i_subject          'Subject of our email'
      i_importance       '9'                " 1~High Priority  5~Average priority 9~Low priority
      i_multirel_service lo_mime_helper ).

       

      Could you please help me out, how can i resolve my issue.

      And also please let me know that if i need to do any additional configuration for HTML content mail sending.

      Thanks in advance.

       

      Best Regards,

      Jagadeesh

      Author's profile photo Mohit Sharma
      Mohit Sharma
      Blog Post Author

      Hi Jagadeesh,

      You will have to check this with your BASIS colleagues, as this sometimes occurs due to insufficient resources on the application server.

      In case, you find any other solution or reason, please help us all with that as well.

      Thanks and Regards,
      Mohit Sharma

      Author's profile photo Andy Pataselano
      Andy Pataselano

      Hi Mohit,

      Thank you for nice blog.

      I want set multiple email address as 'Reply To' email address using method SET_REPLY_TO, but unfortunately, only last email address in internal table can set as 'Reply To' email address.

      For your information, I can add multiple e-mail addresses as 'reply to' email adresses in Microsoft Outlook (please refer to How to Change the “Reply To” Address for Email Messages in Outlook).

      Could you give advice for solve this problem?

       

      Best regards,

      Andy Pataselano

      Author's profile photo Mohit Sharma
      Mohit Sharma
      Blog Post Author

      Hi Andy,

      You can loop over your recipients and add them via method add_recipient.

      Regards,

      Mohit Sharma

      Author's profile photo Andy Pataselano
      Andy Pataselano

      Hi Mohit,

      'Reply To' is not same as recipients. So, I can't add 'Reply To' via method add_recipient.

      Best regards,

      Andy Pataselano

      Author's profile photo Dipak Zombade
      Dipak Zombade

      How to send mail with 2 attachments from application server.