Skip to Content
Author's profile photo Gregor Wolf

Inbound mail processing – Attach files to Opportunity

References

With this great SDN content it was easy to develop this functionality:

Business Case

With our new copiers our users can also use a scan to E-Mail functionality. Because there often get long specification faxes for projects we had the need to allow an easy way to attach these documents to CRM Opportunities. These are the steps:

  • Scan specification fax to E-Mail
  • Forward E-Mail to a special E-Mail Account on the CRM Server
  • Change the Subject to the Opportunity Number
  • CRM Server attaches the Documents to the Opportunity

Implementation

I suggest that you fist follow the Weblog from Thomas Jung on Receiving E-Mail and processing it with ABAP – Version 610 and Higher. You can really copy & paste this solution except from the line:

* set sender
 lo_sender = cl_sapuser_bcs=>create( 'KEGSAPSUP' ).

in the Method SEND_REPLY. Change KEGSAPSUP to a Username existing in your client.

For the processing of the Attachments I’ve only adopted the PROCESS_INBOUND method. Here is the source:

METHOD if_inbound_exit_bcs~process_inbound .

  DATA: sender TYPE REF TO if_sender_bcs.
  DATA: sender_addr TYPE string.
  DATA: lo_reply TYPE REF TO cl_send_request_bcs .
  DATA: li_document TYPE REF TO if_document_bcs,
        l_subject   TYPE so_obj_des,
        ls_text     TYPE soli,
        lt_text     TYPE soli_tab.

  TRY.
**** init
      CLEAR e_retcode.
      CLEAR es_t100msg.

**** Get a pointer to the reply email object
      lo_reply = io_sreq->reply( ).

**** Check to make sure this is from an approved Sender
      sender = io_sreq->get_sender( ).
      sender_addr = sender->address_string( ).
      TRANSLATE sender_addr TO UPPER CASE.

**** Only reply if this message came from within out mail system
      IF sender_addr CS '@SITECO.DE' OR
      sender_addr CS '@SITECO.NET'.

**** Process Attachment
        DATA: l_parts                TYPE int4,
              anhang_nr              TYPE string,
              attribute              TYPE bcss_dbpa,
              lt_attachments         TYPE TABLE OF int4,
              ls_attachments         LIKE LINE OF lt_attachments,
              ls_content             TYPE bcss_dbpc,
              lv_request_guid_c      TYPE crmt_object_guid32,
              ls_file_info           TYPE crmt_icss_file_info,
              lt_file_content_binary TYPE TABLE OF sdokcntbin,
              l_sender_subject       TYPE char50,
              lt_cont_hex            TYPE solix_tab,
              ls_cont_hex            LIKE LINE OF lt_cont_hex,
              lv_objkey              TYPE swo_typeid,
              size                   TYPE string.

**** Data Types for Binary Conversion
        DATA: v_struct  TYPE sdokcntbin,
              v_cur_pos TYPE i,
              v_line    TYPE sdok_sdatx,
              v_temp    TYPE xstring,
              v_length  TYPE i.
**** get document
        li_document = io_sreq->get_document( ).

**** get subject
        l_sender_subject = li_document->get_subject( ).
**** Get Opportunity GUID from Subject
        DATA: iv_opportunity_id TYPE crmt_object_id,
              lt_opportunity    TYPE TABLE OF crmt_icm_opportunity_descrpt,
              ls_opportunity    LIKE LINE OF lt_opportunity,
              opp_guid          TYPE string.

        iv_opportunity_id = l_sender_subject.

        CALL FUNCTION 'CRM_ICM_OPPORTUNITY_SEARCH'
          EXPORTING
            iv_opportunity_id = iv_opportunity_id
*           IV_OPPORTUNITY_DESCRIPTION =
*           IV_OPPORTUNITY_GUID =
          TABLES
            et_opportunity    = lt_opportunity
          EXCEPTIONS
            no_authorization  = 1
            error_occured     = 2
            OTHERS            = 3.
**** Only if we get a valid GUID we process the Attachments
        READ TABLE lt_opportunity INDEX 1 INTO ls_opportunity.
        IF sy-subrc <> 0
        OR ls_opportunity-guid = '00000000000000000000000000000000'.
          CONCATENATE
          'No Opportunity with number:'
          iv_opportunity_id 'was found'
          INTO ls_text SEPARATED BY space.
          APPEND ls_text TO lt_text.
          l_subject = ls_text.
        ELSE.
**** Assign Opportunity GUID for display and FM input
          opp_guid = ls_opportunity-guid.
          lv_request_guid_c = ls_opportunity-guid.
**** Insert Opportunity GUID and Description into the reply text
          CONCATENATE 'Opportunity GUID:' opp_guid
          'Description:' ls_opportunity-description
          INTO ls_text
          SEPARATED BY space.
          APPEND ls_text TO lt_text.

**** get no. of body parts
          l_parts = li_document->get_body_part_count( ).

**** Read which body part contains the file we are looking for (PDF or TIF)
          DO l_parts TIMES.
            attribute = li_document->get_body_part_attributes( sy-index ).
            TRANSLATE attribute-subject TO UPPER CASE.
            IF attribute-subject CS '.PDF'
            OR attribute-subject CS '.TIF'.
              MOVE sy-index TO ls_attachments.
              APPEND ls_attachments TO lt_attachments.
            ENDIF.
          ENDDO.

          LOOP AT lt_attachments INTO ls_attachments.
**** Read the actual content
            ls_content = li_document->get_body_part_content( ls_attachments ).
            attribute = li_document->get_body_part_attributes( ls_attachments ).
            anhang_nr = ls_attachments.

            ls_file_info-filename = attribute-filename.
            v_cur_pos = 0.
**** Fill v_temp
            CLEAR v_temp.
            LOOP AT ls_content-cont_hex INTO ls_cont_hex.
              CONCATENATE v_temp ls_cont_hex-line INTO v_temp IN BYTE MODE.
            ENDLOOP.
**** Detect Lenth of File
            ls_file_info-length = xstrlen( v_temp ).
**** Fill Table for Attachment
            CLEAR lt_file_content_binary.
            WHILE NOT v_temp IS INITIAL.
              v_line = v_temp.
              v_struct-line = v_line.
              INSERT v_struct INTO TABLE lt_file_content_binary.
              SHIFT v_temp LEFT BY 1022 PLACES IN BYTE MODE.
            ENDWHILE.

**** Attach Document to Opportunity
            CALL FUNCTION 'CRM_ICSS_UPLOAD_SR_ATTACHMENT'
              EXPORTING
                iv_request_guid_c   = lv_request_guid_c
                icss_file_info      = ls_file_info
              IMPORTING
                ev_objkey           = lv_objkey
              TABLES
                file_content_binary = lt_file_content_binary.
**** Return Objectkey and other File information
            size = ls_file_info-length.
            CONCATENATE 'Attachment No.' anhang_nr
            'Filename:' attribute-filename
            'Size:' size
            INTO ls_text
            SEPARATED BY space.
            APPEND ls_text TO lt_text.

          ENDLOOP.

**** send reply
          CONCATENATE
          'Attachment was added to Opportunity' iv_opportunity_id
          INTO l_subject
          SEPARATED BY space.

        ENDIF.

        me->send_reply( io_reply = lo_reply
        ip_subject = l_subject
        it_content = lt_text ).
      ENDIF.

* ----------------------------------------------------------------------------
* error handling
* ----------------------------------------------------------------------------
* system error
    CATCH cx_os_object_not_found cx_alert_recipient_unknown
    cx_document_bcs cx_send_req_bcs cx_address_bcs.
      TRY.
**** send reply
          l_subject = 'Message could not be processed'.
**** build content for reply
          ls_text = 'An internal system error occured!! Please send the message again.'.
          APPEND ls_text TO lt_text.
          ls_text = 'If this error occurs again please call your system administrator.'.
          APPEND ls_text TO lt_text.

          me->send_reply( io_reply = lo_reply
          ip_subject = l_subject
          it_content = lt_text ).

* e_retcode = 4.
        CATCH cx_document_bcs cx_address_bcs cx_send_req_bcs.
* e_retcode = 4.
      ENDTRY.
  ENDTRY.

**** exit has done its work
  e_retcode = if_inbound_exit_bcs=>gc_terminate.

ENDMETHOD.

    

Assigned Tags

      34 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member
      This article was very helpful. However, I need to attach a file thru XI. I tried it using the same FM 'CRM_ICSS_UPLOAD_SR_ATTACHMENT'. I passed the Opportunity GUID to this FM.

      Does this FM have any limitation on the size of the "file_content_binary" parameter ?

      I have manually attached a file to an opportunity using the FM "CRM_ICSS_UPLOAD_SR_ATTACHMENT", passing the opp. GUID. But when I run "CRMD_ORDER" transaction, then the attached document is not visible in the "attachment" tab (for that opportunity). However, when i called the FM "CRM_ICSS_UPLOAD_SR_ATTACHMENT", it did return me an CRM object id.

      Can the attached document be made visible in CRMD_ORDER transaction. ?
      Any help ?

      Author's profile photo Former Member
      Former Member
      This article was very helpful. However, I need to attach a file thru XI. I tried it using the same FM 'CRM_ICSS_UPLOAD_SR_ATTACHMENT'. I passed the Opportunity GUID to this FM.

      Does this FM have any limitation on the size of the "file_content_binary" parameter ?

      I have manually attached a file to an opportunity using the FM "CRM_ICSS_UPLOAD_SR_ATTACHMENT", passing the opp. GUID. But when I run "CRMD_ORDER" transaction, then the attached document is not visible in the "attachment" tab (for that opportunity). However, when i called the FM "CRM_ICSS_UPLOAD_SR_ATTACHMENT", it did return me an CRM object id.

      Can the attached document be made visible in CRMD_ORDER transaction. ?
      Any help ?

      Author's profile photo Former Member
      Former Member
      This article was very helpful. However, I need to attach a file thru XI. I tried it using the same FM 'CRM_ICSS_UPLOAD_SR_ATTACHMENT'. I passed the Opportunity GUID to this FM.

      Does this FM have any limitation on the size of the "file_content_binary" parameter ?

      I have manually attached a file to an opportunity using the FM "CRM_ICSS_UPLOAD_SR_ATTACHMENT", passing the opp. GUID. But when I run "CRMD_ORDER" transaction, then the attached document is not visible in the "attachment" tab (for that opportunity). However, when i called the FM "CRM_ICSS_UPLOAD_SR_ATTACHMENT", it did return me an CRM object id.

      Can the attached document be made visible in CRMD_ORDER transaction. ?
      Any help ?

      Author's profile photo Former Member
      Former Member
      hi
      Is it possible to use this same method or a generic business object upload method to attach documents to a business partner?
      WHat is the correct way to attach documents to a business partner?

      Thx

      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi,

      the basic principle should be the same.

      Regards
      Gregor

      Author's profile photo Former Member
      Former Member
      hi
      Is it possible to use this same method or a generic business object upload method to attach documents to a business partner?
      WHat is the correct way to attach documents to a business partner?

      Thx

      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi,

      the basic principle should be the same.

      Regards
      Gregor

      Author's profile photo Former Member
      Former Member
      hi
      Is it possible to use this same method or a generic business object upload method to attach documents to a business partner?
      WHat is the correct way to attach documents to a business partner?

      Thx

      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi,

      the basic principle should be the same.

      Regards
      Gregor

      Author's profile photo Former Member
      Former Member
      Hello,

      This is very helpful article, as commented before. Anyway, I'm trying to do a little different thing: to attach the mail itself to the oportunity, but I don't get it yet. I tried  retrieving email as MIME format string by using li_document->as_mime_document or io_sreq->as_mim ie_message, and then calling  CRM_ICSS_UPLOAD_SR_ATTACHMENT fm. But the email is displayed in an "uninterpreted" format, for instance, showing the HTML tags of the body. ¿Does anybody know how to attach the email properly?
      Tnanks.

      Author's profile photo Former Member
      Former Member
      Hello,

      This is very helpful article, as commented before. Anyway, I'm trying to do a little different thing: to attach the mail itself to the oportunity, but I don't get it yet. I tried  retrieving email as MIME format string by using li_document->as_mime_document or io_sreq->as_mim ie_message, and then calling  CRM_ICSS_UPLOAD_SR_ATTACHMENT fm. But the email is displayed in an "uninterpreted" format, for instance, showing the HTML tags of the body. ¿Does anybody know how to attach the email properly?
      Tnanks.

      Author's profile photo Former Member
      Former Member
      Hello,

      This is very helpful article, as commented before. Anyway, I'm trying to do a little different thing: to attach the mail itself to the oportunity, but I don't get it yet. I tried  retrieving email as MIME format string by using li_document->as_mime_document or io_sreq->as_mim ie_message, and then calling  CRM_ICSS_UPLOAD_SR_ATTACHMENT fm. But the email is displayed in an "uninterpreted" format, for instance, showing the HTML tags of the body. ¿Does anybody know how to attach the email properly?
      Tnanks.

      Author's profile photo Former Member
      Former Member
      Gregor do you think deleting one of inbound queque in crm could result ipc pricing could not performed?
      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hello Indah,

      I don't think that your question matches the topic of this Blog. Please ask it in the CRM Forums.

      Regards
      Gregor

      Author's profile photo Former Member
      Former Member
      Gregor do you think deleting one of inbound queque in crm could result ipc pricing could not performed?
      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hello Indah,

      I don't think that your question matches the topic of this Blog. Please ask it in the CRM Forums.

      Regards
      Gregor

      Author's profile photo Former Member
      Former Member
      Gregor do you think deleting one of inbound queque in crm could result ipc pricing could not performed?
      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hello Indah,

      I don't think that your question matches the topic of this Blog. Please ask it in the CRM Forums.

      Regards
      Gregor

      Author's profile photo Former Member
      Former Member
      Hi Thomas,

      i'm look for a class, witch takes over the attributes of a task from Outlook.
      For example: Date beginn/end, Priority....
      Can you support me?
      Thank you
      Margit

      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi Margit,

      for that requirement you should check out the SAP CRM Groupware Connector technology. It allows a server to server integration of the CRM System with Exchange. Using that technology it is possible to sync CRM Activities / Tasks with Outlook Appointments and Tasks.

      Best regards
      Gregor

      Author's profile photo Former Member
      Former Member
      Hi Thomas,

      i'm look for a class, witch takes over the attributes of a task from Outlook.
      For example: Date beginn/end, Priority....
      Can you support me?
      Thank you
      Margit

      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi Margit,

      for that requirement you should check out the SAP CRM Groupware Connector technology. It allows a server to server integration of the CRM System with Exchange. Using that technology it is possible to sync CRM Activities / Tasks with Outlook Appointments and Tasks.

      Best regards
      Gregor

      Author's profile photo Former Member
      Former Member
      Hi Thomas,

      i'm look for a class, witch takes over the attributes of a task from Outlook.
      For example: Date beginn/end, Priority....
      Can you support me?
      Thank you
      Margit

      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi Margit,

      for that requirement you should check out the SAP CRM Groupware Connector technology. It allows a server to server integration of the CRM System with Exchange. Using that technology it is possible to sync CRM Activities / Tasks with Outlook Appointments and Tasks.

      Best regards
      Gregor

      Author's profile photo Former Member
      Former Member
      You did a great job. I found your blog very helpful. I have a question for you. How can I specify the destination folder in the Change Document?
      Thanks,
      Antonello
      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi Antonello,

      I think for that you should check the class CL_CRM_DOCUMENTS. Would be nice if you could share if you got it working.

      Best regards
      Gregor

      Author's profile photo Former Member
      Former Member
      You did a great job. I found your blog very helpful. I have a question for you. How can I specify the destination folder in the Change Document?
      Thanks,
      Antonello
      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi Antonello,

      I think for that you should check the class CL_CRM_DOCUMENTS. Would be nice if you could share if you got it working.

      Best regards
      Gregor

      Author's profile photo Former Member
      Former Member
      You did a great job. I found your blog very helpful. I have a question for you. How can I specify the destination folder in the Change Document?
      Thanks,
      Antonello
      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author
      Hi Antonello,

      I think for that you should check the class CL_CRM_DOCUMENTS. Would be nice if you could share if you got it working.

      Best regards
      Gregor

      Author's profile photo Former Member
      Former Member

      Great job Gregor... I really made a big impression to my boss using information in your blog! (and Thomas as well)

      In addition I added some parts to manage .txt attachment and a couple of org. checks .. is it a problem if I create a blog referencing to yours?

      Author's profile photo Gregor Wolf
      Gregor Wolf
      Blog Post Author

      Hi Mauro,

      perhaps it would be a good idea to start a project on SAP Code Exchange and create a sophisticated solution out of it.

      Best regards
      Gregor

      Author's profile photo Former Member
      Former Member

      Hi Gregor,

      nice and valuable idea, I'm on it. Let me know the next step and I'll be glad to share the feature I've included (and the coming ones, since I'm expected to release more ERMS services in the near future)

      Regards

      Mauro

      Author's profile photo Eva Priester
      Eva Priester

      Hi @all,

      I want to add the mail itself as attachment to the Opportunity. Is there anybody. who knows how to get the mail data to create an attachment?

      I spend several hours debugging and analyzing but didn't find a solution yet. :-/

      Best regards,
      Eva