{"id":9180,"date":"2026-04-09T15:09:25","date_gmt":"2026-04-09T06:09:25","guid":{"rendered":"https:\/\/sdinnovation.work\/?page_id=9180"},"modified":"2026-06-13T10:29:12","modified_gmt":"2026-06-13T01:29:12","slug":"%e5%86%85%e7%b7%9a%e9%9b%bb%e8%a9%b1%ef%bc%91%ef%bc%90%ef%bc%91-2","status":"publish","type":"page","link":"https:\/\/www.sdinnovation.jp\/?page_id=9180","title":{"rendered":"\u5185\u7dda\u96fb\u8a71\uff11\uff10\uff11"},"content":{"rendered":"\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/sip.js\/0.20.0\/sip.min.js\"><\/script>\n\n<div id=\"phone-app\" style=\"max-width: 450px; margin: 20px auto; font-family: sans-serif;\">\n    <div style=\"padding: 20px; border-radius: 20px; background: white; box-shadow: 0 10px 25px rgba(0,0,0,0.1); border: 1px solid #eee;\">\n        <h2 style=\"text-align: center; color: #2c3e50;\">\u9632\u707d\u5185\u7dda\u30b7\u30b9\u30c6\u30e0<\/h2>\n        \n        <div style=\"margin-bottom: 20px; padding: 10px; background: #f8f9fa; border-radius: 12px; display: flex; justify-content: space-around; font-size: 0.8em;\">\n            <div id=\"stat-101\">\u25cf 101<\/div>\n            <div id=\"stat-102\">\u25cf 102<\/div>\n            <div id=\"stat-103\">\u25cf 103<\/div>\n            <div id=\"stat-104\">\u25cf 104<\/div>\n        <\/div>\n\n        <div style=\"text-align: center; margin-bottom: 20px;\">\n            <div id=\"reg-status\" style=\"font-weight: bold; color: #95a5a6;\">\u63a5\u7d9a\u4e2d&#8230;<\/div>\n            <div id=\"my-number-display\" style=\"font-size: 0.8em; color: #7f8c8d;\"><\/div>\n        <\/div>\n\n        <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 20px;\">\n            <button onclick=\"quickCall('101')\" style=\"padding: 10px; border-radius: 5px; border: 1px solid #ddd; cursor: pointer;\">\ud83c\udfe2 101 \u672c\u90e8<\/button>\n            <button onclick=\"quickCall('102')\" style=\"padding: 10px; border-radius: 5px; border: 1px solid #ddd; cursor: pointer;\">\ud83d\ude91 102 \u6551\u6025<\/button>\n            <button onclick=\"quickCall('103')\" style=\"padding: 10px; border-radius: 5px; border: 1px solid #ddd; cursor: pointer;\">\ud83d\ude92 103 \u6d88\u9632<\/button>\n            <button onclick=\"quickCall('104')\" style=\"padding: 10px; border-radius: 5px; border: 1px solid #ddd; cursor: pointer;\">\ud83d\udea8 104 \u73fe\u5834<\/button>\n            <button onclick=\"quickCall('8000')\" style=\"grid-column: span 2; padding: 12px; background: #f4ecf7; border: 1px solid #d7bde2; border-radius: 5px; color: #8e44ad; font-weight: bold; cursor: pointer;\">\ud83d\udce2 \u707d\u5bb3\u5bfe\u7b56\u4f1a\u8b70 (8000)<\/button>\n        <\/div>\n\n        <input type=\"text\" id=\"dest-number\" placeholder=\"\u756a\u53f7\u5165\u529b\" style=\"width: 100%; padding: 10px; margin-bottom: 10px; text-align: center; box-sizing: border-box;\">\n        <button id=\"call-btn\" style=\"width: 100%; padding: 15px; background: #27ae60; color: white; border: none; border-radius: 10px; font-weight: bold; cursor: pointer;\" disabled=\"\">\u901a\u8a71\u958b\u59cb<\/button>\n        <button id=\"hangup-btn\" style=\"width: 100%; padding: 15px; background: #e74c3c; color: white; border: none; border-radius: 10px; font-weight: bold; cursor: pointer; display: none;\">\u7d42\u4e86<\/button>\n        <audio id=\"remoteAudio\" autoplay=\"\"><\/audio>\n    <\/div>\n\n    <div id=\"incoming-modal\" style=\"display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.8); z-index:9999; justify-content:center; align-items:center; flex-direction:column; color:white;\">\n        <div style=\"background:#1a252f; padding:40px; border-radius:20px; text-align:center; border:2px solid #e74c3c;\">\n            <div style=\"margin-bottom:10px; color:#e74c3c;\">\ud83d\udea8 \u7dca\u6025\u7740\u4fe1<\/div>\n            <div id=\"caller-info\" style=\"font-size:2em; font-weight:bold; margin-bottom:30px;\">\u5185\u7dda &#8212;<\/div>\n            <button id=\"answer-btn\" style=\"padding:15px 40px; background:#27ae60; color:white; border:none; border-radius:10px; font-size:1.2em; cursor:pointer;\">\u5fdc\u7b54<\/button>\n            <button id=\"reject-btn\" style=\"background:none; color:#ccc; border:none; margin-top:20px; cursor:pointer;\">\u62d2\u5426<\/button>\n        <\/div>\n        <audio id=\"ringtone\" loop=\"\" src=\"https:\/\/www.soundjay.com\/phone\/phone-calling-1.mp3\"><\/audio>\n    <\/div>\n<\/div>\n\n<script>\n(function() {\n    \/\/ --- \u5404\u7aef\u672b\u3067\u3053\u3053\u3092\u66f8\u304d\u63db\u3048 ---\n    const MY_EXTENSION = \"1001\"; \n    const MY_PASSWORD  = \"demopassword123\"; \n    const SERVER_DOMAIN = \"wss:\/\/34.85.112.171:8089\/ws\";\n\n    let userAgent, currentSession, registerer;\n\n    \/\/ UI\u66f4\u65b0\u7528\u306e\u88dc\u52a9\u95a2\u6570\uff08\u30a8\u30e9\u30fc\u56de\u907f\u306e\u305f\u3081\u95a2\u6570\u5ba3\u8a00\u3067\u8a18\u8ff0\uff09\n    function updateStatusUI(extension, status) {\n        const el = document.getElementById(\"stat-\" + extension);\n        if (el) {\n            el.style.color = (status === \"online\") ? \"#27ae60\" : \"#e74c3c\";\n            el.style.fontWeight = (status === \"online\") ? \"bold\" : \"normal\";\n        }\n    }\n\n    \/\/ \u30af\u30a4\u30c3\u30af\u30c0\u30a4\u30e4\u30eb\u95a2\u6570\u3092\u30b0\u30ed\u30fc\u30d0\u30eb\u306b\u516c\u958b\n    window.quickCall = function(num) {\n        document.getElementById(\"dest-number\").value = num;\n        setTimeout(() => { document.getElementById(\"call-btn\").click(); }, 200);\n    };\n\n    window.addEventListener(\"load\", async () => {\n        document.getElementById(\"my-number-display\").innerText = \"\u81ea\u5c40\u5185\u7dda: \" + MY_EXTENSION;\n        \n        const uri = SIP.UserAgent.makeURI(\"sip:\" + MY_EXTENSION + \"@\" + SERVER_DOMAIN);\n        userAgent = new SIP.UserAgent({\n            uri: uri,\n            transportOptions: { \n                server: \"wss:\/\/\" + SERVER_DOMAIN + \"\/ws\",\n                connectionTimeout: 10,\n                keepAliveInterval: 20\n            },\n            authorizationUsername: MY_EXTENSION,\n            authorizationPassword: MY_PASSWORD,\n            reconnectionOptions: { delay: 5, maxAttempts: 10 },\n            delegate: {\n                onInvite: (invitation) => {\n                    const modal = document.getElementById(\"incoming-modal\");\n                    const ringtone = document.getElementById(\"ringtone\");\n                    document.getElementById(\"caller-info\").innerText = \"\u5185\u7dda \" + invitation.remoteIdentity.uri.user;\n                    modal.style.display = \"flex\";\n                    ringtone.play().catch(e => {});\n\n                    document.getElementById(\"answer-btn\").onclick = () => {\n                        modal.style.display = \"none\";\n                        ringtone.pause();\n                        setupSession(invitation);\n                        invitation.accept();\n                    };\n                    document.getElementById(\"reject-btn\").onclick = () => {\n                        modal.style.display = \"none\";\n                        ringtone.pause();\n                        invitation.reject();\n                    };\n                }\n            }\n        });\n\n        registerer = new SIP.Registerer(userAgent);\n\n        try {\n            await userAgent.start();\n            await registerer.register();\n            const st = document.getElementById(\"reg-status\");\n            st.innerText = \"\u30aa\u30f3\u30e9\u30a4\u30f3\";\n            st.style.color = \"#27ae60\";\n            document.getElementById(\"call-btn\").disabled = false;\n            \/\/ \u81ea\u5206\u306e\u72b6\u614b\u3092\u30aa\u30f3\u30e9\u30a4\u30f3\u8868\u793a\u306b\n            updateStatusUI(MY_EXTENSION, \"online\");\n        } catch (e) {\n            document.getElementById(\"reg-status\").innerText = \"\u63a5\u7d9a\u30a8\u30e9\u30fc\";\n        }\n    });\n\n    function setupSession(session) {\n        currentSession = session;\n        document.getElementById(\"call-btn\").style.display = \"none\";\n        document.getElementById(\"hangup-btn\").style.display = \"block\";\n\n        session.stateChange.addListener((state) => {\n            if (state === SIP.SessionState.Established) {\n                const remoteStream = new MediaStream();\n                session.sessionDescriptionHandler.peerConnection.getReceivers().forEach(r => {\n                    if (r.track) remoteStream.addTrack(r.track);\n                });\n                document.getElementById(\"remoteAudio\").srcObject = remoteStream;\n            }\n            if (state === SIP.SessionState.Terminated) { resetUI(); }\n        });\n    }\n\n    function resetUI() {\n        document.getElementById(\"call-btn\").style.display = \"block\";\n        document.getElementById(\"hangup-btn\").style.display = \"none\";\n        currentSession = null;\n    }\n\n    document.getElementById(\"call-btn\").onclick = async () => {\n        const dest = document.getElementById(\"dest-number\").value;\n        if (!dest) return;\n        const target = SIP.UserAgent.makeURI(\"sip:\" + dest + \"@\" + SERVER_DOMAIN);\n        const inviter = new SIP.Inviter(userAgent, target);\n        setupSession(inviter);\n        await inviter.invite();\n    };\n\n    document.getElementById(\"hangup-btn\").onclick = async () => {\n        if (currentSession) { await currentSession.bye(); resetUI(); }\n    };\n})();\n<\/script>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u9632\u707d\u5185\u7dda\u30b7\u30b9\u30c6\u30e0 \u25cf 101 \u25cf 102 \u25cf 103 \u25cf 104 \u63a5\u7d9a\u4e2d&#8230; \ud83c\udfe2 101 \u672c\u90e8 \ud83d\ude91 102 \u6551\u6025 \ud83d\ude92 103 \u6d88\u9632 \ud83d\udea8 104 \u73fe\u5834 \ud83d\udce2 \u707d\u5bb3\u5bfe\u7b56\u4f1a\u8b70 (8000) \u901a\u8a71\u958b\u59cb \u7d42\u4e86 \ud83d\udea8 \u7dca\u6025\u7740\u4fe1 [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-9180","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.sdinnovation.jp\/index.php?rest_route=\/wp\/v2\/pages\/9180","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sdinnovation.jp\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.sdinnovation.jp\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.sdinnovation.jp\/index.php?rest_route=\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sdinnovation.jp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=9180"}],"version-history":[{"count":4,"href":"https:\/\/www.sdinnovation.jp\/index.php?rest_route=\/wp\/v2\/pages\/9180\/revisions"}],"predecessor-version":[{"id":11126,"href":"https:\/\/www.sdinnovation.jp\/index.php?rest_route=\/wp\/v2\/pages\/9180\/revisions\/11126"}],"wp:attachment":[{"href":"https:\/\/www.sdinnovation.jp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9180"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}