themar/messaging-rabbitmq 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

themar/messaging-rabbitmq

Composer 安装命令:

composer require themar/messaging-rabbitmq

包简介

Laravel Package To Easily Send Messages Through RabbitMQ

README 文档

README

Themar Messaging Library provides the ability to establish a communication way between themar microservices using RabbitMQ.

Installation

To install the package, use Composer:

composer require themar/messaging-rabbitmq

After installation, publish the package configuration:


php artisan vendor:publish --provider="Messaging\RabbitMQ\Providers\RabbitMQServiceProvider"

Then Update your .env file with the RabbitMQ connection details:

RABBITMQ_HOST=127.0.0.1
RABBITMQ_PORT=5672
RABBITMQ_USER=guest
RABBITMQ_PASSWORD=guest

Note: Make sure RabbitMQ is installed and running before using the package.

Send Notification

When comes to sending notifications there is an event class you can use called NotificationEvent when you dispatch this event a new job will be sent to RabbitMQ here is how you can use it:

use Messaging\RabbitMQ\Enums\NotificationTemplateName;
use Messaging\RabbitMQ\Events\NotificationEvent;
use Messaging\RabbitMQ\Helpers\NotificationConfig;

public function sendNotification(){
    
    $configs = NotificationConfig::create(
        lang:'ar', //Required
        email:'mouhannad@gmail.com', // Required
        phone:'9999999999',  //Required
        fcmTokenWeb:'fcm-web-token', //Required
        fcmTokenMobile:'fcm-mobile-token', //Required
        userId:1, //Optional
        userType:"App\\Models\\Borrower", //Optional
        projectId:1, //Optional
        notificationTemplateId:1, //Optional
        notificationHistoryId:1  //Optional
        );

    event(NotificationEvent::create(
        notification:NotificationTemplateName::ACCOUNT_DISABLED_BORROWER->value,
        variables: [], 
        configs:$configs));
    
    return "Queued Successfully.";
}

The NotificationConfig class is used to configure the notification like (lang,email,phone...)

Send Notification Anonymously

Sometimes you want to send notifications but you don't have all the required user information , you can use the createAnonymous method on NotificationConfig class and pass phone or email only with lang here is how you can use it :


use Messaging\RabbitMQ\Enums\NotificationTemplateName;
use Messaging\RabbitMQ\Events\NotificationEvent;
use Messaging\RabbitMQ\Helpers\NotificationConfig;

public function sendNotificationAnonymously(){
    
    $configs = NotificationConfig::createAnonymous(
        lang:'ar', //Required
        email:'mouhannad@gmail.com', //Optional (Required if no `phone` provided)
        phone:'9999999999', //Optional (Required if no `email` provided)
        userId:1, //Optional
        userType:"App\\Models\\Borrower", //Optional
        projectId:1, //Optional
        notificationTemplateId:1, //Optional
        notificationHistoryId:1  //Optional
        );

    event(NotificationEvent::create(
        notification:NotificationTemplateName::LOGIN_ATTEMPT->value,
        variables: [
            'otp' => '123456'
        ], 
        configs:$configs));
    
    return "Queued Successfully.";
}

The NotificationConfig class is used to configure the notification like (lang,email,phone...)

Send Event Bus Message

When you want to send an event message to other services to interact with you
can send predefined event bus messages in this library .
here is how you can use it :

use Messaging\RabbitMQ\Messages\EventBus\EventBusMessageTest;

public function sendEventBusMessage(){
    
    $message= new EventBusMessageTest(name:"mouhannad",email:"mouhannad@gmail.com",phone:"999999999");

    event($message);

    return "Message Sent Successfully.";
}

Now automatically the package will deliver this message to RabbitMQ where other services will be listening and interacting.

Note: You can find all Available Event Bus Messages here.

Consume Event Bus Messages

Now when you want to receive event bus messages from other services you can make new Consumer class to listen to specific messages here is how you can achieve this:

first make new Consumer

php artisan make:consumer TestEventBusMessageConsumer

You will have the following class :

<?php

namespace App\Console\Commands\Consumers\EventBus;

use Messaging\RabbitMQ\Messages\EventBus\EventBusMessageTest;
use Messaging\RabbitMQ\Commands\Base\EventBusMessageConsumer;

class TestEventBusMessageConsumer extends EventBusMessageConsumer
{
public function __construct()
{
    //target message to listen
    parent::__construct(className:EventBusMessageTest::class);
}

/**
    * The name and signature of the consumer command.
    *
    * @var string
    */
protected $signature = 'consume:test-event-bus-message-consumer';

/**
    * The console command description.
    *
    * @var string
    */
protected $description = 'Command description';

/**
    * process message received by consumer.
    */
public function processMessage($message) {
    //handle message of targeted type.
    }
}

