Русский
Русский
English
Статистика
Реклама

Chrome extension

Приглашаем на DINS JS EVENING (online) обсуждаем рефакторинг приложений и SvelteJS

22.09.2020 14:11:12 | Автор: admin
Встречаемся 30 сентября в 19:00.

В этот вечер Андрей Владыкин из DINS расскажет, с какими трудностями столкнулся при рефакторинге Chrome Extension и с помощью каких технических решений справился с этой задачей. Михаил Кузнецов из ING Bank сделает обзор нового фреймворка SvelteJS и проведет демо с разработкой простого приложение в прямом эфире. Участники встречи смогут задать вопросы спикерам.

Участие бесплатное, но нужна предварительная регистрация. Под катом подробная программа и информация о спикерах.

image


Программа


19:00-19:30 Рефакторинг приложения на примере Chrome Extension (Андрей Владыкин, DINS)
При рефакторинге Chrome Extension Андрею пришлось написать приложение, которое на тот момент не имело аналогов: WebRTC-клиент для звонков через браузер. Вы узнаете, с какими трудностями он столкнулся, как выбирал инженерные решения, какие задачи получилось решить, а какие нет. Еще Андрей расскажет, как выстроить работу, если требования к продукту постоянно меняются.
Доклад будет интересен начинающим фронтенд-разработчикам.

Андрей Владыкин Frontend Developer в DINS. Успел поработать в Enterprise-разработке и с сервисами для контактных центров. Сейчас работает над приложением для видеоконференций. В основном пишет на React.

19:30-20:10 Разработка быстрых и легких веб-приложений на SvelteJS (Михаил Кузнецов, ING Bank)
Михаил расскажет о SvelteJS новом фреймворке, при использовании которого генерируется минимальный итоговый бандл. Вы узнаете, с чем связана популярность фреймворка и почему его стоит применить в вашем следующем проекте.
Во время доклада Михаил сделает обзор функций SvelteJS, поделится опытом его использования. Вы увидите разработку простого приложения в прямом эфире и сможете на практике познакомиться с этим продуктом, его синтаксисом и компонентами.
Уровень начальный. Доклад будет интересен тем, кто еще не сталкивался со SvelteJS на практике и только хочет попробовать им воспользоваться.

Михаил Кузнецов Team Lead в ING Bank. Разработчик, спикер, тимлид, преподаватель. Хорошо относится к фронтенду, также пишет на других стеках.

Как присоединиться


Участие бесплатное. В день проведения митапа мы пришлем ссылку на трансляцию на указанный при регистрации имейл.

Как проходят встречи


Записи предыдущих митапов можно посмотреть на нашем YouTube-канале.

О нас


DINS IT EVENING это место встречи и обмена знаниями технических специалистов по направлениям Java, DevOps, QA и JS. Несколько раз в месяц мы организуем встречи, чтобы обсудить с коллегами из разных компаний интересные кейсы и темы. Открыты для сотрудничества, если у вас есть наболевший вопрос или тема, которой хочется поделиться пишите на itevening@dins.ru!
Подробнее..

Я никогда не писал расширения для Хрома, но меня допекли

30.10.2020 02:05:23 | Автор: admin


Если вы узнали стиль заголовка и вам больше не нужны никакие подробности вот ссылка на репозиторий.


Если вы недоумеваете что это такое и почему я отнимаю место в ленте у хороших авторов тогда немного контекста будет под катом.


Все мы знаем, что на Хабре есть несколько авторов которые пишут ради хайпа или исключительно ради денег. В целом в этом нет ничего плохого, конечно, при условии, что контент качественный. К сожалению, некоторые авторы, скажем вежливо, грешат. Плохие переводы, корпоративные блоги (не все), не просто отвлекают вниманию, они еще и "съедают" место хорошего контента. В потоке мусора качественная техническая статья быстро теряется, что негативно сказывается на мотивации авторов. Кроме того, некачественный контент так же понижает общую планку Хабра. Если раньше ты вылизывал статью потому что "это же Хабр!" то теперь закрадывается мысль, что прокатит и так. Что, конечно же, рекурсивно.


Сделать что-то с этим сложно.


Можно стараться голосовать за каждую техническую статью, просто потому что это не рассказ о том, как получить золотой паспорт на Кипре. В перспективе, если все так начнут делать, это принесет позитивный эффект. Но, будем реалистами, массово так делать не будут.


Можно репортить откровенно плохие статьи в надежде что их удалят. Но Хабру вроде как жить за что-то надо, так что корпоративные блоги удалять никто не будет. Да и сама идея массовых репортов отдает гарью, что мне не по душе.


Поэтому самый простой и одновременно эффективный способ (в краткосрочной перспективе) это скрыть некоторых авторов хотя бы из основной ленты. Способ не нов, мы о нем уже давно просили, но, пока без успешно. И это тоже в общем то понятно. Если все начнут массово удалять корпоративные блоги из ленты, Хабр станет гораздо менее интересной площадкой для корпоративного сегмента что приведет к уменьшению прибыли. А кушать хотят все. Так что скорее всего, в ближайшее время такой функционал не увидим. Кстати, отчасти поэтому я не стал скрывать эти посты из "ЧИТАЮТ СЕЙЧАС" табы. Если пост становится популярным, возможно, вам все же будет интересно его увидеть, а площадка дополучит свои просмотры.


Зато мы можем написать такой функционал самостоятельно, что я и сделал где-то за 4 часа из которых часа 3 ушло на UI.


Итак встречайте https://github.com/Drag13/HabrSanitizer расширение для удаления постов от нежелательных авторов. Не судите строго, расширение писал впервые, может где-то накосячил.


Все работает довольно просто. На странице настройки расширения мы задаем список ников авторов которых больше не хотим видеть и с помощью chrome.storage.sync.set({ settings }) сохраняем их. Кстати, поэтому расширение требует разрешение использовать storage. Потом, когда Habr загружается, в контексте страницы загружается sanitizer.js который сначала загружает из storage список авторов, а потом находит и удаляет их статьи со страницы.


Поиск довольно примитивный
    function searchByAuthorName(author) {        const [...allArticles] = document.getElementsByTagName('article');        const articlesFromAuthour = allArticles.filter((article) =>            equalsCaseInsensetive(article.querySelector(`.user-info__nickname`)?.textContent, author)        );        return articlesFromAuthour;    }

Естественно, меня как автора тоже можно заблокировать, думаю это вполне справедливо, хотя и иронично.


Из дополнительного функционала можно выгрузить свой бан-лист и поделиться им с товарищами. Было бы очень любопытно собрать статистику самых непопулярных авторов, но я не в восторге от телеметрии поэтому пропустим.


На этом с функционалом все, как видите все предельно минималистично.


Теперь о том, как его попробовать.


Сначала установите расширение. Для этого вам нужно


  • Клонировать репозиторий
  • Открыть chrome://extensions/ табу
  • Включить режим разработчика (правый верхний угол)
  • Загрузить расширение из папки src репозитория

Теперь настройте его под себя перейдя по вкладке Extension options:


я хотел это сделать как минимум полгода


Все, расширением можно пользоваться. Если вы волнуетесь за приватность, то:


  • Расширение требует всего два разрешения "activeTab", "storage"
  • Запускается только домена вида "http://personeltest.ru/aways/habr.com/*"
  • 0 постороннего кода и все на виду, никаких node_modules, никаких зависимостей.

А поскольку устанавливаете его нужно вручную, вы всегда видите именно тот код, который будет работать у вас в браузере, а не тот который я запушил в маркет. Поэтому я не стал настраивать какую-то минификацию (но авто-преттиер потом поставлю). Так что все должно быть в порядке. Но если у вас есть какие то сомнения напишите в ЛС или создайте issue.


На этом у меня все, надеюсь кому-то это окажется полезным.


Доброй ночи господа.


П.С. И хотя я умышленно потроллил одного из авторов, мой список блокировки я не выкладываю, тут уже каждый должен решать сам.
П.П.С. Если найдется человек который нарисует иконку это было бы просто замечательно. Художник из меня очень плохой.

Подробнее..

Перевод Использование Redux в MV3 расширениях Chrome

23.12.2020 16:22:50 | Автор: admin

Примечание к переводу: Оригинальная статья была написана до того как стало известно о MV3. Тем не менее она полностью актуальна и для MV3 расширений (по крайней мере на данный момент). Поэтому я решил немного изменить ее название, добавив упоминание "MV3", что нисколько не противоречит содержанию. Если кто не в курсе: MV3 новый формат/стандарт расширений Chrome, должен быть введен в январе 2021 года.


