An example to showcase the integration of SendGrid and Crowdin Enterprise
The goal of this project is to show how easily you can create and deploy your Crowdin Application.
Using this Application you can easily localize your SendGrid content in Crowdin Enterprise.
- Requirements
- Running
- App Installation in Crowdin
- Project Structure
- Creating an App
- Contributing
- Authors
- License
- Node.js 12.x.x
- npm 6.x.x
First of all, you need to clone the repository:
git clone https://github.com/crowdin-community/crowdin-sendgrid-example.git
-
Install dependencies
cd crowdin-sendgrid-example
npm install
-
Use ngrok to make your server public:
ngrok http 8000
-
Create
keys.js
file:cp keys.sample.js keys.js
-
Open
keys.js
file and fill in the following values:Variable Description <your_ngrok_tunnel>
Your NGROK tunnel hash, started in step 2 crowdinClientId
crowdinClientSecret
Crowdin OAuth Client ID and Client Secret.
App Callback URL -https://<your_ngrok_tunnel>.ngrok.io/installed
UniqueCryptoSecret
Unique random string. Will be used to encrypt data in DB -
Start Node server (default port is 8000):
- Run the command below in the App directory:
node index.js
Or you can use nodemon for running Node server, watching changes in the project and automatically reload server:
- Install globally:
npm install -g nodemon
- Start server using nodemon:
nodemon --watch crowdin-sendgrid-example crowdin-sendgrid-example/index.js
or from working directory
npm run dev
-
Navigate to the project directory:
cd crowdin-sendgrid-example
- Create
keys.js
file:
cp keys.sample.js keys.js
- Create Heroku App:
heroku create <app_name>
- Add Postgres add-on to your App:
heroku addons:create heroku-postgresql:hobby-dev
-
Open
keys.js
file and fill in your<app_name>
-
Navigate to your App on Heroku, then go to the Settings tab and define the following Config Vars:
Variable | Description |
---|---|
CROWDIN_CLIENT_ID CROWDIN_CLIENT_SECRET |
Crowdin OAuth Client ID and Client Secret. App Callback URL - https://<app_name>.herokuapp.com/installed |
CRYPTO_SECRET |
Unique random string. Will be used to encrypt data in DB |
Also, you can fill in appropriate variables in keys.js
file instead of defining environment variables.
- Commit your changes:
git commit -am "Setup"
- Deploy your code:
git push heroku master
For more about Node.js Apps on Heroku read "Getting Started on Heroku with Node.js" article.
- In the upper-right corner, click your profile photo and select Organization Settings.
- Select Apps tab and click Install Application.
- Fill in the Manifest URL:
- for local environment with ngrok:
https://<your_ngrok_tunnel>.ngrok.io/manifest.json
- for Heroku App:
https://<app_name>.herokuapp.com/manifest.json
- for local environment with ngrok:
- Click Install button.
- Now your App will be available on Integrations & API tab for each project of the current organization.
Name | Description |
---|---|
assets/logo.svg | App logo |
models/integration.js | Code to work with external service (configuring OAuth links, tokens, content management) |
models/organization.js | Code to work with Crowdin (authorization, files list, translation progress) |
templates/app.html | Small front application that configured to work with current backend |
templates/closeAuthModal.html | Helper file to close integration authModal and reload the page |
uploadToCrowdin.js | Code to upload files for localization to Crowdin |
uploadToIntegration.js | Code to upload translations to external service |
config.js | App Configuration file |
db_connect.js | Database configuration file |
middleware.js | Routes validation, checking and providing some important data |
index.js | Application backend routes configuration file |
helpers.js | Small helper things |
This example is created for the purpose to show how easy to create Crowdin App and provide an opportunity to create a new App from a template with minimal effort.
Change assets/logo.svg to your own. Recommended dimensions are 50x50px. File name cannot be modified.
App configuration located in config.js file. Each field with possible values described in the table below:
Field | Description | Possible values |
---|---|---|
identifier | Unique identifier for your App | Alphanumeric, dash, and underscore are allowed. Length 3-255 symbols |
name | Name of your App. Will be displayed in the Apps list | 3-255 symbols |
baseUrl | App URL. e.g. https://<app_name>.herokuapp.com |
Valid URL |
authentication | Authentication type. Required if you want to make API calls to Crowdin | An object with the following keys: - type : none or authorization_code - client_id - OAuth App Client ID (required only for authorization_code type) |
events | Endpoints which Crowdin will trigger when certain events occur | -installed - an event when App being installed into organization - uninstall - an event when App being uninstalled |
scopes | Defines the access type your application needs | Understanding Scopes for OAuth Apps |
modules | Defines the place where App will appear in Crowdin UI | |
integrations | Integrations tab on Project page | An array of objects with the following keys: - key - unique alphanumeric key. Used in the App URL- name - App name. Will be displayed on the App card- description - App description- logo - App logo- url - An App route which will be opened in IFrame |
Database is used to store Crowdin, SendGrid OAuth tokens (for executing API requests) and Crowdin files to SendGrid files mapping. By default, Postgres is used for production and Sqlite for local environment.
If you want to use another DB, feel free to change it in db_connect.js file. For more about all possible databases read Sequelize docs.
This example is using custom authentication flow for the SendGrid side.
You can simply modify authentication strategy you need in integration.js file by replacing code to your own.
Content management in this type of integrations is based on pulling content to Crowdin from external service and pushing back localized content.
First of all, you need to fetch localizable content from external service and display it on the right side of App.
Code responsible for localizable content fetching is located in models/integration.js file. You need to implement getData
function returning an array of objects representing file items.
You need to follow the structure below in the getData
response:
[
{
id: <file unique ID>,
name: <file name>,
parent_id: <Id of parent item (directory or branch). default - 0>,
type: <File type. e.g. html>,
icon: <Custom icon URL (optional)>,
node_type: nodeTypes.FOLDER | nodeTypes.FILE | nodeTypes.BRANCH,
},
{
...
},
...
]
Code responsible for pulling localizable content is located in the uploadToCrowdin.js file.
This example is using Crowdin API v2 Client for making API requests to Crowdin. For more details about Crowdin API v2 read the documentation.
There are few steps to upload files for localization:
- Using
fileIds
(external service file IDs selected in UI) you need get files content by using external service API. - Fill
integrationFiles
array with objects with the following structure:{"title": "...", "name": "...", "content": "..."}
. - In the
crowdinApi.uploadStorageApi.addStorage
method call provide right filename (It depends on content type provided by external service). - The next code will do all the necessary work.
Code responsible for pushing localized content into external service is located in the uploadToIntegration.js file.
There are few steps to push localized content into external service:
- In the
translations
array stored list of Crowdin file IDs and language IDs selected for pushing translations. - Implement external service files fetching in the
prepareData
method. - Implement translations upload in
updateIntegrationFile
method according to external service API requirements.
If you find any problems or would like to suggest a feature, please feel free to file an issue on Github at Issues Page.
Also, we are happy to accept contributions from community. For more details about how to contribute read the CONTRIBUTING.md file.
- Yevhen Oliynyk
The Crowdin-SendGrid example is licensed under the MIT License.
See the LICENSE file distributed with this work for additional
information regarding copyright ownership.
Except as contained in the LICENSE file, the name(s) of the above copyright
holders shall not be used in advertising or otherwise to promote the sale,
use or other dealings in this Software without prior written authorization.