inside the processMessage you write your logic for the incoming message.

now you can run this consumer and start listening using the command

php artisan consume:test-event-bus-message-consumer

Send Queue Message

When you want to send a queue message to other services to consume you
can send predefined queue messages in this library .
here is how you can use it :

use Messaging\RabbitMQ\Messages\Queue\QueueMessageTest;

public function sendQueueMessage(){
    
    $message= new QueueMessageTest(name:"mouhannad",email:"mouhannad@gmail.com",phone:"999999999");

    event($message);

    return "Message Sent Successfully.";
}

Now automatically the package will deliver this message to RabbitMQ where other services will be consuming.

Note: You can find all Available Queue Messages here.

Consume Queue Messages

Now when you want to receive queue messages from other services you can make new Consumer class to listen to specific messages here is how you can achieve this:

first make new Consumer

php artisan make:consumer TestQueueMessageConsumer --queue

You will have the following class :

<?php

namespace App\Console\Commands\Consumers\Queue;

use Messaging\RabbitMQ\Messages\Queue\QueueMessageTest;
use Messaging\RabbitMQ\Commands\Base\QueueMessageConsumer;

class TestQueueMessageConsumer extends QueueMessageConsumer
{
public function __construct()
{
    parent::__construct(queueName:config('rabbitmq.queues.messages'));
}

/**
    * The name and signature of the consumer command.
    *
    * @var string
    */
protected $signature = 'consume:test-queue-message-consumer';

/**
    * The console command description.
    *
    * @var string
    */
protected $description = 'Command description';

/**
    * process message received by consumer.
    */
public function processMessage($message) {
    //handle typed message.
    }
}

inside the processMessage you write your logic for the incoming message.

now you can run this consumer and start listening using the command

php artisan consume:test-queue-message-consumer

Themar File Adapter

When you want to use the themar file adapter you can achieve this as follow:


Storage::disk('themar')->url(fileId:1);

some of the adapter functions needs configuration such as


    Storage::disk('themar')
        ->withNote("note")
        ->withStakeHolder(1, "tst")
        ->private()
        ->frontendDisplayed()
        ->putFile(path:'path/of/the/file', file:$request->file('file'));

this method putFile has a third parameter which is fileId (option) when you provide this fileId it will updates the record of the file instead of creating new one.

some of the adapter functions needs authorization token such as


    Storage::disk('themar')
        ->withToken("token")
        ->delete(fileId:1);

available disk methods are :

withStakeHolder => (string stakeholderId,string stakeholderType):self
withNote => (string note):self
frontendDisplayed => (bool isDisplayed = true):self
private => (bool isPrivate = true):self
withFieldName => (string fieldName ):self
withFileName => (string fileName ):self
withDestinationPath => (string destinationPath ):self
withDestinationPath => (string destinationPath ):self
putFile => (string path,UploadedFile file,?string fileId=null ):string
url => (string fileId):string
getPublicUrl => (string fileId):string
downloadPrivateFile => (string fileId):StreamedResponse AUTHENTICATED
exists => (string fileId):bool
missing => (string fileId):bool
delete => (string fileId):void AUTHENTICATED
download => (string fileId):StreamedResponse
resizeOnTheFly => (string fileId,int width,int height,?int quality=null, ?string format = null, bool download = false):Response
storeBase64 => (string path,UploadedFile file,?string fileId=null ):string

Available Event Bus Messages

This section outlines the Event Bus Messages that can be published and consumed within the system. Each entry specifies the message class and its payload, indicating the data it carries.

EventBusMessageTest::class => For Testing

ApproveRequestSubmitted::class => When an Approval Document Request is Submitted

  • Payload: request_id, document_id, document_type, users

ApproveRequestUserApproved::class => When a User Approves a Document

  • Payload: request_id, user_id

ApproveRequestUserRejected::class => When a User Rejects a Document

  • Payload: request_id, user_id

ApproveRequestApproved::class => When All Users Approve a Document

  • Payload: request_id, document_id, document_type, users

ApproveRequestRejected::class => When One or More Users Reject a Document

  • Payload: request_id, document_id, document_type, users

ApproveRequestExpired::class => When an Approval Document Request Expires

  • Payload: request_id, document_id, document_type, users

NewUserRegistered::class => When a New User Registers

  • Payload: user_id

ProjectUpdatedToClose::class => When a Project's Status is Updated to 'Closed'

  • Payload: project_id, project_name, borrower_id, old_status