В этой статье, предназначенной для опытных веб-разработчиков, рассматривается (и решается) проблема использования Redux в т.н. событийно-ориентированных (event-driven) расширениях Chrome.


Специфика событийно-ориентированных расширений


Событийно-ориентированная модель расширения впервые появилась в Chrome 22 в 2012 г. В этой модели фоновый скрипт расширения (если есть) загружается/выполняется только когда это нужно (в основном в ответ на события) и выгружается из памяти когда он ничего не делает.


Документация Chrome разработчика настоятельно советует использовать событийно-ориентированную модель для всех новых расширений, а для уже существующих расширений, использующих постоянную (persistent) модель делать миграцию. Есть правда одно исключение (в MV3 уже не актуально, в т.ч. поэтому переход на новую модель в MV3 обязателен). Но похоже что многие расширения до сих пор используют постоянную модель, даже если могут быть событийно-ориентированными. Конечно, многие из них были впервые выпущены до того, как стало известно о событийно-ориентированной модели. И теперь у их авторов просто нет стимула переходить на новую модель. С одной стороны это (пока) необязательно, а с другой означает необходимость множества изменений, не только в фоновом скрипте, но и в других компонентах расширения. К тому же многие при разработке используют кроссбраузерный подход, собирая готовые расширения для разных браузеров из одного и того же исходного кода. Событийно-ориентированная модель на данный момент поддерживается только в Chrome и она существенно отличается от постоянной модели, поддерживаемой остальными браузерами. Естественно, это усложняет кроссбраузерную разработку.


Вместе с тем, некоторые из относительно новых расширений Chrome также используют постоянную модель, при том что могут быть событийно-ориентированными. В конечном счете причина здесь та же, что и в случае миграции: существенные различия между событийно-ориентированной и постоянной моделями, которые в основном выражаются в способах управления состоянием расширения.


Проблема с Redux


Управление состоянием одна из вещей, имеющих особое значение в современной веб-разработке. Каждое веб-приложение (в т.ч. браузерное расширение), как только оно становится достаточно сложным, нуждается в едином и последовательном способе управления своим состоянием. И это то в чем силен Redux.


Redux популярная библиотека, помогающая управлять состоянием приложения единым, последовательным и достаточно простым способом. Но беда в том что Redux не предназначен для использования в расширениях браузера.


Прежде всего, в любом браузерном расширении может всплыть проблема с правилом "единого источника" это один из фундаментальных принципов Redux, по которому все состояние приложения должно храниться в одном месте. Расширения браузера часто состоят из нескольких отдельных компонентов (таких как фоновые и внедряемые скрипты), что затрудняет соблюдение данного принципа. К счастью эта проблема решаема и есть библиотеки, такие как Webext Redux, которые решают ее с помощью передачи сообщений. К несчастью такое решение неприменимо к событийно-ориентированным расширениям из-за уже упоминавшихся различий между событийно-ориентированной и постоянной моделями. Теперь самое время рассмотреть подробно эти различия.


В постоянной модели расширения его состояние обычно хранится в локальной переменной внутри постоянного (persistent) фонового скрипта, живущего в течение всей сессии браузера, до самого его закрытия. Так что такое состояние всегда доступно остальным компонентам расширения (например, внедряемым скриптам) через фоновый скрипт, который таким образом выполняет роль сервера. Это стандартный постоянный подход к управлению состоянием, который используется в библиотеках, таких как Webext Redux.



Что касается событийно-ориентированной модели, то здесь в принципе не может быть такого сервера как при постоянном подходе, поскольку все компоненты расширения, включая фоновый скрипт, равны с точки зрения времени жизни. Другими словами, здесь нельзя хранить состояние в фоновом скрипте, т.к. последний может быть выгружен из памяти в любой момент (который нельзя узнать заранее). К счастью эта проблема также имеет решение.


Решение


Решение заключается в том, чтобы использовать chrome.storage как непосредственное место/способ хранения/изменения состояния. Этот подход (между прочим он явно предлагается в руководстве по миграции) предполагает, что состояние хранится непосредственно в chrome.storage, чье API вызывается всякий раз когда нужно изменить состояние, либо отследить такие изменения.



