Jump to content


Most Liked Content


#10513 X2CRM 5.2 Summer Release Roadmap

Posted by John Roberts on 01 July 2015 - 02:22 PM

Hello X2CRM Community,

 

With X2CRM 5.0 release this past December we have been spending most of 2015 working on fine tuning X2 with a number of small releases ending with 5.0.9. On the side we have been working on our next functional enhancement release, X2CRM 5.2 scheduled for release at the end of July or the first week of August. It is likely we will follow 5.2 with 5.3 in September including additional mostly calendar focused enhancements. We will be sending out newsletters and such with more detail, until then here is high level list of the features planned for 5.2-3 later this month. 

 

X2CRM 5.2 - End of July Release

X2Flow Macros Buttons on Detail Records - so user can activate an X2Flow on a record 

Topics Discussion Board, extension of Activity Feed

- Themes - Color Coded Modules
- Major Module Detail View UI Update 
- Calendar Enhancements  
- Campaigns/Marketing Easy of Use Enhancements 
- Packaged Cloud Deployment options - AWS,  Digital Ocean, GoogleCloudCompute, X2VPS 
- Import/Export Worksheets for mass record updates 
- Mass Action updates for Tags, Actions, Comments, more 
- Deduplication Improvements 
- X2Flow Robustness Enhancements
- User Permissions Roles update performance improvements 
- New Documentation and Training Videos - see http://www.x2crm.com...aining-library/
- Weblead widget for Activity Feed Dashboard 

- Email Widget for Activity Feed Dashboard

- Updated, improved Administration Panel 

- X2CRM App Rebrand, removing X2Engine branding. 

X2CRM 5.3 August/September 
- Calendaring 5.3 

- Two way Google Calendar/Contact Synch 
- User Statistics  
- Wordpress Plug-in 
- Reports 3.0
- Scheduled Campaigns 

 

X2CRM 6.0 December/January 2016

- Yii 2.0 

- TBD

 

 

Best,

 

X2CRM Team

Santa Cruz




#9761 How-to: X2flows - Send an SMS with Twilio using Zapier

Posted by that0n3guy on 23 February 2015 - 01:06 PM

This how-to will be a little bit technical, but its really not that bad.  It also requires the pro or platnium downloadable version of x2engine.  It also requires the use of composer...

 

Setup

  • Install Composer: Make sure you have composer installed: https://getcomposer....-linux-unix-osx
  • Add phone number package: Add https://github.com/g...enumber-for-phpto your main composer.json: composer require giggsey/libphonenumber-for-php:~7.0
  • Add composer autoload to config files:
    • Create the file custom/protected/config/web.php . Add to the top (after <?php):  require_once dirname(__FILE__)."/../../../vendor/autoload.php";
    • Create the file custom/protected/config/console.php . Add to the top (after <?php):  require_once dirname(__FILE__)."/../../../vendor/autoload.php";
    • Also add to the bottom of custom/protected/config/console.php: $config['components']['request']['hostInfo'] = 'https://yourx2.domain.com';

Setup should be done.   Reload your site, see if it still works.  If not, you broke something.  Also test out a console command and see if it still works.

  • NOTE:  In my custom console.php, I also have to have this line: unset($config['controllerMap']); // Fix weird error when running console commands.  Some where proConfig.php is getting included.
    • I'm not sure why... could be my servers setup... could be an x2engine bug.

Create a custom shortcode.php

  • Create a new file here: custom/protected/components/x2flow/shortcodes.php
  • Add the following contents to the shortcodes.php: 
<?php

/* pulling the "core" file so that if it changes, my tweaks will just be added to the end */
$originalFile = str_replace(DIRECTORY_SEPARATOR.'custom','',__FILE__);
$shortcodes = include($originalFile);

