Розширення для хрому: створення, публікація, досвід
У пошуках нових майданчиків для діяльності, я звернув увагу на “віджети” хрому, якими користуюся давно, але ніколи не надавав їм значення. Тут же захотілося спробувати що-небудь реалізувати.
Ідеєю стало створення таск-менеджера для розробника (і не тільки), який був би завжди під рукою. У ньому повинні були з’явитися актуальні тікети trello і jira, реквесты в gitlab і т. п. Це ті речі, які я зазвичай шукав, набираючи ключові слова в адресний рядок браузера, типу “jira PM-20”.
Розширення для хрому
Я точно знав, що розширення в браузерах — це звичайні html-сторінки, підживлені js-скриптами. Але при цьому не мав уявлення, як їх створювати. Перше, що видав мені гугл з цього питання — статтю на medium, а не офіційну документацію. Це було навіть краще, т. к. це була оглядова стаття найпростішого віджета від ідеї до публікації.
Стаття дала мені уявлення про те, що розробка “віджета” — справа не дуже хитре. Я тут же приступив до створення “hello world!”.
Структура
Виявилося, що потрібно створити mainfest.json в корені проекту. Він описує розширення: назва, опис, автора, іконки, дозволи і т. п. Першу версію я зробив без вивчення документації.
Перший manifest.json
Розширення дозволяють запускати js-скрипти в тлі, які роблять щось навіть коли користувач ними не користується. Цей функціонал я помацав дуже поверхнево, просто, щоб зрозуміти, як він може працювати. Він просто міняв заголовок < / h1> “віджета”.
Інтерес для мене представляла сама сторінка html, яка показується, при натисканні на іконку в браузері, вона називається popup.html в моєму маніфесті.
Цю сторінку, до речі, можна відкрити в браузері як і будь-який сайт, тільки в якості “протоколу” буде chrome-extension, наприклад chrome-extension://id-виджета-в-webstore/popup.html. Таким чином, ви можете переглянути исходники будь-якого розширення, що у вас встановлено.
Працює вона точно так само, як і будь-який веб-сайт, за винятком пари можливостей, наприклад: переходи по посиланнях працюють тільки з target=”_blank”. Є і технічні обмеження, керовані розробником, наприклад Content Security Policyабо permissions до функціоналу браузера, які запитуються у користувача.
Запустити розширення
Після створення папки з manifest.json і popup.html всередині, можна вже запустити її як віджет. На службовій сторінці хрому chrome://extensions є кнопка Завантажити розпакований розширення. З допомогою неї вибираємо папку
і розширення відразу відображається у списку “віджетів” поряд з адресним рядком.
З цього моменту розширення вже можна тестувати: змінювати popup.htmlі бачити зміни, переоткрыв “віджет” натисканням на його іконку.
Публікація в webstore
Почнемо з того, що можливість публікації перших 20 розширень коштує 5$. Відбувається вона в dashboard вебстора, для цього потрібно залити zip-архів вмісту папки розширення і попрацювати над рекламними текстами та малюнками.
Підготовка до публікації розширення
Перша частина опису розширення буде відображатися властивості description маніфесту
розширення, решта дописується в Detailed description в управлінні розширенням на webstore.
Розширення має гнучкі налаштування публікації: можна вибрати регіони світу для публікації, а також видимість розширення.
Потрібно пам’ятати, що якщо ви вибираєте для публікації тільки РФ, то в інших країнах розширення не з’явиться. Я натрапив на це перебуваючи в Таїланді: не міг зрозуміти чому, через 2 дні, розширення не шукається у сторі навіть за прямим назвою.
Просунуті опції
Я описав необхідні кроки для публікації простого розширення, щоб процес був зрозумілий. Тепер хочу висвітлити деякі деталі для написання більш складного “віджета“.
Суть мого розширення у використанні чужих API для отримання інформації. Для цього мені потрібен як мінімум localStorage, щоб запам’ятовувати токени авторизації.
Я скористався “permissions”: [“storage”] у своєму маніфесті.
OAuth2
У більшості випадків розробники API пропонують OAuth2 протокол для авторизації.
Якщо ви не знайомі з цим протоколом: він пропонує безпечний процес аутентифікації та авторизації програми від імені користувача без доступу до логіну/паролю з боку цього додатка.
Протокол описує кілька способів для авторизації. В ідеалі потрібно використовувати Authorization Code Flow, яке передбачає наявність бекенду програми; API редиректит користувача з Auth-кодом на додаток, а на додаток бэкенде обмінює його на токен.
Є також спрощений Implicit Flow, дозволяє авторизовуватись без бекенду: API після авторизації редиректит користувача на додаток з токеном в URL.
Як же користуватися цією “редиректной” авторизацією в розширенні хрому? Заводити веб-сайт? Виявляється, що не обов’язково.
Мої милиці
Спочатку я взявся інтегруватися з Gitlalb і Trello. З Gitlab все виявилося просто: відправляєш користувача в адмінку до його Gitlab, щоб він зробив токен і передав його тобі. З таким підходом довго возитися не довелося, я просто зробив поле для введення токена і описав як його отримати.
Trello ж надав OAuth2, я відразу ж помітив, що в ньому є implicit flow, але трохи дивний: токен відображається на їх сторінці /approve в такому вигляді
Не став заглиблюватися, я так само зробив поле для введення сертифіката в своєму розширенні і описав користувачеві, як це зробити.
Правильний спосіб
Як правило, гарне рішення приходить не відразу. Я на нього натрапив, коли почав інтеграцію з Jira, яка має тільки Authorization Code Flow.
Якось випадково я натрапив на chrome.identity: функціонал браузера, вже реалізував всі “милиці” для авторизації. Цей функціонал вимагає включення identityу дозволах маніфесту. Я доповнив свій маніфест: “permissions”: [“storage”, “identity”].
Як я вже і говорив: у кожного є розширення URL типу chrome-extension://<id>/. Такий адресу ні для чого не годиться, але chrome.identity надає справжній URL https://<app-id>.chromiumapp.org/*, який можна передати в API з OAuth2 як redirectUrl. API, після авторизації, відправить користувача на нього з додатковими параметрами, будь то authCode або token, а хром їх підхопить і передасть ваш js-callback розширення.
Для цього потрібно скористатися chrome.identity.launchWebAuthFlow(), яка відкриває сторінку авторизації API в новому вікні:
chrome.identity.launchWebAuthFlow(
{
'url': JiraApi.url(),
'interactive': true
},
jira.callback()
);
Відразу ж скажу: це вікно виглядає не зовсім як вікно основного браузера, що у мене викликало б питання, якби я був звичайним користувачем, т. до. воно схоже на якийсь фішингових блок, а не вікно. Може бути це тільки моє сприйняття, може бути так тільки в моїй операційці.
Вікно авторизації chrome.identity.launchWebAuthFlow
Інші опції
Коли з’являється ідея реалізувати будь-який функціонал, рекомендую гуглити chrome API, оскільки в ньому вже достатньо багато подібних фіч, які полегшать вам роботу. Наприклад повний manifest.json вражає:
{
// Required
"app": {
"background": {
// Optional
"scripts": ["background.js"]
}
},
"manifest_version": 2,
"name": "My App",
"version": "versionString",
// Recommended
"default_locale": "en",
"description": "A plain text description",
"icons": {...},
// Optional
"action_handlers": ["new_note"],
"author": ...,
"automation": ...,
"bluetooth": {
"uuids": ["1105", "1006"]
},
"commands": {...},
"current_locale": ...,
"event_rules": [{...}],
"externally_connectable": {
"matches": ["*://*.example.com/*"]
},
"file_handlers": {...},
"file_system_provider_capabilities": {
"configurable": true,
"multiple_mounts": true,
"source": "network"
},
"import": [{"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}],
"key": "publicKey",
"kiosk": {
"always_update": ...,
"required_platform_version": ...
},
"kiosk_enabled": true,
"kiosk_only": true,
"kiosk_secondary_apps": ...,
"minimum_chrome_version": "versionString",
"nacl_modules": [...],
"oauth2": ...,
"offline_enabled": true,
"optional_permissions": ["tabs"],
"permissions": ["tabs"],
"platforms": ...,
"вимога": {...},
"sandbox": [...],
"short_name": "Short Name",
"signature": ...,
"sockets": {
"tcp": {
"connect": "*"
},
udp: {
"send": "*"
}
},
"storage": {
"managed_schema": "schema.json"
},
"system_indicator": ...,
"update_url": "http://path/to/updateInfo.xml",
"url_handlers": {...},
"usb_printers": {
"filters": [...]
},
"version_name": "aString",
"webview": {...}
}
Попередньо розбиратися з усіма можливостями може виявитися дуже марнотратним, т. к. їх величезна кількість.
До того ж тільки js-сторона розширення сама по собі може збільшитися до великих розмірів.
Моя поточна схема
Просування
Трохи варто згадати просування свого розширення. Особливістю “віджетів” є те, що вони спрямовані на користувачів десктопів, які в останні роки встигли стати меншиною.
Я спробував контекстну рекламу та рекламу в соціальних мережах. Отримав невеликий досвід і нульову конверсію.
Контекстна реклама
Мій досвід поки обмежився одним майданчиком, не можу говорити за інші, але думаю, там те ж саме.
Виявляється, що в контекстній рекламі яндекса можна налаштовувати таргетинг по пристроїв і браузерам. Так що якщо ваше розширення тільки для хрому, показувати рекламу доведеться і людям, що сидять на інших браузерах, переходи яких принесуть тільки зайві збитки.
Я не хотів робити окремий сайт для свого розширення, тому рекламував його сторінку в webstore. Мінус цього підходу в тому, що ти можеш довіряти статистиці рекламного кабінету і не можеш побачити як користувачі ведуть себе на рекламовану сторінку.
Соціальні мережі
Вони як раз і відносяться до категорії сайтів, на яких десктоп це вмираюче меншість.
Вконтакте надає націлювання на мобільний і повну версію свого сайту. Але ця галочка прихована в самому кінці налаштувань, особисто я її не помітив до того, як злив бюджет і побачив у статистиці сумний охоплення
Насправді в той день мобільні перегляди були сильно більше
Думки наостанок
Я вважаю, що розширення це потужний інструмент для людей, які працюють в інтернеті, т. к. в браузері ми проводимо багато часу, який іноді хочеться оптимізувати. Наприклад віджет гугл-перекладача, який перекладає текст при виділенні, хороший приклад оптимізації. Рішення проблеми величезної кількості відкритих вкладок “на пізніше” я теж вирішив з допомогою віджета.
Написання розширень дає досвід у вивченні підводної частини айсберга “Chrome” і написанні “фронтенда” (особливо якщо ви бекенд-розробник). Розширення можна писати на тому ж React JS з якого можна перекинутися на написання програм під мобільні пристрої. Процес написання і того і того дуже схожий.