ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Passing a Variable to SNDSMTPEMM

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Passing a Variable to SNDSMTPEMM

    Is it possible to pass a variable to the *NOTE parameter in the SNDSMTPEMM?

  • #2
    Sure, if the command is in a CL program.

    DCL VAR(&NOTETXT) TYPE(*CHAR) LEN(400)
    SNDSMTPEMM RCP(recipient) NOTE(&NOTETXT)

    Comment


    • #3
      Thanks Brian,

      I'm attempting to send QSYSOPR messages to my email. I've been toying around and haven't been successful as of yet.

      First, I wrote something in C (below), with embedded SQL statements that returns the latest inquiry message from QSYSOPR. It made sense in my mind to pass it to SNDSMTPEMM, which doesn't seem to work. Which is unfortunate. Maybe there is a way, but my brain is getting tired at the moment.

      Perhaps I can write the pertinent information to a text file and email that to myself. But I'd prefer to have it in the email.

      Code:
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <fcntl.h>
      #include <unistd.h>
      #include <sys/types.h>
      #include <errno.h>
      #include <time.h>
      #include <sqlsystm.h>
      #include <ctype.h>
      exec sql include sqlca;
      
      char MSG_ID[7];
      char data[10];
      
      int main(){
      
      EXEC SQL
      SELECT MESSAGE_ID INTO :MSG_ID
      FROM QSYS2.MESSAGE_QUEUE_INFO
      WHERE MESSAGE_TYPE = 'INQUIRY'
      ORDER BY MESSAGE_TIMESTAMP DESC
      FETCH FIRST 1 ROWS ONLY;
      
      //printf("%s\n", MSG_ID);
      
      snprintf(data, 7, "%s", MSG_ID);
      
      printf("%s\n", data);
      
      EXEC SQL
      CALL QSYS2.QCMDEXC('SNDSMTPEMM RCP((OPERATORS@REPUBLICBANK.COM))
      SUBJECT(MSGTEST) NOTE(data)');
      
      };

      I've tried a simple CL program (below) that pulls messages from QSYSOPR using RCVMSG, and I've been able to send along some info, but not quite what I'm looking for.

      Code:
      PGM
      
      DCL &MSGID *CHAR LEN(7)
      DCL &MSGTXT *CHAR LEN(1024)
      DCL &MSGDTA *CHAR LEN(1024)
      
      RCVMSG MSGQ(QSYS/QSYSOPR) MSGTYPE(*ANY) RMV(*KEEPEXCP) MSGDTA(&MSGDTA) +
      MSGID(&MSGID)
      
      SNDSMTPEMM RCP((OPERATORS@REPUBLICBANK.COM)) SUBJECT('"TEST') NOTE(&MSGDTA)
      
      
      ENDPGM

      Comment


      • #4
        That CL is grabbing message data, which doesn't contain the text of the message.

        I think if you replace this MSGDTA(&MSGDTA) with MSG(&MSG) in your RCVMSG statement, you'll have better luck.

        Cheers,

        Emmanuel

        Comment


        • #5
          If you use RCVMSG, you want to use the MSG parameter to receive the text of the message with the variable message data filled in and then email that. The NOTE parameter has a maximum variable length of 400 characters. Also, you probably want to use RMV(*NO) so that the messages are not removed from the QSYSOPR message queue. I'm not a C programmer so I'll stick with CL for my examples.

          Code:
          DCL &MSGTXT *CHAR LEN(400)
          
          RCVMSG MSGQ(QSYS/QSYSOPR) MSGTYPE(*ANY) RMV(*NO) MSG(&MSGTXT)
          SNDSMTPEMM RCP(('OPERATORS@REPUBLICBANK.COM')) SUBJECT('TEST') NOTE(&MSGTXT)

          Comment


          • #6
            Originally posted by EmmanuelW1 View Post
            That CL is grabbing message data, which doesn't contain the text of the message.

            I think if you replace this MSGDTA(&MSGDTA) with MSG(&MSG) in your RCVMSG statement, you'll have better luck.

            Cheers,

            Emmanuel
            Thanks Emmanuel,

            perhaps I'm not picking up what you're putting down. I changed my RCVMSG to what you suggested

            Code:
            RCVMSG MSGQ(QSYS/QSYSOPR) MSGTYPE(*ANY) RMV(*KEEPEXCP) MSG(&MSG) + MSGID(&MSGID)
            And, I'm only picking up the very first Message to QSYSOPS from 12/04.
            12/04/21 00:05:42 Audit journal extraction process completed normally.
            The date thing may be a parameter I'm not pulling with RCVMSG, in which case I can look into that. But I certainly want that MSG text or MSGDTA, but I haven't been able to find anything on how to format the SNDSMTPEMM NOTE parameter to allow me to write something and concat the variable.




            Comment


            • Brian Rusch
              Brian Rusch commented
              Editing a comment
              If you want to receive the last message instead of the first, change MSGTYPE(*ANY) to MSGTYPE(*LAST).

          • #7
            Also, please note that RCVMSG only receives one message at a time.

            To implement receiving newly received messages and email them, the program would need to be never-ending, and the WAIT parameter should be set to *MAX.

            Having a never-ending program like that allows for some pretty powerful stuff to be done based on the messages received. For example, we've implemented automated record lock handling (any RPG1218/RNQ1218 message) with locking-user notification via email and break message, along with automatic R replies. No more hung up jobs due to record locks!

            Cheers,

            Emmanuel

            Comment


            • #8
              Originally posted by EmmanuelW1 View Post
              Having a never-ending program like that allows for some pretty powerful stuff to be done based on the messages received. For example, we've implemented automated record lock handling (any RPG1218/RNQ1218 message) with locking-user notification via email and break message, along with automatic R replies. No more hung up jobs due to record locks!
              I would like to hear more about this. Can you share more details, Emmanuel?

              Comment


              • #9
                Hi Ted,

                Sure - we've had a never-ending program to monitor QSYSOPR (and another one for QSYSMSG) messages for some time with email notification for certain messages and most inquiry messages. We'd get jobs hung up in MSGW due to record locks.

                One of the cool parameters on the RCVMSG command is SENDER - that will contain the job information for the job that sent the message. For RPG1218/RNQ1218 messages, the job log of the job sending the message will contain details of the job locking the record that the sender job is trying to use - message ID CPF5027. Using the QMHLJOBL API (via an example program written by SK), we retrieve the message details for that CPF5027 and send a break message to the workstation, and using the user ID, look up the user's email address (we use Robot/Alert) to notify the user via email as well. We pause about 30 seconds then send an R to retry to the ???1218 message and if it pops up again, just keep retrying the R response, while limiting user notifications to three.

                In the case of a non-interactive job locking the record, IS staff is notified, and the R to retry is still sent repeatedly in reply to the lock message.

                Cheers,

                Emmanuel

                Comment


                • #10
                  Here's an example of the email that is sent to IS staff when a RPG1218/RNQ1218 message hits QSYSOPR:

                  Unable to allocate a record in file F98301 (R C G D F). From job: 079637/USER_ID/J7400C1___ - which generated the following message in its job log: Record 379029 in use by job or transaction 079206/USER_ID/QPADEV000H. An automatic "R", to retry, reply will be entered in 30 seconds. The user locking the record has been notified via email and break message.

                  Cheers,

                  Emmanuel

                  Comment


                  • #11
                    Ok,

                    for everyone interested and biting their nails to see if I made progress or not, I did. Below is the code I wrote to be called from the iNavigator message monitor that will email the latest message in QSYSOPR to an email address. It is written in C with embedded SQL.

                    One issue though, an inquiry message hits QSYSOPR the monitor keeps firing even when the message has been responded to. If anyone has any idea how to help with that, I'm all ears.

                    Code:
                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <string.h>
                    #include <fcntl.h>
                    #include <unistd.h>
                    #include <sys/types.h>
                    #include <errno.h>
                    #include <time.h>
                    #include <sqlsystm.h>
                    #include <ctype.h>
                    EXEC SQL INCLUDE SQLCA;
                    
                    char MSG_ID[7];
                    char data[1025];
                    char cmdstmt[2000];
                    char mysubj[15];
                    
                    int main(){
                    
                    char end[8] = "MESSAGE";
                    
                    EXEC SQL
                    SELECT MESSAGE_TEXT INTO :data FROM QSYS2.MESSAGE_QUEUE_INFO
                    WHERE MESSAGE_QUEUE_NAME = 'QSYSOPR'
                    AND MESSAGE_TYPE = 'INQUIRY'
                    ORDER BY MESSAGE_TIMESTAMP DESC
                    FETCH FIRST 1 ROWS ONLY;
                    
                    snprintf(cmdstmt, 2000,
                    "SNDSMTPEMM RCP(address@domain.com) SUBJECT(%s) NOTE('%s')",
                    end, data);
                    
                    EXEC SQL
                    CALL QSYS2.QCMDEXC(:cmdstmt);
                    
                    };

                    Comment


                    • #12
                      On this page from IBM https://www.ibm.com/docs/en/i/7.4?to...ueue-info-view there is an example at the bottom to get Inquiry messages and their replies. Modifying that will get you Inquiry that do not have a reply.

                      The original example from web page above

                      Code:
                      SELECT a.message_timestamp, a.message_text, a.from_user, b.message_timestamp, b.message_text, b.from_user
                      FROM qsys2.message_queue_info a
                      INNER JOIN qsys2.message_queue_info b ON a.message_key = b.associated_message_key
                      WHERE a.message_type = 'INQUIRY' AND b.message_type = 'REPLY'
                      ORDER BY b.message_timestamp DESC;
                      Here is an UNTESTED version to get Inquiry messages that do not have a reply - I don't have a new enough system to test on at the moment so might need a little adjustment

                      Code:
                      SELECT a.message_timestamp, a.message_text, a.from_user, b.message_timestamp, b.message_text, b.from_user
                      FROM qsys2.message_queue_info a
                      LEFT JOIN qsys2.message_queue_info b ON a.message_key = b.associated_message_key AND b.message_type = 'REPLY'
                      WHERE a.message_type = 'INQUIRY' AND b.message_type is null
                      ORDER BY b.message_timestamp DESC;

                      Comment


                      • rynspate
                        rynspate commented
                        Editing a comment
                        Hey Scott,

                        thanks for the input. I've been able to get the program I wrote to send emails using the stock iNavigator Message Monitoring. I made a tweak to the message monitoring and it's behaving as expected. More than likely I will make changes to allow for HTML.
                    Working...
                    X