ProjectUpdatedToComplete::class => When a Project's Status is Updated to 'Complete'

  • Payload: project_id, project_name, borrower_id, contract_type, borrower_verified_bank_account_iban (nullable), seller_iban (nullable)

ProjectUpdatedToInitialApproval::class => When a Project's Status is Updated to 'Initial Approval'

  • Payload: project_id, project_name, amount, min_funding_amount, max_funding_amount, borrower_id

ProjectUpdatedToPaymentInProgress::class => When a Project's Status is Updated to 'Payment In Progress'

  • Payload: project_id, borrower_id, is_test

ProjectUpdatedToRejected::class => When a Project's Status is Updated to 'Rejected'

  • Payload: project_id, project_name, borrower_id

ProjectUpdatedToUnderReview::class => When a Project's Status is Updated to 'Under Review'

  • Payload: project_id, project_name, borrower_id

ProjectUpdatedToUnderStudy::class => When a Project's Status is Updated to 'Under Study'

  • Payload: project_id, project_name, borrower_id

TransferRequestUpdate::class => When a Transfer Request is Updated

  • Payload: transfer_request_id, type, status, financial_transaction_id (nullable), amount, payment_request_status, old_status (nullable), old_payment_request_status (nullable)

AcceptFocalRisk::class => When Focal Risk is Accepted

  • Payload: user_id, user_type

AuditCustom::class => For Custom Auditing Events

  • Payload: auditable_type, auditable_id, event_name, old_data (array), new_data (array)

AutoInvestSettingSaved::class => When an Auto-Invest Setting is Saved

  • Payload: investor_id, risk_levels (array), max_invest_amount, investor_has_verified_bank_account

BidUpdated::class => When a Bid is Updated

  • Payload: bid_id, new_status, new_amount, was_amount_changed, was_status_changed_to_paid

BorrowerCreated::class => When a New Borrower is Created

  • Payload: borrower_id, bank_account_type_digits

IdVerificationRequestVerified::class => When an ID Verification Request is Verified

  • Payload: user_id, user_type, user_email, user_display_name

InvestorCreated::class => When a New Investor is Created

  • Payload: investor_id, bank_account_type_digits

NafathCallbackReceived::class => When a Nafath Callback is Received

  • Payload: user_id, user_type

NotWhiteListedTransactionAccepted::class => When a Non-Whitelisted Transaction is Accepted

  • Payload: transaction_id, transaction_type, transaction_amount, transaction_unique_id, to_financial_account_id (nullable), bank_response (array)

    Available Queue Messages

    QueueMessageTest::class => For Testing

Authentication & Authorization

The package provides JWT-based authentication and authorization capabilities for your microservices.

Authenticated User Model

To enable permission checks, all user models in consuming projects must extend the AuthenticatedUser model:

<?php

namespace App\Models;

use Messaging\RabbitMQ\Models\AuthenticatedUser;

class User extends AuthenticatedUser
{
    // Your custom model implementation
}

API Authentication Middleware

JWT Requirement: Ensure your application has Valid OAuth public key at storage/oauth-public.key

In order to avoid invalid token error, all applications must have the same APP KEY as the one who issued the token

For API endpoints, use the JWTTokenAuthorization middleware:

// routes/api.php
Route::middleware(JWTTokenAuthorization::class)->group(function () {
    // Protected API routes
});

Features:

  • Validates Bearer tokens in Authorization header.
  • Auto-login user from JWT claims.
  • Checks token signature and expiration.
  • Provides user object.

Web Session Authentication Middleware

JWT Requirement: Ensure your application has Valid OAuth public key at storage/oauth-public.key

In order to avoid invalid token error, all applications must have the same APP KEY as the one who issued the token

For traditional web applications, use JWTTokenSessionAuthorization:

// routes/web.php
Route::middleware(JWTTokenSessionAuthorization::class)->group(function () {
    // Protected web routes
});

Features:

  • Looks for token in session (access_token key).
  • Checks token signature and expiration.
  • Provides user object.

Permission System

The package uses Redis to check permissions. Permissions are mapped via PlatformPermissionEnum.

$user->can(PlatformPermissionEnum::ADMIN_FCM_MANAGE_SHOW->value);

Key Requirements:

  • Redis server must be running.
  • Permissions must be populated in Redis using the users_permissions key structure.

themar/messaging-rabbitmq 适用场景与选型建议

themar/messaging-rabbitmq 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 419 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 03 月 04 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「notifications」 「rabbitmq」 「laravel」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 themar/messaging-rabbitmq 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 themar/messaging-rabbitmq 我们能提供哪些服务?
定制开发 / 二次开发

基于 themar/messaging-rabbitmq 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 419
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-03-04