Documentation.
All checks were successful
Build and Push Docker Image / build (push) Successful in 55s
Build and Push Docker Image / docker (push) Successful in 36s

This commit is contained in:
2025-07-05 00:54:59 +02:00
parent 80395e3b2c
commit 9edc579bfe
3 changed files with 488 additions and 4 deletions

View File

@ -83,20 +83,23 @@ Tunnel on port `80` to send traffic. Consume HTTP endpoints:
### `POST /send` ### `POST /send`
Sends message and returns it's ID. Minimal message body where `user2` sends a text message to `user1`, and since `user2` can only message to `user1` and nobody else, they don't even have to specify recipient, the system infers it automatically: Sends message and returns it's ID. Minimal message body where `user2` sends a text message to `user1`, and since `user2` can only message to `user1` and nobody else, they don't even have to specify recipient, the system infers it automatically.
Request:
http /send (post) header: Authorization: Bearer f480568f-8884-47e5-a6d7-82480f1ffb3b http /send (post) header: Authorization: Bearer f480568f-8884-47e5-a6d7-82480f1ffb3b
{ {
"payload": "This is a message." "payload": "This is a message."
} }
Response Response:
http (json): http (json):
"5f33b4bd-dc2a-4ace-947a-1aadc6045995" "5f33b4bd-dc2a-4ace-947a-1aadc6045995"
Optionally, messages can be complex. Here is a message from `user1` to `user3`, both `payload` and `payloadType` are `nvarchar` fields and their content can be whatever: Optionally, messages can be complex. Here is a message from `user1` to `user3`, both `payload` and `payloadType` are `nvarchar` fields and their content can be whatever.
Request:
http /send (post) header: Authorization: Bearer 81ccf737-d424-4f83-929c-92d20491abfa http /send (post) header: Authorization: Bearer 81ccf737-d424-4f83-929c-92d20491abfa
{ {
"payloadType": "STATUS", "payloadType": "STATUS",
@ -105,13 +108,21 @@ Optionally, messages can be complex. Here is a message from `user1` to `user3`,
"lifespanInSeconds": "3600" "lifespanInSeconds": "3600"
} }
Response:
http (json):
"5f33b4bd-dc2a-4ace-947a-1aadc6045995"
### `GET /receive` ### `GET /receive`
Receives all waiting messages. Receives all waiting messages.
Request:
http /receive (get) header: Authorization: Bearer 81ccf737-d424-4f83-929c-92d20491abfa http /receive (get) header: Authorization: Bearer 81ccf737-d424-4f83-929c-92d20491abfa
Response Response:
http (json): http (json):
"messages": [ "messages": [
@ -124,6 +135,39 @@ Response
} }
] ]
### `POST /ack`
Acknowledges delivered message. The client that received the message is the only party able to acknowledge.
Request:
http /ack (post) header: Authorization: Bearer 81ccf737-d424-4f83-929c-92d20491abfa
{
"messageId": "5f33b4bd-dc2a-4ace-947a-1aadc6045995"
}
Response:
http (json) 200 OK:
(empty)
### `GET /verify`
Sender can call this to get delivery status of message that has been sent earlier:
Request:
http /verify?messageId=5f33b4bd-dc2a-4ace-947a-1aadc6045995 (get) header: Authorization: Bearer 81ccf737-d424-4f83-929c-92d20491abfa
Response:
http (json) 200 OK:
{
"isDelivered": true,
"isAcknowledged": true
}
## Testing ## Testing
See postman collection to generate code for your desired language or test the API instance. The collection also works as test suite, just fill out the environment variables for URL and api keys of your users and it will run and test all endpoints, with expected outputs. See postman collection to generate code for your desired language or test the API instance. The collection also works as test suite, just fill out the environment variables for URL and api keys of your users and it will run and test all endpoints, with expected outputs.

View File

@ -0,0 +1,383 @@
{
"info": {
"_postman_id": "b8400b20-a16f-4c2a-a8ec-0eec25611319",
"name": "endpoints",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "248257"
},
"item": [
{
"name": "cors/send",
"request": {
"method": "OPTIONS",
"header": [
{
"key": "Access-Control-Request-Method",
"value": "POST",
"type": "text"
},
{
"key": "Access-Control-Request-Headers",
"value": "content-type",
"type": "text"
},
{
"key": "Content-Type",
"value": "application/json",
"type": "text"
},
{
"key": "Origin",
"value": "{{FrontEndUrl}}",
"type": "text"
},
{
"key": "Referer",
"value": "{{FrontEndUrl}}",
"type": "text"
}
],
"url": {
"raw": "{{Url}}/send",
"host": [
"{{Url}}"
],
"path": [
"send"
]
}
},
"response": []
},
{
"name": "yellowpages",
"event": [
{
"listen": "test",
"script": {
"exec": [
"let response = pm.response.json();\r",
"pm.environment.set(\"User2IdFromYellowpages\", response.users[0].id);\r",
"\r",
"pm.test(\"User2 address returned should match our expectation.\", function () {\r",
" const u2id = pm.environment.get(\"User2Id\");\r",
" const u2idFromResponse = pm.environment.get(\"User2IdFromYellowpages\");\r",
" pm.expect(u2id, `Expected returned value (${u2idFromResponse}) to equal expected value (${u2id})`).to.eql(u2idFromResponse);\r",
"});"
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{User1ApiKey}}",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"type": "text"
},
{
"key": "Origin",
"value": "www.google.com",
"type": "text"
}
],
"url": {
"raw": "{{Url}}/yellowpages",
"host": [
"{{Url}}"
],
"path": [
"yellowpages"
]
}
},
"response": []
},
{
"name": "send",
"event": [
{
"listen": "test",
"script": {
"exec": [
"let response = pm.response.json();\r",
"pm.environment.set(\"MessageId\", response);"
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{User1ApiKey}}",
"type": "string"
}
]
},
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\r\n \"payloadType\": \"Whatever\",\r\n \"payload\": \"This is a message.\",\r\n \"toUserId\": \"{{User2Id}}\"\r\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{Url}}/send",
"host": [
"{{Url}}"
],
"path": [
"send"
]
}
},
"response": []
},
{
"name": "verify",
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{User1ApiKey}}",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": "",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{Url}}/verify?messageId={{MessageId}}",
"host": [
"{{Url}}"
],
"path": [
"verify"
],
"query": [
{
"key": "messageId",
"value": "{{MessageId}}"
}
]
}
},
"response": []
},
{
"name": "peek",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"We have expected 1 message during call.\", function () {\r",
" const count = parseInt(pm.response.text(), 10);\r",
" const expectedCount = 1;\r",
" pm.expect(count, `Expected returned value (${count}) to equal expected value (${expectedCount})`).to.eql(expectedCount);\r",
"});\r",
"\r",
"pm.test(\"Response status is 200 OK\", function () {\r",
" pm.response.to.have.status(200);\r",
"});"
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{User2ApiKey}}",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"url": {
"raw": "{{Url}}/peek",
"host": [
"{{Url}}"
],
"path": [
"peek"
]
}
},
"response": []
},
{
"name": "receive",
"event": [
{
"listen": "test",
"script": {
"exec": [
"let response = pm.response.json();\r",
"\r",
"pm.test(\"MessageId returned should match MessageId from Send call.\", function () {\r",
" const idFromCall = response.messages[0].id;\r",
" const idFromSend = pm.environment.get(\"MessageId\");\r",
" pm.expect(idFromCall, `Expected returned value (${idFromCall}) to equal expected value (${idFromSend})`).to.eql(idFromSend);\r",
"});"
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{User2ApiKey}}",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"url": {
"raw": "{{Url}}/receive",
"host": [
"{{Url}}"
],
"path": [
"receive"
]
}
},
"response": []
},
{
"name": "ack",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Response status is 200 OK\", function () {\r",
" pm.response.to.have.status(200);\r",
"});"
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{User2ApiKey}}",
"type": "string"
}
]
},
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\r\n \"messageId\": \"{{MessageId}}\"\r\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{Url}}/ack",
"host": [
"{{Url}}"
],
"path": [
"ack"
]
}
},
"response": []
}
],
"auth": {
"type": "bearer"
},
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"packages": {},
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"packages": {},
"exec": [
""
]
}
}
]
}

View File

@ -0,0 +1,57 @@
{
"id": "15acfd9e-f24e-479b-82fa-2c022f726558",
"name": "messengerapi-localhost",
"values": [
{
"key": "User1ApiKey",
"value": "aab8f7e9-ad13-4bf8-bb2e-0cd93d81adc0",
"type": "secret",
"enabled": true
},
{
"key": "User1Id",
"value": "f696442b-e8dc-4074-b34f-94bcece8e74b",
"type": "default",
"enabled": true
},
{
"key": "User2ApiKey",
"value": "8f73f683-7cb3-40df-998e-6e604aef0e53",
"type": "secret",
"enabled": true
},
{
"key": "User2Id",
"value": "15d97720-f5b7-47aa-9c1a-71f98b0b9248",
"type": "any",
"enabled": true
},
{
"key": "Url",
"value": "http://localhost:5259",
"type": "default",
"enabled": true
},
{
"key": "MessageId",
"value": "",
"type": "any",
"enabled": true
},
{
"key": "FrontEndUrl",
"value": "https://example.com",
"type": "default",
"enabled": true
},
{
"key": "User2IdFromYellowpages",
"value": "",
"type": "any",
"enabled": true
}
],
"_postman_variable_scope": "environment",
"_postman_exported_at": "2025-07-04T22:53:28.963Z",
"_postman_exported_using": "Postman/11.52.6"
}