---
# System prepended metadata

title: Hjemmelegene Chat integration - dev notes

---

# Hjemmelegene Chat integration - dev notes

[TOC]



### Flow overview

- Customer logs in
- gets through the IF coverage verification
- gets to some sort of next step of the wizard in which he likely fills up the nature of his desired consultation in a text field
- backend creates and fetches jwt shared secret from SEALD
- backend creates  and redirects his ass in a URL (same url he'd get via SMS if he was in the referral flow)
- he gets there and is being show a spinner or sth that basically tells them to wait
- doctor starts a consultation, video and chat widgets begin to work
- they're done talking
- doctor finishes a consultation, video and chat switch off
- customer is redirected to review page




```plantuml
@startuml

actor    Patient as pat
actor    Doctor as doc

entity   Backend as back
boundary Seald as se

== patient creates \na consultation == 
pat -> back : `GQL: createCustomerConsultation(...)`

back -> se : Call to Seald API for sharedsecret 

back -> back:  2 JWTs are created, one for the patient and one for the doctor

back -> pat : returns data on Consultation, Doctor and Patient to the frontend

pat -> back : `GQL: consultation(id: 345678)` patient|doctor fetches details of consultation

note over pat, se: frontend injects those data to the Chat React component?

note over pat, se: Patient starts chat-consultation


@enduml
```

### JWT settings

```ruby=
      JWT.encode(
        {
          iat: Time.zone.now.to_i, # current EPOCH timestamp
          exp: expiry,  # EPOCH, currently: 1 day for patient, 14 days for the doctor
          iss: jwt_shared_secret_id, # from SEALD API
          jti: SecureRandom.uuid, # just UUIDv4
          scopes: [required_token_permissions], # [1]
          recipients: recipient_ids, # eg. ['Consultation/4567', 'Patient/4567']
          join_team: true,
          owner: owner_id # will be sth like `Consultation/4567` for doctor and
                          # `Patient/4567` for patient side
        },
        jwt_shared_secret, # from SEALD API
        'HS256'
      )
```


### API calls

Note: I dont expect you to have to make those calls. Rather I expect Alex/Alexa to implement them,
and once they receive the response, they'd just pass some of the fields as props to the Chat React component

```graphql=
query {
  consultation(id: 20) {
    id
    patient {
        id
        name
        phoneNumber
    }
    serviceProvider {
        id
        fullName
    }
    source
    state
    videoRoom {
        name
        externalId
        serviceProviderKey // only for doctor obvsly
        patientKey // only for patient
    }
    chatRoom {
        id
        serviceProviderJwt // only for doctor
        patientJwt // only for patient
    }
    serviceProviderId
    enabledChannels
    primaryChannel
    category
    code
    options
  }
}
```
or as curl
```curl=
curl --location --request POST 'http://localhost:5000/graphql' \
--header 'Content-Type: application/json' \
--header 'Cookie: _session_id=blahblahblah' \
--data-raw '{"query":"query {\n  consultation(id: 20) {\n    id\n    patient {\n        id\n        name\n        phoneNumber\n    }\n    serviceProvider {\n        id\n        fullName\n    }\n    source\n    state\n    videoRoom {\n        name\n        externalId\n        serviceProviderKey\n    }\n    chatRoom {\n        id\n        serviceProviderJwt\n    }\n    serviceProviderId\n    enabledChannels\n    primaryChannel\n    category\n    code\n    options\n  }\n}","variables":{}}'
```

#### Payload when logged user is a doctor (note `serviceProviderJwt`)
```jsonld=
{
    "data": {
        "consultation": {
            "id": "20",
            "patient": {
                "id": "1",
                "name": "jerem poiraudau",
                "phoneNumber": "+4791222120"
            },
            "serviceProvider": {
                "id": "1",
                "fullName": "Helen Karal Melbergtest"
            },
            "source": "direct",
            "state": "PENDING",
            "videoRoom": {
                "name": "C-ufF7woVa-d74mGWRt",
                "externalId": "af048d83-b663-4efa-9d1c-fa56c7531240",
                "serviceProviderKey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyIjoiQy11ZkY3d29WYS1kNzRtR1dSdCIsIm8iOnRydWUsInVkIjoiQ29uc3VsdGF0aW9uLzIwIiwidSI6Im1lZGlzaW5zayBhcmJlaWRlciIsImQiOiI4ZGNjY2E5Zi04YmM4LTRkMGYtODRlNC1jZGY0NmU0MzcxN2UiLCJpYXQiOjE2Njk5Njc4Mzh9.8ZXC5yJJ18X8jqmvbXkUNL85B1cDvkqW8pQqrQTSTQU"
            },
            "chatRoom": {
                "id": "1",
                "serviceProviderJwt": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2Njk5Njc4MzksImV4cCI6MTY3MTE3NzQzOSwiaXNzIjpudWxsLCJqdGkiOiIzMTA0NWI1Yi1jNjQ2LTRlYmYtOTFmNC1mOWFhNTlhZjA5ZDUiLCJzY29wZXMiOlsiMSJdLCJyZWNpcGllbnRzIjpbIkNvbnN1bHRhdGlvbi8yMCIsIlBhdGllbnQvMSJdLCJqb2luX3RlYW0iOnRydWUsIm93bmVyIjoiQ29uc3VsdGF0aW9uLzIwIn0.nFCImbMCiIaRK51Ey6NQnifj187WbdVDkfoxAUfal2E"
            },
            "serviceProviderId": "1",
            "enabledChannels": [
                "PHONE",
                "CHAT",
                "VIDEO"
            ],
            "primaryChannel": "VIDEO",
            "category": "insurance",
            "code": "ufF7woVa",
            "options": null
        }
    }
}
```


#### Payload when logged user is a patient (note `patientJwt`)
```jsonld=
{
    "data": {
        "consultation": {
            "id": "20",
            "patient": {
                "id": "22",
                "name": "test guy",
                "phoneNumber": "+4791222122"
            },
            "serviceProvider": {
                "id": "1",
                "fullName": "Helen Karal Melbergtest"
            },
            "source": "direct",
            "state": "PENDING",
            "videoRoom": {
                "name": "C-ufF7woVa-d74mGWRt",
                "externalId": "af048d83-b663-4efa-9d1c-fa56c7531240",
                "patientKey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyIjoiQy11ZkY3d29WYS1kNzRtR1dSdCIsIm8iOmZhbHNlLCJ1ZCI6IlBhdGllbnQvMSIsInUiOiJtZWRpc2luc2sgYXJiZWlkZXIiLCJkIjoiOGRjY2NhOWYtOGJjOC00ZDBmLTg0ZTQtY2RmNDZlNDM3MTdlIiwiaWF0IjoxNjY5OTY3ODM4fQ.WIHqeImL52XHeGI7GS4qY86NfAA1hR5zCvsm3Mpi8mc"
            },
            "chatRoom": {
                "id": "1",
                "patientJwt": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2Njk5Njc4MzksImV4cCI6MTY3MDA1NDIzOSwiaXNzIjpudWxsLCJqdGkiOiIzNWMzNDgwMy02OTA1LTQ5MmQtOGU4ZS05YTA3NjNmZThhZmQiLCJzY29wZXMiOlsiMSJdLCJyZWNpcGllbnRzIjpbIkNvbnN1bHRhdGlvbi8yMCIsIlBhdGllbnQvMSJdLCJqb2luX3RlYW0iOnRydWUsIm93bmVyIjoiUGF0aWVudC8xIn0.iBJl-G2nGkANl-sVxE-Ob05qf1X7jCgrADjY7aYArk8"
            },
            "serviceProviderId": "1",
            "enabledChannels": [
                "PHONE",
                "CHAT",
                "VIDEO"
            ],
            "primaryChannel": "VIDEO",
            "category": "insurance",
            "code": "ufF7woVa",
            "options": null
        }
    }
}
```

