create-a-plugin.rst (26309B)
1 Creating Plugins 2 ================ 3 4 **NOTE: this page introduces the Jami Plugins SDK.** 5 6 As from September of 2020, Jami team has added plugins as a call feature 7 for GNU/Linux, Windows, and Android users. This meaning that now you can 8 personalize your call and chat experience by using one of our available 9 plugins. But that is not all, you can also transform your awesome ideas 10 into a brand new plugin! 11 12 Here you will be guided throught the SDK that will help you start your 13 plugin developpment. The text is organized as: \* A description of our 14 `#SDK <#sdk>`__; \* An example of how to create your own base plugin 15 with our SDK - `#Create my first plugin <#create-my-first-plugin>`__. 16 17 SDK 18 --- 19 20 We developped a Plugin System for Jami and we have a few plugins 21 available to be used. However as an open source project, we now desire 22 users to be able to create, use, and distribute their own plugins. To 23 achieve that goal, we also developped a Jami Plugins SDK. This kit is 24 fully writen in python, and can be invoked running pluginMainSDK.py from 25 ``<plugins>`` folder. To get started you must: 26 27 .. code:: bash 28 29 mkdir jami-plugins && cd jami-plugins 30 git clone https://review.jami.net/ring-daemon daemon 31 git clone https://review.jami.net/jami-plugins plugins 32 cd plugins 33 pip3 install -r SDK/requirements.txt 34 python3 SDK/pluginMainSDK.py 35 36 You will notice that this script will generate a Jami Plugins SDK shell 37 that allows users to: 38 39 - `Create full plugin skeleton <#create-full-plugin-skeleton>`__; 40 - `Create, modify or delete a 41 manifest.json <#create-modify-or-delete-manifest-json>`__; 42 - `Create a package.json <#create-a-package-json>`__; 43 - `Create or delete a preference <#create-or-delete-a-preference>`__; 44 - `Create functionality <#create-functionality>`__; 45 - `Create main <#create-main>`__; 46 - `Assemble files <#assemble-files>`__; 47 - `Build <#build>`__; 48 - `Merge jpls <#merge-jpls>`__. 49 50 Each one of these functionalities will be detailled next. We also will 51 explain the importance of the files it generates and any related SDK 52 limitations. 53 54 Create full plugin skeleton 55 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56 57 This option performs a sequence of actions to properly create all base 58 files needed to start a plugin development. The steps are: 59 60 1. gather authorship information; 61 2. define a plugin name; 62 3. create manifest; 63 4. create functionalities and preferences; 64 5. create main file; 65 6. define basic package.json; 66 7. define basic build files (build.sh and CMakeLists.txt). 67 68 If all is completed successfully, the plugin may be build, installed, 69 and loaded. Also the functionallities may be toggled, however, since 70 their data processes are not implemented, they will perform no action. 71 In our ``HelloWorld`` plugin, we implement a simple process using 72 **OpenCV**. For more complex options, you can refer to our available 73 plugins at 74 `jami-plugins <https://git.jami.net/savoirfairelinux/jami-plugins>`__. 75 Feel free to implement any ideas you may have, but you should respect 76 those constrains: \* use ffmpeg, opencv, and onnx from ring-daemon 77 project; \* if using tensorflow, choose version 2.1.0. Why? \* We have 78 all needed header files of tensorflow 2.1.0 in /contrib/libs.tar.gz; \* 79 We provide docker images with libraries for Tensorflow C++ API and 80 Tensorflow Lite, for both Android and Linux development. \* if you need 81 other libraries, check if we support it’s build with ring-daemon 82 project, otherwise, you will have to build it and ensure correct link to 83 the plugin libraries. 84 85 To fully create a basic plugin with pre-implementation of desired 86 functionalities APIs, preferences, package, manifest, main file, and 87 basic build related files, from inside Jami Plugins SDK shell, the user 88 must call: 89 90 :: 91 92 (Jami Plugins SDK) plugin 93 94 The SDK will ask other informations needed to correctly accomplish the 95 task. 96 97 Create, modify or delete manifest.json 98 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 100 Every plugin must have a manifest. This file contains the official name, 101 a description, and carries the plugin build version as in the example 102 bellow. Without it, the plugin system will not be able to find the 103 plugin library it should load. Due to it’s importance, every time Jami 104 Plugin SDK is told to create files to a non existing plugin or to a 105 plugin with no manifest, it will first create a new manifest. 106 107 .. code:: bash 108 109 { 110 "name": "HelloWorld", 111 "description" : "HelloWorld plugin will guide you throught Jami Plugins SDK use!", 112 "version" : "1.0.0" 113 } 114 115 To create/modify (or to delete) a manifest.json, from inside Jami 116 Plugins SDK shell, the user must call: 117 118 :: 119 120 (Jami Plugins SDK) manifest (-del) 121 122 The SDK will ask other informations needed to correctly accomplish the 123 task. 124 125 Create a package.json 126 ~~~~~~~~~~~~~~~~~~~~~ 127 128 Jami currently supports plugins for GNU/Linux, Android and Windows. For 129 the latter, the build system used is the same as for Jami, it is, we 130 call the plugin build using a python script. This script will look for a 131 ``package.json`` file to aquire build informations and commands. Without 132 this file our build pipeline for Windows will not work. 133 134 An example package.json file is shown bellow. \* ``name`` and 135 ``version`` in the package.json and manifest.json files should match. \* 136 ``extractLibs`` indicates to the build system if the files under 137 ``<jami-plugins>/contrib/libs.tar.gz`` will be used. This archive 138 contains header files for **Tensorflow**. Thus, you only need to set 139 ``extractLibs`` to true if you plan to use this library. \* To play with 140 audio or video, the plugin is dependent of **ffmpeg**. By adding it to 141 ``deps``, the build system will automatically compile this library from 142 ``<ring-daemon>/contrib`` if needed. We also provide **OpenCV** build 143 from inside ``<ring-daemon>/contrib`` ! If you want to use Tensorflow, 144 we provide built libraries for GNU/Linux and Android with our docker 145 images 146 `here <https://hub.docker.com/repository/docker/sflagsantos/tensorflow-cuda>`__ 147 and 148 `here <https://hub.docker.com/repository/docker/sflagsantos/tensorflowlite>`__. 149 For more information about OpenCV and Tensorflow build, please refer to 150 `jami-plugins <plugins>`__ technical documentation. There we have a 151 step-by-step! \* If you’re using cmake, your can set configuration 152 definition in ``defines`` property. Exemple: if your configuration line 153 is of the form ``cmake -DCPU=TRUE ..`` you may set 154 ``"defines": ["CPU=TRUE"]``. \* Any command directly related to the 155 plugin build can be defined inside ``custom_scripts``. Bellow we create 156 the build folder to with the plugins project will be configured with 157 ``mkdir msvc`` and we also set the build command as 158 ``cmake --build ./msvc --config Release``. Our example CMakeLists.txt 159 may have pre and post build instruction that are not listed here. 160 161 .. code:: bash 162 163 { 164 "name": "Hello World", 165 "version": "1.0.0", 166 "extractLibs": false, 167 "deps": [ 168 "ffmpeg" 169 ], 170 "defines": [], 171 "custom_scripts": { 172 "pre_build": [ 173 "mkdir msvc" 174 ], 175 "build": [ 176 "cmake --build ./msvc --config Release" 177 ], 178 "post_build": [] 179 } 180 } 181 182 To create a package.json, from inside Jami Plugins SDK shell, the user 183 must call: 184 185 :: 186 187 (Jami Plugins SDK) package 188 189 The SDK will ask other informations needed to correctly accomplish the 190 task. After the base package.json creation, the user must add or modify 191 any information not previewed by the SDK process. 192 193 Create or delete a preference 194 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 195 196 A preference is a internal variable that will be used upon loading or 197 while running the plugin. There is limited types of preferences 198 supported by the plugin system and each of them must contain generic and 199 specific informations. Those informations must be placed under a certain 200 structure that will form one preference and each preference must be 201 listed inside a ``preference.json`` file. 202 203 The generic properties of a preference are those that must be set by any 204 type of preference: ``category``, ``type``, ``key``, ``title``, 205 ``summary``, ``defaultValue``, and ``scope``. The specific ones are 206 linked to the type of the preference constructed. For ``EDITTEXT`` 207 preferences there is no other property to be set. For ``PATH`` 208 preferences we have: ``mimeType``. For ``LIST`` preferences we have: 209 ``entries`` and ``entryValues``. A ``LIST`` preference must have a list 210 of possible values to be used and a list of ‘names’ for these values. 211 For example: If you have two ``entriesValues``: ‘0’ and ‘1’, these 212 values may not be understandable by the user. Jami’s UI will take the 213 values from ``entries`` to be shown as ‘names’ for each one of these 214 ``entryValues``. Then you can call ‘0’ and ‘1’ as ‘sent’ and ‘received’. 215 The UI will show these names that are more user friendly! It is 216 important to note that ``entries`` and ``entryValues`` must have the 217 same number of items. 218 219 Another important point to be noted for the preferences is that their 220 values could be modified during runtime if, and only if, two conditions 221 are satisfied: 222 223 1. the code that applies the new value is within your functionality 224 implementation and; 225 2. this functionality is listed in the preference’s ``scope`` property. 226 227 To better explain, we have to detail what is a scope and how a 228 preference changement is implemented inside the plugin. 229 230 - **Scope**: A scope is a list of functionalities that can modify a 231 preference value even if the functionality is under use. It is, 232 imagine you have a functionality called “Circle” that prints a 233 colored circle to your video. Consider also that the color of that 234 circle is set by a preference and that this preference lists “Circle” 235 as one of it’s scopes. In that scenario “Circle” will be able to 236 modify the default circle color to another one. 237 - **Code implementation**: Continuing our example above, “Circle” also 238 is the implementation of an abstract API class from Daemon (for more 239 details check `#Create functionality <#create-functionality>`__. When 240 a user changes a preference value, the plugin system will call the 241 ``setPreferenceAttribute`` implementation for each of the 242 functionalities listed by the preference’s scope. By it’s turn, this 243 function will match the preference unique ``key`` and call an 244 internal function to apply the new value. 245 246 For a pratical example, you can check the ‘Foreground Segmentation’ 247 functionality of the GreenScreen plugin - 248 `pluginMediaHandler.cpp <https://git.jami.net/savoirfairelinux/jami-plugins/blob/master/GreenScreen/pluginMediaHandler.cpp>`__ 249 and 250 `preferences-onnx.json <https://git.jami.net/savoirfairelinux/jami-plugins/blob/master/GreenScreen/preferences-onnx.json>`__. 251 This plugin has both ``LIST`` and ``PATH`` preferences and also has one 252 preference that can be modified during runtime. Can you tell wich one? 253 254 To create (or delete) a preference, from inside Jami Plugins SDK shell, 255 the user must call: 256 257 :: 258 259 (Jami Plugins SDK) preference (-del) 260 261 The SDK will ask other informations needed to correctly accomplish the 262 task. If a preference is created from outside a functionality creation 263 pipeline, any API implementation will not be changed in order to avoid 264 overwrittings. Thus, if you want to allow values changement during 265 runtime, you may need to manually modify your functionality 266 implementation to fit running time changements conditions. 267 268 Create functionality 269 ~~~~~~~~~~~~~~~~~~~~ 270 271 A Jami plugin may wrap one or multiple functionalities. It is, the same 272 plugins may have a functionality to change background and to draw a 273 circle to a video for example. Each functionality must implement an 274 abstract API class defined by Jami plugins System. That way, we can say 275 that one functionality is one implementation of an API. Currently we 276 have the ``MediaHandler`` which allows access to audio or video frames 277 and we have ``ChatHandler`` which allows acces to messages exchanged in 278 a conversation. 279 280 When defining a new a functionality, the SDK will create basic header 281 and cpp files for you work on. However, your new functionality can not 282 be added to the scopes of a previously existing preference. For more 283 information, please refer to `Create or delete a 284 preference <#create-or-delete-a-preference>`__. 285 286 To create a functionality, from inside Jami Plugins SDK shell, the user 287 must call: 288 289 :: 290 291 (Jami Plugins SDK) functionality 292 293 The SDK will ask other informations needed to correctly accomplish the 294 task. 295 296 Create main 297 ~~~~~~~~~~~ 298 299 This option create plugin’s ``main.cpp``. A file that implements the 300 plugin external loading function that Jami Plugin System will call to 301 initialize and register all functionalities for latter use. 302 303 The SDK is set to rewrite the main file every time you create a new 304 functionality. Thus, if you want to manually create or delete a 305 functionality, we recomend calling this option instead. 306 307 To create a ``main.cpp``, from inside Jami Plugins SDK shell, the user 308 must call: 309 310 :: 311 312 (Jami Plugins SDK) main 313 314 The SDK will ask other informations needed to correctly accomplish the 315 task. 316 317 Assemble files 318 ~~~~~~~~~~~~~~ 319 320 The final plugin file is an archive compressed to a ``JPL`` format. This 321 archive contains libraries, manifest.json, preferences.json, icons and 322 other custom important files for your plugin. OBS.: files added by the 323 developper must be organized under the ``data/`` folder. 324 325 The SDK assemble option has two different behaviours: 326 327 - it creates a build folder and copies there all files that will be 328 compressed to the final plugin archive. For linux host: 329 ``<plugins>/<HelloWorld>/build-local/jpl/`` and for a windows host: 330 ``<plugins>/<HelloWorld>/msvc/jpl/``; 331 - it compresses all files inside the build folder to the jpl archive 332 wich is output under ``<plugins>/build``. 333 334 Both process should be called from inside the CMakeLists.txt as 335 POST_BUILD and PRE_BUILD commands, respectively. Also, the build.sh 336 script should call them. For more information about CMakeLists.txt and 337 build.sh files, please refere to `build <#build>`__ and to our available 338 plugins at 339 `jami-plugins <https://git.jami.net/savoirfairelinux/jami-plugins>`__. 340 341 To create a build folder and copy all important files there, from inside 342 Jami Plugins SDK shell, the user must call: 343 344 :: 345 346 (Jami Plugins SDK) assemble -pre 347 348 To compress all assembled to a jpl archive, from inside Jami Plugins SDK 349 shell, the user must call: 350 351 :: 352 353 (Jami Plugins SDK) assemble 354 355 The SDK will ask other informations needed to correctly accomplish the 356 task. 357 358 Build 359 ~~~~~ 360 361 The SDK build option has two different behaviours: 362 363 - it creates basic CMakeLists.txt and buils.sh files; 364 - it build the plugin library with default options defined at the files 365 mentioned above. 366 367 A description of thes CMakeLists.txt and buils.sh files are found 368 further in this section. 369 370 To create basic CMakeLists.txt and buils.sh files, from inside Jami 371 Plugins SDK shell, the user must call: 372 373 :: 374 375 (Jami Plugins SDK) build -def 376 377 To build plugin library with default configuration, from inside Jami 378 Plugins SDK shell, the user must call: 379 380 :: 381 382 (Jami Plugins SDK) build 383 384 The SDK will ask other informations needed to correctly accomplish the 385 task. For the moment, the build option does not support 386 cross-compilation neither non default builds. If you have build 387 variables to be set differently than the default option, please directly 388 use the ``<plugins>/build-plugin.py`` script. 389 390 CMakeLists.txt 391 ^^^^^^^^^^^^^^ 392 393 This file is used only by Jami’s Windows build pipeline. 394 395 If you need to pass any defines to cmake generation, your definitions 396 can be in ``package.json`` as explained in the package section. The 397 package.json created specifies the default configuration that calling 398 the build from Jami Plugins SDK will consider. If you want to build with 399 no default configuration, you can: directly use the script mentioned 400 above and pass non-default definitions as an argument or; you also can 401 manually change your package.json file. For examples, you can refer to 402 our available plugins at 403 `jami-plugins <https://git.jami.net/savoirfairelinux/jami-plugins>`__. 404 405 Another important information about CMakeLists.txt is that it has to add 406 custom commands. For PRE_BUILD, it must call the pre-assemble 407 functionality process. For POST_BUILD, it must copy the built library to 408 the build folder and call the assemble functionality process. In the 409 end, your jpl archive may be found under ``<plugins>/build``. The 410 CMakeLists.txt file automatically created by our SDK, already respects 411 these constraints. 412 413 build.sh 414 ^^^^^^^^ 415 416 This file is used by Jami to build plugins for GNU/Linux and Android 417 platforms. 418 419 The basic script consider the environment variable ``DAEMON`` that must 420 point to the ring-daemon folder. Besides, you can pass an argument for 421 the platform used like ``-t android`` if you want to cross-compile for 422 Android. Further custom definitions and environment variables should be 423 handled by the plugin developper. If you want to build with no default 424 configuration, you can modify the environment variables values and then 425 call the build. Ie: for android, you can set which ABI you want to build 426 with ``export ANDROID_ABI="arm64-v8a armeabi-v7a``. For other examples, 427 you can refer to our `technical 428 documentation <https://git.jami.net/savoirfairelinux/ring-project/wikis/technical/7.-Jami-plugins>`__ 429 and to our `available 430 plugins <https://git.jami.net/savoirfairelinux/jami-plugins>`__. 431 432 Another important information about build.sh is that it has to call pre 433 and post assemble. Before the build, it must call the pre-assemble 434 functionality process. After it, it must copy the built library to the 435 build folder and call the assemble functionality process. In the end, 436 your jpl archive may be found under ``<plugins>/build``. The build.sh 437 file automatically created by our SDK, already respects these 438 constraints. 439 440 Merge jpls 441 ~~~~~~~~~~ 442 443 If you have more than one jpl archives, like one build for Android and 444 anothe for GNU/Linux platforms, you can merge them into one to easy it’s 445 distribution. However, you should know that merging two or more jpls may 446 inccur orverwritting some of the files inside them if they are not equal 447 for all archives. The only files that may not present conflicting 448 contents are the ones that do not repeate themselves. If conflicts 449 occur, files from the first jpl in the arguments will prevail over the 450 others. 451 452 To merge two or more jpls, from inside Jami Plugins SDK shell, the user 453 must simple call: 454 455 :: 456 457 (Jami Plugins SDK) merge 458 459 The SDK will ask other informations needed to correctly accomplish the 460 task. 461 462 Create my first plugin 463 ---------------------- 464 465 Through this section we will present a step-by-step construction of a 466 ``HelloWorld`` plugin using our SDK. Our goal is to print a coloured 467 circle in the midle of the video frames using **OpenCV**. The color of 468 that circle will be defined by a preference which will be changeable 469 during runtime. Also we can set a stream preferece to define if the 470 plugin will modify the video sent or the one received, this time we 471 don’t want to allow a changement during runtime. We can define a second 472 functionality that will aways draw a circle in the right top corner, 473 with the color defined by the same preference as the previous 474 functionality but that cannot be changed during runtime. At the end we 475 will exemplify how to build your plugin with and without the SDK. 476 477 Step 1 - prepare developpment environment 478 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 480 The first step towards plugin development is to properly prepare the 481 environment. 482 483 .. code:: bash 484 485 mkdir jami-plugins && cd jami-plugins 486 git clone https://review.jami.net/ring-daemon daemon 487 git clone https://review.jami.net/jami-plugins plugins 488 cd plugins 489 pip3 install -r SDK/requirements.txt 490 491 Step 2 - create HelloWorld with one functionality 492 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 494 - Use Jami Plugins SDK to create the plugin skeleton 495 496 .. code:: python 497 498 python3 SDK/pluginMainSDK.py 499 500 .. 501 502 (Jami Plugins SDK) plugin 503 504 Tell us who you are? 505 506 .. 507 508 What’s your name? Aline Gondim Santos 509 510 What’s your e-mail? aline.gondimsantos@savoirfairelinux.com 511 512 .. 513 514 Leave Empty or Press ‘q’ to quit this option. 515 516 Now, you need to tell how you want yout plugin to be called. 517 518 .. 519 520 Choose a cool name for your plugin: Hello World 521 522 Nice! Your HelloWorld will be awesome! 523 524 .. 525 526 Defining a manifest for “HelloWorld” plugin, we gonna need more 527 information.. 528 529 Press ‘q’ to quit this option. 530 531 .. 532 533 Tell us a description: HelloWorld draws a circle in the center of a 534 call’s video 535 536 Version must be of the form X.Y.Z Set plugin version (default 0.0.0): 537 1.0.0 538 539 .. 540 541 Chose a functionality name: CenterCircle 542 543 Choose a API for functionality “CenterCircle”. 544 545 .. 546 547 Available APIs: (1) video during a call (Media Handler API) (2) audio 548 during a call (Media Handler API) (3) chat messages (Chat Handler 549 API) For more information about the API, call help preferences. 550 551 Enter a data type number: 1 552 553 .. 554 555 Add another functionaliy? [y/N] 556 557 Would you like to add a preference? [y/n] y 558 559 .. 560 561 Your preferences options available are: (0) List; (1) Path; (2) 562 EditText; 563 564 Which preference type do you choose: 0 Type a value for category: 565 stream Type a value for key: videostream Type a value for title: 566 Video stream Type a value for summary: select a video direction Type 567 a value for defaultValue: 0 568 569 .. 570 571 Would you like to add a scope? [y/n] n 572 573 Do you want to add a new entry Value? [y/n] y Type one new entry: 0 574 575 .. 576 577 Do you want to add a new entry Value? [y/n] y Type one new entry: 1 578 579 Do you want to add a new entry Value? [y/n] n Type an entry name for 580 ‘0’: sent Type an entry name for ‘1’: received 581 582 .. 583 584 Would you like to add a preference? [y/n] y 585 586 Your preferences options available are: (0) List; (1) Path; (3) 587 EditText; 588 589 .. 590 591 Which preference type do you choose: 0 Type a value for category: 592 color Type a value for key: color Type a value for title: Circle 593 color Type a value for summary: select a color Type a value for 594 defaultValue: ##00FF00 595 596 Would you like to add a scope? [y/n] y 597 598 .. 599 600 Possible values for scope: (0) centerCircle; 601 602 Which scope do you choose: 0 603 604 .. 605 606 Do you want to add a new entry Value? [y/n] y Type one new entry: 607 #0000FF 608 609 Do you want to add a new entry Value? [y/n] y Type one new entry: 610 #00FF00 611 612 .. 613 614 Do you want to add a new entry Value? [y/n] y Type one new entry: 615 #FF0000 616 617 Do you want to add a new entry Value? [y/n] n Type an entry name for 618 ‘#0000FF’: blue Type an entry name for ‘#00FF00’: green Type an entry 619 name for ‘#FF0000’: red 620 621 .. 622 623 Would you like to add a preference? [y/n] n 624 625 The preference Circle color will be changeable during running time 626 for centerCircle functionality? [y/n] y 627 628 .. 629 630 Package ok. 631 632 CMakeLists.txt and build.sh ok. 633 634 - modify CenterCircleMediaHandler.cpp, CenterCircleVideoSubscriver.h, 635 CenterCircleVideoSubscriber.cpp; 636 - You will need to modify package.json, CMakeLists.txt and build.sh to 637 add OpenCV dependencies. 638 639 All final files can be found 640 `here <https://git.jami.net/savoirfairelinux/jami-plugins>`__ 641 642 Step 3 - build 643 ~~~~~~~~~~~~~~ 644 645 Before building the HelloWorld, you should compile ffmpeg and OpenCV 646 dependencies. This can be achieved by following the build instructions 647 for OpenCV `here <plugins>`__. Ffmpeg will be automatically build if you 648 follow those instructions. To build you plugin, you can either: \* Call 649 the build from Jami Plugins SDK (works for GNU/Linux and Windows): 650 651 .. code:: python 652 653 python3 SDK/pluginMainSDK.py 654 655 .. 656 657 (Jami Plugins SDK) build 658 659 Leave Empty or Press ‘q’ to quit this option. 660 661 .. 662 663 Plugin to pass build related step: HelloWorld 664 665 DAEMON not provided, building with ./../../daemon 666 667 - Call plugin-build.py script (works for GNU/Linux, Windows and 668 Android): 669 670 - GNU/Linux or Windows: > python3 build-plugin.py –projects=HelloWorld 671 672 - Android: > python3 build-plugin.py –projects=HelloWorld 673 –distribution=android 674 675 OBS: For Android, you can set ``ANDROID_ABI`` environment variable to 676 the ABI you want to build. Currently Jami supports ``x86_64``, 677 ``armeabi-v7a``, and ``arm64-v8a``. Plugins will be build for the three 678 options by default. 679 680 Step 4 - create another functionality for HelloWorld and rebuild 681 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 682 683 Now that you tested and your HelloWorld is working, you can try to do 684 add another functionality to it. 685 686 .. code:: python 687 688 python3 SDK/pluginMainSDK.py 689 690 .. 691 692 (Jami Plugins SDK) functionality 693 694 Tell us who you are? 695 696 .. 697 698 What’s your name? Aline Gondim Santos 699 700 What’s your e-mail? aline.gondimsantos@savoirfairelinux.com 701 702 .. 703 704 Leave Empty or Press ‘q’ to quit this option. 705 706 Plugin to be modified or created: HelloWorld 707 708 .. 709 710 Chose a functionality name: CoinCircle 711 712 Choose a API for functionality “CoinCircle”. 713 714 .. 715 716 Available APIs: (1) video during a call (Media Handler API) (2) audio 717 during a call (Media Handler API) (3) chat messages (Chat Handler 718 API) For more information about the API, call help preferences. 719 720 Enter a data type number: 1 721 722 .. 723 724 Add another functionaliy? [y/N] n 725 726 Would you like to add a preference? [y/n] n 727 728 .. 729 730 CMakeLists.txt and build.sh ok. 731 732 Again, all code modifications are available 733 `here <https://git.jami.net/savoirfairelinux/jami-plugins>`__ 734 735 Optionally, you can change your plugin version and description: 736 737 .. code:: python 738 739 python3 SDK/pluginMainSDK.py 740 741 .. 742 743 (Jami Plugins SDK) manifest Leave Empty or Press ‘q’ to quit this 744 option. 745 746 Plugin to be modified or created: HelloWorld New description for your 747 plugin (ignore to keep previous description): HelloWorld can draw a 748 circle at the center or at the top-left of a call’s video New plugin 749 version (ignore to keep previous version): 2.0 750 751 Finally, you can rebuild the plugin using the same steps as before! 752 753 Now you can start your own creations! Do not forget to tag Jami or 754 Savoir-Faire Linux in your repository, this way we can get to know how 755 the community is developping their own plugins!