Question about Email Notifications to Portal Users

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jflores
    Member
    • Aug 2019
    • 57

    Question about Email Notifications to Portal Users

    Hi there -

    I have a few questions about email notifications to Portal Users.

    1. First, under a Portal User's "Preferences," this option: Email notifications about posts and status updates...what is it supposed to do? We have it checked on all of our portal users, but no email notifications are going out to portal users. Emails internally are working fine.
    2. Related to (1): Do/can email notifications work for the Stream in custom Entities?
    3. What if I only want email notifications to go out when there's a "mention?"

    In my ideal world, we can use the Stream for two-way communication, where Portal Users get notified when we 'mention' them in the Stream of a Custom Entity. Is this possible out of the box? If not, what modifications do I need to make to make it work?

    Thanks for the help!
  • jflores
    Member
    • Aug 2019
    • 57

    #2
    Update.

    What I care most about is emailing Portal Users when they're mentioned on a Post.

    I've gone through as much of the codebase & past commits as I can understand to try to accomplish this.

    Here are some things I've changed/believe:

    1. In application/Espo/Resoures/metadata/app/aclPortal.json I've changed receiveMentionEmailNotifications to true under scopeFieldLevel.
    2. In application/Espo/Resource/layouts/Preferences/detailPortal.json I've added a row with [{"name":"receiveMentionEmailNotifications"},fal se] to the "Notifications" area. The checkbox is filled in.
    3. In client/src/views/preferences/record/edit.js I've updated the logic around line 130 to
    Code:
    if (!this.getConfig().get('assignmentEmailNotifications')) {...
    as well as around line 160 updated the line to
    Code:
     if (!this.getConfig().get('mentionEmailNotifications')) {
    In both cases, I'm trying to remove the portal exclusion
    4. When I look at /api/v1/Preferences/user_id, I can see that "receiveMentiongEmailNotifications" is set to "true," as expected.

    My expectation was that when I set the preference, this line
    Code:
    $mentionEmailNotifications = $this->getConfig()->get('mentionEmailNotifications');
    inside of the "process" function in application/Espo/Services/EmailNotification.php would send notifications out to PortalUsers now.

    It doesn't.

    My next thought was to look at this section of code:

    Code:
    $typeList = [];
    if ($mentionEmailNotifications) {
    $typeList[] = 'MentionInPost';
    }
    and figure out how "MentionInPost" was set.

    My thought was that it was set in "client/src/views/stream/notes/mention-in-post.js" or 'views/stream/fields/post,' but I'm not sure.

    I also looked at 'processNotificationMentionInPost' in application/Espo/Services/EmailNotification.php and it looks like, according to the logic, my emails should be sending. The thing I can't figure out is where the function is getting called or how 'userId' is derived from $notification.

    The best I can come up with is that the userId isn't being properly set? When I inspect the request in teh network tab for mentioning a 'regular' user & a portal user, the structure looks the same. The objects look the same and yet the 'regular' user gets notifications emailed adn the portal user doesn't.

    What am I missing?

    PS. I know I need to move these into the proper “custom” folders once it’s ready to be put in production. I just didn’t want to mess w/ it yet in development.
    Last edited by jflores; 03-02-2020, 02:47 AM.

    Comment

    • jflores
      Member
      • Aug 2019
      • 57

      #3
      Hate to be a pebble in the shoe, but can I get some direction, even if only high-level? I'm content to spend some time figuring it out, but I feel like I've pulled the threads I know to pull. Really just hoping for a new one to send me down a more righteous path.

      Comment


      • esforim
        esforim commented
        Editing a comment
        There is only a few people here (on top of my head, for example telecastg or maximus) that is knowledgeable enough to provide some feedback to your problem. I read it your thread as a learning and future reference but can't help.

        Don't be discourage and keep trying and posting new update.
    • telecastg
      Active Community Member
      • Jun 2018
      • 907

      #4
      I think that the answer would be to develop a custom hook for Note (Stream is a collection of Notes), extending the script application\Espo\Hooks\Note\Notifications.php which defines the list of persons to be notified.

      Hope that helps

      Saludos

      Comment


      • jflores
        jflores commented
        Editing a comment
        Thanks for the suggestion - I'll try that path. Thanks!

      • telecastg
        telecastg commented
        Editing a comment
        You're welcome, if it works please share your implementation.
    • jflores
      Member
      • Aug 2019
      • 57

      #5
      Ok, I have a working implementation of this, albeit with one big caveat.

      Relevant files changed:
      • custom/Espo/Custom/Hooks/Note/Mentions.php
      • custom/Espo/Custom/Resources/layouts/metadata/app/aclPortal.json
      • custom/Espo/Custom/Resources/layouts/Preferences/detailPortal.json
      Here are the implementations:

      custom/Espo/Custom/Resources/layouts/metadata/app/aclPortal.json
      Code:
      {
        "mandatory": {
          "scopeFieldLevel": {
            "Preferences": {
              "followEntityOnStreamPost": true,
              "autoFollowEntityTypeList": true,
              "receiveAssignmentEmailNotifications": true,
              "receiveMentionEmailNotifications": true
            }
          }
        }
      }
      custom/Espo/Custom/Hooks/Note/Mentions.php
      public function beforeSave (same as parent)

      public function addMentionData (same as parent)

      Code:
      protected function notifyAboutMention(Entity $entity, \Espo\Entities\User $user, Entity $parent = null)
      {
          if ($user->isPortal())
          {
              if($parent && !$entity->get('isInternal')) {
                  $this->getNotificationService()->notifyAboutMentionInPost($user->id, $entity->id);
              }
             return;
          }
          if ($parent) {
              if (!$this->getAclManager()->check($user, $parent, 'stream')) return;
          }
          $this->getNotificationService()->notifyAboutMentionInPost($user->id, $entity->id);
      }
      The method that mattered was "notifyAboutMention" -> the line "if($parent)...." was removing portal users because they don't have access to the parent entity.

      The thing I tried to do (and would be ideal) would be to invoke AclManager for the portal, but I could not figure out how to do that. When I tried to instantiate that object and use it to check portal stream permissions, I kept getting an error "Portal not defined" furhter up the chain.

      So, this solution is a kluge - it will bypass Acl and allow a portaluser to receive an email notification regardless of permissions, so long as the note isn't marked 'internal' and they're formall mentioned.

      Using AclManager would be better, but I couldn't figure it out, so this kluge will do until I can.

      Comment


      • jflores
        jflores commented
        Editing a comment
        telecastg FYI - thanks for the 'hook' tip. I extended "mention" instead of 'notification' b/c that's what I wanted to be able to do: email a portal user who was mentioned. This is a kluge though.
    • telecastg
      Active Community Member
      • Jun 2018
      • 907

      #6
      You're welcome @jflores

      I don't see anything wrong with your implementation, it is bypassing Acl in a single operation only to notify a Portal User who was mentioned in a Post, regardless of the Portal User access privileges to the parent entity which is exactly what you wanted to do. In my opinion, "elegant" doesn't always equate with simple and efficient :-)

      I'm only curious about the use case for this implementation: when would you want to alert a Portal User of a mention if that user doesn't have access to the parent entity ?

      Thanks so much for posting your solution, this will help all of us further learning how to make Espo better for our applications.

      Saludos
      Last edited by telecastg; 05-03-2020, 07:46 PM.

      Comment

      • jflores
        Member
        • Aug 2019
        • 57

        #7
        telecastg good question:

        when would you want to alert a Portal User of a mention if that user doesn't have access to the parent entity ?
        I generally wouldn't want to alert a Portal User of a mention if they don't have access to the parent entity. The only reason this implementation does that is because I couldn't figure out how to trigger Acl for a Portal User properly in the hook.

        If you look at the source in the core at this method:

        Code:
        protected function notifyAboutMention(Entity $entity, \Espo\Entities\User $user, Entity $parent = null)
            {
                if ($user->isPortal()) return;
                if ($parent) {
                    if (!$this->getAclManager()->check($user, $parent, 'stream')) return;
                }
                $this->getNotificationService()->notifyAboutMentionInPost($user->id, $entity->id);
            }
        The methods are structurally the same, but when "/application/Espo/Core/Portal/AclManager" is instantiated and processed, it expects (further up the stack) a $portal object. I could not easily figure out how to write a method that could send a $portal object and kept getting a $portal not defined (or something like that) error.

        The method I wrote bypasses .../Portal/AclManager only because that's the best I could come up with given my skill and the amount of time I had available.

        In an ideal world, the method would look something more like this:

        Code:
        protected function notifyAboutMention(Entity $entity, \Espo\Entities\User $user, Entity $parent = null)
            {
                if ($parent)
                    { if ($user->isPortal())
                        if (!$this->getPortalAclManager()->check($user, $parent, 'stream')) return;
                    elsif
                    {
                       if (!$this->getInternalAclManager()->check($user, $parent, 'stream')) return;
                    }
            }
            $this->getNotificationService()->notifyAboutMentionInPost($user->id, $entity->id);
        }
        But I couldn't figure out how to get the PortalAclManager to work properly inside the method. I'm sure I'll go back and try to figure it out at some point.

        The more general use case I wanted was just to give customers limited access to different entities in the Portal and then have bi-directional communication scoped to that particular entity. But, since customers don't live in the CRM like we do, I wanted us to be able to 'mention' them and send a notification, so they could reply or log in and respond to our queries.

        Not sure if that clarifies or confuses, but that's the logic :-)
        Last edited by jflores; 05-03-2020, 11:09 PM.

        Comment

        Working...