Автоматичний вхід до Lync конференції в Linux

Привіт, Хабре!

Для мене ця фраза схожа на hello world, тому що я дістався нарешті до своєї першої публікації. Довго відкладав цей чудовий момент, так як і писати не було про що, а обсмоктувати те, що вже купою обсмоктано, теж не хотілося. Взагалі для своєї першої публікації хотілося щось оригінальне, корисне іншим і яке містить якийсь челенж і вирішення проблем. І ось я вже можу поділитись цим. Тепер про все по порядку.

Вступ

Почалося все з того, що якийсь час тому я на робочому комп'ютері накотив собі Linux Mint. Багато хто напевно знає, що Pidgin з плагіном Sipe цілком придатна заміна Microsoft Lync (зараз називається Skype for business) для Linux систем. В силу специфіки роботи мені часто доводиться брати участь у sip-конференціях, і під час перебування віндузятника вхід у конференції був елементарним: отримуємо запрошення поштою, клацаємо на посилання входу, готове ми всередині.

При переході на темну сторону Linux все трохи ускладнилося: вхід у конференції в Pidgin звичайно ж теж є, але там для цього потрібно у властивостях вашого sip-акаунта вибрати пункт приєднання до конференції в меню і у вікні вставити посилання на конференцію або ввести ім'я організатора та conf id. І через якийсь час я почав замислюватися: «Чи не можна це спростити». Ага, скажете ви, на який біса тобі це знадобилося, сидів би собі на вінді і в вус не дув.

Крок 1. Дослідження

«Втем'яшиться в голову якесь дурощі — колом її звідти не виб'єш» — так говорив Некрасов у своєму творі «Кому на Русі жити добре».

Отже, якщо думка потрапила в голову, то через якийсь час виникла і перша ідея для реалізації. Здавалося все просто - потрібно перехоплювати звернення до посилань meet.company.com/user/confid — поставити на тачці локальний процес веб-додатка на 127.0.0.1 і в /etc/hosts занести статичну запис для домену компанії, через який здійснюється вхід у конференції, що вказує на localhost. Далі цей веб-сервер повинен обробити посилання, що прийшло йому, і якось передати всередину Pidgin (відразу скажу, що на цьому етапі у мене не було ще розуміння як мені це йому взагалі віддати). Рішення звичайно пахне милицями, але ми ж програмісти, милиці нас не лякають (щітка).

Потім випадково я якось відкрив посилання на запрошення в Google Chrome (а зазвичай завжди використовую Mozilla Firefox). І на мій подив веб-сторінка виглядала зовсім інакше — не було форми введення даних і відразу після входу на сторінку виходив запит на відкриття чогось через xdg-open. Заради інтересу натискаю «так» і виходить повідомлення про помилку – посилання lync15:confjoin?url=https://meet.company.com/user/confid не може бути відкрито. Хмм. Що це за xdg-open такий і що йому потрібно, щоб такі посилання відкривалися? Розкриття читання документації показало, що це обробник графічної оболонки, який допомагає запускати асоційовані додатки або протоколами для uri scheme, або з певними типами файлів. Асоціації налаштовуються через зіставлення mime-type. Отже, бачимо, що ми запускається пошук зіставленого докладання для uri scheme з ім'ям lync15 і посилання передається в xdg-open, який далі за ідеєю повинен передати її якомусь додатку, який відповідає за цей тип посилань. Якого в нас, звісно, ​​у системі немає. А якщо ні, то як діють у світі опенсорсу? Правильно ми напишемо його самі.

Подальше занурення у світ Linux і особливо вивчення того, як працює графічна оболонка (desktop environment, DE), до речі у мене це Xfce в Linux Mint, показало що додатки і асоційований з ним mime-type прописується зазвичай прямо у файлах ярликів з розширенням .desktop. Ну а чому б і ні, створюю простий ярлик програми, який повинен просто запустити баш-скрипт і вивести переданий йому аргумент на консоль, наводжу тільки сам файл ярлика:

[Desktop Entry]
Name=Lync
Exec=/usr/local/bin/lync.sh %u
Type=Application
Terminal=false
Categories=Network;InstantMessaging;
MimeType=x-scheme-handler/lync15;

запускаю xdg-open з консолі з передачею того ж посилання, яке йде з браузера та… облом. Знову каже, що не може обробити посилання.

Як виявилося, я не оновив каталог асоційованих mime-type з моїм додатком. Робиться це простою командою:

xdg-mime default lync.desktop x-scheme-handler/lync15

яка просто редагує файл ~/.config/mimeapps.list.

Спроба номер 2 із викликом xdg-open — і знову невдача. Нічого, труднощі нас не лякають, лише підігрівають інтерес. І озброївшись усією міццю баша (тобто трасуванням) пірнаємо з головою у налагодження. Тут важливо відзначити, що xdg-open просто шелл-скриптом.

bash -x xdg-open $url

Аналізуючи висновок після трасування стає зрозуміло, що далі управління передається в екзо-відкритий. А це вже бінарний файл і розуміти, чому він повертає неуспішний код повернення при передачі йому посилання в аргументі вже складніше.

Пробігши нутрощами xdg-open я з'ясував, що він аналізує різні параметри оточення і передає управління далі або якимось інструментам для відкривання файлів посилань специфічних для конкретного DE, або у нього є fallback у вигляді функції open_generic

open_xfce()
{
if exo-open --help 2>/dev/null 1>&2; then
exo-open "$1"
elif gio help open 2>/dev/null 1>&2; then
gio open "$1"
elif gvfs-open --help 2>/dev/null 1>&2; then
gvfs-open "$1"
else
open_generic "$1"
fi

if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}

Швидко впилюю сюди невеликий хак з аналізом переданого аргументу і якщо там знаходиться наш специфічний підрядок lync15:, то передаємо відразу управління у функцію open_generic.

Спроба номер 3, і ви думаєте заробило? Ага, зараз, як же. Але повідомлення про помилку вже змінилося, це вже прогрес — зараз він мені говорив, що файл не знайдений і у вигляді файлу писав мені те саме посилання, передане у вигляді аргументу.

Цього разу справа опинилася у функції is_file_url_or_path, яка аналізує передано на вхід посилання на файл file:// або шлях до файлу або щось інше. І перевірка не працювала вірно через те, що наш префікс (url scheme) має цифри, а регулярне вираз перевіряється лише набір символів, що складається з: alpha: точки та тире. Після консультації зі стандартом rfc3986 для uniform resource identifier стало зрозуміло, що цього разу Майкрософт нічого не порушує (хоча в мене була така версія). Просто клас символів: alpha: містить лише літери латинського алфавіту. Швидко змінюю перевірку з регулювання на alphanumeric. Готово, ви чудові, все нарешті запускається, управління після всіх перевірок віддається в наш скрипт-додаток, на консоль виводиться наше посилання, все як годиться. Після цього починаю підозрювати, що всі проблеми у exo-open теж через валідацію формату посилання через цифри у схемі. Для перевірки гіпотези змінюю реєстрацію mime-type у програми на просто схему рись і вуаля - все працює без перевизначення функції open_xfce. Але нам це ніяк не допоможе, тому що веб-сторінка для входу до конференції створює саме посилання з lync15.

Отже, першу частину шляху пройдено. Ми вміємо перехоплювати виклик посилання і далі його потрібно якось обробити та передати всередину Pidgin. Для того, щоб зрозуміти як воно працює всередині при введенні даних за посиланням в меню «приєднання до конференції», я схилював гіт репозиторій проекту Sipe і приготувався знову пірнати в код. Але тут мене на щастя залучили скрипти у каталозі contrib/dbus/:

  • sipe-join-conference-with-uri.pl
  • sipe-join-conference-with-organizer-and-id.pl
  • sipe-call-phone-number.pl
  • SipeHelper.pm

Виявляється плагін Sipe доступний для взаємодії через dbus (desktop bus) і всередині скриптів прямо є приклади приєднання до конференції за посиланням, або через ім'я організатора та conf-id, або можна ініціювати дзвінок через sip. Це ж саме чого нам не вистачало.

