├── .gitignore ├── package.json ├── .idea ├── derweili-fb-chat-plugin.iml ├── modules.xml └── workspace.xml ├── .editorconfig ├── .distignore ├── readme.txt ├── Gruntfile.js ├── assets ├── css │ └── derweili-chat-plugin.css └── js │ └── derweili-chat-plugin.js └── derweili-fb-chat-plugin.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | phpcs.xml 3 | phpunit.xml 4 | Thumbs.db 5 | wp-cli.local.yml 6 | node_modules/ 7 | *.sql 8 | *.tar.gz 9 | *.zip 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "derweili-fb-chat-plugin", 4 | "version": "0.1.0", 5 | "main": "Gruntfile.js", 6 | "author": "derweili", 7 | "devDependencies": { 8 | "grunt": "~0.4.5", 9 | "grunt-wp-i18n": "~0.5.0", 10 | "grunt-wp-readme-to-markdown": "~1.0.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.idea/derweili-fb-chat-plugin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # WordPress Coding Standards 5 | # https://make.wordpress.org/core/handbook/coding-standards/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | indent_style = tab 15 | indent_size = 4 16 | 17 | [{.jshintrc,*.json,*.yml}] 18 | indent_style = space 19 | indent_size = 2 20 | 21 | [{*.txt,wp-config-sample.php}] 22 | end_of_line = crlf 23 | -------------------------------------------------------------------------------- /.distignore: -------------------------------------------------------------------------------- 1 | # A set of files you probably don't want in your WordPress.org distribution 2 | .distignore 3 | .editorconfig 4 | .git 5 | .gitignore 6 | .gitlab-ci.yml 7 | .travis.yml 8 | .DS_Store 9 | Thumbs.db 10 | behat.yml 11 | bin 12 | circle.yml 13 | composer.json 14 | composer.lock 15 | Gruntfile.js 16 | package.json 17 | package-lock.json 18 | phpunit.xml 19 | phpunit.xml.dist 20 | multisite.xml 21 | multisite.xml.dist 22 | phpcs.xml 23 | phpcs.xml.dist 24 | README.md 25 | wp-cli.local.yml 26 | yarn.lock 27 | tests 28 | vendor 29 | node_modules 30 | *.sql 31 | *.tar.gz 32 | *.zip 33 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Facebook Chat Opt-In === 2 | Contributors: derweili 3 | Donate link: https://example.com/ 4 | Tags: sp 5 | Requires at least: 4.4 6 | Tested up to: 4.9.4 7 | Stable tag: 0.1.0 8 | License: GPLv2 or later 9 | License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 | 11 | Here is a short description of the plugin. This should be no more than 150 characters. No markup here. 12 | 13 | == Description == 14 | 15 | This plugin implements the Facebook Chat with an Opt-In Function to comply with German law. 16 | https://developers.facebook.com/docs/messenger-platform/discovery/customer-chat-plugin 17 | 18 | 19 | 20 | == Installation == 21 | 22 | 1. Upload `derweili-fb-chat-plugin.php` to the `/wp-content/plugins/` directory 23 | 2. Activate the plugin through the 'Plugins' menu in WordPress 24 | 3. Go to Customizer and add your Facebook APP ID and your Facebook Page ID 25 | 26 | == Frequently Asked Questions == 27 | 28 | = Where do I find more Information about the Facebook Chat = 29 | 30 | An answer to that question. 31 | 32 | = What about foo bar? = 33 | 34 | https://developers.facebook.com/docs/messenger-platform/discovery/customer-chat-plugin 35 | 36 | == Screenshots == 37 | 38 | 39 | 40 | == Changelog == 41 | 42 | = 0.1 = 43 | * First plugin version 44 | 45 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function( grunt ) { 2 | 3 | 'use strict'; 4 | 5 | // Project configuration 6 | grunt.initConfig( { 7 | 8 | pkg: grunt.file.readJSON( 'package.json' ), 9 | 10 | addtextdomain: { 11 | options: { 12 | textdomain: 'derweili-fb-chat-plugin', 13 | }, 14 | update_all_domains: { 15 | options: { 16 | updateDomains: true 17 | }, 18 | src: [ '*.php', '**/*.php', '!\.git/**/*', '!bin/**/*', '!node_modules/**/*', '!tests/**/*' ] 19 | } 20 | }, 21 | 22 | wp_readme_to_markdown: { 23 | your_target: { 24 | files: { 25 | 'README.md': 'readme.txt' 26 | } 27 | }, 28 | }, 29 | 30 | makepot: { 31 | target: { 32 | options: { 33 | domainPath: '/languages', 34 | exclude: [ '\.git/*', 'bin/*', 'node_modules/*', 'tests/*' ], 35 | mainFile: 'derweili-fb-chat-plugin.php', 36 | potFilename: 'derweili-fb-chat-plugin.pot', 37 | potHeaders: { 38 | poedit: true, 39 | 'x-poedit-keywordslist': true 40 | }, 41 | type: 'wp-plugin', 42 | updateTimestamp: true 43 | } 44 | } 45 | }, 46 | } ); 47 | 48 | grunt.loadNpmTasks( 'grunt-wp-i18n' ); 49 | grunt.loadNpmTasks( 'grunt-wp-readme-to-markdown' ); 50 | grunt.registerTask( 'default', [ 'i18n','readme' ] ); 51 | grunt.registerTask( 'i18n', ['addtextdomain', 'makepot'] ); 52 | grunt.registerTask( 'readme', ['wp_readme_to_markdown'] ); 53 | 54 | grunt.util.linefeed = '\n'; 55 | 56 | }; 57 | -------------------------------------------------------------------------------- /assets/css/derweili-chat-plugin.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Fake messenger icon 3 | */ 4 | #derweili-fb-chat-icon{ 5 | width: 60px; 6 | height: 60px; 7 | border-radius: 50%; 8 | /*background-color: rgb(0, 132, 255);*/ 9 | background-color: rgba(46, 157, 255, 0.51); 10 | display: block; 11 | position: fixed; 12 | z-index: 99999; 13 | bottom: 24px; 14 | right: 24px; 15 | -webkit-box-shadow: 0 8px 10px 1px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.3); 16 | box-shadow: 0 8px 10px 1px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.3); 17 | cursor: pointer; 18 | } 19 | 20 | #derweili-fb-chat-opt-in-message{ 21 | display: none; 22 | width: 100%; 23 | width: calc(100% - 20px); 24 | max-width: 300px; 25 | position: fixed; 26 | bottom: 108px; 27 | right: 24px; 28 | background-color: white; 29 | z-index: 99999; 30 | -webkit-box-shadow: 0 8px 10px 1px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.3); 31 | box-shadow: 0 8px 10px 1px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.3); 32 | border-radius: 3px; 33 | 34 | } 35 | 36 | #derweili-fb-chat-opt-in-message.active{ 37 | display: block; 38 | } 39 | 40 | #derweili-fb-chat-opt-in-message .inner{ 41 | padding: 20px; 42 | } 43 | 44 | #derweili-fb-chat-opt-in-message a { 45 | text-align: center; 46 | display: block; 47 | font-size: 0.8em; 48 | } 49 | 50 | /* Accept Button Style */ 51 | #derweili-fb-chat-opt-in-message .button{ 52 | -webkit-box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.3); 53 | box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.3); 54 | padding: 10px 10px; 55 | background: #4267b2; 56 | text-align: center; 57 | color: white; 58 | border-radius: 3px; 59 | margin-bottom: 10px; 60 | font-size: 1em; 61 | cursor: pointer; 62 | } 63 | 64 | #derweili-fb-chat-opt-in-message .close { 65 | position: absolute; 66 | top: 18px; 67 | right: 20px; 68 | width: 15px; 69 | cursor: pointer; 70 | } 71 | .derweili-fb-hidden { 72 | 73 | } 74 | 75 | /* 76 | * Chrome auto scroll-down bugfix 77 | * https://stackoverflow.com/questions/47959861/facebook-customer-chat-plugin-auto-scroll-to-bottom 78 | */ 79 | .fb_dialog, .fb_reset {position: fixed !important;z-index: 10000 !important;} -------------------------------------------------------------------------------- /assets/js/derweili-chat-plugin.js: -------------------------------------------------------------------------------- 1 | (function($){ 2 | 3 | var $chatIcon = $('#derweili-fb-chat-icon'), 4 | $optInMessage = $('#derweili-fb-chat-opt-in-message'), 5 | $acceptButton = $($optInMessage).find('#accept'), 6 | $closeButton = $($optInMessage).find('.close'), 7 | $optOutLink = $('.derweili-fb-opt-out-link'), 8 | appId = $($optInMessage).attr('data-app-id'), 9 | cookieName = $($optInMessage).attr('data-cookie-name'); 10 | console.log('cookie name', cookieName); 11 | 12 | console.log($chatIcon); 13 | 14 | $($chatIcon).on('click', function(e){ 15 | e.preventDefault(); 16 | $optInMessage.toggleClass('active'); 17 | }); 18 | $($closeButton).on('click', function(e){ 19 | e.preventDefault(); 20 | $optInMessage.toggleClass('active'); 21 | }); 22 | 23 | 24 | $($acceptButton).on('click', function(e){ 25 | e.preventDefault(); 26 | loadFbStuff(); 27 | hideOptInStuff(); 28 | setCookieOptInCookie(); 29 | }) 30 | 31 | 32 | function loadFbStuff(){ 33 | console.log('loadFbStuff'); 34 | window.fbAsyncInit = function() { 35 | console.log('fbAsyncInit'); 36 | FB.init({ 37 | appId : appId, 38 | autoLogAppEvents : true, 39 | xfbml : true, 40 | version : 'v2.12' 41 | }); 42 | }; 43 | (function(d, s, id){ 44 | var js, fjs = d.getElementsByTagName(s)[0]; 45 | if (d.getElementById(id)) {return;} 46 | js = d.createElement(s); js.id = id; 47 | js.src = "https://connect.facebook.net/de_DE/sdk.js"; 48 | fjs.parentNode.insertBefore(js, fjs); 49 | }(document, 'script', 'facebook-jssdk')); 50 | 51 | 52 | } 53 | 1 54 | function setCookieOptInCookie() 55 | { 56 | var expires = new Date(); 57 | expires.setTime(expires.getTime() + (1 * 24 * 60 * 60 * 1000)); 58 | 59 | var value = 1; 60 | 61 | document.cookie = cookieName + '=' + value +';path=/'+ ';expires=' + expires.toUTCString(); 62 | } 63 | 64 | function hideOptInStuff(){ 65 | $optInMessage.fadeOut('200'); 66 | $chatIcon.fadeOut('200'); 67 | } 68 | 69 | // opt out link 70 | $optOutLink.on('click', function(e){ 71 | console.log('opt-out'); 72 | 73 | var cookieName = $(this).attr('data-cookie-name'); 74 | 75 | e.preventDefault(); 76 | 77 | var expires = new Date(); 78 | expires.setTime(expires.getTime() + (1 * 24 * 60 * 60 * 1000)); 79 | 80 | var value = 0; 81 | 82 | document.cookie = cookieName + '=' + value +';path=/'+ ';expires=' + expires.toUTCString(); 83 | }); 84 | 85 | 86 | 87 | 88 | 89 | 90 | })(jQuery); 91 | -------------------------------------------------------------------------------- /derweili-fb-chat-plugin.php: -------------------------------------------------------------------------------- 1 | version; 40 | } 41 | 42 | public function get_slug(){ 43 | return $this->slug; 44 | } 45 | 46 | public function run(){ 47 | 48 | $this->load_dependencies(); 49 | 50 | 51 | 52 | } 53 | 54 | private function load_dependencies(){ 55 | 56 | add_action('wp_enqueue_scripts', array(&$this, 'enqueue_scripts') ); 57 | add_action('wp_head', array(&$this, 'load_fb_code'), 10000); 58 | add_action('customize_register',array(&$this, 'register_customizer_settings')); 59 | 60 | } 61 | 62 | 63 | public function enqueue_scripts(){ 64 | 65 | wp_enqueue_script( 'derweili_fb_chat_plugin', plugin_dir_url($this->plugin_dir) . 'assets/js/derweili-chat-plugin.js', array('jquery'), '0.1', true ); 66 | wp_enqueue_style( 'derweili_fb_chat_plugin', plugin_dir_url($this->plugin_dir) . 'assets/css/derweili-chat-plugin.css', [], '0.1' ); 67 | 68 | } 69 | 70 | private function is_cookie_set(){ 71 | return isset( $_COOKIE[Derweili_FB_Chat_Plugin::$cookie_name] ) && $_COOKIE[Derweili_FB_Chat_Plugin::$cookie_name]; 72 | } 73 | 74 | 75 | public function load_fb_code(){ 76 | 77 | if( ! get_theme_mod('derweili_fb_chat_app_id', null) || ! get_theme_mod('derweili_fb_chat_page_id', null) ) return; 78 | 79 | if( $this->is_cookie_set() ): 80 | 81 | ?> 82 | 83 | 101 | 102 | 105 | 106 |
107 | 108 | 109 |
110 | 111 |
112 |
113 |
114 |

115 | 116 |

117 |
118 | 119 | 120 | 121 | 122 | 123 | 124 |
125 |
126 |
127 |
128 |
129 | 130 | 131 | 132 | 135 | 136 |
140 | logged_in_greeting="" 141 | 142 | 143 | logged_out_greeting="" 144 | 145 | > 146 |
147 | 148 | " . $content . ""; 156 | 157 | } 158 | 159 | 160 | 161 | public function register_customizer_settings($wp_customize){ 162 | 163 | 164 | $wp_customize->add_section( 'derweili_fb_chat_settings_section', array( 165 | 'title' => __( 'Facebook Chat Settings' ), 166 | 'priority' => 100, 167 | ) ); 168 | 169 | $wp_customize->add_setting( 170 | 'derweili_fb_chat_app_id', 171 | array( 172 | 'default' => '', 173 | 'transport' => 'refresh' 174 | ) 175 | ); 176 | $wp_customize->add_setting( 177 | 'derweili_fb_chat_page_id', 178 | array( 179 | 'default' => '', 180 | 'transport' => 'refresh' 181 | ) 182 | ); 183 | $wp_customize->add_setting( 184 | 'derweili_fb_chat_theme_color', 185 | array( 186 | 'default' => '', 187 | 'transport' => 'refresh' 188 | ) 189 | ); 190 | $wp_customize->add_setting( 191 | 'derweili_fb_chat_logged_in_greeting', 192 | array( 193 | 'default' => '', 194 | 'transport' => 'refresh' 195 | ) 196 | ); 197 | $wp_customize->add_setting( 198 | 'derweili_fb_chat_logged_out_greeting', 199 | array( 200 | 'default' => '', 201 | 'transport' => 'refresh' 202 | ) 203 | ); 204 | $wp_customize->add_setting( 205 | 'derweili_fb_chat_infotext_headline', 206 | array( 207 | 'default' => '', 208 | 'transport' => 'refresh' 209 | ) 210 | ); 211 | $wp_customize->add_setting( 212 | 'derweili_fb_chat_infotext', 213 | array( 214 | 'default' => '', 215 | 'transport' => 'refresh' 216 | ) 217 | ); 218 | $wp_customize->add_setting( 219 | 'derweili_fb_chat_privacy_link', 220 | array( 221 | 'default' => '', 222 | 'transport' => 'refresh' 223 | ) 224 | ); 225 | 226 | $wp_customize->add_setting( 227 | 'derweili_fb_chat_start_chat_button_text', 228 | array( 229 | 'default' => 'Start chat', 230 | 'transport' => 'refresh' 231 | ) 232 | ); 233 | 234 | $wp_customize->add_setting( 235 | 'derweili_fb_chat_privacy_policy_link', 236 | array( 237 | 'default' => __('Privacy Policy'), 238 | 'transport' => 'refresh' 239 | ) 240 | ); 241 | 242 | $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'derweili_fb_chat_app_id', array( 243 | 'label' => __('Facebook App ID'), 244 | 'section' => 'derweili_fb_chat_settings_section', 245 | 'settings' => 'derweili_fb_chat_app_id', 246 | ) ) ); 247 | 248 | 249 | $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'derweili_fb_chat_page_id', array( 250 | 'label' => __('Page ID'), 251 | 'section' => 'derweili_fb_chat_settings_section', 252 | 'settings' => 'derweili_fb_chat_page_id', 253 | ) ) ); 254 | 255 | 256 | $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'derweili_fb_chat_theme_color', array( 257 | 'label' => __('Theme Color'), 258 | 'section' => 'derweili_fb_chat_settings_section', 259 | 'settings' => 'derweili_fb_chat_theme_color', 260 | ) ) ); 261 | 262 | 263 | $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'derweili_fb_chat_logged_in_greeting', array( 264 | 'label' => __('Logged in greeting'), 265 | 'section' => 'derweili_fb_chat_settings_section', 266 | 'settings' => 'derweili_fb_chat_logged_in_greeting', 267 | ) ) ); 268 | 269 | $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'derweili_fb_chat_logged_out_greeting', array( 270 | 'label' => __('Logged out greeting'), 271 | 'section' => 'derweili_fb_chat_settings_section', 272 | 'settings' => 'derweili_fb_chat_logged_out_greeting', 273 | ) ) ); 274 | 275 | 276 | $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'derweili_fb_chat_infotext_headline', array( 277 | 'label' => __('Infotext Headline'), 278 | 'section' => 'derweili_fb_chat_settings_section', 279 | 'settings' => 'derweili_fb_chat_infotext_headline', 280 | ) ) ); 281 | 282 | $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'derweili_fb_chat_start_chat_button_text', array( 283 | 'label' => __('Start chat button text'), 284 | 'section' => 'derweili_fb_chat_settings_section', 285 | 'settings' => 'derweili_fb_chat_start_chat_button_text', 286 | ) ) ); 287 | 288 | 289 | 290 | 291 | $wp_customize->add_control( 'derweili_fb_chat_infotext', array( 292 | 'type' => 'textarea', 293 | 'priority' => 10, // Within the section. 294 | 'section' => 'derweili_fb_chat_settings_section', // Required, core or custom. 295 | 'label' => __( 'Infotext' ), 296 | // 'description' => __( 'This is a date control with a red border.' ), 297 | 'setting' => 'derweili_fb_chat_infotext' 298 | ) ); 299 | 300 | 301 | $wp_customize->add_control( 'derweili_fb_chat_privacy_link', array( 302 | 'type' => 'dropdown-pages', 303 | 'priority' => 10, // Within the section. 304 | 'section' => 'derweili_fb_chat_settings_section', // Required, core or custom. 305 | 'label' => __( 'Privacy Link' ), 306 | // 'description' => __( 'This is a date control with a red border.' ), 307 | 'setting' => 'derweili_fb_chat_privacy_link' 308 | ) ); 309 | 310 | 311 | $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'derweili_fb_chat_privacy_policy_link', array( 312 | 'label' => __('Privacy Policy Linktext'), 313 | 'section' => 'derweili_fb_chat_settings_section', 314 | 'settings' => 'derweili_fb_chat_privacy_policy_link', 315 | ) ) ); 316 | 317 | } 318 | 319 | 320 | 321 | 322 | } 323 | 324 | $chat_plugin = new Derweili_FB_Chat_Plugin(); 325 | $chat_plugin->run(); 326 | 327 | 328 | add_shortcode( 'fb-chat-plugin', array( 'Derweili_FB_Chat_Plugin', 'opt_out_cookie' ) ); -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | $cookie_name 103 | cookie_name 104 | 105 | 106 | 107 | 108 | 109 | 110 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | true 125 | DEFINITION_ORDER 126 | 127 | 128 | 129 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |