44 * Module dependencies.
55 */
66
7- var fmt = require ( '@segment/fmt' ) ;
87var integration = require ( '@segment/analytics.js-integration' ) ;
98var is = require ( 'is' ) ;
10- var jsonp = require ( 'jsonp' ) ;
119var url = require ( 'component-url' ) ;
1210var when = require ( 'do-when' ) ;
1311var each = require ( '@ndhoule/each' ) ;
12+
1413// mapping of Standard Marketo API names: restAPIName: soapAPIName
1514var apiNameMapping = {
1615 annualRevenue : 'AnnualRevenue' ,
@@ -82,11 +81,29 @@ var apiNameMapping = {
8281var Marketo = ( module . exports = integration ( 'Marketo V2' )
8382 . assumesPageview ( )
8483 . global ( 'Munchkin' )
84+ . global ( 'MktForms2' )
8585 . option ( 'host' , 'https://api.segment.io' )
8686 . option ( 'accountId' , '' )
8787 . option ( 'projectId' , '' )
88+ . option ( 'marketoHostUrl' , '' )
89+ . option ( 'marketoFormId' , '' )
8890 . option ( 'traits' , [ ] )
89- . tag ( '<script src="//munchkin.marketo.net/munchkin.js">' ) ) ;
91+ . tag ( '<script src="//munchkin.marketo.net/munchkin.js">' )
92+ . tag (
93+ 'forms' ,
94+ '<script src="{{marketoHostUrl}}/js/forms2/js/forms2.min.js">'
95+ ) ) ;
96+
97+ var disableFormSubmitRedirects = function ( form ) {
98+ if ( form ) {
99+ // *** Do not remove this callback ***
100+ // This ensures there are no page refreshes after the form is submitted and handles
101+ // the side effects of multiple form submissions in the same page.
102+ form . onSuccess ( function ( ) {
103+ return false ;
104+ } ) ;
105+ }
106+ } ;
90107
91108/**
92109 * Initialize.
@@ -97,18 +114,51 @@ var Marketo = (module.exports = integration('Marketo V2')
97114 */
98115
99116Marketo . prototype . initialize = function ( ) {
117+ var munchkinId = this . options . accountId ;
118+ var marketoHostUrl = this . options . marketoHostUrl ;
119+ var marketoFormId = parseInt ( this . options . marketoFormId , 10 ) ;
120+
121+ var identifySettingsAreInvalid =
122+ marketoHostUrl === undefined ||
123+ marketoHostUrl === '' ||
124+ Number . isNaN ( marketoFormId ) ||
125+ marketoFormId <= 0 ;
126+
127+ if ( identifySettingsAreInvalid ) {
128+ console . warn (
129+ 'Invalid settings for identify method. Please review your Marketo V2 destination settings.'
130+ ) ;
131+ return ;
132+ }
133+
100134 var self = this ;
101135 this . load ( function ( ) {
102- window . Munchkin . init ( self . options . accountId , {
136+ window . Munchkin . init ( munchkinId , {
103137 asyncOnly : true
104138 } ) ;
139+
105140 // marketo integration actually loads a marketo snippet
106141 // and the snippet loads the real marketo, this is required
107142 // because there's a race between `window.mktoMunchkinFunction = sinon.spy()`
108143 // and marketo's real javascript which overrides `window.mktoMunchkinFunction`
109144 // and deletes the spy.
110145 when ( self . loaded , self . ready ) ;
111146 } ) ;
147+
148+ this . load ( 'forms' , { marketoHostUrl : marketoHostUrl } , function ( ) {
149+ var marketoForm = document . createElement ( 'form' ) ;
150+ marketoForm . setAttribute ( 'id' , 'mktoForm_' + marketoFormId ) ;
151+ marketoForm . setAttribute ( 'style' , 'display:none' ) ;
152+ document . body . appendChild ( marketoForm ) ;
153+ window . MktoForms2 . loadForm (
154+ marketoHostUrl ,
155+ munchkinId ,
156+ marketoFormId ,
157+ function ( form ) {
158+ disableFormSubmitRedirects ( form ) ;
159+ }
160+ ) ;
161+ } ) ;
112162} ;
113163
114164/**
@@ -141,6 +191,12 @@ Marketo.prototype.page = function(page) {
141191 } ) ;
142192} ;
143193
194+ Marketo . prototype . setupAndSubmitForm = function ( traits , form ) {
195+ form . addHiddenFields ( traits , form ) ;
196+ disableFormSubmitRedirects ( form ) ;
197+ form . submit ( ) ;
198+ } ;
199+
144200/**
145201 * Identify.
146202 *
@@ -154,6 +210,7 @@ Marketo.prototype.identify = function(identify) {
154210 return ;
155211 }
156212
213+ var self = this ;
157214 var settings = this . options ;
158215
159216 // we _must_ have an email
@@ -216,50 +273,12 @@ Marketo.prototype.identify = function(identify) {
216273 }
217274 } , settings . traits ) ;
218275
219- // associate the lead on the client-side so that
220- // we can track to the same user
221- this . requestHash ( traitsToSendMarketo . Email , function ( err , hash ) {
222- var marketoFn = window . mktoMunchkinFunction ;
223- if ( marketoFn ) marketoFn ( 'associateLead' , traitsToSendMarketo , hash ) ;
224- } ) ;
225- } ;
226-
227- /**
228- * Generate the URL to the Segment endpoint that hashes Marketo emails.
229- *
230- * @api private
231- * @param {string } email
232- * @return {string }
233- */
234-
235- Marketo . prototype . emailHashUrl = function ( email ) {
236- var host = this . options . host ;
237- var projectId = this . options . projectId ;
238- return fmt (
239- '%s/integrations/marketo/v1/%s/%s/hash-v2' ,
240- host ,
241- projectId ,
242- email
243- ) ;
244- } ;
245-
246- /**
247- * Marketo requires that users' requests come with a hashed version of their
248- * email address. It's a hash that can't be done on the client-side for some
249- * reason.
250- *
251- * Man, it'd have been great if someone had documented this in the first place.
252- *
253- * See https://github.com/segmentio/marketo-hash-app for more details.
254- *
255- * TODO: Improve this documentation
256- *
257- * @api private
258- * @param {string } email
259- * @param {Function } callback
260- */
276+ window . MktoForms2 . whenReady ( function ( form ) {
277+ var marketoFormId = parseInt ( settings . marketoFormId , 10 ) ;
278+ var validFormId = ! ( Number . isNaN ( marketoFormId ) || marketoFormId <= 0 ) ;
261279
262- Marketo . prototype . requestHash = function ( email , callback ) {
263- var url = this . emailHashUrl ( email ) ;
264- jsonp ( url , callback ) ;
280+ if ( validFormId && form . getId ( ) === marketoFormId ) {
281+ self . setupAndSubmitForm ( traitsToSendMarketo , form ) ;
282+ }
283+ } ) ;
265284} ;
0 commit comments