Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions common/components/EventManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
use Segment\Segment;
use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
use Aws\Sqs\SqsClient;
use Aws\Exception\AwsException;
use yii\httpclient\Client;

/**
* Coordinates analytics, queue, endpoint, and webhook event delivery.
*/
class EventManager extends Component
{
/**
Expand Down Expand Up @@ -51,6 +55,11 @@ class EventManager extends Component
*/
public $sqsEndpoint;

/**
* @var string|null bearer token for the event microservice endpoint
*/
public $sqsEndpointApiKey;

/**
* @var string Mixpanel key
*/
Expand Down Expand Up @@ -395,9 +404,19 @@ public function track($event, $eventData, $timestamp = null, $userId = null, $on
}

/**
* API call for webhook
* Send a JSON request to the configured SQS endpoint with a required bearer token.
*
* @param string $method HTTP method to use
* @param string $url endpoint URL to call
* @param array $data JSON payload to send
* @return \yii\httpclient\Response
* @throws InvalidConfigException when EVENT_MANAGER_ENDPOINT_API_KEY is not configured
*/
public function call($method, $url, $data = []) {
if (trim((string) $this->sqsEndpointApiKey) === '') {
throw new InvalidConfigException('EVENT_MANAGER_ENDPOINT_API_KEY must be configured before sending SQS endpoint events.');
}

$client = new Client();

return $client->createRequest()
Expand All @@ -406,7 +425,7 @@ public function call($method, $url, $data = []) {
->setFormat(Client::FORMAT_JSON)
->setData($data)
->addHeaders([
'Authorization' =>'Bearer QstN8_18LmILpl37r2zvdDCp5JjWPCNh',
'Authorization' => 'Bearer ' . trim((string) $this->sqsEndpointApiKey),
"Content-Type" => "application/json",
'User-Agent' => 'request',
])
Expand All @@ -421,4 +440,4 @@ public function flush()
if($this->segmentKey)
Segment::flush();
}
}
}
64 changes: 49 additions & 15 deletions common/components/Yeaster.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace common\components;

use yii\base\InvalidConfigException;
use yii\httpclient\Client;

/**
Expand All @@ -12,56 +13,89 @@
*/
class Yeaster extends \yii\base\Component
{
public $microserviceApiKey = "QstN8_18LmILpl37r2zvdDCp5JjWPCNh";
/**
* @var string|null bearer token used to authenticate calls to the voicemail microservice
*/
public $microserviceApiKey;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

//point to microservice handling voicemails, overriding from main-local.php
/**
* @var string base URL for the voicemail microservice, overridden from main-local.php
*/
public $apiEndpoint = "http://localhost:3001";

/**
* Build authenticated request headers and fail fast if the service token is missing.
*
* @return array<string, string>
* @throws InvalidConfigException when YEASTER_MICROSERVICE_API_KEY is not configured
*/
private function authorizationHeaders()
{
if (trim((string) $this->microserviceApiKey) === '') {
throw new InvalidConfigException('YEASTER_MICROSERVICE_API_KEY must be configured before calling the voicemail microservice.');
}

return [
'Authorization' => 'Bearer ' . trim((string) $this->microserviceApiKey),
'content-type' => 'application/json',
];
}

/**
* Fetch a paginated voicemail listing from the Yeaster microservice.
*
* @param int $page page number to request
* @param int $limit maximum number of voicemails to return
* @return mixed decoded response payload
*/
public function listVoicemails($page, $limit = 10) {

$client = new Client();
$response = $client->createRequest()
->setMethod('GET')
->setUrl($this->apiEndpoint . '/list?page=' . $page . '&limit=' . $limit)
->setFormat(Client::FORMAT_JSON)
->addHeaders([
'Authorization' => 'Bearer ' . $this->microserviceApiKey,
'content-type' => 'application/json',
])
->addHeaders($this->authorizationHeaders())
->send();

return $response->getData();
}

/**
* Fetch a single voicemail payload from the Yeaster microservice.
*
* @param int|string $id voicemail identifier
* @return string raw response content
*/
public function viewVoicemail($id) {

$client = new Client();
$response = $client->createRequest()
->setMethod('GET')
->setUrl($this->apiEndpoint . '/view/'. $id)
->setFormat(Client::FORMAT_JSON)
->addHeaders([
'Authorization' => 'Bearer ' . $this->microserviceApiKey,
'content-type' => 'application/json',
])
->addHeaders($this->authorizationHeaders())
->send();

return $response->content;
}

/**
* Download a voicemail recording from the Yeaster microservice.
*
* @param int|string $id voicemail identifier
* @return string raw response content
*/
public function downloadVoicemail($id) {

$client = new Client();
$response = $client->createRequest()
->setMethod('GET')
->setUrl($this->apiEndpoint . '/download/'. $id)
->setFormat(Client::FORMAT_JSON)
->addHeaders([
'Authorization' => 'Bearer ' . $this->microserviceApiKey,
'content-type' => 'application/json',
])
->addHeaders($this->authorizationHeaders())
->send();

return $response->content;
}
}
}
30 changes: 29 additions & 1 deletion docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,34 @@ Use the provided script in the project root:
./run-tests.sh
```

### Service Integration Secrets

Keep service API tokens in deployment environment variables instead of checked-in
config files or browser bundles:

```bash
WALLET_API_KEY=
YEASTER_MICROSERVICE_API_KEY=
EVENT_MANAGER_ENDPOINT_API_KEY=
```

`WALLET_API_KEY` is used by the legacy wallet integration when enabled.
`YEASTER_MICROSERVICE_API_KEY` authenticates voicemail microservice requests.
`EVENT_MANAGER_ENDPOINT_API_KEY` authenticates EventManager calls to the SQS
bridge endpoint when `sqsEndpoint` is configured.

Configure these values in each deployment environment that enables the
corresponding integration. Production and shared staging environments should use
provider-issued tokens from the wallet service, voicemail microservice, and SQS
bridge service owners; local development can leave an integration unset only
when that feature is not exercised.

Missing values are treated as disabled or invalid credentials. Wallet requests
must not be sent without `WALLET_API_KEY`. Voicemail calls fail fast before
emitting an empty `Authorization` header when `YEASTER_MICROSERVICE_API_KEY` is
missing. EventManager calls to the SQS bridge fail fast when
`EVENT_MANAGER_ENDPOINT_API_KEY` is missing and `sqsEndpoint` is configured.

## Server Requirements

### PHP Extensions
Expand All @@ -56,4 +84,4 @@ cd console && ../yii algolia/index candidate
```bash
./yii cron/update-candidate-stats
./yii cron/update-company-stats
```
```
4 changes: 3 additions & 1 deletion environments/circle-ci/common/config/main-local.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
],
'walletManager' => [
'class' => 'common\components\WalletManager',
'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG',
'apiKey' => getenv('WALLET_API_KEY') ?: null,
'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1',
'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df'
],
'yeaster' => [
'class' => 'common\components\Yeaster',
'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null,
"apiEndpoint" => "http://localhost:3001"
],
'mailer' => [
Expand Down Expand Up @@ -53,6 +54,7 @@
],
'eventManager' => [
'class' => 'common\components\EventManager',
'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null,
"sqsRagion" => "eu-west-2",
"sqsKey" => "AKIAWMITDJRKXNWDOBNJ",
"sqsSecret" => "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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
],
'walletManager' => [
'class' => 'common\components\WalletManager',
'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG',
'apiKey' => getenv('WALLET_API_KEY') ?: null,
'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1',
'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df'
],
'yeaster' => [
'class' => 'common\components\Yeaster',
'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null,
"apiEndpoint" => "http://localhost:3001"
],
'xero' => [
Expand Down Expand Up @@ -84,6 +85,7 @@
],*/
'eventManager' => [
'class' => 'common\components\EventManager',
'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null,
"sqsRagion" => "eu-west-2",
"sqsKey" => "AKIAWMITDJRKXNWDOBNJ",
"sqsSecret" => "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",
Expand Down
4 changes: 3 additions & 1 deletion environments/dev-server-nginx/common/config/main-local.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
],
'walletManager' => [
'class' => 'common\components\WalletManager',
'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG',
'apiKey' => getenv('WALLET_API_KEY') ?: null,
'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1',
'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df'
],
'yeaster' => [
'class' => 'common\components\Yeaster',
'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null,
"apiEndpoint" => "http://localhost:3001"
],
'xero' => [
Expand Down Expand Up @@ -82,6 +83,7 @@
],*/
'eventManager' => [
'class' => 'common\components\EventManager',
'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null,
"sqsRagion" => "eu-west-2",
"sqsKey" => "AKIAWMITDJRKXNWDOBNJ",
"sqsSecret" => "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",
Expand Down
4 changes: 3 additions & 1 deletion environments/dev-server-railway/common/config/main-local.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
//todo: replace with wallet from sandbox
'walletManager' => [
'class' => 'common\components\WalletManager',
'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG',
'apiKey' => getenv('WALLET_API_KEY') ?: null,
'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1',
'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df'
],
//todo: replace with yeaster from sandbox
'yeaster' => [
'class' => 'common\components\Yeaster',
'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null,
"apiEndpoint" => "http://localhost:3001"
],
'xero' => [
Expand Down Expand Up @@ -86,6 +87,7 @@
],*/
'eventManager' => [
'class' => 'common\components\EventManager',
'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null,
"sqsRagion" => "eu-west-2",
"sqsKey" => "AKIAWMITDJRKXNWDOBNJ",
"sqsSecret" => "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",
Expand Down
4 changes: 3 additions & 1 deletion environments/dev-server/common/config/main-local.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
],
'walletManager' => [
'class' => 'common\components\WalletManager',
'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG',
'apiKey' => getenv('WALLET_API_KEY') ?: null,
'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1',
'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df'
],
'yeaster' => [
'class' => 'common\components\Yeaster',
'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null,
"apiEndpoint" => "http://localhost:3001"
],
'xero' => [
Expand Down Expand Up @@ -87,6 +88,7 @@
],*/
'eventManager' => [
'class' => 'common\components\EventManager',
'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null,
"sqsRagion" => "eu-west-2",
"sqsKey" => "AKIAWMITDJRKXNWDOBNJ",
"sqsSecret" => "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",
Expand Down
4 changes: 3 additions & 1 deletion environments/dev/common/config/main-local.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
],
'walletManager' => [
'class' => 'common\components\WalletManager',
'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG',
'apiKey' => getenv('WALLET_API_KEY') ?: null,
'apiEndpoint' => 'http://localhost/wallet/webhook/web/v1',//todo:
'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df'
],
'yeaster' => [
'class' => 'common\components\Yeaster',
'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null,
"apiEndpoint" => "http://localhost:3001"
],
'cache' => [
Expand Down Expand Up @@ -66,6 +67,7 @@
],
'eventManager' => [
'class' => 'common\components\EventManager',
'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null,
"sqsRagion" => "eu-west-2",
"sqsKey" => "AKIAWMITDJRKXNWDOBNJ",
"sqsSecret" => "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",
Expand Down
4 changes: 3 additions & 1 deletion environments/docker/common/config/main-local.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
],
'yeaster' => [
'class' => 'common\components\Yeaster',
'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null,
"apiEndpoint" => "http://192.168.1.5:3001"
],
'xero' => [
Expand All @@ -41,7 +42,7 @@
],
'walletManager' => [
'class' => 'common\components\WalletManager',
'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG',
'apiKey' => getenv('WALLET_API_KEY') ?: null,
'apiEndpoint' => 'http://192.168.1.5/wallet/webhook/web/v1',
'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df'
],
Expand Down Expand Up @@ -73,6 +74,7 @@
],
'eventManager' => [
'class' => 'common\components\EventManager',
'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null,
"sqsRagion" => "eu-west-2",
"sqsKey" => "AKIAWMITDJRKXNWDOBNJ",
"sqsSecret" => "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",
Expand Down
Loading