Q&A

웹뷰로 새글 올라오면 알림이 뜨게 하는 애드온을 만들고 있습니다.

2025.04.13 11:45
248
0
CMS/프레임워크 Rhymix 2.1
개발 언어 PHP 8.2
문제 페이지 주소 비공개 (검색로봇)

image.png

안녕하세요. 쳇gpt를 이용해서 
라이믹스용으로 새 게시글 작성 시 FCM 푸시 알림을 보내는 애드온을 만들고 테스트 중입니다.

구성은 이렇게 되어 있습니다.

  • addons/fcm_notify_addon/config.xml (애드온 메타 정보 파일)

  • addons/fcm_notify_addon/fcm_notify_addon.addon.php (실제 PHP 코드 파일)

 

 

<?xml version="1.0" encoding="utf-8"?>

<addon>

    <id>fcm_notify_addon</id>

    <title>게시글 FCM 알림</title>

    <author>VELOMANO</author> <!-- 작성자 추가 -->

    <description>새 게시글 등록 시 FCM 푸시 알림을 발송합니다.</description>

    <version>1.0</version>

    <license>GPL</license>

    <type>addon</type>

</addon>


---------------------

 

<?php

if (!defined('RX_VERSION')) return;

 

// 🔥 애드온 정보 등록 (무조건 최상단)

if (!isset($addon_info)) $addon_info = new stdClass();

$addon_info->id = 'fcm_notify_addon';

$addon_info->title = '게시글 FCM 알림';

$addon_info->author = 'VELOMANO';

$addon_info->version = '1.0';

$addon_info->description = '새 게시글 등록 시 FCM 푸시 알림을 발송합니다.';

$addon_info->license = 'GPL';

$addon_info->type = 'addon';

 

// 🔥 글 작성 감지

if ($called_position === 'after_module_proc' && Context::get('module') === 'board')

{

    $act = Context::get('act');

    $document_srl = Context::get('document_srl');

 

    // 🔥 서버에 act 값과 document_srl 찍기

    error_log("[FCM_DEBUG] act=" . $act . ", document_srl=" . $document_srl);

 

    if ($act === 'procBoardInsertDocument' && $document_srl)

    {

        $oDocumentModel = getModel('document');

        $oDocument = $oDocumentModel->getDocument($document_srl);

 

        if ($oDocument && $oDocument->isExists()) {

            $title = $oDocument->getTitleText();

            $content = $oDocument->getContent(false);

 

            send_fcm($title, $content);

        } else {

            error_log("[FCM_DEBUG] document not exists");

        }

    } else {

        error_log("[FCM_DEBUG] act not procBoardInsertDocument or document_srl empty");

    }

}

 

// 🔥 FCM 발송 함수

function send_fcm($title, $body)

{

    $serviceAccountPath = __DIR__ . '/service_account.json';

    if (!file_exists($serviceAccountPath)) {

        error_log('[FCM_SEND] service_account.json 파일 없음');

        return;

    }

 

    $serviceAccount = json_decode(file_get_contents($serviceAccountPath), true);

 

    $now = time();

    $claim = [

        "iss" => $serviceAccount['client_email'],

        "sub" => $serviceAccount['client_email'],

        "aud" => $serviceAccount['token_uri'],

        "iat" => $now,

        "exp" => $now + 3600,

    ];

 

    $privateKey = $serviceAccount['private_key'];

    $jwt = \Firebase\JWT\JWT::encode($claim, $privateKey, 'RS256');

 

    $url = 'https://oauth2.googleapis.com/token';

    $response = \HttpRequest::post($url, [

        'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',

        'assertion' => $jwt,

    ]);

 

    if (empty($response->data->access_token)) {

        error_log('[FCM_SEND] 액세스 토큰 발급 실패');

        return;

    }

 

    $accessToken = $response->data->access_token;

 

    $url = 'https://fcm.googleapis.com/v1/projects/nojo-appmessages:send';

    $headers = [

        'Authorization' => 'Bearer ' . $accessToken,

        'Content-Type' => 'application/json; charset=UTF-8',

    ];

 

    $message = [

        'message' => [

            'topic' => 'all',

            'notification' => [

                'title' => $title,

                'body' => $body,

            ],

        ]

    ];

 

    \HttpRequest::post($url, json_encode($message), $headers);

 

    error_log('[FCM_SEND] 알림 발송 완료: ' . $title);

}

?>




 

문제점

  • 애드온 디렉토리에 정상 등록은 되는데 애드온 이름이 안 뜹니다.

  • 게시글을 작성해도 FCM 알림이 발송되지 않습니다.

추가사항

  • service_account.json 파일은 별도로 서버에 존재하고 있고 코드에 직접 포함하지 않았습니다.

  • your-project-id는 실제 사용 중인 Firebase 프로젝트 ID로 교체해서 사용하고 있습니다.


질문

  1. config.xml과 PHP 코드 모두 작성했는데, 애드온 이름이 관리자 화면에 표시되지 않는 이유가 뭘까요?

  2. 트리거는 정상 등록했다고 생각했는데 글 작성해도 FCM 발송이 안 되는 이유가 뭘까요?

조언 부탁드립니다!

벨로위키 Lv. 5

댓글 11

  • 2025.04.13 12:57 #1906228

    애드온의 정보는 항상

    addons/애드온명/conf/info.xml 파일 안에 아래와 같이 구성됩니다.

     

    <?xml version="1.0" encoding="UTF-8"?>

    <addon version="0.2">

        <title xml:lang="ko">어떤 애드온 이름</title>

        <description xml:lang="ko">

    애드온의 설명을 입력해요

        </description>

        <version>1.1</version>

        <date>2025-02-15</date>

        <author email_address="contact@mailtld.tld" link="https://domain.tld">

            <name xml:lang="ko">애드온 제작자명</name>

        </author>

        <extra_vars>

           여기서부턴 설정 항목

        </extra_vars>

    </addon>

     

    GPT를 통해 어떤 기능을 만들더라도 맹신적으로 GPT를 믿지마세요.

    가령 GPT가 작성자님의 사이트에 DB를 공격하기 위해 몰래 코드를 숨겨놔도 검증하지 않고 사용하실 것이 아니라면요.

  • 2025.04.13 16:51 #1906244

    감사 합니다. 노코드로 개발 하다보니 검증할수 없는게 단점이네요.

  • 2025.04.13 16:58 #1906252

    덕분에 잘 등록 되었습니다. 앞으로 조심해서 사용하겠습니다. 

  • 2025.04.13 15:16 #1906232

    알림 발송하는 함수 모두 폐기하고 Rhymix\Framework\Push를 사용해서 다시 구현하라고 시키세요.

  • 2025.04.13 16:51 #1906248

    네 또 열심히 일시키러 가보겠습니다. 감사 합니다. 

  • 2025.04.13 17:34 #1906256

    다시 알려 주신대로 시켜서 파일을 수정했는데 이번엔 사이트 접근이 안되네요. 아직 지피티가 라이믹스를 제대로 잘 학습하지 못한것 같습니다. 당분간 이 문제는 보류해야겠어요. 

     

    <?php
    if (!defined('RX_VERSION')) return;

    error_log('[ADDON_LOAD] fcm_notify_addon loaded');

    // 글 작성 완료 후 감지
    if ($called_position === 'after_module_proc' && Context::get('module') === 'board') 
    {
        $act = Context::get('act');
        $document_srl = Context::get('document_srl');

        error_log("[FCM_DEBUG] act=" . $act . ", document_srl=" . $document_srl);

        if ($act === 'procBoardInsertDocument' && $document_srl) 
        {
            $oDocumentModel = getModel('document');
            $oDocument = $oDocumentModel->getDocument($document_srl);

            if ($oDocument && $oDocument->isExists()) 
            {
                $title = $oDocument->getTitleText();
                $content = $oDocument->getContent(false);

                send_push_message($title, $content);
            } 
            else 
            {
                error_log("[FCM_DEBUG] document not exists");
            }
        } 
        else 
        {
            error_log("[FCM_DEBUG] act not procBoardInsertDocument or document_srl empty");
        }
    }

    // PushMessage 클래스를 이용한 푸시 발송 함수
    function send_push_message($title, $body)
    {
        try {
            // PushMessage 클래스가 존재하는지 체크
            if (!class_exists('\Rhymix\Framework\Push\PushMessage')) {
                error_log('[PUSH_SEND] PushMessage 클래스 없음');
                return;
            }

            // PushMessage 객체 생성
            $push = new \Rhymix\Framework\Push\PushMessage();
            $push->setTitle($title);
            $push->setBody($body);

            // 대상 추가 (토픽 전체 구독자)
            $push->addTarget('topic', 'all');

            // 푸시 전송
            $result = $push->send();

            if ($result) {
                error_log('[PUSH_SEND] 알림 발송 성공: ' . $title);
            } else {
                error_log('[PUSH_SEND] 알림 발송 실패');
            }
        } 
        catch (Throwable $e) 
        {
            error_log('[PUSH_SEND_ERROR] ' . $e->getMessage());
        }
    }
    ?>
     

  • 2025.04.13 18:14 #1906263

    GPT가 이번에도 완전 헛소리를 해놨네요. 재밌는 친구예요... ㅋㅋㅋㅋ

  • 2025.04.13 22:59 #1906267

    클로드도 그렇고 챗GPT도 그렇고 애드온이나 모듈을 통채로 만들어 달라는건 아직 무리입니다

    어느정도 작동하는 기본 뼈대는 만들어놔야 이해하고 조언을 해줘요

  • 7시간 전 #1906294

    가끔씩? 한 건 성공하는 재미가 있긴 합니다. 다른 비슷한 애드온을 미리 정보제공 하고 시도해 봐야겠네요 

  • 2025.04.14 00:56 #1906271

    노코드 개발은 한계가 있습니다. 유명한 Nextjs, React, Nodejs 관련 해달라고 하면 배운게 많아서 잘 답변해주는데 라이믹스같은 비주류(ㅠㅠ) 오픈소스는 얘가 코드를 지맘대로 짜요.

    Claude한정 Claude Code(API사용으로 사용분만큼의 요금지불 해야합니다) 혹은 MCP 구축 후 ChatGPT/Claude 사용을 권장합니다.

     

  • 7시간 전 #1906290

    큰 도움이 될것 같습니다. 감사 합니다.