Как часть стандартного API расширений chrome.storage обладает рядом преимуществ, самое важное из которых то что любой компонент расширения может иметь прямой доступ к нему. Еще одно преимущество автоматическое сохранение состояния между сессиями браузера, что является встроенной фичей, работающей "из коробки".


Также стоит отметить, что данный подход работает одинаковым образом, как в событийно-ориентированной, так и в постоянной модели. Так что в итоге мы получаем универсальное решение, работающее в большинстве браузеров, что облегчает кроссбраузерную разработку.


Остается только одна проблема API chrome.storage отличается от Redux, что делает невозможным его использование в качестве замены Redux. Конечно, можно использовать chrome.storage как есть, либо написать к нему кастомную обертку. Однако, Redux уже успел стать чем-то вроде стандарта в управлении состоянием. Так что было бы неплохо как-нибудь адаптировать chrome.storage к принципам Redux, или другими словами, сделать Redux из chrome.storage).


Наша цель в этой статье получить Redux-совместимый интерфейс к chrome.storage, который будет переводить функционал chrome.storage в термины Redux. В терминах API нам нужно реализовать в рамках chrome.storage интерфейс функционала Redux, имеющего непосредственное отношение к хранилищу (store) Redux. Он включает в себя функцию createStore и возвращаемый ею объект Store (хранилище Redux). Ниже их интерфейсы:


Спецификация интерфейса

Реализация


Итак, прежде всего нам нужно написать класс, реализующий интерфейс Store. Назовем его ReduxedStorage.


Реализовать методы getState и subscribe достаточно просто, т.к. у них есть близкие аналоги в chrome.storage: метод get и событие onChanged. Конечно, они не могут напрямую заменить указанные методы Store, но могут помочь в организации хранения локальной копии состояния в нашем классе. Мы можем инициализировать локальное состояние в нашем классе, вызвав метод get из chrome.storage во время создания экземпляра ReduxedStorage и затем, всякий раз когда появляется событие onChanged, изменять соответственно локальное состояние. Таким образом гарантируется актуальность локального состояния. Тогда getState в рамках нашего класса будет тривиальным геттером. Реализация метода subscribe немного сложнее: он должен добавлять аргумент-функцию к некоторому массиву слушателей, которые будут вызываться всякий раз когда появляется событие onChanged.


В отличие от getState и subscribe, в chrome.storage нет ничего похожего на метод Store.dispatch. Там есть метод set, но его прямое использование противоречит еще одному фундаментальному принципу Redux, по которому состояние Redux присваивается только один раз, во время создания хранилища, после чего оно может быть изменено только через вызов метода dispatch. Так что нам нужно как-то воспроизвести функционал dispatch в нашем классе ReduxedStorage. Есть два способа сделать это. Радикальный предполагает полное воспроизведение соответствующего функционала Redux в рамках нашего класса, короче говоря, тупо скопировать код Redux. Но есть также и компромисный вариант, который и будет рассмотрен ниже.


Идея состоит в том, чтобы создавать новый экземпяр хранилища всякий раз, когда отправляется какое-то действие. Да, это звучит немного странно, но это единственная альтернатива полному копированию выше. Говоря более конкретно, всякий раз когда в нашем классе вызывается метод dispatch, нам нужно создать новый экземпяр хранилища, вызвав "оригинальную" функцию createStore, инициализовать его состояние локальным состоянием из нашего класса и наконец вызвать "оригинальный" метод Store.dispatch, передав ему аргументы из нашего dispatch. Помимо этого, к созданному хранилищу нужно добавить одноразовый слушатель изменения состояния, чтобы когда данное действие дойдет до хранилища, обновить chrome.storage новым состоянием, получающимся в результате данного действия. Далее это обновление должно быть отслежено и обработано слушателем события chrome.storage.onChanged, описанным выше.


Несколько замечаний насчет инициализации состояния: Поскольку метод chrome.storage:get выполняется асинхронно, мы не можем вызывать его из конструктора нашего класса. Поэтому нам придется перенести код вызова chrome.storage:get в отдельный метод, который должен вызываться сразу после конструктора (создания экземпляра класса). Этот метод, назовем его init, будет возвращать промис, который должен быть разрешен, когда метод chrome.storage:get завершит выполнение. В методе init нам также нужно создать еще одно локальное хранилище Redux, чтобы получить дефолтное состояние, которое будет использоваться, если состояние в chrome.storage в данный момент пусто.


