#Email-HTML-文字列: SimpleNotice 生成

Email-HTML 文字列, SimpleNotice 生成 (Email-HTML String, Create SimpleNotice)
ワークフローに流れる案件データを用いてHTMLメール用のテキストを組み立てます。概要文・画像・主文・リンクボタン・副文のブロックにて構成されます。なお、設定データが空白であった場合、当該ブロックはスキップされます。
Configs
  • A1: Magazine Title をセットしてください (例 “SaaS News” ) *#{EL}
  • A2: Magazine Color をセットしてください (例 “#009900” )#{EL}
  • A3: Magazine Font をセットしてください (例 “Meiryo” )#{EL}
  • A4: Magazine Logo URLをセットしてください (例 https://example.com/a.png#{EL}
  • B1: Subject をセットしてください (例 “Questetra v13 自動開始機能が強化されました” ) *#{EL}
  • B2: 概要文をセットしてください (改行はbrに自動変換)#{EL}
  • B3: 画像URLをセットしてください (例 https://example.com/example.png#{EL}
  • B4: 章タイトル1をセットしてください (例 “新機能について” )#{EL}
  • B5: パラグラフ1をセットしてください#{EL}
  • B6: リンクボタンの表示テキストをセットしてください#{EL}
  • B7: リンクボタンのURLをセットしてください#{EL}
  • B8: 章タイトル2をセットしてください (例 “クエステトラについて” )#{EL}
  • B9: パラグラフ2をセットしてください#{EL}
  • C1: 発行者の名称をセットしてください (例 “株式会社クエステトラ” ) *#{EL}
  • C2: 発行者のURLをセットしてください (例 https://example.com/ *#{EL}
  • C3: 発行者メッセージをセットしてください#{EL}
  • D: Email-HTML が格納される文字列型データ項目を選択してください (更新) *
Script (click to open)
// GraalJS Script (engine type: 2)

//////// START "main()" /////////////////////////////////////////////////////////////////
main();
function main(){ 

//// == Config Retrieving / 工程コンフィグの参照 ==
let   strMagazineTitle     = configs.get( "StrConfA1" );          /// REQUIRED
      strMagazineTitle     = encodeHTML( strMagazineTitle );
  if( strMagazineTitle   === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {A1: MagazineTitle} is empty \n" );
  }
let   strMagazineColor     = configs.get( "StrConfA2" ).replace(/\"/g, ""); // NotRequired
  if( strMagazineColor   === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {A2: MagazineColor} is empty (default '#009900' applied)" );
    strMagazineColor = "#009900";
  }
let   strMagazineFont      = configs.get( "StrConfA3" ).replace(/\"/g, "'"); // NotRequired
  if( strMagazineFont    === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {A3: MagazineFont} is empty (default applied)" );
    strMagazineFont = "Arial, -apple-system, Meiryo, Helvetica, sans-serif";
  }
const strLogoUrl           = configs.get( "StrConfA4" );          // NotRequired
  if( strLogoUrl         === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {A4: LogoUrl} is empty" );
  }
let   strSubject           = configs.get( "StrConfB1" );          /// REQUIRED
      strSubject           = encodeHTML( strSubject );
  if( strSubject         === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {B1: Subject} is empty \n" );
  }
let   strAbstract          = configs.get( "StrConfB2" );          // NotRequired
  if( strAbstract        === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {B2: Abstract} is empty" );
  }else{
      strAbstract          = encodeHTML( strAbstract ).replace(/\n/g, '<br>\n');
      strAbstract          = convertMultiSpaces( strAbstract );
  }
const strImageUrl          = configs.get( "StrConfB3" );          // NotRequired
  if( strImageUrl        === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {B3: ImageUrl} is empty" );
  }
let   strSection1          = configs.get( "StrConfB4" );          // NotRequired
  if( strSection1        === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {B4: Section1} is empty" );
  }else{
      strSection1          = encodeHTML( strSection1 );
  }
let   strParagraph1        = configs.get( "StrConfB5" );          // NotRequired
  if( strParagraph1      === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {B5: Paragraph1} is empty" );
  }else{
      strParagraph1        = encodeHTML( strParagraph1 ).replace(/\n/g, '<br>\n');
      strParagraph1        = convertMultiSpaces( strParagraph1 );
  }
let   strLinkButtonText    = configs.get( "StrConfB6" );          // NotRequired
      strLinkButtonText    = encodeHTML( strLinkButtonText );
  if( strLinkButtonText  === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {B6: LinkButtonText} is empty" );
  }
const strLinkButtonUrl     = configs.get( "StrConfB7" );          // NotRequired
  if( strLinkButtonUrl   === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {B7: LinkButtonUrl} is empty" );
  }
if( strLinkButtonText === "" && strLinkButtonUrl !== "" ){
    strLinkButtonText      =    strLinkButtonUrl;
}
let   strSection2          = configs.get( "StrConfB8" );          // NotRequired
  if( strSection2        === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {B4: Section2} is empty" );
  }else{
      strSection2          = encodeHTML( strSection2 );
  }
let   strParagraph2        = configs.get( "StrConfB9" );          // NotRequired
  if( strParagraph2      === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {B5: Paragraph2} is empty" );
  }else{
      strParagraph2        = encodeHTML( strParagraph2 ).replace(/\n/g, '<br>\n');
      strParagraph2        = convertMultiSpaces( strParagraph2 );
  }
let   strPublisherName     = configs.get( "StrConfC1" );          /// REQUIRED
      strPublisherName     = encodeHTML( strPublisherName );
  if( strPublisherName   === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {C1: PublisherName} is empty \n" );
  }
const strPublisherUrl      = configs.get( "StrConfC2" );          /// REQUIRED
  if( strPublisherUrl    === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {C2: PublisherUrl} is empty \n" );
  }
let   strPublisherStatement   = configs.get( "StrConfC3" );         // NotRequired
  if( strPublisherStatement === "" ){
    engine.log( " AutomatedTask ConfigWarning: " +
                " {C3: PublisherStatement} is empty" );
  }else{
      strPublisherStatement   = encodeHTML( strPublisherStatement ).replace(/\n/g, '<br>\n');
      strPublisherStatement   = convertMultiSpaces( strPublisherStatement );
  }
const strPocketHtml           = configs.getObject( "SelectConfD" ); /// REQUIRED



//// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Retrieved via Expression Language in Config Retrieving)


//// == Calculating / 演算 ==
// Build HTML String with Template_literals (ES6)
// ${strMagazineTitle}
// ${strMagazineColor}
// ${strMagazineFont}
// ${strLogoUrl}
// ${strSubject}
// ${strAbstract}
// ${strImageUrl}
// ${strSection1}
// ${strParagraph1}
// ${strLinkButtonText}
// ${strLinkButtonUrl}
// ${strSection2}
// ${strParagraph2}
// ${strPublisherName}
// ${strPublisherUrl}
// ${strPublisherStatement}

let strBlockHeader = `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta http-equiv="Content-Style-Type" content="text/css">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${strMagazineTitle}</title>
</head><body bgcolor="#ffffff"
  style="background-color:#ffffff; margin:0 auto; padding:0; width:100%; font-family:${strMagazineFont}">

<table width="640" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#ffffff"
  style="width:100%; max-width:640px; border:none; margin:0 auto; padding:0; background-color:#ffffff">
`;

let strBlockLogo = `<tr><td height="8" style="height:0.5em"></td></tr>
<tr><td width="100%" style="width:100%; margin:0; padding:0">
  <img src="${strLogoUrl}" alt="Logo Image" style="max-width:100%; height:auto">
</td></tr>
<tr><td height="8" style="height:0.5em"></td></tr>
`;

let strBlockSubject = `<tr><td height="8" style="height:0.5em"></td></tr>
<tr><td style="font-family:${strMagazineFont}">
  ${strMagazineTitle}
</td></tr>
<tr><td>
  <h2 style="font-size:1.8em; color:${strMagazineColor}; font-family:${strMagazineFont}">
  ${strSubject}</h2>
</td></tr>
`;

let strBlockAbstract = `<tr><td style="font-family:${strMagazineFont}">
  ${strAbstract}
</td></tr>
`;

let strBlockImage = `<tr><td height="8" style="height:0.5em"></td></tr>
<tr><td
  width="100%" style="width:100%; margin:0; padding:0">
    <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#ffffff"
    style="width:100%; border:none; margin:0 auto; padding:0; background-color:#ffffff">
    <tr><td width="5%"></td>
        <td width="90%">
          <img src="${strImageUrl}" alt="Featured Image" style="max-width:100%">
        </td>
        <td width="5%"></td></tr>
    </table>
</td></tr>
<tr><td height="8" style="height:0.5em"></td></tr>
`;

let strBlockSection1 = `<tr><td height="8" style="height:0.5em"></td></tr>
<tr><td>
  <h3 style="font-size:1.6em; font-family:${strMagazineFont}">
  ${strSection1}</h3>
</td></tr>
`;

let strBlockParagraph1 = `<tr><td style="font-family:${strMagazineFont}">
  ${strParagraph1}
</td></tr>
`;

let strBlockLinkButton = `<tr><td height="16" style="height:1.0em"></td></tr>
<tr><td
  width="100%" align="center"
  style="width:100%; margin:0px auto">
  <a href="${strLinkButtonUrl}"
  style="display:inline-block; font-weight:bold; border-radius:8px; padding:10px 20px;
  color:#ffffff; background:${strMagazineColor}; border:solid 4px ${strMagazineColor}">
  ${strLinkButtonText}</a>
</td></tr>
<tr><td height="16" style="height:1.0em"></td></tr>
`;

let strBlockSection2 = `<tr><td height="8" style="height:0.5em"></td></tr>
<tr><td>
  <h3 style="font-size:1.6em; font-family:${strMagazineFont}">
  ${strSection2}</h3>
</td></tr>
`;

let strBlockParagraph2 = `<tr><td style="font-family:${strMagazineFont}">
  ${strParagraph2}
</td></tr>
`;

let strBlockFooter = `<tr><td height="32" style="height:2.0em"></td></tr>
<tr><td height="24" bgcolor="#eeeeee" style="height:1.5em; background:#eeeeee"></td></tr>
<tr><td
  width="100%" align="center" bgcolor="#eeeeee"
  style="width:100%; text-align:center; background:#eeeeee; font-size:.8em">
  <a href="${strPublisherUrl}">${strPublisherName}</a>
</td></tr>
<tr><td
  width="100%" align="center" bgcolor="#eeeeee"
  style="width:100%; text-align:center; background:#eeeeee; font-size:.7em">
  ${strPublisherStatement}
</td></tr>
<tr><td height="24" bgcolor="#eeeeee" style="height:1.5em; background:#eeeeee"></td></tr>
<tr><td height="24" style="height:1.5em"></td></tr>

</table></body></html>
`;

let strHtml =  strBlockHeader;
  if( strLogoUrl !== "" ){
    strHtml += strBlockLogo;
  }
    strHtml += strBlockSubject;
  if( strAbstract !== "" ){
    strHtml += strBlockAbstract;
  }
  if( strImageUrl !== "" ){
    strHtml += strBlockImage;
  }
  if( strSection1 !== "" ){
    strHtml += strBlockSection1;
  }
  if( strParagraph1 !== "" ){
    strHtml += strBlockParagraph1;
  }
  if( strLinkButtonUrl !== "" ){
    strHtml += strBlockLinkButton;
  }
  if( strSection2 !== "" ){
    strHtml += strBlockSection2;
  }
  if( strParagraph2 !== "" ){
    strHtml += strBlockParagraph2;
  }
    strHtml += strBlockFooter;


//// == Data Updating / ワークフローデータへの代入 ==
engine.setData( strPocketHtml, strHtml );

} //////// END "main()" /////////////////////////////////////////////////////////////////


function encodeHTML( str ){
  return str.replace(/&/g, '&')
            .replace(/</g, '<')
            .replace(/>/g, '>')
            .replace(/"/g, '"')
            .replace(/'/g, ''');
}

// convert multiple consecutive spaces to "      .."
function convertMultiSpaces( strArg ){
  let re = /\ {2,}/g;
//  let re = /s{2,}/g;
  let strReturn = strArg.replace( re, function( strMatch ){
                    let strNbspSpRepeat = "";
                    for( let i = 0; i < strMatch.length; i++ ){
                      if( (i % 2) === 0 ){ // Even number
                        strNbspSpRepeat += " ";
                      }else{ // Odd number
                        strNbspSpRepeat += " ";
                      }
                    }
                    return strNbspSpRepeat;
                  });
  return strReturn;
}


/*
Notes:
- When a token reaches the automated step, the code for HTML mail is automatically generated.
    - The generated code can be set in "Message Sending Intermediate Event (Email)" (v13.1) as it is.
    - https://support.questetra.com/bpmn-icons/throwing-message-intermediate-event-email/
    - It is also effective to add a human step in downstream to add decorative tags such as strong and span.
- Special characters in workflow data are escaped as appropriate.
    - For example, "<" is automatically converted to "<".
    - Line feed codes in multi-line text are automatically converted to br tags.
- Multiple spaces (two or more spaces) in workflow data are replaced with " " every other character.
    - eg "A   B  C D" to "A   B  C D"
APPENDIX
- The generated HTML code is not guaranteed to be displayed properly in all mailers.
- The HTML code is built on the basis of 640px wide table tags.
    - Basically, the background color is white and the text color is black.
    - Subjects (titles) in the email body will be displayed in the color specified in MagazineColor.
    - The link button in the email will be displayed in the color specified in MagazineColor.
- MagazineLogo image is displayed in its original size.
    - Image with a width greater than 640px will be scaled down.
    - As a guide, the height should be between 20px and 50px.
    - The URL of the MagazineLogo image must be accessible to the recipient.
Notes-ja:
- 案件が自動処理工程に到達した際、HTMLメール用のコードが自動的に生成されます。
    - 生成されたコードは、そのまま『メッセージ送信中間イベント(メール)』(v13.1)にセットできます。
    - https://support.questetra.com/ja/bpmn-icons/throwing-message-intermediate-event-email/
    - 下流に "装飾タグを手動追加する工程"(strong や span など)を配置するのも効果的です。
- ワークフローデータ内の特殊文字は、適宜エスケープ処理されます。
    - たとえば、"<" は "<" に自動的に変換されます。
    - 複数行テキスト内の改行コードは、自動的に br タグに変換されます。
- ワークフローデータ内の連続スペース(2文字以上)は、一文字おきに " " に置換されます。
    - eg "A   B  C D" to "A   B  C D"
APPENDIX-ja
- 生成されるHTML コードは、全てのメーラで正常に表示されることが保証されている訳ではありません。
- HTML コードは、640px 幅の table タグがベースとなって組み立てられます。
    - 背景色は白、文字色は黒が基本となります。
    - メール内に再掲されるサブジェクト(タイトル)は、MagazineColor で指定した色で表示されます。
    - メール内に表示されるリンクボタンは、MagazineColor で指定した色で表示されます。
- Magazine Logo 画像は、そのままのサイズで表示されます。
    - 幅が 640px を超える画像は縮小表示されます。
    - 高さが 20px から 50px が目安となります。
    - Magazine Logo 画像の URL は、受信者がアクセスできるURLでなければなりません。
*/


Download

2021-06-20 (C) Questetra, Inc. (MIT License)
https://support.questetra.com/ja/addons/email-html-string-create-simplenotice-2021/
Addonファイルのインポートは Professional でのみご利用いただけます

Notes

  • 案件が自動処理工程に到達した際、HTMLメール用のコードが自動的に生成されます。
  • ワークフローデータ内の特殊文字は、適宜エスケープ処理されます。
    • たとえば、”<” は “&lt;” に自動的に変換されます。
    • 複数行テキスト内の改行コードは、自動的に br タグに変換されます。
  • ワークフローデータ内の連続スペース(2文字以上)は、一文字おきに “&nbsp; ” に置換されます。
    • eg “A   B  C D” to “A&nbsp; &nbspB&nbsp; C D

Capture

ワークフローに流れる案件データを用いてHTMLメール用のテキストを組み立てます。概要文・画像・主文・リンクボタン・副文のブロックにて構成されます。なお、設定データが空白であった場合、当該ブロックはスキップされます。
ワークフローに流れる案件データを用いてHTMLメール用のテキストを組み立てます。概要文・画像・主文・リンクボタン・副文のブロックにて構成されます。なお、設定データが空白であった場合、当該ブロックはスキップされます。

Appendix

  • 生成されるHTML コードは、全てのメーラで正常に表示されることが保証されている訳ではありません。
  • HTML コードは、640px 幅の table タグがベースとなって組み立てられます。
    • 背景色は白、文字色は黒が基本となります。
    • メール内に再掲されるサブジェクト(タイトル)は、MagazineColor で指定した色で表示されます。
    • メール内に表示されるリンクボタンは、MagazineColor で指定した色で表示されます。
  • Magazine Logo 画像は、そのままのサイズで表示されます。
    • 幅が 640px を超える画像は縮小表示されます。
    • 高さが 20px から 50px が目安となります。
    • Magazine Logo 画像の URL は、受信者がアクセスできるURLでなければなりません。

See also

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む