2185 lines
95 KiB
HTML
2185 lines
95 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<meta name="msapplication-TileColor" content="#ffffff">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/favicon/brevo-favicon.svg">
|
||
<link rel="mask-icon" href="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/favicon/brevo-favicon.svg" color="#5bbad5">
|
||
|
||
<meta name="msapplication-TileImage" content="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/favicon/mstile-144x144.png">
|
||
<meta name="msapplication-config" content="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/favicon/browserconfig.xml">
|
||
|
||
|
||
<meta name='robots' content='index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1' />
|
||
|
||
<!-- This site is optimized with the Yoast SEO plugin v18.4.1 - https://yoast.com/wordpress/plugins/seo/ -->
|
||
<title>Streamlining our incident responses - Brevo Engineering</title>
|
||
<meta name="description" content="How Sendinblue build an application which helps in streamlining our incident responses with slack to get the most out of outages." />
|
||
<link rel="canonical" href="https://engineering.brevo.com/streamlining-our-incident-responses/" />
|
||
<meta property="og:locale" content="en_US" />
|
||
<meta property="og:type" content="article" />
|
||
<meta property="og:title" content="Streamlining our incident responses - Brevo Engineering" />
|
||
<meta property="og:description" content="How Sendinblue build an application which helps in streamlining our incident responses with slack to get the most out of outages." />
|
||
<meta property="og:url" content="https://engineering.brevo.com/streamlining-our-incident-responses/" />
|
||
<meta property="og:site_name" content="Brevo Engineering" />
|
||
<meta property="article:published_time" content="2022-06-30T05:02:59+00:00" />
|
||
<meta property="article:modified_time" content="2023-01-06T10:23:54+00:00" />
|
||
<meta property="og:image" content="https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash.jpg" />
|
||
<meta property="og:image:width" content="2000" />
|
||
<meta property="og:image:height" content="1334" />
|
||
<meta property="og:image:type" content="image/jpeg" />
|
||
<meta name="twitter:card" content="summary_large_image" />
|
||
<meta name="twitter:creator" content="@tanguyantoine" />
|
||
<meta name="twitter:label1" content="Written by" />
|
||
<meta name="twitter:data1" content="Tanguy Antoine" />
|
||
<meta name="twitter:label2" content="Est. reading time" />
|
||
<meta name="twitter:data2" content="14 minutes" />
|
||
<script type="application/ld+json" class="yoast-schema-graph">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://engineering.brevo.com/#website","url":"https://engineering.brevo.com/","name":"Brevo Engineering","description":"Brevo Tech","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://engineering.brevo.com/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https://engineering.brevo.com/streamlining-our-incident-responses/#primaryimage","inLanguage":"en-US","url":"https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash.jpg","contentUrl":"https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash.jpg","width":2000,"height":1334,"caption":"Firefighters"},{"@type":"WebPage","@id":"https://engineering.brevo.com/streamlining-our-incident-responses/#webpage","url":"https://engineering.brevo.com/streamlining-our-incident-responses/","name":"Streamlining our incident responses - Brevo Engineering","isPartOf":{"@id":"https://engineering.brevo.com/#website"},"primaryImageOfPage":{"@id":"https://engineering.brevo.com/streamlining-our-incident-responses/#primaryimage"},"datePublished":"2022-06-30T05:02:59+00:00","dateModified":"2023-01-06T10:23:54+00:00","author":{"@id":"https://engineering.brevo.com/#/schema/person/3a95d97937fdeeb993f1cec00d47f320"},"description":"How Sendinblue build an application which helps in streamlining our incident responses with slack to get the most out of outages.","breadcrumb":{"@id":"https://engineering.brevo.com/streamlining-our-incident-responses/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https://engineering.brevo.com/streamlining-our-incident-responses/"]}]},{"@type":"BreadcrumbList","@id":"https://engineering.brevo.com/streamlining-our-incident-responses/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://engineering.brevo.com/"},{"@type":"ListItem","position":2,"name":"Streamlining our incident responses"}]},{"@type":"Person","@id":"https://engineering.brevo.com/#/schema/person/3a95d97937fdeeb993f1cec00d47f320","name":"Tanguy Antoine","image":{"@type":"ImageObject","@id":"https://engineering.brevo.com/#personlogo","inLanguage":"en-US","url":"https://secure.gravatar.com/avatar/13687a119a443bde3c90115ae6f8458b?s=96&d=mm&r=g","contentUrl":"https://secure.gravatar.com/avatar/13687a119a443bde3c90115ae6f8458b?s=96&d=mm&r=g","caption":"Tanguy Antoine"},"description":"SRE and DPE lead at Sendinblue","sameAs":["https://github.com/tanguyantoine","https://twitter.com/tanguyantoine"],"url":"https://engineering.brevo.com/author/antoine-tanguy/"}]}</script>
|
||
<!-- / Yoast SEO plugin. -->
|
||
|
||
|
||
<link rel='dns-prefetch' href='//engineering.brevo.com' />
|
||
<link rel='dns-prefetch' href='//s.w.org' />
|
||
<link rel="alternate" type="application/rss+xml" title="Brevo Engineering » Streamlining our incident responses Comments Feed" href="https://engineering.brevo.com/streamlining-our-incident-responses/feed/" />
|
||
<script type="text/javascript">
|
||
window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/13.1.0\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/13.1.0\/svg\/","svgExt":".svg","source":{"concatemoji":"https:\/\/engineering.brevo.com\/wp-includes\/js\/wp-emoji-release.min.js?ver=5.9.16"}};
|
||
/*! This file is auto-generated */
|
||
!function(e,a,t){var n,r,o,i=a.createElement("canvas"),p=i.getContext&&i.getContext("2d");function s(e,t){var a=String.fromCharCode;p.clearRect(0,0,i.width,i.height),p.fillText(a.apply(this,e),0,0);e=i.toDataURL();return p.clearRect(0,0,i.width,i.height),p.fillText(a.apply(this,t),0,0),e===i.toDataURL()}function c(e){var t=a.createElement("script");t.src=e,t.defer=t.type="text/javascript",a.getElementsByTagName("head")[0].appendChild(t)}for(o=Array("flag","emoji"),t.supports={everything:!0,everythingExceptFlag:!0},r=0;r<o.length;r++)t.supports[o[r]]=function(e){if(!p||!p.fillText)return!1;switch(p.textBaseline="top",p.font="600 32px Arial",e){case"flag":return s([127987,65039,8205,9895,65039],[127987,65039,8203,9895,65039])?!1:!s([55356,56826,55356,56819],[55356,56826,8203,55356,56819])&&!s([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447]);case"emoji":return!s([10084,65039,8205,55357,56613],[10084,65039,8203,55357,56613])}return!1}(o[r]),t.supports.everything=t.supports.everything&&t.supports[o[r]],"flag"!==o[r]&&(t.supports.everythingExceptFlag=t.supports.everythingExceptFlag&&t.supports[o[r]]);t.supports.everythingExceptFlag=t.supports.everythingExceptFlag&&!t.supports.flag,t.DOMReady=!1,t.readyCallback=function(){t.DOMReady=!0},t.supports.everything||(n=function(){t.readyCallback()},a.addEventListener?(a.addEventListener("DOMContentLoaded",n,!1),e.addEventListener("load",n,!1)):(e.attachEvent("onload",n),a.attachEvent("onreadystatechange",function(){"complete"===a.readyState&&t.readyCallback()})),(n=t.source||{}).concatemoji?c(n.concatemoji):n.wpemoji&&n.twemoji&&(c(n.twemoji),c(n.wpemoji)))}(window,document,window._wpemojiSettings);
|
||
</script>
|
||
<style type="text/css">
|
||
img.wp-smiley,
|
||
img.emoji {
|
||
display: inline !important;
|
||
border: none !important;
|
||
box-shadow: none !important;
|
||
height: 1em !important;
|
||
width: 1em !important;
|
||
margin: 0 0.07em !important;
|
||
vertical-align: -0.1em !important;
|
||
background: none !important;
|
||
padding: 0 !important;
|
||
}
|
||
</style>
|
||
<link rel='stylesheet' id='tabs-block-css-css' href='https://engineering.brevo.com/wp-content/plugins/tabs-block/css/tabs-block.css?ver=5.9.16' type='text/css' media='all' />
|
||
<link rel='stylesheet' id='wp-block-library-css' href='https://engineering.brevo.com/wp-includes/css/dist/block-library/style.min.css?ver=5.9.16' type='text/css' media='all' />
|
||
<style id='global-styles-inline-css' type='text/css'>
|
||
body{--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--duotone--dark-grayscale: url('#wp-duotone-dark-grayscale');--wp--preset--duotone--grayscale: url('#wp-duotone-grayscale');--wp--preset--duotone--purple-yellow: url('#wp-duotone-purple-yellow');--wp--preset--duotone--blue-red: url('#wp-duotone-blue-red');--wp--preset--duotone--midnight: url('#wp-duotone-midnight');--wp--preset--duotone--magenta-yellow: url('#wp-duotone-magenta-yellow');--wp--preset--duotone--purple-green: url('#wp-duotone-purple-green');--wp--preset--duotone--blue-orange: url('#wp-duotone-blue-orange');--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}
|
||
</style>
|
||
<link rel='stylesheet' id='default-page-css' href='https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/css/default-page.css?ver=1789190604' type='text/css' media='all' />
|
||
<link rel='stylesheet' id='grid-min-css' href='https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/css/grid.min.css?ver=1789190604' type='text/css' media='all' />
|
||
<link rel='stylesheet' id='common-min-css' href='https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/css/common.css?ver=1789190604' type='text/css' media='all' />
|
||
<link rel='stylesheet' id='blog-css' href='https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/css/blog.css?ver=1789190604' type='text/css' media='all' />
|
||
<link rel='stylesheet' id='search-component-css' href='https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/css/search2.css?ver=1789190604' type='text/css' media='all' />
|
||
<link rel='stylesheet' id='sib-front-css-css' href='https://engineering.brevo.com/wp-content/plugins/mailin/css/mailin-front.css?ver=5.9.16' type='text/css' media='all' />
|
||
<script type='text/javascript' src='https://engineering.brevo.com/wp-includes/js/jquery/jquery.min.js?ver=3.6.0' id='jquery-core-js'></script>
|
||
<script type='text/javascript' src='https://engineering.brevo.com/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.3.2' id='jquery-migrate-js'></script>
|
||
<script type='text/javascript' src='https://engineering.brevo.com/wp-content/plugins/tabs-block/js/tabs-block.js?ver=5.9.16' id='tabs-block-js-js'></script>
|
||
<script type='text/javascript' id='sib-front-js-js-extra'>
|
||
/* <![CDATA[ */
|
||
var sibErrMsg = {"invalidMail":"Please fill out valid email address","requiredField":"Please fill out required fields","invalidDateFormat":"Please fill out valid date format","invalidSMSFormat":"Please fill out valid phone number"};
|
||
var ajax_sib_front_object = {"ajax_url":"https:\/\/engineering.brevo.com\/wp-admin\/admin-ajax.php","ajax_nonce":"6d28f9abab","flag_url":"https:\/\/engineering.brevo.com\/wp-content\/plugins\/mailin\/img\/flags\/"};
|
||
/* ]]> */
|
||
</script>
|
||
<script type='text/javascript' src='https://engineering.brevo.com/wp-content/plugins/mailin/js/mailin-front.js?ver=1782381777' id='sib-front-js-js'></script>
|
||
<link rel="https://api.w.org/" href="https://engineering.brevo.com/wp-json/" /><link rel="alternate" type="application/json" href="https://engineering.brevo.com/wp-json/wp/v2/posts/554" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://engineering.brevo.com/xmlrpc.php?rsd" />
|
||
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="https://engineering.brevo.com/wp-includes/wlwmanifest.xml" />
|
||
<meta name="generator" content="WordPress 5.9.16" />
|
||
<link rel='shortlink' href='https://engineering.brevo.com/?p=554' />
|
||
<link rel="alternate" type="application/json+oembed" href="https://engineering.brevo.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fengineering.brevo.com%2Fstreamlining-our-incident-responses%2F" />
|
||
<link rel="alternate" type="text/xml+oembed" href="https://engineering.brevo.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fengineering.brevo.com%2Fstreamlining-our-incident-responses%2F&format=xml" />
|
||
<script>jQuery(() => {
|
||
let stickyTop = 0,
|
||
scrollTarget = false
|
||
|
||
let timeline = jQuery('.timeline__nav'),
|
||
items = jQuery('li', timeline),
|
||
milestones = jQuery('.timeline__section .milestone'),
|
||
offsetTop = parseInt(timeline.css('top'))
|
||
|
||
const TIMELINE_VALUES = {
|
||
start: 190,
|
||
step: 30
|
||
}
|
||
|
||
jQuery(window).resize(function () {
|
||
timeline.removeClass('fixed')
|
||
|
||
stickyTop = timeline.offset().top - offsetTop
|
||
|
||
jQuery(window).trigger('scroll')
|
||
}).trigger('resize')
|
||
|
||
jQuery(window).scroll(function () {
|
||
if (jQuery(window).scrollTop() > stickyTop) {
|
||
timeline.addClass('fixed')
|
||
} else {
|
||
timeline.removeClass('fixed')
|
||
}
|
||
// if (jQuery(window).scrollTop() > stickyTop) {
|
||
// timeline.css('position', 'absolute')
|
||
// timeline.css('bottom', '250px')
|
||
// } else {
|
||
// timeline.css('position', 'fixed')
|
||
// timeline.css('bottom', 'unset')
|
||
// }
|
||
}).trigger('scroll')
|
||
|
||
items.find('span').click(function () {
|
||
let li = jQuery(this).parent(),
|
||
index = li.index(),
|
||
milestone = milestones.eq(index)
|
||
|
||
if (! li.hasClass('active') && milestone.length) {
|
||
scrollTarget = index
|
||
|
||
let scrollTargetTop = milestone.offset().top - 200
|
||
|
||
jQuery('html, body').animate({ scrollTop: scrollTargetTop }, {
|
||
duration: 400,
|
||
complete: function complete() {
|
||
scrollTarget = false
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
jQuery(window).scroll(function () {
|
||
let viewLine = jQuery(window).scrollTop() + jQuery(window).height() / 3,
|
||
active = -1
|
||
|
||
if (scrollTarget === false) {
|
||
milestones.each(function () {
|
||
if (jQuery(this).offset().top - viewLine > 0) {
|
||
return false
|
||
}
|
||
|
||
active++
|
||
})
|
||
} else {
|
||
active = scrollTarget
|
||
}
|
||
|
||
timeline.css('top', -1 * active * TIMELINE_VALUES.step + TIMELINE_VALUES.start + 'px')
|
||
|
||
items.filter('.active').removeClass('active')
|
||
|
||
items.eq(active != -1 ? active : 0).addClass('active')
|
||
}).trigger('scroll')
|
||
})
|
||
jQuery(function() {
|
||
var loc = window.location.href;
|
||
if(/tech-events/.test(loc)) {
|
||
jQuery('main.sib-blog').addClass('brevo-tech-events');
|
||
}
|
||
});</script><style class="wpcode-css-snippet">.brevo-tech-events h1, .brevo-tech-events h2 {
|
||
font-family: tomato-grotesk-semibold;
|
||
}
|
||
.brevo-tech-events h2 {
|
||
margin-top: 0 !important;
|
||
font-size: 32px;
|
||
}
|
||
.brevo-tech-events h3 {
|
||
font-size: 26px;
|
||
}
|
||
.brevo-tech-events {
|
||
font-family: inter-regular;
|
||
}
|
||
.brevo-tech-events .wrapper {
|
||
margin: 10px 0 auto;
|
||
padding: 0 0 0 220px;
|
||
width: 100%;
|
||
}
|
||
.brevo-tech-events .timeline {
|
||
position: relative;
|
||
max-width: 980px;
|
||
margin: 0 auto;
|
||
}
|
||
.brevo-tech-events .timeline-card {
|
||
padding: 25px 30px 5px;
|
||
background-color: white;
|
||
position: relative;
|
||
border-radius: 10px;
|
||
box-shadow: 0 10px 40px 0 rgba(0, 0, 0, 0.1);
|
||
/* border-left: 4px solid #0b996f; */
|
||
}
|
||
/* .brevo-tech-events .timeline-card::before {
|
||
content: " ";
|
||
height: 0;
|
||
position: absolute;
|
||
top: 22px;
|
||
width: 0;
|
||
z-index: 1;
|
||
left: 30px;
|
||
border: medium solid #0b996f;
|
||
border-width: 10px 10px 10px 0;
|
||
border-color: transparent #0b996f transparent transparent;
|
||
} */
|
||
.brevo-tech-events .timeline::after {
|
||
left: 190px;
|
||
top:25px;
|
||
}
|
||
.brevo-tech-events .timeline-container {
|
||
width: 100%;
|
||
padding: 0;
|
||
margin: 20px 0 50px 0;
|
||
}
|
||
.brevo-tech-events .sib-single-page .sib-post-content .sib-post-content-text .timeline-card ul li::before {
|
||
padding-right: 0;
|
||
}
|
||
.brevo-tech-events .timeline-container::after {
|
||
left: -45px;
|
||
top: 20px;
|
||
}
|
||
|
||
.brevo-tech-events .timeline__nav {
|
||
position: fixed;
|
||
z-index: 99;
|
||
padding-top: 35px;
|
||
transition: top 0.3s ease-out;
|
||
}
|
||
.brevo-tech-events .timeline__nav ul {
|
||
list-style: none;
|
||
list-style-position: inside;
|
||
margin: 15px 0;
|
||
}
|
||
.brevo-tech-events .timeline__nav ul li {
|
||
margin: 15px 0;
|
||
padding: 5px 15px 5px 15px !important;
|
||
list-style-type: none;
|
||
color: #bfc1c3;
|
||
border-bottom: 0;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease-out;
|
||
font-family: tomato-grotesk-semibold;
|
||
}
|
||
.brevo-tech-events .timeline__nav ul li.active {
|
||
font-weight: bold;
|
||
color: #f94125;
|
||
transform: scale(1.2);
|
||
background: #e8fedf;
|
||
border-radius: 6px;
|
||
border: 1px solid #0b996f;
|
||
border-right: 3px solid #0b996f;
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .brevo-tech-events .timeline__nav ul li.active::before {
|
||
content: " ";
|
||
height: 0;
|
||
position: absolute;
|
||
top: 8px;
|
||
width: 0;
|
||
z-index: 1;
|
||
right: -21px;
|
||
border: medium solid #0b996f;
|
||
border-width: 10px 0 10px 10px;
|
||
border-color: transparent transparent transparent #0b996f;
|
||
}
|
||
.brevo-tech-events .timeline__nav ul li:hover {
|
||
color: #000;
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .brevo-tech-events .timeline__nav ul li::before {
|
||
color: #0b996f;
|
||
top: 6px;
|
||
content: "";
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .brevo-tech-events .timeline__nav span {
|
||
color: #0b996f;
|
||
font-weight: bold;
|
||
font-family: tomato-grotesk-semibold;
|
||
padding: 5px;
|
||
}
|
||
.events-badge {
|
||
background-color: #6358de;
|
||
color: white;
|
||
padding: 4px 10px;
|
||
text-align: center;
|
||
border-radius: 5px;
|
||
position: relative;
|
||
left: 2px;
|
||
top: -5px;
|
||
}
|
||
|
||
.tech-event-slides {display: none;}
|
||
img {vertical-align: middle;}
|
||
|
||
/* Slideshow container */
|
||
.tech-event-slideshow-container {
|
||
max-width: 1000px;
|
||
position: relative;
|
||
margin: auto;
|
||
}
|
||
|
||
/* Caption text */
|
||
.text {
|
||
color: #f2f2f2;
|
||
font-size: 15px;
|
||
padding: 8px 12px;
|
||
position: absolute;
|
||
bottom: 8px;
|
||
width: 100%;
|
||
text-align: center;
|
||
}
|
||
|
||
/* Number text (1/3 etc) */
|
||
.numbertext {
|
||
color: #f2f2f2;
|
||
font-size: 12px;
|
||
padding: 8px 12px;
|
||
position: absolute;
|
||
top: 0;
|
||
}
|
||
|
||
/* The dots/bullets/indicators */
|
||
.dot {
|
||
height: 15px;
|
||
width: 15px;
|
||
margin: 0 2px;
|
||
background-color: #bbb;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
transition: background-color 0.6s ease;
|
||
}
|
||
|
||
.active {
|
||
background-color: #717171;
|
||
}
|
||
|
||
/* Fading animation */
|
||
.fade {
|
||
animation-name: fade;
|
||
animation-duration: 1.5s;
|
||
}
|
||
|
||
@keyframes fade {
|
||
from {opacity: .4}
|
||
to {opacity: 1}
|
||
}
|
||
|
||
/* On smaller screens, decrease text size */
|
||
@media only screen and (max-width: 300px) {
|
||
.text {font-size: 11px}
|
||
}
|
||
|
||
.caption-text{
|
||
background: #e8fedf8f;
|
||
color: #0b996f !important;
|
||
}
|
||
|
||
@media only screen and (max-width: 640px) {
|
||
.brevo-tech-events .timeline__nav {
|
||
display: none;
|
||
}
|
||
.brevo-tech-events .wrapper {
|
||
padding: 0;
|
||
}
|
||
.brevo-tech-events .container {
|
||
padding-left: 0;
|
||
padding-right: 0;
|
||
}
|
||
.brevo-tech-events .timeline {
|
||
padding-top: 0;
|
||
}
|
||
.brevo-tech-events {
|
||
width: 100%;
|
||
}
|
||
.brevo-tech-events .caption-text {
|
||
bottom: -15px;
|
||
line-height: 20px;
|
||
}
|
||
.brevo-tech-events img {
|
||
width: 100%;
|
||
}
|
||
.sib-blog.brevo-tech-events .sib-single-page .sib-post-content .sib-post-content-text {
|
||
margin-top: 10px !important;
|
||
}
|
||
}</style><style class="wpcode-css-snippet">.data-grid {
|
||
color: #444343;
|
||
}
|
||
.data-grid, .data-grid-head {
|
||
display: grid;
|
||
grid-template-columns: 1fr 2fr 0.7fr;
|
||
}
|
||
.data-grid-head {
|
||
margin-bottom: 20px;
|
||
color: #555;
|
||
}
|
||
.data-grid-head-column {
|
||
padding: 20px 20px 0 20px;
|
||
}
|
||
.data-grid-row {
|
||
padding: 20px;
|
||
margin-bottom: 20px;
|
||
}
|
||
.data-grid-row.row-1 {
|
||
background: #dbd9f7;
|
||
}
|
||
.data-grid-row.row-2 {
|
||
background: #ffe7e0;
|
||
}
|
||
.data-grid-row.row-3 {
|
||
background: #dbf4f4;
|
||
}
|
||
.data-grid-row.row-4 {
|
||
background: #fce2eb;
|
||
}
|
||
|
||
|
||
.data-grid .data-grid-row:nth-child(1) {
|
||
border-radius: 10px 0 0 10px;
|
||
}
|
||
.data-grid .data-grid-row:nth-child(3) {
|
||
border-radius: 0 10px 10px 0;
|
||
}
|
||
|
||
.data-grid h4, .data-grid h5, .data-grid h6 {
|
||
margin: 0 !important;
|
||
}
|
||
.judges {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 20px;
|
||
}
|
||
.judges a {
|
||
text-decoration: none;
|
||
border-radius: 10px;
|
||
}
|
||
.judges a:hover {
|
||
background: #f9fff6;
|
||
}
|
||
|
||
.judge-grid {
|
||
display: grid;
|
||
grid-template-columns: 100px 1fr;
|
||
gap: 20px;
|
||
border: 1px dashed;
|
||
border-radius: 10px;
|
||
padding: 10px;
|
||
}
|
||
.judge-photo {
|
||
display: inline-flex;
|
||
}
|
||
.judge-name h5 {
|
||
margin-bottom: 5px !important;
|
||
margin-top: 10px !important;
|
||
}
|
||
.judge-photo img {
|
||
width: 100px;
|
||
height: 100px;
|
||
border-radius: 50px;
|
||
}
|
||
@media screen and (max-width: 600px) {
|
||
.data-grid {
|
||
grid-template-columns: 100px 1fr 70px;
|
||
}
|
||
.data-grid-row {
|
||
padding: 10px;
|
||
}
|
||
.judges {
|
||
grid-template-columns: auto;
|
||
}
|
||
}</style><style class="wpcode-css-snippet">.podium {
|
||
display: flex;
|
||
align-items: flex-end;
|
||
gap: 20px;
|
||
justify-content: center;
|
||
}
|
||
.podium__item {
|
||
min-width: 200px;
|
||
color: #1b1b1b;
|
||
text-align: center;
|
||
}
|
||
|
||
.podium__rank {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-size: 35px;
|
||
color: #1b1b1b;
|
||
border-radius: 24px 24px 0 0;
|
||
}
|
||
|
||
.podium__city {
|
||
text-align: center;
|
||
padding: 0 .5rem;
|
||
}
|
||
|
||
.podium__number {
|
||
width: 27px;
|
||
height: 75px;
|
||
}
|
||
|
||
.podium .first {
|
||
min-height: 350px;
|
||
padding: 20px;
|
||
background:
|
||
#dbd9f7;
|
||
}
|
||
|
||
.podium .second {
|
||
min-height: 250px;
|
||
background: #fce2eb;
|
||
}
|
||
|
||
.podium .third {
|
||
min-height: 150px;
|
||
background: #dbf4f4;
|
||
}
|
||
@media screen and (max-width: 600px) {
|
||
.podium {
|
||
display: grid;
|
||
gap: 0;
|
||
}
|
||
.podium__item.podium-first {
|
||
grid-row-start: 1;
|
||
}
|
||
}
|
||
|
||
/* Slideshow container */
|
||
.slideshow-container {
|
||
max-width: 1000px;
|
||
position: relative;
|
||
margin: auto auto 20px auto;
|
||
padding-bottom: 40px;
|
||
}
|
||
|
||
/* Next & previous buttons */
|
||
.prev, .next {
|
||
|
||
cursor: pointer;
|
||
position: absolute;
|
||
top: 45%;
|
||
width: auto;
|
||
padding: 16px;
|
||
margin-top: -22px;
|
||
color: #0b996f;
|
||
font-weight: bold;
|
||
font-size: 18px;
|
||
transition: 0.6s ease;
|
||
border-radius: 0 3px 3px 0;
|
||
user-select: none;
|
||
}
|
||
|
||
/* Position the "next button" to the right */
|
||
.next {
|
||
right: 0;
|
||
border-radius: 3px 0 0 3px;
|
||
}
|
||
|
||
/* On hover, add a black background color with a little bit see-through */
|
||
.prev:hover, .next:hover {
|
||
background-color: rgb(232 254 223);
|
||
}
|
||
|
||
/* Caption text */
|
||
.caption-text {
|
||
background: #e8fedf8f;
|
||
color: #0b996f;
|
||
font-size: 15px;
|
||
padding: 8px 12px;
|
||
position: absolute;
|
||
bottom: -2px;
|
||
width: 100%;
|
||
text-align: center;
|
||
}
|
||
|
||
/* Number text (1/3 etc) */
|
||
.numbertext {
|
||
color: #f2f2f2;
|
||
font-size: 12px;
|
||
padding: 8px 12px;
|
||
position: absolute;
|
||
top: 0;
|
||
}
|
||
|
||
/* The dots/bullets/indicators */
|
||
.dot {
|
||
cursor: pointer;
|
||
height: 15px;
|
||
width: 15px;
|
||
margin: 0 2px;
|
||
background-color: #96cbb7;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
transition: background-color 0.6s ease;
|
||
}
|
||
|
||
.active, .dot:hover {
|
||
background-color: #0b996f;
|
||
}
|
||
|
||
/* Fading animation */
|
||
.fade {
|
||
animation-name: fade;
|
||
animation-duration: 1.5s;
|
||
}
|
||
|
||
@keyframes fade {
|
||
from {opacity: .4}
|
||
to {opacity: 1}
|
||
}
|
||
|
||
/* On smaller screens, decrease text size */
|
||
@media only screen and (max-width: 300px) {
|
||
.prev, .next,.text {font-size: 11px}
|
||
}</style><style class="wpcode-css-snippet">@font-face {
|
||
font-display: swap;
|
||
font-family: tomato-grotesk-regular;
|
||
font-weight: 400;
|
||
src: url(https://designsystem.brevo.com/designsystem/20da0e968a325ad7053e.eot);
|
||
src: url(https://designsystem.brevo.com/designsystem/20da0e968a325ad7053e.eot?#iefix) format("embedded-opentype"),url(https://designsystem.brevo.com/designsystem/c69f9599d6da6a5cd427.woff2) format("woff2"),url(https://designsystem.brevo.com/designsystem/25d91f8bdc1c16195b4d.woff) format("wotff")
|
||
}
|
||
|
||
@font-face {
|
||
font-display: swap;
|
||
font-family: tomato-grotesk-bold;
|
||
font-weight: 700;
|
||
src: url(https://designsystem.brevo.com/designsystem/2e1c33cda9d474eac0ca.eot);
|
||
src: url(https://designsystem.brevo.com/designsystem/2e1c33cda9d474eac0ca.eot?#iefix) format("embedded-opentype"),url(https://designsystem.brevo.com/designsystem/5f348e586fe63ce239cb.woff2) format("woff2"),url(https://designsystem.brevo.com/designsystem/ca2d703262f2c42b9332.woff) format("woff")
|
||
}
|
||
|
||
@font-face {
|
||
font-display: swap;
|
||
font-family: tomato-grotesk-semibold;
|
||
font-weight: 600;
|
||
src: url(https://designsystem.brevo.com/designsystem/675d409330175c2afea3.eot);
|
||
src: url(https://designsystem.brevo.com/designsystem/675d409330175c2afea3.eot?#iefix) format("embedded-opentype"),url(https://designsystem.brevo.com/designsystem/25686c99905194b41e07.woff2) format("woff2"),url(https://designsystem.brevo.com/designsystem/be82567fe7313924a478.woff) format("wotff")
|
||
}
|
||
|
||
@font-face {
|
||
font-display: swap;
|
||
font-family: tomato-grotesk-medium;
|
||
font-weight: 500;
|
||
src: url(https://designsystem.brevo.com/designsystem/48723423b8339b44d147.woff) format("wotff"),url(https://designsystem.brevo.com/designsystem/802ce516d00330864f24.woff2) format("woff2")
|
||
}
|
||
|
||
@font-face {
|
||
font-display: swap;
|
||
font-family: inter-regular;
|
||
font-weight: 400;
|
||
src: url(https://designsystem.brevo.com/designsystem/c8ba52b05a9ef10f4758.woff2) format("truetype")
|
||
}
|
||
|
||
@font-face {
|
||
font-display: swap;
|
||
font-family: inter-medium;
|
||
font-weight: 500;
|
||
src: url(https://designsystem.brevo.com/designsystem/293fd13dbca5a3e450ef.woff2) format("truetype")
|
||
}
|
||
|
||
@font-face {
|
||
font-display: swap;
|
||
font-family: inter-semibold;
|
||
font-weight: 600;
|
||
src: url(https://designsystem.brevo.com/designsystem/b5f0f109bc88052d4000.woff2) format("truetype")
|
||
}
|
||
|
||
@font-face {
|
||
font-display: swap;
|
||
font-family: inter-bold;
|
||
font-weight: 700;
|
||
src: url(https://designsystem.brevo.com/designsystem/ec64ea577b0349e055ad.woff2) format("truetype")
|
||
}
|
||
.tabcontent {
|
||
font-family: inter-regular;
|
||
}
|
||
.tabcontent h1, .tabcontent h2, .tabcontent h3,
|
||
.tabcontent h4, .tabcontent h5, .tabcontent h6 {
|
||
font-family: tomato-grotesk-semibold;
|
||
}
|
||
|
||
/* Core styles/functionality */
|
||
.accordion .tab {
|
||
overflow: hidden;
|
||
width: 100%;
|
||
border: 1px dashed;
|
||
padding: 2px;
|
||
margin: 0 0 20px 0;
|
||
border-radius: 10px;
|
||
font-family: inter-regular;
|
||
}
|
||
.accordion .tab.tab-1 {
|
||
border-color: #6358de;
|
||
}
|
||
.accordion .tab.tab-2 {
|
||
border-color: #ef6639;
|
||
}
|
||
.accordion .tab.tab-3 {
|
||
border-color: #1eb8b8;
|
||
}
|
||
.accordion .tab.tab-4 {
|
||
border-color: #f3397e;
|
||
}
|
||
|
||
|
||
.tab input {
|
||
position: absolute;
|
||
opacity: 0;
|
||
z-index: -1;
|
||
}
|
||
.tab__content {
|
||
max-height: 0;
|
||
overflow: hidden;
|
||
transition: all 0.35s;
|
||
}
|
||
.tab__content h4 {
|
||
margin: 0 0 10px 0;
|
||
}
|
||
.tab input:checked ~ .tab__content {
|
||
max-height: max-content;
|
||
padding: 15px;
|
||
}
|
||
.tab input:checked ~ .tab__content p {
|
||
padding: 0;
|
||
}
|
||
|
||
/* Visual styles */
|
||
.accordion {
|
||
overflow: hidden;
|
||
}
|
||
.tab__label,
|
||
.tab__close {
|
||
display: flex;
|
||
color: #1b1837;
|
||
background: #227093;
|
||
cursor: pointer;
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
}
|
||
.tab__label {
|
||
justify-content: space-between;
|
||
padding: 1rem;
|
||
border-radius: 7px;
|
||
font-family: tomato-grotesk-semibold;
|
||
}
|
||
.tab__label::after {
|
||
content: "\276F";
|
||
width: 1em;
|
||
height: 1em;
|
||
text-align: center;
|
||
transform: rotate(90deg);
|
||
transition: all 0.35s;
|
||
}
|
||
.tab input:checked + .tab__label::after {
|
||
transform: rotate(270deg);
|
||
}
|
||
.tab__content p {
|
||
margin: 0;
|
||
padding: 1rem;
|
||
}
|
||
.tab__close {
|
||
justify-content: flex-end;
|
||
padding: 0.5rem 1rem;
|
||
font-size: 0.75rem;
|
||
}
|
||
.accordion--radio {
|
||
--theme: var(--secondary);
|
||
}
|
||
|
||
/* Arrow animation */
|
||
.tab input:not(:checked) + .tab__label:hover::after {
|
||
animation: bounce .5s infinite;
|
||
}
|
||
@keyframes bounce {
|
||
25% {
|
||
transform: rotate(90deg) translate(.25rem);
|
||
}
|
||
75% {
|
||
transform: rotate(90deg) translate(-.25rem);
|
||
}
|
||
}
|
||
.event-card {
|
||
padding: 20px 30px;
|
||
background-color: white;
|
||
position: relative;
|
||
border-radius: 24px;
|
||
margin: 10px 0 40px 0;
|
||
transition: transform 250ms ease 0s, box-shadow 250ms ease 0s, color 250ms ease 0s;
|
||
}
|
||
.event-card:hover, .event-card:focus {
|
||
transform: translateY(-0.25rem);
|
||
box-shadow: rgb(68 63 140) 0px 2px 4px, rgba(0, 0, 0, 0.12) 0px 5px 10px;
|
||
}
|
||
.card-1 {
|
||
background: #dbd9f7;
|
||
}
|
||
.card-2 {
|
||
background: #ffe7e0;
|
||
}
|
||
.card-3 {
|
||
background: #dbf4f4;
|
||
}
|
||
|
||
.card-4 {
|
||
background: #fce2eb;
|
||
}
|
||
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ul li {
|
||
margin-bottom: 10px;
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ul li::before {
|
||
content: "\2022";
|
||
color: #000;
|
||
font-weight: bold;
|
||
display: inline-block;
|
||
padding-right: 11px;
|
||
margin-left: -22px;
|
||
top: 1px;
|
||
position: relative;
|
||
font-size: 24px;
|
||
}
|
||
.sib-blog.sib-hackathon .sib-single-page h1 {
|
||
font-size: 0 !important;
|
||
line-height: 0 !important;
|
||
}
|
||
.sib-blog.sib-hackathon .sib-single-page h1:after {
|
||
content: " ";
|
||
background: url(https://engineering.brevo.com/wp-content/uploads/2023/10/Hackstone-e1698423504612.png);
|
||
position: relative;
|
||
display: inline-block;
|
||
height: 100px;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
width: 500px;
|
||
background-size: contain;
|
||
background-repeat: no-repeat;
|
||
margin-left: -60px;
|
||
}
|
||
.w3-content {
|
||
max-width: 780px;
|
||
}
|
||
.w3-display-left {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 0%;
|
||
transform: translate(0%,-50%);
|
||
-ms-transform: translate(-0%,-50%);
|
||
}
|
||
.w3-display-right {
|
||
position: absolute;
|
||
top: 50%;
|
||
right: 0%;
|
||
transform: translate(0%,-50%);
|
||
-ms-transform: translate(0%,-50%);
|
||
}
|
||
.w3-content, .w3-auto {
|
||
margin-left: auto;
|
||
margin-right: auto;
|
||
}
|
||
.w3-tooltip, .w3-display-container {
|
||
position: relative;
|
||
}
|
||
.w3-btn, .w3-button {
|
||
border: none;
|
||
display: inline-block;
|
||
padding: 8px 16px;
|
||
vertical-align: middle;
|
||
overflow: hidden;
|
||
text-decoration: none;
|
||
color: inherit;
|
||
background-color: inherit;
|
||
text-align: center;
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
}
|
||
.w3-black, .w3-hover-black:hover {
|
||
color: #fff!important;
|
||
background-color: #000!important;
|
||
}
|
||
/* .mySlides {display:none;} */
|
||
|
||
@media screen and (max-width: 420px) {
|
||
.sib-blog.sib-hackathon .sib-single-page h1:after {
|
||
width: 350px;
|
||
margin-left: 0;
|
||
}
|
||
}
|
||
@media screen and (max-width: 640px) {
|
||
footer .row.links-section {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 40px 20px;
|
||
}
|
||
}
|
||
|
||
.about-content, .about-list {
|
||
display: flex;
|
||
}
|
||
@media screen and (max-width: 640px) {
|
||
.about-content {
|
||
flex-direction: column;
|
||
}
|
||
.about-list {
|
||
flex-direction: column;
|
||
}
|
||
}
|
||
</style><style class="wpcode-css-snippet">/* The actual timeline (the vertical ruler) */
|
||
.timeline {
|
||
position: relative;
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
/* The actual timeline (the vertical ruler) */
|
||
.timeline::after {
|
||
content: '';
|
||
position: absolute;
|
||
width: 3px;
|
||
background: linear-gradient(to bottom, rgba(230, 230, 230, 0) 0%, #0b996f 10%, #0b996f 90%, rgba(230, 230, 230, 0) 100%);
|
||
top: 0;
|
||
bottom: 0;
|
||
left: 50%;
|
||
margin-left: -3px;
|
||
opacity: 0.5;
|
||
}
|
||
|
||
/* Container around content */
|
||
.timeline-container {
|
||
padding: 10px 40px;
|
||
position: relative;
|
||
background-color: inherit;
|
||
width: 50%;
|
||
}
|
||
|
||
/* The circles on the timeline */
|
||
.timeline-container::after {
|
||
content: '';
|
||
position: absolute;
|
||
width: 25px;
|
||
height: 25px;
|
||
right: -11px;
|
||
background-color: white;
|
||
border: 4px solid #0b996f;
|
||
top: 15px;
|
||
border-radius: 50%;
|
||
z-index: 1;
|
||
}
|
||
|
||
/* Place the container to the left */
|
||
.left {
|
||
left: 0;
|
||
}
|
||
|
||
/* Place the container to the right */
|
||
.right {
|
||
left: 50%;
|
||
}
|
||
|
||
/* Add arrows to the left container (pointing right) */
|
||
.left::before {
|
||
content: " ";
|
||
height: 0;
|
||
position: absolute;
|
||
top: 22px;
|
||
width: 0;
|
||
z-index: 1;
|
||
right: 30px;
|
||
border: medium solid #0b996f;
|
||
border-width: 10px 0 10px 10px;
|
||
border-color: transparent transparent transparent #0b996f;
|
||
}
|
||
|
||
/* Add arrows to the right container (pointing left) */
|
||
.right::before {
|
||
content: " ";
|
||
height: 0;
|
||
position: absolute;
|
||
top: 22px;
|
||
width: 0;
|
||
z-index: 1;
|
||
left: 30px;
|
||
border: medium solid #0b996f;
|
||
border-width: 10px 10px 10px 0;
|
||
border-color: transparent #0b996f transparent transparent;
|
||
}
|
||
|
||
/* Fix the circle for containers on the right side */
|
||
.right::after {
|
||
left: -16px;
|
||
}
|
||
.container .date {
|
||
position: absolute;
|
||
display: inline-block;
|
||
top: 15px;
|
||
text-align: center;
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
color: #006E51;
|
||
text-transform: uppercase;
|
||
letter-spacing: 1px;
|
||
z-index: 1;
|
||
width: 200px;
|
||
}
|
||
.timeline-container.left .date {
|
||
right: -240px;
|
||
text-align: left;
|
||
}
|
||
.timeline-container.right .date {
|
||
left: -240px;
|
||
text-align: right;
|
||
}
|
||
/* The actual content */
|
||
.content {
|
||
padding: 20px 30px;
|
||
background-color: white;
|
||
position: relative;
|
||
border-radius: 10px;
|
||
box-shadow: 0 10px 40px 0 rgba(0, 0, 0, 0.1);
|
||
|
||
}
|
||
.timeline-container .content h4 {
|
||
margin-top: 0 !important;
|
||
}
|
||
.timeline-container.left .content {
|
||
border-right: 4px solid #0b996f;
|
||
}
|
||
.timeline-container.right .content {
|
||
border-left: 4px solid #0b996f;
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .timeline-container .content p:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
/* Media queries - Responsive timeline on screens less than 600px wide */
|
||
@media screen and (max-width: 600px) {
|
||
/* Place the timelime to the left */
|
||
.timeline::after {
|
||
left: 50%;
|
||
z-index: -1;
|
||
}
|
||
|
||
/* Full-width containers */
|
||
.container {
|
||
width: 100%;
|
||
padding-left: 70px;
|
||
padding-right: 25px;
|
||
}
|
||
|
||
/* Make sure that all arrows are pointing leftwards */
|
||
.container::before {
|
||
left: 60px;
|
||
border: medium solid #0b996f;
|
||
border-width: 10px 10px 10px 0;
|
||
border-color: transparent white transparent transparent;
|
||
}
|
||
|
||
/* Make sure all circles are at the same spot */
|
||
.left::after, .right::after {
|
||
left: 15px;
|
||
}
|
||
|
||
/* Make all right containers behave like the left ones */
|
||
.right {
|
||
left: 0%;
|
||
}
|
||
}
|
||
@media screen and (max-width: 600px) {
|
||
.timeline {
|
||
padding-top: 60px;
|
||
}
|
||
.timeline-container {
|
||
width: 100%;
|
||
margin-bottom: 80px;
|
||
padding: 10px 0;
|
||
}
|
||
.timeline-container.left .date {
|
||
right: 0;
|
||
text-align: left;
|
||
left: 0;
|
||
top: -65px;
|
||
}
|
||
.timeline-container::after, .timeline::after {
|
||
display: none;
|
||
}
|
||
.left::before, .right::before {
|
||
content: " ";
|
||
height: 0;
|
||
position: absolute;
|
||
top: 6px;
|
||
width: 0;
|
||
z-index: 1;
|
||
right: 30px;
|
||
border: medium solid #0b996f;
|
||
border-width: 0px 10px 10px 10px;
|
||
border-color: transparent transparent #0b996f transparent;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
}
|
||
.timeline-container.left .content, .timeline-container.right .content {
|
||
border-top: 4px solid #0b996f;
|
||
border-left: 0;
|
||
border-right: 0;
|
||
}
|
||
.timeline-container.right .date {
|
||
left: 0;
|
||
text-align: left;
|
||
top: -65px;
|
||
}
|
||
}</style><style class="wpcode-css-snippet">.sib-blog .sib-single-page .sib-post-content .sib-post-content-text a {
|
||
color: #000;
|
||
}
|
||
.tab button {
|
||
font-family: inter-regular !important;
|
||
}
|
||
.tab button.active {
|
||
color: #6358de !important;
|
||
font-weight: 600;
|
||
background-color: #efeefc !important;
|
||
border-radius: 8px;
|
||
}
|
||
.tab button:hover {
|
||
background-color: #efeefc !important;
|
||
border-radius: 8px;
|
||
}
|
||
.custom-list li {
|
||
display: inline-block !important;
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ol li {
|
||
margin: 1em 0;
|
||
color: #1b1b1b;
|
||
border: 1px dashed #777;
|
||
border-radius: 10px;
|
||
padding: 1em;
|
||
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ol li:before,
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ol li:hover:after {
|
||
background: #009688;
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ol li:after,
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ol li:hover:after {
|
||
background: none;
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ol li:before {
|
||
top: 20px;
|
||
left: -40px;
|
||
width: 1.6em;
|
||
height: 1.6em;
|
||
line-height: 1.6em;
|
||
}
|
||
@media screen and (max-width: 600px) {
|
||
.sib-hackathon .container {
|
||
padding-left: 0;
|
||
padding-right: 0;
|
||
}
|
||
.sib-blog .sib-single-page .sib-post-content .sib-post-content-text .tabcontent ol li:before {
|
||
left: -30px;
|
||
}
|
||
}</style><style class="wpcode-css-snippet">@media (max-width: 640px) {
|
||
.sib-event-banner {
|
||
margin-top: 55px !important;
|
||
margin-bottom: -10px;
|
||
}
|
||
}</style> <style>
|
||
@font-face {
|
||
font-family: OpenSans-Regular;
|
||
src: url(https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/fonts/OpenSans-Regular.ttf);
|
||
font-weight: normal;
|
||
}
|
||
|
||
@font-face{
|
||
font-family:PublicoHeadline-Bold-Web;
|
||
src:url(https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/fonts/PublicoHeadline-Bold-Web.woff2);
|
||
font-display:swap;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
(function(w, d, s, l, i) {
|
||
w[l] = w[l] || []
|
||
w[l].push({
|
||
'gtm.start': new Date().getTime(),
|
||
event: 'gtm.js'
|
||
})
|
||
var f = d.getElementsByTagName(s)[0],
|
||
j = d.createElement(s),
|
||
dl = l != 'dataLayer' ? '&l=' + l : ''
|
||
j.async = true
|
||
j.src =
|
||
'https://www.googletagmanager.com/gtm.js?id=' + i + dl
|
||
f.parentNode.insertBefore(j, f)
|
||
})(window, document, 'script', 'dataLayer', 'GTM-MKMDTST')
|
||
</script>
|
||
|
||
</head>
|
||
|
||
<body class="post-template-default single single-post postid-554 single-format-standard" >
|
||
<!-- Google Tag Manager (noscript) -->
|
||
<noscript>
|
||
<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MKMDTST" height="0" width="0" style="display:none;visibility:hidden"></iframe>
|
||
</noscript>
|
||
<!-- End Google Tag Manager (noscript) -->
|
||
<header>
|
||
<div class="wrapper">
|
||
<div class="container-logo">
|
||
<a href="https://engineering.brevo.com/" class="logo">
|
||
<img class="logo-color skip-lazy" src="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/images/common/logo-color.svg" alt=""/>
|
||
</a>
|
||
<div class="burger">
|
||
<div class="line"></div>
|
||
<div class="line"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="sib-blog">
|
||
<div class="container-fluid mt-5 pt-3 sib-single-page" data-view="main">
|
||
<div class="container">
|
||
|
||
<div class="row mt-5 mb-4 sib-single-date">
|
||
<span>June 30, 2022</span>
|
||
</div>
|
||
<h1 class="text-center mt-3">Streamlining our incident responses</h1>
|
||
|
||
|
||
<div class="sib-post-content mt-3 row">
|
||
<div class="col-12 col-sm-9 offset-sm-1">
|
||
<div class="row mb-2">
|
||
<div class="col-12 col-md-5 sib-reading-time mt-4">
|
||
<svg height='18px' width='18px' fill="#878787" version="1.1" x="0px" y="0px"
|
||
viewBox="0 0 100 100">
|
||
<g transform="translate(0,-952.36218)">
|
||
<path
|
||
style="text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;color:#000000;enable-background:accumulate;"
|
||
d="m 50.000002,970.36213 c -17.6612,0 -32,14.3388 -32,31.99997 0,17.6612 14.3387,32.0001 32,32.0001 17.661196,0 31.999996,-14.3389 31.999996,-32.0001 0,-17.66117 -14.3388,-31.99997 -31.999996,-31.99997 z m 0,2 c 16.5803,0 29.999996,13.4197 29.999996,29.99997 0,16.5803 -13.419696,30.0001 -29.999996,30.0001 -16.5803,0 -30,-13.4198 -30,-30.0001 0,-16.58027 13.4196,-29.99997 30,-29.99997 z m 0,10 c -0.5523,0 -1,0.4477 -1,1 l 0,18.99997 c 0,0.2762 0.10035,0.5378 0.28125,0.7188 l 12.03125,12 c 0.3905,0.3905 1.01575,0.3905 1.40625,0 0.3906,-0.3906 0.3906,-1.0157 0,-1.4063 l -11.71875,-11.75 0,-18.56247 c 0,-0.5523 -0.4477,-1 -1,-1 z"
|
||
fill="#000000" fill-opacity="1" stroke="none" marker="none" visibility="visible"
|
||
display="inline" overflow="visible"></path>
|
||
</g>
|
||
</svg>
|
||
<span>Reading time about 19 min </span>
|
||
</div>
|
||
<div class="sib-post-rating col-12 col-md-7 mt-4">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sib-post-thumbnail">
|
||
<img width="2000" height="1334" src="https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="Firefighters" srcset="https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash.jpg 2000w, https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash-300x200.jpg 300w, https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash-1024x683.jpg 1024w, https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash-768x512.jpg 768w, https://engineering.brevo.com/wp-content/uploads/2022/06/firefighters-connor-betts-unsplash-1536x1025.jpg 1536w" sizes="(max-width: 2000px) 100vw, 2000px" /> </div>
|
||
|
||
<div class="row mt-5 mb-5 sib-post-content-text">
|
||
|
||
<p>At <a href="https://www.sendinblue.com" target="_blank" rel="noreferrer noopener">Sendinblue</a>, we send billions of emails per month. Keeping our services up and running and ensuring our customers’ businesses are not impacted is not an option. No one, even FAANG companies, escapes outages. An email must go through different services before it lands in the user mailbox. It happens that one (or many) of these layers fail and disrupt partially or totally the Outbound Email delivery. In this article, we will drive you through our journey of building SIMA (Slack Incident Management Application), learning from our outages and streamlining our responses to incidents to make Sendinblue a world-class platform.</p>
|
||
|
||
|
||
|
||
<p>SIMA and this article are highly inspired by a ManoMano Tech team’s article: <a href="https://medium.com/manomano-tech/incident-management-with-a-bot-7e80deb5b5e5" target="_blank" rel="noreferrer noopener">Incident Management with a bot</a></p>
|
||
|
||
|
||
|
||
<h2>Problem statement</h2>
|
||
|
||
|
||
|
||
<p>Prior to SIMA, incident responses (diagnosis, discussions, etc…) were happening in single massive Slack threads.</p>
|
||
|
||
|
||
|
||
<p>Most of the time, incidents’ timelines were shaped that way:</p>
|
||
|
||
|
||
|
||
<ul><li>a slack message posted in a production issues-related channel (either from Customer Care or engineering team members)</li><li>reporters were posting updates within a slack thread until the issue has been fixed</li><li>eventually, post mortem was written and actions taken</li></ul>
|
||
|
||
|
||
|
||
<p>The thread approach can work in a small organization (or for small incidents) but the more complex or longer the incident is the harder it is to keep up. It became obvious we were not suited to respond to production incidents.</p>
|
||
|
||
|
||
|
||
<p>We pulled ourselves together and identified some bottlenecks:</p>
|
||
|
||
|
||
|
||
<ul><li>no clear and streamlined way to declare an incident. We had a Slack workflow but it was not much used</li><li>to getting up to speed when you join an incident later took a lot of time and effort (reading a 100 messages thread is time-consuming)</li><li>post-mortems were not systematically created. We strongly believe they are key to improving and communicating (internally and externally) as they help us</li><li>no root cause tracking: knowing your weakness is not an option</li><li>Nobody tracked MTTR. We had no standard way to record the start and end time of the incident</li><li>internal communication was okay but we knew we could do better</li></ul>
|
||
|
||
|
||
|
||
<p>These bottlenecks and the fact that Sendinblue’s team and customers list were growing (and still) at a fast pace was impacting our ability to manage incidents efficiently. For that reason, we decided to re-think our incident responses. We started building SIMA to help us improve on multiple aspects: resolution, communication, and analysis.</p>
|
||
|
||
|
||
|
||
<h2>What is incident management?</h2>
|
||
|
||
|
||
|
||
<p>Incident management is the process of managing disruptions, responding to unplanned events or service interruptions, taking actions to restore the services to its operational state and ensuring all the stakeholders involved are well informed about each stage of the incident timeline. Incident management is a very common practice in the software industry and companies follow it to mitigate the business impact. It triggers when an incident happens and ends when an incident is recovered.</p>
|
||
|
||
|
||
|
||
<h2>The incident metrics</h2>
|
||
|
||
|
||
|
||
<blockquote class="wp-block-quote"><p>You can’t improve what you don’t measure</p></blockquote>
|
||
|
||
|
||
|
||
<p>We had to change the way we were managing incidents so that we can learn from them and, even better, take advantage of them. We strongly believe that the reliability of our platform is key to the success of our customer’s business. Everyone dreams of 100% availability but it is nearly impossible to achieve it (at a reasonable cost and effort). Knowing that we all have to embrace failure and try to achieve the slowest downtime possible.</p>
|
||
|
||
|
||
|
||
<h3>Creating/saving the metrics</h3>
|
||
|
||
|
||
|
||
<p>We wanted to approach our incident management the same way as SRE does for every system: create metrics and use them to get better.</p>
|
||
|
||
|
||
|
||
<p>Every time an incident is raised, we request the reporter to provide some information:</p>
|
||
|
||
|
||
|
||
<ul><li><strong>domain</strong>: The affected domain of Sendinblue’s services (ex: API, Outbound Email Delivery, global, etc…)</li><li><strong>descriptive information</strong>: a summary and clear description explaining the situation (summary and description). </li><li><strong>impact</strong>: the number of clients affected by the outage. This information might be unknown at the time of the incident opening and filled in later.</li><li><strong>severity</strong>: long story short, how does it affect our customers’ business</li></ul>
|
||
|
||
|
||
|
||
<figure class="wp-block-image size-full"><img loading="lazy" width="420" height="585" src="https://engineering.sendinblue.com/wp-content/uploads/2022/06/app.slack_.com_client_T03FYB9QV_C028ZSE0VM5-736x1024-3.jpg" alt="open incident modal" class="wp-image-625" srcset="https://engineering.brevo.com/wp-content/uploads/2022/06/app.slack_.com_client_T03FYB9QV_C028ZSE0VM5-736x1024-3.jpg 420w, https://engineering.brevo.com/wp-content/uploads/2022/06/app.slack_.com_client_T03FYB9QV_C028ZSE0VM5-736x1024-3-215x300.jpg 215w" sizes="(max-width: 420px) 100vw, 420px" /><figcaption>Open Incident Modal</figcaption></figure>
|
||
|
||
|
||
|
||
<p>Later in the incident lifecycle, incident actors have the opportunity to provide more details about the incident (start date, notes, etc…)</p>
|
||
|
||
|
||
|
||
<p>On top of this information, given by stakeholders, every incident update or taken action leads to a database entry (events).</p>
|
||
|
||
|
||
|
||
<ul><li><strong>MTTR(recovery)</strong> – Mean Time To Recovery, the time it takes to get the system back since the outage started.</li></ul>
|
||
|
||
|
||
|
||
<ul><li><strong>MTTA(acknowledge)</strong> – Mean Time To Acknowledge: the time it takes to get the incident from open to investigating state. Some situations may not be predictable and may miss proper monitors and alerts. The faster we get the alert and we get the expert in, the faster we can get the system back.</li></ul>
|
||
|
||
|
||
|
||
<ul><li><strong>MTTR(repair)</strong> – Mean Time To Repair, the duration it takes a domain expert to get the system in a normal state. It includes understanding the problem, identifying the root cause, and fixing the issue.</li></ul>
|
||
|
||
|
||
|
||
<figure class="wp-block-image size-full"><img loading="lazy" width="1024" height="539" src="https://engineering.sendinblue.com/wp-content/uploads/2022/06/incident-timeline-1-1024x539-1.jpeg" alt="incident response timeline" class="wp-image-613" srcset="https://engineering.brevo.com/wp-content/uploads/2022/06/incident-timeline-1-1024x539-1.jpeg 1024w, https://engineering.brevo.com/wp-content/uploads/2022/06/incident-timeline-1-1024x539-1-300x158.jpeg 300w, https://engineering.brevo.com/wp-content/uploads/2022/06/incident-timeline-1-1024x539-1-768x404.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Incident Timeline</figcaption></figure>
|
||
|
||
|
||
|
||
<p>I highly recommend you to read the Atlassian’s if you want to learn more incident metrics: <a href="https://www.atlassian.com/incident-management/kpis/common-metrics" target="_blank" rel="noreferrer noopener">Common Metrics</a></p>
|
||
|
||
|
||
|
||
<p>At this point, we were able to generate precise metrics from events generated by SIMA’s users. We finally could improve our incident responses.</p>
|
||
|
||
|
||
|
||
<h3>Improving the time to Acknowledge (MTTA)</h3>
|
||
|
||
|
||
|
||
<p>Our system runs 24/7 and 365 days per year and has a direct impact on our customers’ business. They require experts to be available at any time in case of emergency. The faster you are able to get the right person to investigate the faster you reach the recovery state.</p>
|
||
|
||
|
||
|
||
<p>SIMA allows 2 ways of opening an incident:</p>
|
||
|
||
|
||
|
||
<ul><li><strong>Slack app UI</strong>: anyone at the company can (theoretically) open an incident if the situation requires it. Most of the time, incidents are opened by engineers or Customer Care team members.</li><li><strong>Webhooks</strong>: we recently rolled out a way to open incidents from the outside of Slack. We’ve defined some monitors on critical aspects of Sendinblue (ex: Outbound Email Delivery, API) and expect them to open an incident automatically lowering the time to open the incident (and so the time to acknowledge)</li></ul>
|
||
|
||
|
||
|
||
<p>Behind the scenes and as soon as an incident is opened, SIMA performs some actions in this order</p>
|
||
|
||
|
||
|
||
<ul><li>creates a dedicated slack channel (ex incident_MM_DD_summary-slug)</li><li>we raised an alert on PagerDuty for the service (domain) impacted. The alert sent contains a deep-link to the slack channel, it lowers the time to join the conversation to its minimum.</li></ul>
|
||
|
||
|
||
|
||
<p>Thanks to this, we are able to bring domain experts very quickly to an incident and make the MTTA as low as possible. The runbook we have is a bit more complex than these 2 steps but you understand that automating as much as possible is key to reactiveness.</p>
|
||
|
||
|
||
|
||
<h3>Reducing the MTTR (Mean Time to Repair)</h3>
|
||
|
||
|
||
|
||
<p>The time to repair period starts as soon as the incident is acknowledged. Different from the Time To Recovery, it focuses only on the operational part and calculates the time it takes to identify and fix the root cause.</p>
|
||
|
||
|
||
|
||
<p>A faulty release is trivial to roll back and should not take long as soon as it has been identified (most of the time 😉 ) but infrastructure outages can be tricky and complex to identify. An example comes to my mind where we lost a switch within a data center last year that lead to a <a href="https://status.sendinblue.com/pages/incident/586a5ae632dde2fc5b0013c1/61149f59c34053098f1c1b86" target="_blank" rel="noreferrer noopener">full day of disruption</a> .(We took concrete action, afterward, to make sure this issue does not happen in the future)</p>
|
||
|
||
|
||
|
||
<p>Our take on lowering the root cause finding: to provide our detectives the tools that would reduce the time to take the temperature</p>
|
||
|
||
|
||
|
||
<h4>Easy access to information</h4>
|
||
|
||
|
||
|
||
<p>Between the time, the expert receives the PagerDuty alert and the time they join the incident’s channel, SIMA executes some actions:</p>
|
||
|
||
|
||
|
||
<ul><li><strong>share info in a dedicated channel:</strong> post a message in the incident channel (title, description, service, severity, and impact) and pin it within the channel</li><li><strong>invite stakeholders:</strong> at the moment only the reporter is invited as they may have more detail about the current issue. The on-call person will join soon after</li><li><strong>broadcast the incident:</strong> post a message within the company-wide channel dedicated to production issues (bots only)</li></ul>
|
||
|
||
|
||
|
||
<p>These automated actions come in addition to slack commands we implemented</p>
|
||
|
||
|
||
|
||
<p>Having access to information is critical when you are under heavy fire, pushing the critical and most important one ensures our firefighters get up to speed as fast as possible</p>
|
||
|
||
|
||
|
||
<h4><strong>Defining roles</strong></h4>
|
||
|
||
|
||
|
||
<p>In order to keep things clean and organized, we’ve defined 2 roles (Inspiration: <a href="https://www.atlassian.com/incident-management/incident-response/roles-responsibilities" target="_blank" rel="noreferrer noopener">Roles and responsibilities</a>)</p>
|
||
|
||
|
||
|
||
<ul><li><strong>Incident Manager:</strong> in charge of driving efforts and people in the right direction, take the decisions to get the situation back to normal as fast and smoothly as possible.</li><li><strong>Communication lead:</strong> In charge of both internal and external communication, this person communicates with the Incident Manager allowing operational people to focus on what matters the most: recover</li></ul>
|
||
|
||
|
||
|
||
<p>These roles have been in place for months and seem to be adopted. They prevent duplication of work and unknown performed in the dark actions. The incident manager drives the efforts and activities of people while the communication lead follows the situation and asks for clarification if needed.</p>
|
||
|
||
|
||
|
||
<h4><strong>Actionable in every situation</strong></h4>
|
||
|
||
|
||
|
||
<p>Messages with any Call To Action do not cut the mustard. Every event, actions, and messages are opportunities to save time and reduce the time to repair.</p>
|
||
|
||
|
||
|
||
<p>Example of CTA we display given situations:</p>
|
||
|
||
|
||
|
||
<p>When someone joins an incident’s channel:</p>
|
||
|
||
|
||
|
||
<ul><li>show help</li><li>Become incident manager</li><li>update incident state</li><li>Show Incident info</li><li>etc…</li></ul>
|
||
|
||
|
||
|
||
<p>When someone mistypes a command:</p>
|
||
|
||
|
||
|
||
<ul><li>show help</li><li>Show Incident info</li><li>update incident state</li><li>edit incident</li><li>escalate</li><li>etc…</li></ul>
|
||
|
||
|
||
|
||
<figure class="wp-block-image size-full"><img loading="lazy" width="1024" height="296" src="https://engineering.sendinblue.com/wp-content/uploads/2022/06/app.slack_.com_client_T03FYB9QV_C028ZSE0VM5-1-1024x296-1.jpg" alt="joined channel's message" class="wp-image-628" srcset="https://engineering.brevo.com/wp-content/uploads/2022/06/app.slack_.com_client_T03FYB9QV_C028ZSE0VM5-1-1024x296-1.jpg 1024w, https://engineering.brevo.com/wp-content/uploads/2022/06/app.slack_.com_client_T03FYB9QV_C028ZSE0VM5-1-1024x296-1-300x87.jpg 300w, https://engineering.brevo.com/wp-content/uploads/2022/06/app.slack_.com_client_T03FYB9QV_C028ZSE0VM5-1-1024x296-1-768x222.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Joined channel’s message</figcaption></figure>
|
||
|
||
|
||
|
||
<p>Adding relevant CTA, when the situation is suitable, increases user engagement and reduces human errors (read typos) and so frustration.</p>
|
||
|
||
|
||
|
||
<p>We highlighted some metrics we collect through SIMA to get better at incident responses. Measuring and automating was key in making the incident resolution as quick as possible.</p>
|
||
|
||
|
||
|
||
<p>The next section will drive us through the communication and analysis aspect</p>
|
||
|
||
|
||
|
||
<h2>Incident management and beyond</h2>
|
||
|
||
|
||
|
||
<p>Responding to an incident is no easy task and requires a lot of brain cells to make it a success.</p>
|
||
|
||
|
||
|
||
<p>We had to re-think the way we communicated, automated, and learned from incidents so that we became better at this exercise</p>
|
||
|
||
|
||
|
||
<h3>Improving the communication</h3>
|
||
|
||
|
||
|
||
<p>Before SIMA, slack threads and video calls were the way to go for bridging everyone. The incident communication was okay but we were missing an important part: the internal communication, between teams and stakeholders.</p>
|
||
|
||
|
||
|
||
<p>We focused on reducing the number of notifications sent and the cognitive load required to process the notifications</p>
|
||
|
||
|
||
|
||
<p>We defined different types of messages (and notifications), gave them one purpose, and made them easy to read (using a dedicated format for each message type):</p>
|
||
|
||
|
||
|
||
<ul><li><strong>broadcast message</strong>: in order to keep everyone in the company aligned about current ongoing issues, SIMA posts a minimalistic message within an organization-wide and known channel <code>production-issues-bot</code> . It gives everyone the global picture and the opportunity to jump into the dedicated channel easily</li><li><strong>incident update message:</strong> Each time the Incident Manager (or communication lead) updates the incident status, SIMA saves the information into the database and posts 2 messages:<ul><li><strong>An update</strong> – posted on the incident’s slack channel. Every stakeholder is on the same page.</li><li><strong>A reply</strong> – added to the broadcast message’s thread. People may subscribe to the broadcast message rather than join the war room. Broadcast messages see their content updated accordingly, keeping their content fresh.</li></ul></li><li><strong>post-mortems</strong>: as soon as the situation goes back to normal and is considered stable, we generate and pre-fill a post-mortem on Notion. Similar to previous messages, post-mortems follow the same pattern (it evolved, during our journey, in favor of a lighter format). More on post-mortems later.</li></ul>
|
||
|
||
|
||
|
||
<p>Each of these messages is generated by SIMA. They help involved people to focus on solving the problem rather than wasting time formatting messages. Thanks to the Slack Block API for making the formatting easy</p>
|
||
|
||
|
||
|
||
<h3>Learning from incidents</h3>
|
||
|
||
|
||
|
||
<p>How do we learn and improve from these incidents?</p>
|
||
|
||
|
||
|
||
<h4><strong>Post-mortems</strong></h4>
|
||
|
||
|
||
|
||
<p>Each incident, except in the case of false positives, gives place to a Post-mortem. The incident Manager, Communication lead, and some stakeholders regroup and collaborate to fill up the auto-generated post-mortem with various information.</p>
|
||
|
||
|
||
|
||
<p>Writing a post-mortem requires the team to step back and analyze the events and actions taken so that we become better and prevent a similar class of incidents to arise in the future.</p>
|
||
|
||
|
||
|
||
<p>Here’s an auto-generated post-mortem:</p>
|
||
|
||
|
||
|
||
<figure class="wp-block-image size-large"><img loading="lazy" width="740" height="1024" src="https://engineering.sendinblue.com/wp-content/uploads/2022/11/pm-740x1024.jpg" alt="" class="wp-image-1202" srcset="https://engineering.brevo.com/wp-content/uploads/2022/11/pm-740x1024.jpg 740w, https://engineering.brevo.com/wp-content/uploads/2022/11/pm-217x300.jpg 217w, https://engineering.brevo.com/wp-content/uploads/2022/11/pm-768x1062.jpg 768w, https://engineering.brevo.com/wp-content/uploads/2022/11/pm.jpg 900w" sizes="(max-width: 740px) 100vw, 740px" /><figcaption>Post mortem template</figcaption></figure>
|
||
|
||
|
||
|
||
<p>To make sure each incident has a positive impact on our company/products/methodology/culture, the team defines action items that we will plan and implement to become stronger than ever.</p>
|
||
|
||
|
||
|
||
<p>When finished, post-mortems are shared internally. They allow everyone in the company to find the information they need, either out of curiosity or because of a customer asking for detail.</p>
|
||
|
||
|
||
|
||
<h4>Reading the numbers</h4>
|
||
|
||
|
||
|
||
<p>SIMA started as a Proof Of Concept and slowly became an internal tool used by a lot of people. We are quite happy with the current implementation and will probably continue to tweak it.</p>
|
||
|
||
|
||
|
||
<p>We didn’t want to make this project a full-time job and took some shortcuts. One of these shortcuts was to not build any admin dashboard at first. In the beginning, we extracted data and numbers manually.</p>
|
||
|
||
|
||
|
||
<p>Today, there is no regret in making this decision. We rely on <a href="https://metabase.com" target="_blank" rel="noreferrer noopener">Metabase</a> to analyze the metrics we collected. It helps us get the most of our data and build nice dashboards in a very short period of time.</p>
|
||
|
||
|
||
|
||
<p>We could have spent time building a UI to read and analyze our data but Metabase made the job very simple and allowed us to find bottlenecks faster than if we had built an in-house visualization tool.</p>
|
||
|
||
|
||
|
||
<h4>Gather feedback</h4>
|
||
|
||
|
||
|
||
<p>After we made the switch to the new incident response (SIMA) we started to gather feedback from incident stakeholders, the Customer-Care team, and engineers.</p>
|
||
|
||
|
||
|
||
<p>These feedback sessions were invaluable and in some part responsible for the success of SIMA. The customer care team helped us focus on different topics (ex: communication) and pushed SIMA to the next level, making the experience as clear and streamlined as possible</p>
|
||
|
||
|
||
|
||
<p>Do not underestimate teammates’ feedback</p>
|
||
|
||
|
||
|
||
<h2>What did we learn/discover?</h2>
|
||
|
||
|
||
|
||
<h3>Building is easy</h3>
|
||
|
||
|
||
|
||
<p>Building SIMA was the easiest part. If you ever used some APIs and are familiar with typescript or python or any language listed here <a href="https://api.slack.com/tools"></a><a href="https://api.slack.com/tools" target="_blank" rel="noreferrer noopener">https://api.slack.com/tools</a> you should be able to build a working app in not much time (our first version was online after 1 week)</p>
|
||
|
||
|
||
|
||
<p>Once you get used to the Slack Block kit, you can achieve almost everything in slack.</p>
|
||
|
||
|
||
|
||
<p>Relying on API makes you move faster. Behind the scenes, SIMA interacts with Slack, PagerDuty, and Notion APIs. At the moment, we didn’t experience any issues</p>
|
||
|
||
|
||
|
||
<p>PagerDuty for the alerting, Firestore and Notion for the knowledge, Slack for the communication, and Metabase for the analysis is an excellent combo from our past experience</p>
|
||
|
||
|
||
|
||
<p>If you don’t have any resources don’t go down that path, if you have some it is definitely worth it.</p>
|
||
|
||
|
||
|
||
<h3>Don’t expect people to use your product the way you imagined it</h3>
|
||
|
||
|
||
|
||
<p>… unless you explicitly explain how it works</p>
|
||
|
||
|
||
|
||
<p>When rolled out SIMA noticed a couple of things:</p>
|
||
|
||
|
||
|
||
<ul><li>incident updates were uncommon</li><li>post-mortem neglected</li><li>unused/underused features </li><li>etc…</li></ul>
|
||
|
||
|
||
|
||
<p>We understood we missed an important part: Training</p>
|
||
|
||
|
||
|
||
<p>To bear the situation, we documented SIMA as if we were building the documentation for our customers.</p>
|
||
|
||
|
||
|
||
<ul><li>We included some decision trees (should they open an incident, update the status page, etc..)</li><li>We listed all the commands and features available</li><li>and added some examples</li></ul>
|
||
|
||
|
||
|
||
<p>It could have been enough but we wanted more. We created a dedicated slack channel where people could find resources, ask questions or provide feedback. Every time we release a new feature(s), we post a message on this channel.</p>
|
||
|
||
|
||
|
||
<p>At the time of writing, we are releasing internally some lessons through Lessonly to ensure everyone in the company shares the same knowledge and understanding of what SIMA is for (including new joiners, maybe you? 🙂 )</p>
|
||
|
||
|
||
|
||
<h3>Adoption is key</h3>
|
||
|
||
|
||
|
||
<blockquote class="wp-block-quote"><p>Rome wasn’t built in a day</p></blockquote>
|
||
|
||
|
||
|
||
<p>Before we released it internally and communicated it to everyone, we put ourselves in the shoes of people working on both sides of the incident: Frontline and Backline.</p>
|
||
|
||
|
||
|
||
<p>Frontline, during an incident, is the Customer Care team. CC team receives and processes customers’ requests, and questions from different location whenever a problem arise (but not only)</p>
|
||
|
||
|
||
|
||
<p>The backline is most of the time, our engineering and infrastructure team.</p>
|
||
|
||
|
||
|
||
<p>Both sides, even if working for the same goal, have different expectations of the situation. Frontline expects communication updates and details to feed our customers’ questions. Backline expects system information, focus, and efficiency to diagnose and repair.</p>
|
||
|
||
|
||
|
||
<p>Communication between lines was very important and was the primary source of frustration. Being too pushy is equally inefficient as not communicating (from both sides)</p>
|
||
|
||
|
||
|
||
<p>As the primary objective is to get our customers successful, making the communication streamlined to get the most out of the situation became a piece of evidence.</p>
|
||
|
||
|
||
|
||
<p>The first incidents managed through SIMA were copies of slack thread but managed by the SRE team in the dark. Progressively, we introduced SIMA to people who became part of the experiment and later ambassadors. During this phase, we learned what every team was looking for (read information, updates, etc…). We drove each of our developments in a neutral and not (too :-P) opinionated way.</p>
|
||
|
||
|
||
|
||
<p>Finally, everyone has been participating in the development and evolution of SIMA in an equal way. Both sides suggested features and improvements that could benefit everyone.</p>
|
||
|
||
|
||
|
||
<p>Getting everyone to use and break SIMA was the best way to learn and improve our incident responses.</p>
|
||
|
||
|
||
|
||
<h2>Conclusion</h2>
|
||
|
||
|
||
|
||
<p>Nowadays, we consider SIMA as adopted. The number of incidents raised is growing and that is a good sign. It does not mean we have more production issues but people are confident that opening an incident will make us stronger than before. Even people not convinced, at the beginning of the project, are pushing SIMA to the forefront.</p>
|
||
|
||
|
||
|
||
<p>Building SIMA has been an incredible journey and it wouldn’t have been possible without the support of every team (and members) at <a href="https://engineering.sendinblue.com/" target="_blank" rel="noreferrer noopener">Sendinblue</a>.</p>
|
||
|
||
|
||
|
||
<h3>Credits</h3>
|
||
|
||
|
||
|
||
<p>We would like to <a href="https://fr.linkedin.com/in/tarik-ihadjadene-269b1a19" target="_blank" rel="noreferrer noopener">Tarik</a> and <a href="https://fr.linkedin.com/in/jbourdale" target="_blank" rel="noreferrer noopener">Jules</a> for their contributions (development and reviews :-))</p>
|
||
|
||
|
||
|
||
<h2>References</h2>
|
||
|
||
|
||
|
||
<ul><li><a href="https://medium.com/manomano-tech/incident-management-with-a-bot-7e80deb5b5e5" target="_blank" rel="noreferrer noopener">https://medium.com/manomano-tech/incident-management-with-a-bot-7e80deb5b5e5</a></li><li><a href="https://www.atlassian.com/incident-management/kpis/common-metrics" target="_blank" rel="noreferrer noopener">https://www.atlassian.com/incident-management/kpis/common-metrics</a></li><li><a href="https://www.atlassian.com/incident-management/incident-response/roles-responsibilities" target="_blank" rel="noreferrer noopener">https://www.atlassian.com/incident-management/incident-response/roles-responsibilities</a></li><li><a href="https://api.slack.com/tools" target="_blank" rel="noreferrer noopener">https://api.slack.com/tools</a></li></ul>
|
||
</div>
|
||
</div>
|
||
<div class="sib-post-share-buttons col-12 col-sm-1 mt-5">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sib-post-footer mt-5">
|
||
<div class="container">
|
||
<div class="row mb-4">
|
||
<div class="col-12 col-md-8 sib-about-author">
|
||
<p>About the Author</p>
|
||
<div class="row">
|
||
<div class="col-12 col-sm-2 sib-author-image p-4">
|
||
<img alt='' src='https://secure.gravatar.com/avatar/13687a119a443bde3c90115ae6f8458b?s=85&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/13687a119a443bde3c90115ae6f8458b?s=170&d=mm&r=g 2x' class='avatar avatar-85 photo' height='85' width='85' loading='lazy'/> </div>
|
||
<div class="col-12 col-sm-10 sib-author-right p-3">
|
||
<span class="author-name">Tanguy Antoine</span>
|
||
<span class="author-desc">SRE and DPE lead at Sendinblue</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-12 col-md-4 p-4 mt-4 text-center">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="single-post__featured-posts-section container">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- end of main content -->
|
||
</main>
|
||
|
||
|
||
<footer>
|
||
<div class="footer-container">
|
||
<div class="mt-3 p-3 row">
|
||
<div class="footer-logo col-md-8 col-12">
|
||
<img loading="lazy" width="277" height="33" src="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/images/common/logo-color.svg" alt="Logo Sendinblue">
|
||
</div>
|
||
<div class="sib-social-media-footer col-md-4 col-12">
|
||
<a href="https://twitter.com/brevo_official" target="_blank" aria-label="Twitter Brevo" rel="noopener">
|
||
<img loading="lazy" width="24" height="24" src="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/images/footer/Twitter-Negative.svg" alt="Twitter Brevo" />
|
||
</a>
|
||
<a href="https://www.linkedin.com/company/brevo/" target="_blank" aria-label="Linkedin Brevo" rel="noopener">
|
||
<img loading="lazy" width="24" height="24" src="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/images/footer/rs-linkedin.svg" alt="Linkedin Brevo" />
|
||
</a>
|
||
<a href="https://instagram.com/brevo" target="_blank" aria-label="Instagram Brevo" rel="noopener">
|
||
<img loading="lazy" width="24" height="24" src="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/images/footer/rs-instagram.svg" alt="Instagram Brevo" />
|
||
</a>
|
||
<a href="https://www.youtube.com/@brevo_official" target="_blank" aria-label="Youtube Brevo" rel="noopener">
|
||
<img loading="lazy" width="24" height="24" src="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/images/footer/rs-youtube.svg" alt="Youtube Brevo" />
|
||
</a>
|
||
<a href="https://facebook.com/brevo.official" target="_blank" aria-label="Facebook Brevo" rel="noopener">
|
||
<img loading="lazy" width="24" height="24" src="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/images/footer/rs-facebook.svg" alt="Facebook Brevo" />
|
||
</a>
|
||
<a href="https://www.tiktok.com/@brevo.official" target="_blank" aria-label="TikTok Brevo" rel="noopener">
|
||
<img loading="lazy" width="24" height="24" src="https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/images/footer/" alt="TikTok Brevo" />
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="container-fluid">
|
||
<div class="row links-section">
|
||
<div class="col-md-2 section">
|
||
<span class="section-title">
|
||
Product </span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/features/email-marketing/">Email marketing</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/products/transactional-email/">Transactional email</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/features/wallet/">Wallet</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/solutions/enterprise/">Enterprise solution</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/features/">All features</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/pricing/">Pricing</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/plugins/">Integrations</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/company/gdpr/">GDPR</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/features/data-security/">Security</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/releases/">Product updates</a>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-2 section">
|
||
<span class="section-title">
|
||
Compare </span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/bulk-email-service/">Bulk email service</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/blog/best-email-marketing-services/">Email marketing platforms</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/mailchimp/">Brevo vs Mailchimp</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/hubspot/">Brevo vs HubSpot</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/constant-contact/">Brevo vs Constant Contact</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/klaviyo/">Brevo vs Klaviyo</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/blog/mailchimp-alternatives/">Mailchimp alternatives</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/blog/hubspot-competitors/">HubSpot alternatives</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/free-smtp-server/">Free SMTP server</a>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-2 section">
|
||
<span class="section-title">
|
||
Resources </span>
|
||
<div>
|
||
<a class="link" href="https://help.brevo.com/hc/en-us">Help center</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://status.brevo.com/">Platform status</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://community.brevo.com/">Community</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/blog/">Blog</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/glossary/">Glossary</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/features/email-templates/">Email templates</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/resources/">Ebooks & webinars</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://developers.brevo.com/">Developers</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://help.brevo.com/hc/en-us/articles/10285672223378-Mailchimp-integration-by-Brevo-Import-and-update-your-contacts-to-migrate-to-Brevo">Migrate from Mailchimp</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/tools/">Tools & Calculators</a>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-2 section">
|
||
<span class="section-title">
|
||
Partners </span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/partners/">All partner programs</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/affiliates/">Affiliates</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/experts/">Agency partners</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/startups/">Startups & VCs</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/integration-program/">Integration partners</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/expert-directory/">Find an expert</a>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-2 section">
|
||
<span class="section-title">
|
||
Company </span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/company/about/">About us</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/contact/">Contact us</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/company/leadership/">Leadership</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/careers/">Careers</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/press-room/">Press</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/company/bcorp/">B Corp</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/company/carbon-footprint/">Carbon footprint</a>
|
||
</div>
|
||
</span>
|
||
<div>
|
||
<a class="link" href="https://www.brevo.com/company/ngos/">Non Profits</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row sib-footer-copyright">
|
||
|
||
<div class="flex-container">
|
||
<div class="sib-language-dropdown js-sib-language-dropdown sib-language-dropdown-footer skip-lazy">
|
||
[sc_msls] <svg width="12" class="dropdown-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 6 4">
|
||
<path id="arrow-3" fill-rule="evenodd" d="M3 4l3-4H0z"/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-12 col-md-10 sib-legal-links">
|
||
<p>
|
||
<a class="optanon-toggle-display">Cookie Settings</a>
|
||
<a href="https://www.brevo.com/legal/antispampolicy/">Acceptable Use Policy</a>
|
||
<a href="https://www.brevo.com/legal/privacypolicy/">Privacy</a>
|
||
<a href="https://www.brevo.com/legal/termsofuse/">Terms of service</a>
|
||
<a href="https://www.brevo.com/legal-notice/">Legal notice</a>
|
||
<a href="https://www.brevo.com/legal/responsible-disclosure/">Responsible Disclosure</a>
|
||
<span>© Brevo 2026. All rights reserved</span>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
<script>let slideIndex = 1;
|
||
showSlides(slideIndex);
|
||
|
||
function plusSlides(n) {
|
||
showSlides(slideIndex += n);
|
||
}
|
||
|
||
function currentSlide(n) {
|
||
showSlides(slideIndex = n);
|
||
}
|
||
|
||
function showSlides(n) {
|
||
let i;
|
||
let slides = document.getElementsByClassName("mySlides");
|
||
let dots = document.getElementsByClassName("dot");
|
||
if (n > slides.length) {slideIndex = 1}
|
||
if (n < 1) {slideIndex = slides.length}
|
||
for (i = 0; i < slides.length; i++) {
|
||
slides[i].style.display = "none";
|
||
}
|
||
for (i = 0; i < dots.length; i++) {
|
||
dots[i].className = dots[i].className.replace(" active", "");
|
||
}
|
||
slides[slideIndex-1].style.display = "block";
|
||
dots[slideIndex-1].className += " active";
|
||
}
|
||
|
||
/* React2024 */
|
||
let slideReact2024Index = 1;
|
||
showSlidesReact2024(slideReact2024Index);
|
||
|
||
function plusReact2024Slides(n) {
|
||
showSlidesReact2024(slideReact2024Index += n);
|
||
}
|
||
|
||
function currentReact2024Slide(n) {
|
||
showSlidesReact2024(slideReact2024Index = n);
|
||
}
|
||
|
||
function showSlidesReact2024(n) {
|
||
let i;
|
||
let slides = document.getElementsByClassName("mySlidesReact2024");
|
||
let dots = document.getElementsByClassName("dotReact2024");
|
||
if (n > slides.length) {slideReact2024Index = 1}
|
||
if (n < 1) {slideReact2024Index = slides.length}
|
||
for (i = 0; i < slides.length; i++) {
|
||
slides[i].style.display = "none";
|
||
}
|
||
for (i = 0; i < dots.length; i++) {
|
||
dots[i].className = dots[i].className.replace(" active", "");
|
||
}
|
||
slides[slideReact2024Index-1].style.display = "block";
|
||
dots[slideReact2024Index-1].className += " active";
|
||
}
|
||
|
||
/* Hackathon */
|
||
let slideHackathonIndex = 1;
|
||
showSlidesHackathon(slideHackathonIndex);
|
||
|
||
function plusHackathonSlides(n) {
|
||
showSlidesHackathon(slideHackathonIndex += n);
|
||
}
|
||
|
||
function currentHackathonSlide(n) {
|
||
showSlidesHackathon(slideHackathonIndex = n);
|
||
}
|
||
|
||
function showSlidesHackathon(n) {
|
||
let i;
|
||
let slides = document.getElementsByClassName("mySlidesHackathon");
|
||
let dots = document.getElementsByClassName("dotHackathon");
|
||
if (n > slides.length) {slideHackathonIndex = 1}
|
||
if (n < 1) {slideHackathonIndex = slides.length}
|
||
for (i = 0; i < slides.length; i++) {
|
||
slides[i].style.display = "none";
|
||
}
|
||
for (i = 0; i < dots.length; i++) {
|
||
dots[i].className = dots[i].className.replace(" active", "");
|
||
}
|
||
slides[slideHackathonIndex-1].style.display = "block";
|
||
dots[slideHackathonIndex-1].className += " active";
|
||
}
|
||
|
||
|
||
/* AsyncJS */
|
||
let slideAsyncJSIndex = 1;
|
||
showSlidesAsyncJS(slideHackathonIndex);
|
||
|
||
function plusAsyncJSSlides(n) {
|
||
showSlidesAsyncJS(slideAsyncJSIndex += n);
|
||
}
|
||
|
||
function currentAsyncJSSlide(n) {
|
||
showSlidesAsyncJS(slideAsyncJSIndex = n);
|
||
}
|
||
|
||
function showSlidesAsyncJS(n) {
|
||
let i;
|
||
let slides = document.getElementsByClassName("mySlidesAsyncJS");
|
||
let dots = document.getElementsByClassName("dotAsyncJS");
|
||
if (n > slides.length) {slideAsyncJSIndex = 1}
|
||
if (n < 1) {slideAsyncJSIndex = slides.length}
|
||
for (i = 0; i < slides.length; i++) {
|
||
slides[i].style.display = "none";
|
||
}
|
||
for (i = 0; i < dots.length; i++) {
|
||
dots[i].className = dots[i].className.replace(" active", "");
|
||
}
|
||
slides[slideAsyncJSIndex-1].style.display = "block";
|
||
dots[slideAsyncJSIndex-1].className += " active";
|
||
}
|
||
|
||
/* Tech Meetup */
|
||
let slideTechMeetupIndex = 1;
|
||
showSlidesTechMeetup(slideTechMeetupIndex);
|
||
|
||
function plusTechMeetupSlides(n) {
|
||
showSlidesTechMeetup(slideTechMeetupIndex += n);
|
||
}
|
||
|
||
function currentTechMeetupSlide(n) {
|
||
showSlidesTechMeetup(slideTechMeetupIndex = n);
|
||
}
|
||
|
||
function showSlidesTechMeetup(n) {
|
||
let i;
|
||
let slides = document.getElementsByClassName("mySlidesTechMeetup");
|
||
let dots = document.getElementsByClassName("dotTechMeetup");
|
||
if (n > slides.length) {slideTechMeetupIndex = 1}
|
||
if (n < 1) {slideTechMeetupIndex = slides.length}
|
||
for (i = 0; i < slides.length; i++) {
|
||
slides[i].style.display = "none";
|
||
}
|
||
for (i = 0; i < dots.length; i++) {
|
||
dots[i].className = dots[i].className.replace(" active", "");
|
||
}
|
||
slides[slideTechMeetupIndex-1].style.display = "block";
|
||
dots[slideTechMeetupIndex-1].className += " active";
|
||
}</script><script>function openTab(evt, tabName) {
|
||
var i, tabcontent, tablinks;
|
||
tabcontent = document.getElementsByClassName("tabcontent");
|
||
for (i = 0; i < tabcontent.length; i++) {
|
||
tabcontent[i].style.display = "none";
|
||
}
|
||
tablinks = document.getElementsByClassName("tablinks");
|
||
for (i = 0; i < tablinks.length; i++) {
|
||
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
||
}
|
||
document.getElementById(tabName).style.display = "block";
|
||
evt.currentTarget.className += " active";
|
||
}
|
||
document.getElementById("defaultOpen").click();
|
||
|
||
jQuery(function() {
|
||
var eventLocation = window.location.href; // returns the full URL
|
||
if(/hackathon-2023/.test(eventLocation)) {
|
||
jQuery('main.sib-blog').addClass('sib-hackathon');
|
||
}
|
||
|
||
});
|
||
|
||
</script><script type='text/javascript' src='https://engineering.brevo.com/wp-includes/js/jquery/ui/core.min.js?ver=1.13.1' id='jquery-ui-core-js'></script>
|
||
<script type='text/javascript' src='https://engineering.brevo.com/wp-includes/js/jquery/ui/tabs.min.js?ver=1.13.1' id='jquery-ui-tabs-js'></script>
|
||
<script type='text/javascript' src='https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/js/blog.js?ver=1' id='blog-js'></script>
|
||
<script type='text/javascript' src='https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/js/header-min.js?ver=1789190604' id='sib-header-js'></script>
|
||
<script type='text/javascript' src='https://engineering.brevo.com/wp-content/themes/brevo-blog/assets/js/search.js?ver=1' id='search-js'></script>
|
||
|
||
<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"a55b2fabb8a048daa4443e82ad0a075d","spa":2}' crossorigin="anonymous"></script>
|
||
</body>
|
||
</html>
|