Skip to content

Instantly share code, notes, and snippets.

Avatar

Stephen Bussey sb8244

View GitHub Profile
@sb8244
sb8244 / caching.ex
Last active May 25, 2022
Local/Distributed Caching
View caching.ex
defmodule MyApp.AccountLookup.Cache do
@moduledoc """
Provides a cache that can be used for account lookups. This cache is backed by
Cachex for local storage and pg2 for remote distribution. Keys are set to expire
after 7-10 days (randomly distributed) in order to prevent stale data in our cache
over a long time period.
"""
use Cachex.DistributedCache
@sb8244
sb8244 / sso.json
Last active May 19, 2022
Clove SSO schema
View sso.json
{
"user": {
"id": "(Required) String: The ID of the user logging into Clove",
"email": "String: The email address of the user",
"name": "String: Full name of the user",
"given_name": "String: First name of the user",
"family_name": "String: Last name of the user",
"custom_data": "Map: Arbitrary data container for your application",
"organization": {
"id": "(Required if organization key present) String: The ID of the organization this user belongs to",
View 1_hooks.ts
export const SpaceLayoutEditor = {
// Not important for the integration, just something for my specific use case
recentItems: [],
mounted() {
// IMPORTANT LINE: LiveView -> React data flow
this.handleEvent("react.update_items", ({ items }: { items: string }) => {
const newItems: SpaceItem[] = JSON.parse(items)
this.mountEditor(newItems)
})
@sb8244
sb8244 / 1_hooks.ts
Last active Apr 13, 2022
Example hooks + React mounter for LiveView application
View 1_hooks.ts
export const SpaceLayoutEditor = {
mounted() {
// I use webpack chunks to reduce LiveView entry file size
import(/* webpackChunkName: "space-layout-editor-lv" */ '../entry/space-layout-editor-lv').then((mounter) => {
this.unmountComponent = mounter.default(this.el.id, {
editorOpts: this.editorOpts()
})
}).catch(console.error)
},
View intercom.html
{% if user %}
<script>
window.intercomSettings = {
app_id: "YOUR_APP_ID",
user_id: "{{ user.id }}",
email: "{{ user.email }}",
user_hash: "{{ user.id | encrypt: "hmac", "YOUR_IDENTITY_VERIFICATION_SECRET" }}"
};
</script>
{% else %}
View head.html
<script type="text/javascript">
if (window.top !== window.self) {
const msg = {
urlChange: {
pathname: window.location.pathname,
search: window.location.search,
href: window.location.href
}
}
window.top.postMessage(msg, '*')
View embed.html
<!-- Note: un-minified source code available at clove-embed.js -->
<script type="text/javascript" src="https://public-cdn.cloveapp.io/clove-embed.min.js"></script>
<script type="text/javascript">
CloveEmbed.installFrameListener()
CloveEmbed.setFrameUrl("https://yourhub.example.com")
</script>
View header.html
<script type="text/javascript">
if (window.top !== window.self) {
document.body.classList.add('in-iframe')
}
</script>
View hook-example.js
/**
* This example is just copy/pasted from my code base. The gist of it is that `this.pushEventTo` on the hook
* will send an event over the LiveView channel that is processed by the component/LiveView that's mounted at
* that element.
*
* I recommend using pushEventTo instead of pushEvent because I've run into situations where the event gets sent
* to the incorrect component or LiveView.
*/
const GeneratePDFButton = {
mounted() {
@sb8244
sb8244 / notion.ex
Created Dec 22, 2021
Example of fetching pages and blocks from Notion's public API in Elixir
View notion.ex
defmodule Clove.Connections.Client.Notion do
# There is not a way to filter last_edited_time, so consumer should check if it needs to fetch the blocks or not
# This will help for deletion detection, though
def retrieve_pages(connection) do
request = %{
method: :post,
url: "#{base_url()}/v1/search",
params: %{
"query" => "",
"sort" => %{