Ниже пример как может выглядеть наш класс ReduxedStorage в первом приближении:


Реализация в первом приближении

Замечание: Мы обращаемся к части данных в chrome.storage под определенным ключом (this.key), чтобы иметь возможность сразу получить новое (измененное) состояние в слушателе chrome.storage.onChanged, не вызывая дополнительно метод chrome.storage:get. Кроме того, это может быть полезно при хранении в состоянии непосредственно массивов, т.к. chrome.storage позволяет хранить на корневом уровне только объект.


К сожалению, в реализации выше есть скрытый недостаток, который возникает из-за того, что мы обновляем свойство this.state не напрямую, а через метод chrome.storage:set, выполняющийся асинхронно. Само по себе это не проблема. Но при создании локального хранилища Redux внутри метода dispatch используется значение свойства this.state, что может представлять проблему, т.к. this.state не всегда может содержать актуальное состояние. Так может быть, если несколько действий отправляются синхронно сразу друг за другом. В этом случае 2-й и все последующие вызовы dispatch имеют дело с устаревшими данными в свойстве this.state, которое еще не успевает обновиться из-за асинхронного выполнения метода chrome.storage:set. Таким образом, синхронное отправление нескольких действий друг за другом может приводить к нежелательным результатам.


Чтобы решить указанную проблему, можно изменить код dispatch так, чтобы использовать для таких синхронных действий одно и то же хранилище Redux. Такое буферизированное хранилище должно быть сброшено по истечении небольшого периода времени (допустим 100 мсек), чтобы для следующих действий использовалось уже новое хранилище. Для этого решения нам потребуется добавить в наш класс дополнительные свойства для буферизированного хранилища и соответствующего состояния. Ниже пример как может выглядеть такая буферизированная версия метода dispatch:


Буферизированная версия dispatch

Как это часто бывает, решая одну проблему, можно получить другую. В нашем случае использование буферизированного многоразового варианта хранилища вместо локального одноразового может сломать асинхронную логику в Redux. Асинхронная логика, по умолчанию отсутствующая в Redux, может быть введена с помощью middleware, такого как Redux Thunk. С Redux Thunk можно например отложить отправку действия, используя создатель действия, который возвращает функцию вместо действия. Ниже пример такого создателя действия:


Пример отложенного создателя действия

delayAddTodo откладывает отправку действия 'ADD_TODO' на 1 сек.


Если мы попытаемся использовать такой создатель действия с буферизированным вариантом dispatch выше, мы получим ошибку во время вызова this.buffStore.getState внутри колбека this.buffStore.subscribe. Причина в том что колбек this.buffStore.subscribe вызывается как минимум через 1 сек после вызова нашего метода dispatch, когда this.buffStore уже сброшен в null (через 100 мсек после вызова dispatch). При этом предыдущий вариант dispatch без проблем работает с такими асинхронными создателями действий, т.к. использует локальное хранилище, которое всегда доступно соответствующему колбеку subscribe.


Таким образом, нам нужно совместить оба варианта, т.е. использовать, как буферизированный, так и локальный вариант хранилища Redux. Первый будет использоваться для синхронных действий, а последний для асинхронных, занимающих какое-то время, таких как delayAddTodo. Однако, это не значит, что нам нужны два отдельных экземпляра хранилища Redux в одном вызове dispatch. Можно создать экземпляр хранилища один раз, сначала сохранив его в свойстве this.buffStore, а затем скопировать ссылку на него в локальной переменной, назовем ее lastStore. Тогда, когда свойство this.buffStore будет сброшено, lastStore все еще будет указывать на тот же самый экземпляр хранилища и будет доступен соответствующему колбеку subscribe. Следовательно, внутри колбека subscribe можно использовать переменную lastStore как запасную ссылку на хранилище на тот случай, если свойство this.buffStore недоступно, что означает асинхронное действие "в действии"). Когда изменение состояния будет обработано внутренним колбеком subscribe, было бы полезно отписать данный колбек/слушатель от хранилища и сбросить переменную lastStore, чтобы высвободить соответствующие ресурсы.


