feat: Use yaMetrika number in settings

This commit is contained in:
2025-12-01 19:44:14 +03:00
parent c670e38392
commit cedc49f0d5
5 changed files with 54 additions and 46 deletions

View File

@@ -11,7 +11,7 @@
</li> </li>
<li :class="{active: route.name === 'metrics'}"> <li :class="{active: route.name === 'metrics'}">
<RouterLink :to="{name: 'metrics'}">Метрики</RouterLink> <RouterLink :to="{name: 'metrics'}">Метрика</RouterLink>
</li> </li>
<li :class="{active: route.name === 'store'}"> <li :class="{active: route.name === 'store'}">

View File

@@ -6,24 +6,47 @@
Задействовать Яндекс.Метрику для Telegram магазина. Задействовать Яндекс.Метрику для Telegram магазина.
</ItemBool> </ItemBool>
<ItemTextarea <ItemInput
label="Код счётчика Яндекс Метрики" label="Номер счётчика Яндекс.Метрика"
v-model="settings.items.metrics.yandex_metrika_counter" v-model="settings.items.metrics.yandex_metrika_counter"
placeholder="Вставьте код счётчика Яндекс.Метрики" placeholder="Вставьте код счётчика Яндекс.Метрики"
> >
<p>Код счётчика нужно предварительно настроить, чтобы он работал корректно с Telegram Mini App. <ButtonGroup>
<a href="https://telecart-labs.github.io/docs/analitycs/start/" target="_blank"> <Button
Инструкция как настроить i.fa.fa-external-link as="a"
</a>.</p> :href="ymCheckUrl"
<p>Для проверки интеграции через кнопку "Проверить" в интерфейсе Яндекс Метрики, target="_blank"
необходимо сначала включить "Режим разработчика" на вкладке "Общие".</p> variant="text"
</ItemTextarea> :disabled="settings.items.app.app_debug === false"
v-tooltip.top="'Чтобы проверить интеграцию, включите режим разработчика на вкладке Общие и сохраните настройки.'"
>
Проверить интеграцию
</Button>
<Button
as="a"
href="https://telecart-labs.github.io/docs/analitycs/start/"
target="_blank"
variant="text"
>
Как получить номер счётчика <i class="fa fa-external-link"></i>
</Button>
</ButtonGroup>
</ItemInput>
</template> </template>
<script setup> <script setup>
import {useSettingsStore} from "@/stores/settings.js"; import {useSettingsStore} from "@/stores/settings.js";
import ItemTextarea from "@/components/Settings/ItemTextarea.vue";
import ItemBool from "@/components/Settings/ItemBool.vue"; import ItemBool from "@/components/Settings/ItemBool.vue";
import ItemInput from "@/components/Settings/ItemInput.vue";
import {Button, ButtonGroup} from 'primevue';
import {computed} from "vue";
const settings = useSettingsStore(); const settings = useSettingsStore();
const ymCheckUrl = computed(() => {
const url = settings.items.telegram.mini_app_url.replace(/\#\/$/, '');
return `${url}?_ym_status-check=104849385&_ym_lang=ru`;
});
</script> </script>

View File

@@ -53,6 +53,12 @@ settings.load()
throw new Error('App disabled (maintenance mode)'); throw new Error('App disabled (maintenance mode)');
} }
}) })
.then(() => settings.ya_metrika_enabled && injectYaMetrika())
.then(() => {
if (! window.Telegram.WebApp.initData) {
throw new Error('Invalid init data. Application not in Telegram View');
}
})
.then(() => pulse.initFromStartParams()) .then(() => pulse.initFromStartParams())
.then(() => pulse.catchTelegramCustomerFromInitData()) .then(() => pulse.catchTelegramCustomerFromInitData())
.then(() => pulse.ingest(TC_PULSE_EVENTS.WEBAPP_OPEN)) .then(() => pulse.ingest(TC_PULSE_EVENTS.WEBAPP_OPEN))
@@ -73,11 +79,6 @@ settings.load()
})(); })();
}) })
.then(() => blocks.processBlocks(settings.mainpage_blocks)) .then(() => blocks.processBlocks(settings.mainpage_blocks))
// .then(async () => {
// console.debug('Load default filters for the main page');
// const filtersStore = useProductFiltersStore();
// filtersStore.applied = await filtersStore.fetchFiltersForMainPage();
// })
.then(() => { .then(() => {
console.debug('[Init] Set theme attributes'); console.debug('[Init] Set theme attributes');
document.documentElement.setAttribute('data-theme', settings.theme[window.Telegram.WebApp.colorScheme]); document.documentElement.setAttribute('data-theme', settings.theme[window.Telegram.WebApp.colorScheme]);
@@ -108,7 +109,6 @@ settings.load()
app.mount('#app'); app.mount('#app');
}) })
.then(() => window.Telegram.WebApp.ready()) .then(() => window.Telegram.WebApp.ready())
.then(() => settings.ya_metrika_enabled && injectYaMetrika())
.catch(error => { .catch(error => {
console.error(error); console.error(error);
const errorApp = createApp(ApplicationError, {error}); const errorApp = createApp(ApplicationError, {error});

View File

@@ -17,11 +17,11 @@ export function injectYaMetrika() {
script.src = '/index.php?route=extension/tgshop/handle/ya_metrika'; script.src = '/index.php?route=extension/tgshop/handle/ya_metrika';
// script.async = true; // script.async = true;
document.head.appendChild(script); document.head.appendChild(script);
console.debug('[Init] Yandex Metrika injected to the page.'); console.debug('[ym] Yandex Metrika injected to the page.');
script.onload = () => { script.onload = () => {
window.YA_METRIKA_ID = getMetrikaId(); window.YA_METRIKA_ID = getMetrikaId();
console.debug('[Init] Detected Yandex.Metrika ID:', window.YA_METRIKA_ID); console.debug('[ym] Detected Yandex.Metrika ID:', window.YA_METRIKA_ID);
const yaMetrika = useYaMetrikaStore(); const yaMetrika = useYaMetrikaStore();
yaMetrika.initUserParams(); yaMetrika.initUserParams();
window.dataLayer = window.dataLayer || []; window.dataLayer = window.dataLayer || [];

View File

@@ -95,37 +95,22 @@ class ControllerExtensionTgshopHandle extends Controller
->bootAndHandleRequest(); ->bootAndHandleRequest();
} }
function extractPureJs($input) /** @noinspection PhpUnused */
{
// Убираем <noscript>...</noscript>
$input = preg_replace('#<noscript>.*?</noscript>#is', '', $input);
// Убираем <!-- комментарии -->
$input = preg_replace('#<!--.*?-->#s', '', $input);
// Извлекаем содержимое <script>...</script>
if (preg_match('#<script[^>]*>(.*?)</script>#is', $input, $matches)) {
return trim($matches[1]);
}
return '';
}
private function safeJsonDecode(?string $input = null, $default = null)
{
try {
return json_decode($input, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
return $default;
}
}
public function ya_metrika(): void public function ya_metrika(): void
{ {
$json = $this->model_setting_setting->getSetting('module_telecart'); $json = $this->model_setting_setting->getSetting('module_telecart');
if (isset($json['module_telecart_settings'])) { if (isset($json['module_telecart_settings'])) {
$raw = Arr::get($json, 'module_telecart_settings.metrics.yandex_metrika_counter'); $yaCounterId = Arr::get($json, 'module_telecart_settings.metrics.yandex_metrika_counter');
$raw = $this->extractPureJs($raw); $raw = <<<JS
(function(m,e,t,r,i,k,a){
m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
})(window, document,'script','https://mc.yandex.ru/metrika/tag.js?id={$yaCounterId}', 'ym');
ym({$yaCounterId}, 'init', {ssr: true, defer: true, ecommerce:"dataLayer", accurateTrackBounce:true, trackLinks:true});
JS;
http_response_code(200); http_response_code(200);
header('Content-Type: application/javascript'); header('Content-Type: application/javascript');