$myShortCodes = array(
    'twilioFormattedPhone'=> '
        $phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
        try {
            $USnumberProto = $phoneUtil->parse($model->phone, "US");
            $formatedphone = $phoneUtil->format($USnumberProto, \libphonenumber\PhoneNumberFormat::E164);
            return $formatedphone;
        } catch (\libphonenumber\NumberParseException $e) {
            //@todo do something here??
        }
    ');


return array_merge($shortcodes, $myShortCodes)
?>

This basically adds any shortcodes we put in this file to the default shortcodes that are found here: protected/components/x2flow/shortcodes.php .   The above file adds the shortcode {twilioFormattedPhone}.  This is JUST for the contact field with the name of 'phone'.   I should note that if you use this on other entities (opportunities, accounts, etc...) it won't probably won't work.  If you have a contact field called something different than 'phone'... you can change where you see `$model->phone` above to `$model->yourphonefield'.

 

A {twilioFormattedPhone} shortcode will be replaced with a phone number formatted in a way that twilio likes.  

 

How to use it in x2flows

 

Use a remote api action like so:

Attached File  x2_send_sms_zapier.png   30.59KB   0 downloads

 

  1. The url provided by zapier
  2. our shortcode (the phone number formatted how twilio likes).
  3. our message that we want sent
  4. A key.  Used just so that other people can't use our zapier url to send SMS's to people.

Setup Zapier like so:

 

Attached File  x2_send_sms_zapier_zap.png   430.47KB   1 downloads




#9319 use x2idenity data to add or remove from remarketing

Posted by that0n3guy on 06 January 2015 - 09:09 AM

My progress (untested... going live on my site today so I can test).  

 

So, basic usage.  

 

Step 1: Enable UserID in your google analytics account:

Admin->tracking info->user id.  See this image: http://screencast.com/t/nUv0J3MhdGZ

 

Step 2: Add the following javascript to your site (below the webTracker.php script):

    /**************************************************************
     * included from http://www.quirksmode.org/js/cookies.html
     *************************************************************/

    function createCookie(name, value, days) {
        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            var expires = "; expires=" + date.toGMTString();
        }
        else var expires = "";
        document.cookie = name + "=" + value + expires + "; path=/";
    }

    function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }
        return null;
    }

    function eraseCookie(name) {
        createCookie(name, "", -1);
    }

    /**************************************************************
     * Actual code below
     *************************************************************/

    var cookieRegistry = [];

    function listenCookieChange(cookieName, callback) {
        setInterval(function() {
            if (cookieRegistry[cookieName] || readCookie(cookieName) != null) {
                if (readCookie(cookieName) != cookieRegistry[cookieName]) {
                    // update registry so we dont get triggered again
                    cookieRegistry[cookieName] = readCookie(cookieName);
                    return callback();
                }
            } else {
                cookieRegistry[cookieName] = readCookie(cookieName);
            }
        }, 100);
    }

    /**************************************************************
     * Test below
     *************************************************************/

    // bind the listener
    var x2cookieName = 'x2_key';
    listenCookieChange(x2cookieName, function() {
        // Set the user ID using signed-in user_id.
        if (readCookie(x2cookieName) != null) {
            ga('set', '&uid', readCookie(x2cookieName));
        }
    });

So, my site looks like so: 

<script src="https://x2.myx2site.com/webTracker.php"></script>
<script>
    /**************************************************************
     * included from http://www.quirksmode.org/js/cookies.html
     *************************************************************/

    function createCookie(name, value, days) {
        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            var expires = "; expires=" + date.toGMTString();
        }
        else var expires = "";
        document.cookie = name + "=" + value + expires + "; path=/";
    }

    function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }
        return null;
    }

    function eraseCookie(name) {
        createCookie(name, "", -1);
    }

    /**************************************************************
     * Actual code below
     *************************************************************/

    var cookieRegistry = [];

    function listenCookieChange(cookieName, callback) {
        setInterval(function() {
            if (cookieRegistry[cookieName] || readCookie(cookieName) != null) {
                if (readCookie(cookieName) != cookieRegistry[cookieName]) {
                    // update registry so we dont get triggered again
                    cookieRegistry[cookieName] = readCookie(cookieName);
                    return callback();
                }
            } else {
                cookieRegistry[cookieName] = readCookie(cookieName);
            }
        }, 100);
    }

    /**************************************************************
     * Test below
     *************************************************************/

// create the cookie
//    createCookie('foo', 'bar');

    // bind the listener
    var x2cookieName = 'x2_key';
    listenCookieChange(x2cookieName, function() {
        // Set the user ID using signed-in user_id.
        if (readCookie(x2cookieName) != null) {
            ga('set', '&uid', readCookie(x2cookieName));
        }
    });
</script>

A minified version of the above script is as follows:

function createCookie(e,t,n){if(n){var r=new Date;r.setTime(r.getTime()+n*24*60*60*1e3);var i="; expires="+r.toGMTString()}else var i="";document.cookie=e+"="+t+i+"; path=/"}function readCookie(e){var t=e+"=";var n=document.cookie.split(";");for(var r=0;r<n.length;r++){var i=n[r];while(i.charAt(0)==" ")i=i.substring(1,i.length);if(i.indexOf(t)==0)return i.substring(t.length,i.length)}return null}function eraseCookie(e){createCookie(e,"",-1)}function listenCookieChange(e,t){setInterval(function(){if(cookieRegistry[e]||readCookie(e)!=null){if(readCookie(e)!=cookieRegistry[e]){cookieRegistry[e]=readCookie(e);return t()}}else{cookieRegistry[e]=readCookie(e)}},100)}var cookieRegistry=[];var x2cookieName="x2_key";listenCookieChange(x2cookieName,function(){if(readCookie(x2cookieName)!=null){ga("set","&uid",readCookie(x2cookieName))}})

What this does:

 

This basically sets the universal analytic userID if the user on the site to the x2_key (web tracking code) for that user.  If the webTracker changes the x2_key, it will see that it changed and change the userID as well.

 

Why do this:

I've not tested this yet.  But you should be able to setup some x2flows that will send user data to google via the "remote api call" trigger.  

 

For example.  User gets tagged with "white t-shirt".  Then you send an event to google like: 

http://www.google-analytics.com/collect?v=1&tid=UA-123456-1&uid={trackingKey}&t=pageview&dp=x2engine%2Fwhite-t-shirts

The above essentially logs a website "hit" at the url "x2engine/white-t-shirts"  (so if your domain for UA-123456-1 was "mysite.com", the url would be mysite.com/x2engine/white-t-shirts).  Now you could do remarketing campaigns based on website users who have been to "x2engine/white-t-shirts".

 

Issues with this:

  • I've not tested this fully yet. 
  • The url needs to be UTF-8 encoded.  That means that if you try to insert things with spaces from x2engine (example: {firstname}... don't do firstname though, google doesn't like personally identifiable info), it probably won't work.  So if you add a web url like I did (ie, x2engine/white-t-shirts) you will have to encode it yourself (http://meyerweb.com/...tools/dencoder/).
  • The documentation from google says you need a "cid" perameter, I don't know if that is true IF you have a UID (based on http://cutroni.com/b...-the-user-id/).

References:




#9941 Thanks a lot

Posted by Colin on 25 March 2015 - 07:58 PM

This is just a big shout out to Raymond.......who never fails to respond and deal with my technical issues promptly. Thanks a lot for the great customer service

 

Cheers

Colin




#9083 x2 engine version 5.0 Update problem

Posted by X2Raymond on 08 December 2014 - 10:55 AM

As you noted, the reason for this failure is the presence of a dropdown in the reserved ID range. IDs less than 1000 are intended to be used internally by the software, but something caused one of your user defined dropdowns to have and ID less than 1000.

 

Please see my explanation for a fix in another thread: http://x2community.c...-421/#entry8747 and let me know if you need any more clarification.




#8956 Manual unsubscribe a contact from a newsletter

Posted by eugeneb on 20 November 2014 - 11:44 PM

Hi Tony,

 

with the above discussion in mind, how do I re-subscribe a contact to a newsletter. it seems if they clicked unsubscribe its done. they can NEVER resubscribe. Even if I toggle the Don't Email tick boxes in their contact details. And as discussed above, the tabulated Newsletter subs list, although showing who gets and doesn't get, cannot be changed by admin. 

 

You guys I think will seriously have to ad functionality to control this Newsletter subscription tick boxes manually. This includes if someone unsubscribed and they fill in the same newsletter webform again for the same newsletter, that the unsubs clears based on their own decision.

 

Will any of this possibly be solved in v5.0?

 

Thanks




#8448 How To Resend Campaign To Those That Didn't Open It?

Posted by sflich86 on 06 September 2014 - 05:50 AM

Hi, I'm a platinum customer.

 

I want to send an email marketing campaign and after 3 days resend it again (with a different subjet line) but only to those that didn't open the first email.

This is a really basic feature of every email marketing service out there (not even marketing automation)

 

But I'm not able to express this using X2 Flow

 

I know open data is saved as an action on a record, but I can't access that information from x2 flow  to create this flow.

 

How can I do it? 

 

Would love to get a response from the X2 staff




#8099 One X2Engine instance for multiple websites?

Posted by X2Derek on 14 July 2014 - 06:13 PM

This should be possible. Our web tracker, web lead forms, and targeted content embed codes should all work regardless of what you have set as your "External / Public Base Url" in your admin settings.

 

Setting the "External / Public Base Url," at least for the purposes of web tracking, merely determines the url that gets used when embed codes are automatically generated. If, for example, your public base url is set to "http:// www.siteA.com," then your generated web tracker embed code will look like this:

 

<script src="http:// www.siteA.com/webTracker.php"></script>

 

If you wanted to track contacts on www.siteB.com, you could manually replace "siteA" with "siteB" in the web tracker embed code.

 

Within your flows, you can use conditions to determine which url the tracked contact visited.

 

So yes, it should be possible to track contacts across multiple domains but it currently requires you to manually adjust the embed codes. Eventually I would like to make this more convenient to set up by adding the ability to configure multiple tracking urls.




#7734 Individual Email Signature used dynamivaly in x2flow

Posted by Guest on 27 May 2014 - 03:18 PM

Hi, Alv

 

Set up your signatures as from the 'edit profile' option on your profile page:

 

Attached File  edit profile.png   50.13KB   3 downloads
 

To add the signature to a marketing campaign, an email template document, or an X2Flow email, you can use the following shortcode: {signature}. Simply add that into the text edit field as in the following example:

 

dear {firstName},

Did you get that thing I sent you?

{signature}

 

The appropriate user's signature will automatically replace the shortcode. In a marketing campaign, the user whose signature will be used is whoever the Assigned To user is. For an email template, the replacement will take place as soon as you select the template from the dropdown menu. For an X2Flow send email action, the signature will be that of the person who is the sender of the email.

 

-Tony




#6826 Unsubscribe Function for Mass E-Mail Campaigns

Posted by X2Derek on 30 December 2013 - 01:04 PM

Hey,

 

Being able to customize the unsubscribe link would be a sensible feature to have. Unfortunately it's not possible yet. There is, however, a way of positioning the unsubscribe link within your email. Placing the insertable attribute "{_unsub}" in your campaign text will cause the unsubscribe link be positioned wherever the insertable attribute is, instead of at the end of the email body.




#2152 New Service App in the works

Posted by John Roberts on 26 October 2012 - 10:30 AM

We are working on a new customer service module for X2EngineCRM. For the 1.0 its is a straight forward case management module. Please feel free to post your requested features to this forum so we can try and include them in the module.
-john


#12606 X2TechTalk V - X2CRM 6.5 Preview

Posted by John Roberts on 21 December 2016 - 02:12 PM

Hello everyone,

 

Boy this TechTalk is a bit overdue, I delayed it a few week so we could give 6.5 more time. It does provide good introductions to new location or X2Checkin, Google Maps, major Calendaring and Google sync improvements and X2Touch mobile 2.0 features. We are about to release 6.5.2 within the next few days. Over the coming weeks we are planning to do major documentation, video and website updates to help show you how to easily design, deploy and manage your X2CRM system.

 

X2TechTalk V: X2CRM 6.5 Preview

https://player.vimeo...&profile_id=174

 

Best, 

X2CRM Team




#12340 WordPress Plugin

Posted by PixelStudio_99 on 05 September 2016 - 11:47 AM

Found a Wordpress plugin that works with Contact Form 7 as an alternative method for capturing web leads to the x2CRM packaged web forms. Also, adds the web tracking snippet to the website for tracking visitors.

 

Figured I share in the event someone was looking

 

http://bit.ly/2cmZDLp 




#11958 X2CRM 6.0 Released - now with open source X2Workflow & Mobile

Posted by John Roberts on 02 May 2016 - 04:34 PM

Last week we released X2CRM version 6.0. This release has a number of exciting features but first I would like to provide a general X2Engine | X2CRM update and forward looking road map for the remainder of this year.

 

Founded in 2011 and after five years of growth we are now at the stage where X2CRM Cloud Hosting Services now can fully fund company operations – thank you X2VPS customers. At the same time it was felt 6.0 was the right time to fully open source X2Platinum Edition. With version 6, all commercial X2CRM editions have now been combined into a single release and relicensed under the GNU Affero GPL v3 open source license. X2CRM is fully committed to providing the best open source CRM software. Having one open source edition will make it easier to add new features and also to share the full power of X2CRM as free and open software.

 

As software developers, you not only want to be successful with the applications you create, but also see them used as fully as possible, by as many folks as possible. Now having only one, X2CRM software application will enable a much richer extension ecosystem around the fully open source X2CRM platform. Join us in the coming weeks as we transform X2Community.com into a real thriving code and CRM knowledge sharing destination.

 

The X2CRM 6.0 release centered on user experience improvements with the additional of a new lighter default theme and a new Night theme. X2Touch mobile applications continue to be a priority and are in active development with new versions rolling out over the next few weeks..




#11693 Installation ok, but X2CRM very slow

Posted by PublishItNow on 11 February 2016 - 05:33 PM

Hi Raymond,

 

Thankyou for the advice. I dug in a bit deeper and did some experimentation, and discovered what was slowing PHP down was actually having FastCGI Application setup to handle PHP. When I changed it over to a standard CGI Application, everything sped up quite nicely. Thought it might be worth mentioning in case someone else runs into the same issue. 

 

Warmest regards,

 

Andrew




#11666 Default font for email template

Posted by eugeneb on 08 February 2016 - 05:19 AM

Hi guys,

 

is there a way to set the default system font for new emails, docs and templates to something like Verdana. The email defaults to Times and one has to change it manually to something else. We use Verdana as default.

 

it would help greatly with generating emails.

 

Thanks

 

Eugene




#12909 How to increment value of field from a workflow action

Posted by X2Raymond on 24 February 2017 - 10:12 AM

That is correct, you will want to use the Update Record action. To increase the leadscore, you'll want to use the formula syntax with the {leadscore} insertable attribute:

 

= {leadscore} + 1


  • dev likes this


#12908 About "Compare Attribute" conditions in workflows

Posted by X2Raymond on 24 February 2017 - 10:06 AM

You can perform dynamic date calculations by using the "formula" syntax, similar to that in Excel but with the X2CRM insertable attributes. You can use the {timestamp} attribute to represent the current time represented as a UNIX timestamp (number of seconds since the epoch, Jan 1, 1970). Then, add or subtract the number of seconds for your offset, like:

 

={timestamp} + (# of days * # of hours * # of minutes * # of seconds)

 

Outside of the formula, you can also use string representations like "today" when under the English locale. Please see this related thread for more detailed information: http://community.x2c...d-calculations/


  • dev likes this


#12891 How do I send a lead a PDF file as part of an automated email?

Posted by X2Raymond on 21 February 2017 - 10:27 AM

You'll want to use the Email Contact action in X2Workflow after your New Web Lead trigger. Currently the Email Contact action in X2Workflow does not have a facility for directly adding attachments, so this would need to be performed by providing a link to the ebook. However, adding the PDF as a native attachment would be preferable, so I'll mark this as a feature request and see about enhancing this for a future release.




#12883 Error when Create Action

Posted by X2Raymond on 20 February 2017 - 11:37 AM

Hello Paolo,

 

Please find the answer pasted below:

 

Following up on the calendar issue: this issue is caused due to the use of an arrray_merge instead of the plus operator, which in turn squashes the keys of the associative array. You can patch your instance by updating both protected/modules/actions/views/actions/_actionForm.php and protected/modules/actions/views/actions/_form.php, around lines 82 and 307 respectively, to use the plus operator. After modifying, the code in question should read:

            $editableCalendars =
                array('' => Yii::t('actions', 'None')) +
                X2CalendarPermissions::getEditableUserCalendarNames();