Get author id inside Jira connector

Hi all. I am write simple Jira connector which allow me to talk with bot inside jira ticket using comments. Bot works fine. But my workflow in more complicated:

  1. User create jira ticket with access request in ticket title or description (like asking to add some email to gitlab)
  2. Bot recognize intent and ask about missing entities (I use form, works fine)
  3. After submitting form bot ask security engineer to approve inviting new member to gitlab.
  4. Here is problem. I use jira ticket id (or key like GTD-3345) as sender_id and recipient_id in connector. So, context == jira ticket. Question is: how can I send additional info like comment author for verifying that exactly he approve inviting?

Possible solutions I found:

  • I can include comment author email as prefix inside each UserMessage text, like "some@gmail.com: comment text here". But in this case bot will recognize email as entity each time. Also, all my intents will start from some name. Looks not quite right…
  • Add slot “comment_author” and extract it from each text message using regex feature, like ^([a-zA-Z.]+):. From this point one more question: how can I put “True” to slot “security_eng_approve” only if “comment_author” is pre-defined security eng and intent is “affirm”? Maybe I need to create one more form special for security eng approv?

Any ideas? :slight_smile:

I change my NLU model, now I have intents access_request and comment. access_request can be without “author”, comment should contain “author”:

## intent:access_request
- [vladimir](author): [add](action:create) [gitlab](service) access to [dima@gmail.com](email)
- [provide](action:create) [gitlab](service) access to [someone@gmail.com](email)
## intent:comment
- [vladimir](author): please [add](action:create)
- [eduard](author): please [provide](action:create)
- [nik](author): [remove](action:delete) it
- [john](author): email is [dima@gmail.com](email)
- [sath](author): [mike@gmail.com](email)

Also other general intents like “affirm”, “deny”, “email” as regexp and so on. Now it looks like:

And next problem: I can’t extract “security_eng_approve” slot from second form “approve_form”. I tried to use examples like:

def slot_mappings(self):
    return {
        "security_eng_approve": [
            self.from_intent(intent="affirm", value=True),
            self.from_intent(intent="deny", value=False)
        ]
    }

but always receive error: Failed to extract slot security_eng_approve with action approve_form

It works if text recognized as just affirm intent, but now I always have comment intents. I need to extract affirm/deny from comment intent. Who know how to do this?

Any ideas? :slight_smile: :slight_smile:

@akelad need your help :slight_smile:

Ok, model evolved to simple: one approve_form with 4 required slots:

  • action
  • service
  • email
  • security_eng_approve

All slots required, and security_eng_approve slot validated as:

    def validate_security_eng_approve(
            self,
            value: Text,
            dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any],
    ) -> Optional[Text]:

        approver = 'eduard' #pre-defined approver that should be taken from jira group
        if tracker.get_slot('author') == approver and value is True:
            dispatcher.utter_message("Thank you master {}!".format(approver))
            return {"security_eng_approve": True}
        else:
            dispatcher.utter_message("I am trust only {}, sorry.".format(approver))
            return {"security_eng_approve": None}

This is simple, but I still can’t extract intent from intent :worried:

UPD: Also I tried to extract from entity, like

def slot_mappings(self):
    return {
        "action": self.from_entity(entity="action"),
        "service": self.from_entity(entity="service"),
        "email": self.from_entity(entity="email"),
        "security_eng_approve": self.from_entity("affirm")
    }

But I still receive error Failed to extract slot security_eng_approve with action approve_form. Not sure why I cant extract entity, in interactive learning I manually set text as comment intent, and specified [vladimir](author): [yes](affirm). affirm in domain, yes.

Finally got it. Next construction works:

def slot_mappings(self):
    return {
        "action": self.from_entity(entity="action"),
        "service": self.from_entity(entity="service"),
        "email": self.from_entity(entity="email"),
        "security_eng_approve": [
            self.from_intent(intent=["comment", "affirm"], value=True),
            self.from_intent(intent=["comment", "deny"], value=False),
        ],
    }

Now, if someone except eduard say something in security_eng_approve slot - bot won’t believe him.

Hope this will help someone to do logic similar this.

Aaaand next problem: I don’t know how to put variable value to domain template when asking security engineer to approve access request. What I have:

utter_ask_security_eng_approve:
  - text: "{security_eng} please approve"
  - text: "{security_eng}, please check it."

Error when form asking next slot:

Failed to fill utterance template '{'text': '{security_eng}, please check it.'}'. Tried to replace 'security_eng' but could not find a value for it. There is no slot with this name nor did you pass the value explicitly when calling the template. Return template without filling the template.

Why it required to solve: When this text will be as comment in jira, target security engineer receive notification/mention.

Possible solutions:

  • programmatically add slot security_eng, and put required value to it. (still don’t know how to do this. Maybe need to add custom action after access_request only for setting slot programmatically, but I want to find is possible inside form or not. )
  • split approve_form to: access_request_form -> action_ask_security_eng -> approve_form. In this case from custom action I can do: dispatcher.utter_message("{} please approve".format(target_approver)).
  • hardcode it in domain file, but it’s absolutely bad idea :slight_smile:

Tried to use custom action before main form. Works, but not as expected. Was before (without custom action):

me: add vpn access
bot: specify email address
me: someone@gmail.com

-------or--------

me: add vpn access for someone@gmail.com
bot: Security eng, please approve

Now when custom action triggered after first phrase (as access_request):

me: add vpn access
bot: specify action add/delete/update

It means that bot forgets entities from first intent.

action code:

class ActionSetSecurityEng(Action):
    def name(self):
        return 'action_set_security_eng'

    def run(self, dispatcher, tracker, domain):
        return [SlotSet("security_eng", get_security_eng())]

And solution here. I think is dirty hack, but… How to set slot programmatically inside form:

@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
    tracker.slots['security_eng'] = get_security_eng()
    return ["action", "service", "email", "security_eng_approve"]

And in result I see that slot value used in template, but in “Current slots” I see “security_eng: None”:

 5    slot{"author": "vladimir"}
      approve_form 1.00
      sath please approve
      slot{"email": "dima@gmail.com"}
      slot{"requested_slot": "security_eng_approve"}

Current slots:
	action: create, author: vladimir, email: dima@gmail.com, requested_slot: security_eng_approve, security_eng: None, security_eng_approve: None, service: vpn

It works now, but I feel that exist better way…

Hi @v-avdeev sorry, this is a lot of text :sweat_smile: what are the open questions you still have?

So, this topic now looks like story: question -> find answer myself, post answer -> new question -> and so on.

Currently I completely change dialog/phrase structure. I will post current questions soon in new topic :slight_smile:

@akelad quick question here: do action server have health or status endpoint? I want to put core and action servers to kubernetes and I need to define livenessProbe/readinessProbe.

@v-avdeev yes they have a /health endpoint