Крок 2. Реалізація обробника для автоджойна

Якщо вже є готові приклади на перл, то я вирішив просто використати sipe-join-conference-with-uri.pl і трохи доопрацювати під себе. Писати на перл я вмію, тому особливих складнощів це не завдало.

Після тестування скрипту окремо, я вписав його виклик у файл lync.desktop. І то була перемога! При вході на сторінку приєднання до конференції та дозволу запуску xdg-open спливаюче вікно конференції з Pidgin відкривалося автоматично. Як же я тріумфував.
Натхненний успіхом, я вирішив зробити те саме і для свого основного браузера Mozilla Firefox. При вході через лисицю відкривається сторінка для авторизації і ще в самому низу є кнопка join using office communicator. Вона й привернула мою увагу. При натисканні на неї в браузері відбувається перехід за адресою:

conf:sip:{user};gruu;opaque=app:conf:focus:id:{conf-id}%3Frequired-media=audio

на що він мені люб'язно каже, що не знає як її відкрити і, можливо, я не маю асоційованого додатка для такого протоколу. Ну, це ми вже проходили.

Швиденько реєструю свою програму-скрипт ще й для uri-схеми конф і... нічого не відбувається. Браузер продовжує скаржитися, що немає програми, яка обробляє мої посилання. При цьому виклик з консолі xdg-open із параметрами працює чудово.

"Set custom protocol handler in firefox" - з цим питанням я вийшов в Інтернет. Прошерстивши кілька обговорень на stackoverflow (а куди ж без нього), начебто відповідь знайшлася. Потрібно створити спеціальний параметр у про: конфігурації (Звичайно замінивши foo на conf):

network.protocol-handler.expose.foo = false

Створюємо, відкриваємо посилання і ... не тут було. Браузер як ні в чому не бувало говорить що не знає наш додаток.

Читаю офіційну документацію з реєстрації протоколу Mozilla, є варіант прописати асоціації в самому gnome desktop (замінивши звичайно foo на conf):

gconftool-2 -s /desktop/gnome/url-handlers/foo/command '/path/to/app %s' --type String
gconftool-2 -s /desktop/gnome/url-handlers/foo/enabled --type Boolean true

Реєструю, відкриваю браузер і знову борода.

Тут на очі трапляється рядок із документації:

Next time you click a link of protocol-type foo you will be asked which application to open it with.

- Семен Семенич
- Ааа

Ми ж не натискаємо на посилання, а просто веб-сторінка робить зміну window.location через javascript. Пишу простий html файл із посиланням на conf протокол, відкриваю в браузері, клацну по посиланню - Yos! Відкривається вікно з питанням у якому додатку потрібно відкрити наше посилання і там у списку ми вже маємо наш додаток Lync — ми ж його чесно зареєстрували всіма можливими способами. Там же у віконці є галочка «запам'ятати вибір і завжди відкривати посилання в нашому додатку», відзначаємо, натискаємо бл. І це друга перемога – вікно конференції відчиняється. При цьому вже відкриття конференцій працює і не тільки при натисканні на посилання, а й при переході з потрібної нам сторінки приєднання до конференції.

Потім я перевірив видалення параметрів network.protocol-handler.expose.conf ніяк не спричинило роботу протоколу в лисиці. Посилання продовжували працювати.

Висновок

Я залив усі свої напрацювання до репозиторію на гітхаб, посилання на всі ресурси будуть наприкінці статті.
Мені буде цікаво отримати зворотний зв'язок від тих, хто захоче скористатися моїми напрацюваннями. Відразу зазначу, що я все робив розробку тільки під свою систему Linux Mint, тому якісь інші дистрибутиви або робочі столи можуть не заробити в тому варіанті. Точніше я навіть майже впевнений у цьому, тому що я пропатчив у xdg-open тільки одну функцію, що стосується тільки мого DE. Якщо ви захочете додати підтримку інших систем чи декстопів, пишіть мені пул-реквести у гітхабі.

Реалізація всього проекту зайняла 1 вечір.

Посилання:

Джерело: habr.com

Додати коментар або відгук