Write, Review, and Publish directly to Medium.com with Kintone Web Database
- Get Started
- Create a Kintone Web Database App
- Create a Medium API Token
- Get Your Medium Author ID
- Create a
.env
file - Edit Your customize-manifest.json
- Edit main.ts
- Build & Upload the customization
- View Your Article
- Check Your Work
First, let's download the sean-kintone/publish-to-medium Repo and go inside the folder.
Once you are inside the folder, let's install the dependencies!
cd Downloads
git clone https://github.com/sean-kintone/publish-to-medium
cd publish-to-medium
npm install
npm install -g @kintone/customize-uploader
Let's create a Publish to Medium Kintone App!
This is where you will be writing up the Markdown that will be published on your Medium.com account.
Here are the required fields & their configurations for our workshop:
Field Type | Field Name | Field Code | Note |
---|---|---|---|
Blank Space | --- | publishToMedium |
This is where our button will attach |
Text | Title | title |
The title of our medium.com article |
Text Area | Body | body |
The body text of our medium.com article |
Be sure to click the Save and Activate App buttons! 💪
Confused? 🤔 → Check out the How to Create a Kintone Database App video 📺
First, head to medium.com/me/settings to open up your Medium account setting page.
Click on the Integration tokens section.
Create a new API Token.
Don't worry; we have already revoked the one in this screenshot. 😈
Input token description | Grab your integration token / API token |
---|---|
With the API token, we can easily get our Medium.com Author ID.
Copy the curl command below and replace MY_API_TOKEN
with your API token.
Then paste the command into your terminal & hit enter!
cd publish-to-medium
curl -H "Authorization: Bearer MY_API_TOKEN" https://api.medium.com/v1/me | json_pp
Here is the curl command with a dummy token:
cd publish-to-medium
curl -H "Authorization: Bearer 2d6755756a12c743b4312f85fad0246a7953c68b78ef19c9efef134ef6dd8a429" https://api.medium.com/v1/me | json_pp
This will return your Author ID and other information in the terminal like so:
{
"data" : {
"id" : "1df66a8dd2779709d3ca3b3526a4a0190972b...",
"imageUrl" : "https://cdn-images-1.medium...",
"name" : "Kintone Developer Relations",
"url" : "https://medium.com/@kin...",
"username" : "kintone_dev..."
}
}
Copy and keep the "id"
string, as we will be pasting it into our .env file shortly.
Using the .env.example file as a temple, create a .env
file that will contain your login credentials and API Token.
Here is what your .env
might look like:
KINTONE_BASE_URL="https://example.kintone.com"
KINTONE_USERNAME="example@gmail.com"
KINTONE_PASSWORD="ILoveKintone!"
VITE_AUTHOR_ID="12345abcde67890"
VITE_API_TOKEN="09876edcba54321"
Paste your API Token from Medium into the VITE_API_TOKEN
field and your Author ID into the VITE_AUTHOR_ID
field.
.env.example is used by env-cmd to verify that .env
file is correctly configured.
Next, we need to tell our uploading scripts which Kintone App we will be working on.
Open your customize-manifest.json & update the "app"
variable!
This is what it will look like:
{
"app": "26",
"scope": "ALL",
"desktop": {
"js": ["dist/KintoneCustomization.js"],
"css": ["dist/main.css"]
},
"mobile": {
"js": [],
"css": []
}
}
We can easily find our App ID number from the Kintone App's URL!
Go to the Kintone App and grab the URL.
Example: https://devevents.kintone.com/k/36/
Kintone App's URL follows this template:
https://<SUBDOMAIN>.kintone.com/k/<App ID>/show#record=<RECORD ID>
So then the https://devevents.kintone.com/k/26/
URL tells us that this App's ID is 26
For this workshop, we will only be coding in ./src/main.ts.
However, our actual API POST request logic is contained in ./src/requests/post_api.ts. You can check out that file to see how the POST request to the medium.com API is structured.
Lastly, some TypeScript-specific settings (type definitions!) are found in ./fields.d.ts.
If you want to expand on this demo (like adding an image stored in Kintone to your article), you will have to edit this file.
We have two goals for our coding:
-
Format our data (simply called
body
in ./src/main.ts) to send to thepostToMedium
function -
Create a button to click, and when clicked, fire the
postToMedium
function.
First, let's look at our post body.
const body: PostBody = {
title: null, // Article's title (from our Kintone record)
contentFormat: null, // 'markdown' or 'html' (writing format)
content: null, // Article's body (from our Kintone record)
tags: null, // String "tags" for our article. Optional!
publishStatus: null, // The status of our article: 'public', 'draft', or 'unlisted'
notifyFollowers: null // Sends a notification after publishing.
}
For reference, the Medium.com API docs on POST Requests are pretty simple!
Our post title needs to come from our Kintone App.
Remember that we set our Title
field to have a lower-case title
field code in our Kintone App.
We can access the information on the show page easily in our code:
const body: PostBody = {
title: events.record.title.value, // Article's title (from our Kintone record)
contentFormat: null, // 'markdown' or 'html' (writing format)
content: null, // Article's body (from our Kintone record)
tags: null, // String "tags" for our article. Optional!
publishStatus: null, // The status of our article: 'public', 'draft', or 'unlisted'
notifyFollowers: null // Sends a notification after publishing.
}
Next, according to the documentation, Medium articles can be submitted in either Markdown or HTML formats! Pretty cool.
Let's go with markdown
this time:
const body: PostBody = {
title: events.record.title.value, // Article's title (from our Kintone record)
contentFormat: 'markdown', // 'markdown' or 'html' (writing format)
content: null, // Article's body (from our Kintone record)
tags: null, // String "tags" for our article. Optional!
publishStatus: null, // The status of our article: 'public', 'draft', or 'unlisted'
notifyFollowers: null // Sends a notification after publishing.
}
The content
parameter should be our Body
field from our app, which we designated with the body
field code:
Just like above, fill it in with the record variable:
const body: PostBody = {
title: events.record.title.value, // Article's title (from our Kintone record)
contentFormat: 'markdown', // 'markdown' or 'html' (writing format)
content: events.record.title.value, // Article's body (from our Kintone record)
tags: null, // String "tags" for our article. Optional!
publishStatus: null, // The status of our article: 'public', 'draft', or 'unlisted'
notifyFollowers: null // Sends a notification after publishing.
}
Continue to fill in the body parameters.
tags
are up to you, depending on the contents of your article. The POST API accepts an array
of strings
. Here is an example:
tags: ['kintone', 'markdown', 'medium', 'low-code'],
publishStatus
is the status of your article. We will be publishing immediately, but saving to your medium.com account's drafts
is also possible!
notifyFollowers
will do exactly that and takes a boolean, true
or false
. We're testing, so let's set it as false
for now.
Our finished post body should look similar to this:
const body: PostBody = {
title: event.record.title.value, // Article's title (from our Kintone record)
contentFormat: "markdown", // 'markdown' or 'html' (writing format)
content: event.record.body.value, // Article's body (from our Kintone record)
tags: ['kintone', 'markdown', 'medium', 'low-code'], // String "tags" for our article. Optional!
publishStatus: 'public', // The status of our article: 'public', 'draft', or 'unlisted'
notifyFollowers: false // Sends a notification after publishing.
}
And done! This should be good data to pass to our API call...
but we will need a button for our users to click to start the process.
Kintone allows you to append HTML
elements to blank spaces in your Kintone App. When we built our App, we added a blank space
and gave it the Element ID publishToMedium
.
Kintone App's Form Setting Page | Blank Space Settings > Element ID |
---|---|
We tell our App where to append our button by matching the HTML
IDs.
Give your button an ID that matches the field code: publishToMedium
.
// Create a button
const mySpaceFieldButton: HTMLElement = document.createElement('button');
//TODO
mySpaceFieldButton.id = 'publishToMedium'; // Our "Element ID" from our Blank Space in the Kintone App.
// Give it an id & class (for CSS), and text on the button.
mySpaceFieldButton.className = null;
mySpaceFieldButton.innerHTML = null;
Our App's custom CSS
is contained in ./src/style.css. We can style our button with a CSS class, uploadButton
.
Lastly, give our button a nice label, so our users can know what it does.
⚡ You are free to set the button's innerHTML
with any text you want ~
Try including an emoji 💪!
⚡ Button's className
is also up to you. If you set a different CSS class, be sure to update ./src/style.css ~
// Create a button
const mySpaceFieldButton: HTMLElement = document.createElement('button');
//TODO
mySpaceFieldButton.id = 'publishToMedium'; // Our "Element ID" from our Blank Space in the Kintone App.
// Give it an id & class (for CSS), and text on the button.
mySpaceFieldButton.className = 'uploadButton';
mySpaceFieldButton.innerHTML = 'Click me to Publish!';
Last, we need our button to fire a function when clicked. That function should pass our post body
data to the API function postToMedium
.
In the button's onClick
function, call the postToMedium
function we imported from ./src/requests/post_api.ts.
mySpaceFieldButton.onclick = function () {
// We need to call our API POST function with request's body... 🧐
postToMedium(body);
};
Save your work and run kintone-customize-uploader by entering npm run start
in your terminal!
Navigate to your app, create a record, write some Markdown, and click the publish button!
See the slides.pdf for more info!
Navigate to your publications and bathe in your newfound journalistic fame!
Go to medium.com/me/stories/public
Is your code not working?
Compare your ./src/main.ts with the completed-code.md to see if it is all written correctly.
Still got a problem?
Check out README's Debugging section!
And finally, post your Kintone customization questions over at our community forum:
forum.kintone.dev
Good luck coding! 💪