Кроме того, было бы неплохо провести рефакторинг в коде класса, в т.ч.:


  • сделать свойства this.areaName, this.key изменяемыми/настраиваемыми через параметры конструктора.
  • переместить код, непосредственно вызывающий API chrome.storage, в отдельный класс, назовем его WrappedStorage.

Итак, ниже окончательная реализация нашего интерфейса:


Окончательная реализация

Его использование аналогично использованию оригинального Redux, за исключением того, что в нашем интерфейсе создатель хранилища (store creator) обернут в функцию и выполняется асинхронно, возвращая промис вместо созданного хранилища.


Стандартное использование интерфейса выглядит так:


Стандартное использование

Кроме того, с синтаксисом async/await, доступным начиная ES 2017, этот интерфейс может использоваться так:


Продвинутое использование

Исходный код доступен на Github.


Также этот интерфейс доступен как пакет в NPM:


npm install reduxed-chrome-storage
Подробнее..

Не спешите выкидывать свой PolyCom

20.11.2020 18:16:58 | Автор: admin

Если у вас где-то в углу неприкаянно грустит телефон компании Polycom не спешите от него избавляться! Он еще сможет вам послужить. По крайней мере ковыряние с ним может доставить массу удовольствия. Все нижеописанное тестировалось на устаревшей модели Polycom SoundPoint IP 450(от 1500 рублей за БУ на ebay), но также подходит и для большинства более современных моделей т.к. все они работают под управлением одной и той-же операционной системы UC.

Да, именно так и вы не ослышались даже древний офисный телефон работает под управлением проприетарной ОС.

Итак, что-же полезного и интересного можно сделать с телефоном Polycom в домашних условиях:

  • Вывод полезной информации на экран телефона и использование внутреннего браузера

  • SIP телефония & Lync integration(Skype for Business) для SIP моделей

  • Интеграция с Google Chrome набор номера через расширение для google chrome

  • Кастомизация UI телефона

  • Интеграция с LDAP и AD и использование телефонных книг

Итак, обо все по прядку.

Встроенный браузер

Большинство моделей телефонов polycom оснащены тем или иным экранчиком, а прошивка поддерживает xhtml-браузер. У браузера есть 2 режима работы: idle отображается контент во время ожидания и active отображается контент во время использования телефона.

Телефон поддерживает только самые базовые html-теги, а также несколько собственных тегов для управления навигацией:

<html>

<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head>

<body>

<softkey index="1" label="Back" action="SoftKey:Back" />

<softkey index="2" label="Weather" action="SoftKey:Fetch;http://raspberrypi:88" />

<softkey index="3" label="Refresh" action="SoftKey:Refresh" />

<a href="Tel://89264341830">Taxi</a>|

<a href="Tel://89652991881">Суши</a>|

<a href="Tel://84965246699">Пицца</a>|

<br/>

<a href="Key:DoNotDisturb">DNDSettings</a>

</body>

</html>

Современные модели телефонов имеют расширенную поддержку HTML и даже умеют работать с Javascript. Используя встроенный браузер телефона довольно легко каcтомизировать UI/UX под свои предпочтения. В моем случае - это отображение прогноза погоды на основе Yandex Weather API и несколько статических страниц с наиболее часто используемыми телефонами.

Вместо погоды можно выводить последние новости, курсы валют, биржевые индексы и т.д. В моем случае страницы размещены на raspberry PI в домашней сети, но никто не мешает их разместить на любом бесплатном сервисе.

Самый простой способ настроить работу внутреннего браузера это зайти на внутренний сайт телефона (просто введите IP телефона и дефолтный пароль 456) и на вкладке Settings/Microbrowser вы найдете все необходимые настройки:

SIP

Если ваша модель поддерживает SIP протокол вам открывается масса интересных возможностей.

Большинство телефонов может поддерживает несколько линий. Если у вас мегафон, то на одну линию можно завести номер мобильного телефона, предварительно подключив бесплатную услугу мультифон и переадресацию звонков на телефон и SIP как описано здесь.

Используя тариф без абонентской связи вы получаете условно-бесплатный домашний телефон.

На второй линии у меня заведен мой личный номер мобильного телефона, который используется для исходящих звонков или для приема входящих звонков в случае проблем с сотовым покрытием. Ну а на третью линию можно подключить международного SIP провайдера и иметь за доллар или два номер в США или любой другой стране. Это позволит сэкономить колоссальные деньги на международных звонках. Настройку можно осуществить как через упоминаемый ранее внутренний сайт телефона, так и через прямое редактирование файла конфигурации телефона.

Чтобы выгрузить файл конфигурации зайдите в Utilities/Import-Export configuration в раздел Export.

Выгруженный файл конфигурации содержит все настройки телефона кроме паролей!

Информацию о содержимом файла конфигурации можно найти здесь.

В качестве альтернативы можно использовать свободную линию для подключение к Microsoft Lync серверу для интеграции со Skype For Business.

Интеграция с браузером Chrome

Пожалуй основной причиной по которой стационарные телефоны стоят без дела является их крайне неудобная интеграция с телефонными книгами, браузером и поисковиками. В рамках офиса есть возможность подключить к телефон к AD, но искать нужный контакт в телефоне это та еще боль.

Конечно для домашнего использования можно организовать LDAP интеграцию с Google contacts или же загрузить список контактов используя provisioning, но основную проблему с ужасным UX это не исправляет.

Для решения этой проблемы я сделал небольшое расширение для Google chrome, которое позволяет выделить номерна любой страничке и стартовать звонок со стационарного телефона.

Телефоны Polycom поддерживают, так называемые, интеграционные вызовы, когда отправив POST запрос извне на телефон можно заставить его выполнить то или иное действие: Позвонить на указанный номер, перейти в режим Не беспокоить, включить переадресацию, вывести сообщения на экран и т.д. и т.п.

К примеру такой запрос эмулирует нажатие кнопки Status на телефоне:

curl --digest -u Push:Push -d "<PolycomIPPhone><Data priority=\"All\">Key:Status</Data></PolycomIPPhone>" --header "Content-Type: application/x-com-polycom-spipx" -v http://192.168.0.226/push

А такой стартует звонок по указанному номеру на линии 1.:

curl --digest -u Push:Push -d "<PolycomIPPhone><Data priority=\"All\">tel:\\2222222;Line1 </Data></PolycomIPPhone>" --header "Content-Type: application/x-com-polycom-spipx" -v http://192.168.0.226/push

Соответственно все что требуется реализовать в расширении решить нетривиальный вопрос Digest аутентификации в JS, прочитать выделенный текст по вызову из контекстного меню и отправить Post запрос в телефон.

Предварительно необходимо разрешить интеграциионные вызовыв телефоне. Зайдите в раздел Settings/Applications/Push и выберите All в разделе Allow Push Message и не забудьте указать логин и пароль для авторизации вызовов. Без этого рабоать не будет.

В работе это примерно так:

Исходники расширения здесь а само раширение ищите в Google Chrome Extension Store.

Настройка UI телефона

UI Телефона поддается некоторой кастомизации. Кроме замены фона(на ЧБ экране это все равно выглядит ужасно) и отображения web- страниц во встроенном браузере -можно переназначать действие кнопок навигации, предварительно разрешив их переопределение с помощью этих ключей в конфигурации телефона.

feature.enhancedFeatureKeys.enabled="1"

feature.EFKLineKey.enabled="1"

Несколько примеров подобного переопределения:

Открытие странички с погодой во внутреннем браузере телефона:

softkey.1.action="http://personeltest.ru/away/192.168.0.228:88"

softkey.1.enable="1"

softkey.1.label="Инфо"

softkey.1.use.idle="1"

Переход в режим DoNotDesturb

softkey.1.action="Key:DoNotDisturb"

softkey.1.enable="1"

softkey.1.label="DnD"

softkey.1.use.idle="1"

Вызов 1-го контакта из списка быстрого набора

softkey.3.action="$S1$"

softkey.3.enable="1"

softkey.3.label="Такси"

softkey.3.use.idle="1"

Более подробную информацию о переназначении софтверных кнопок можно подчерпнуть здесь.

Телефон также поддерживает т.н. push сообщения, когда он сбрасывает на указанный адрес сообщения для выбранных событий, но практического применения данной функциональности в домашних условиях я не нашёл.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru